4 * ***** BEGIN LGPL LICENSE BLOCK *****
6 * Copyright 2009 Jörg Hermann Müller
8 * This file is part of AudaSpace.
10 * AudaSpace is free software: you can redistribute it and/or modify
11 * it under the terms of the GNU Lesser General Public License as published by
12 * the Free Software Foundation, either version 3 of the License, or
13 * (at your option) any later version.
15 * AudaSpace is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public License
21 * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
23 * ***** END LGPL LICENSE BLOCK *****
26 #include "AUD_OpenALDevice.h"
27 #include "AUD_IFactory.h"
28 #include "AUD_IReader.h"
29 #include "AUD_ConverterReader.h"
40 #define AUD_OPENAL_CYCLE_BUFFERS 3
42 /// Saves the data for playback.
43 struct AUD_OpenALHandle : AUD_Handle
45 /// Whether it's a buffered or a streamed source.
48 /// The reader source.
51 /// Whether to keep the source if end of it is reached.
54 /// OpenAL sample format.
61 ALuint buffers[AUD_OPENAL_CYCLE_BUFFERS];
63 /// The first buffer to be read next.
66 /// Whether the stream doesn't return any more data.
70 struct AUD_OpenALBufferedFactory
73 AUD_IFactory* factory;
75 /// The OpenAL buffer.
79 typedef std::list<AUD_OpenALHandle*>::iterator AUD_HandleIterator;
80 typedef std::list<AUD_OpenALBufferedFactory*>::iterator AUD_BFIterator;
82 /******************************************************************************/
83 /**************************** Threading Code **********************************/
84 /******************************************************************************/
86 void* AUD_openalRunThread(void* device)
88 AUD_OpenALDevice* dev = (AUD_OpenALDevice*)device;
93 void AUD_OpenALDevice::start()
100 pthread_attr_init(&attr);
101 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
103 pthread_create(&m_thread, &attr, AUD_openalRunThread, this);
105 pthread_attr_destroy(&attr);
113 void AUD_OpenALDevice::updateStreams()
115 AUD_OpenALHandle* sound;
121 AUD_DeviceSpecs specs = m_specs;
127 alcSuspendContext(m_context);
131 AUD_HandleIterator it = m_playingSounds->begin();
132 while(it != m_playingSounds->end())
135 // increment the iterator to make sure it's valid,
136 // in case the sound gets deleted after stopping
139 // is it a streamed sound?
140 if(!sound->isBuffered)
142 // check for buffer refilling
143 alGetSourcei(sound->source, AL_BUFFERS_PROCESSED, &info);
147 specs.specs = sound->reader->getSpecs();
149 // for all empty buffers
152 // if there's still data to play back
156 length = m_buffersize;
157 sound->reader->read(length, buffer);
162 sound->data_end = true;
167 alSourceUnqueueBuffers(sound->source, 1,
168 &sound->buffers[sound->current]);
170 if((err = alGetError()) != AL_NO_ERROR)
172 sound->data_end = true;
176 // fill with new data
177 alBufferData(sound->buffers[sound->current],
180 AUD_DEVICE_SAMPLE_SIZE(specs),
183 if((err = alGetError()) != AL_NO_ERROR)
185 sound->data_end = true;
190 alSourceQueueBuffers(sound->source, 1,
191 &sound->buffers[sound->current]);
192 if(alGetError() != AL_NO_ERROR)
194 sound->data_end = true;
198 sound->current = (sound->current+1) %
199 AUD_OPENAL_CYCLE_BUFFERS;
207 // check if the sound has been stopped
208 alGetSourcei(sound->source, AL_SOURCE_STATE, &info);
210 if(info != AL_PLAYING)
212 // if it really stopped
224 alSourcePlay(sound->source);
229 alcProcessContext(m_context);
232 if(m_playingSounds->empty())
249 /******************************************************************************/
250 /**************************** IDevice Code ************************************/
251 /******************************************************************************/
253 bool AUD_OpenALDevice::isValid(AUD_Handle* handle)
255 for(AUD_HandleIterator i = m_playingSounds->begin();
256 i != m_playingSounds->end(); i++)
259 for(AUD_HandleIterator i = m_pausedSounds->begin();
260 i != m_pausedSounds->end(); i++)
266 AUD_OpenALDevice::AUD_OpenALDevice(AUD_DeviceSpecs specs, int buffersize)
268 // cannot determine how many channels or which format OpenAL uses, but
269 // it at least is able to play 16 bit stereo audio
270 specs.channels = AUD_CHANNELS_STEREO;
271 specs.format = AUD_FORMAT_S16;
274 if(alcIsExtensionPresent(NULL, "ALC_ENUMERATION_EXT") == AL_TRUE)
276 ALCchar* devices = const_cast<ALCchar*>(alcGetString(NULL, ALC_DEVICE_SPECIFIER));
277 printf("OpenAL devices (standard is: %s):\n", alcGetString(NULL, ALC_DEFAULT_DEVICE_SPECIFIER));
281 printf("%s\n", devices);
282 devices += strlen(devices) + 1;
287 m_device = alcOpenDevice(NULL);
290 AUD_THROW(AUD_ERROR_OPENAL);
292 // at least try to set the frequency
293 ALCint attribs[] = { ALC_FREQUENCY, specs.rate, 0 };
294 ALCint* attributes = attribs;
295 if(specs.rate == AUD_RATE_INVALID)
298 m_context = alcCreateContext(m_device, attributes);
299 alcMakeContextCurrent(m_context);
301 alcGetIntegerv(m_device, ALC_FREQUENCY, 1, (ALCint*)&specs.rate);
303 // check for specific formats and channel counts to be played back
304 if(alIsExtensionPresent("AL_EXT_FLOAT32") == AL_TRUE)
305 specs.format = AUD_FORMAT_FLOAT32;
307 m_useMC = alIsExtensionPresent("AL_EXT_MCFORMATS") == AL_TRUE;
312 m_buffersize = buffersize;
315 m_playingSounds = new std::list<AUD_OpenALHandle*>();
316 m_pausedSounds = new std::list<AUD_OpenALHandle*>();
317 m_bufferedFactories = new std::list<AUD_OpenALBufferedFactory*>();
319 pthread_mutexattr_t attr;
320 pthread_mutexattr_init(&attr);
321 pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
323 pthread_mutex_init(&m_mutex, &attr);
325 pthread_mutexattr_destroy(&attr);
328 AUD_OpenALDevice::~AUD_OpenALDevice()
330 AUD_OpenALHandle* sound;
333 alcSuspendContext(m_context);
335 // delete all playing sounds
336 while(!m_playingSounds->empty())
338 sound = *(m_playingSounds->begin());
339 alDeleteSources(1, &sound->source);
340 if(!sound->isBuffered)
342 delete sound->reader;
343 alDeleteBuffers(AUD_OPENAL_CYCLE_BUFFERS, sound->buffers);
346 m_playingSounds->erase(m_playingSounds->begin());
349 // delete all paused sounds
350 while(!m_pausedSounds->empty())
352 sound = *(m_pausedSounds->begin());
353 alDeleteSources(1, &sound->source);
354 if(!sound->isBuffered)
356 delete sound->reader;
357 alDeleteBuffers(AUD_OPENAL_CYCLE_BUFFERS, sound->buffers);
360 m_pausedSounds->erase(m_pausedSounds->begin());
363 // delete all buffered factories
364 while(!m_bufferedFactories->empty())
366 alDeleteBuffers(1, &(*(m_bufferedFactories->begin()))->buffer);
367 delete *m_bufferedFactories->begin();
368 m_bufferedFactories->erase(m_bufferedFactories->begin());
371 alcProcessContext(m_context);
373 // wait for the thread to stop
377 pthread_join(m_thread, NULL);
382 delete m_playingSounds;
383 delete m_pausedSounds;
384 delete m_bufferedFactories;
387 alcMakeContextCurrent(NULL);
388 alcDestroyContext(m_context);
389 alcCloseDevice(m_device);
391 pthread_mutex_destroy(&m_mutex);
394 AUD_DeviceSpecs AUD_OpenALDevice::getSpecs() const
399 bool AUD_OpenALDevice::getFormat(ALenum &format, AUD_Specs specs)
404 switch(m_specs.format)
407 switch(specs.channels)
409 case AUD_CHANNELS_MONO:
410 format = AL_FORMAT_MONO16;
412 case AUD_CHANNELS_STEREO:
413 format = AL_FORMAT_STEREO16;
415 case AUD_CHANNELS_SURROUND4:
418 format = alGetEnumValue("AL_FORMAT_QUAD16");
421 case AUD_CHANNELS_SURROUND51:
424 format = alGetEnumValue("AL_FORMAT_51CHN16");
427 case AUD_CHANNELS_SURROUND61:
430 format = alGetEnumValue("AL_FORMAT_61CHN16");
433 case AUD_CHANNELS_SURROUND71:
436 format = alGetEnumValue("AL_FORMAT_71CHN16");
443 case AUD_FORMAT_FLOAT32:
444 switch(specs.channels)
446 case AUD_CHANNELS_MONO:
447 format = alGetEnumValue("AL_FORMAT_MONO_FLOAT32");
449 case AUD_CHANNELS_STEREO:
450 format = alGetEnumValue("AL_FORMAT_STEREO_FLOAT32");
452 case AUD_CHANNELS_SURROUND4:
455 format = alGetEnumValue("AL_FORMAT_QUAD32");
458 case AUD_CHANNELS_SURROUND51:
461 format = alGetEnumValue("AL_FORMAT_51CHN32");
464 case AUD_CHANNELS_SURROUND61:
467 format = alGetEnumValue("AL_FORMAT_61CHN32");
470 case AUD_CHANNELS_SURROUND71:
473 format = alGetEnumValue("AL_FORMAT_71CHN32");
490 AUD_Handle* AUD_OpenALDevice::play(AUD_IFactory* factory, bool keep)
494 AUD_OpenALHandle* sound = NULL;
498 // check if it is a buffered factory
499 for(AUD_BFIterator i = m_bufferedFactories->begin();
500 i != m_bufferedFactories->end(); i++)
502 if((*i)->factory == factory)
505 sound = new AUD_OpenALHandle;
508 sound->isBuffered = true;
509 sound->data_end = true;
511 alcSuspendContext(m_context);
513 // OpenAL playback code
516 alGenSources(1, &sound->source);
517 if(alGetError() != AL_NO_ERROR)
518 AUD_THROW(AUD_ERROR_OPENAL);
522 alSourcei(sound->source, AL_BUFFER, (*i)->buffer);
523 if(alGetError() != AL_NO_ERROR)
524 AUD_THROW(AUD_ERROR_OPENAL);
526 catch(AUD_Exception&)
528 alDeleteSources(1, &sound->source);
532 catch(AUD_Exception&)
535 alcProcessContext(m_context);
540 m_playingSounds->push_back(sound);
542 alSourcei(sound->source, AL_SOURCE_RELATIVE, 1);
545 alcProcessContext(m_context);
549 catch(AUD_Exception&)
560 AUD_IReader* reader = factory->createReader();
563 AUD_THROW(AUD_ERROR_READER);
565 AUD_DeviceSpecs specs = m_specs;
566 specs.specs = reader->getSpecs();
569 bool valid = specs.channels != AUD_CHANNELS_INVALID;
571 if(m_specs.format != AUD_FORMAT_FLOAT32)
572 reader = new AUD_ConverterReader(reader, m_specs);
575 sound = new AUD_OpenALHandle;
577 sound->reader = reader;
579 sound->isBuffered = false;
580 sound->data_end = false;
582 valid &= getFormat(sound->format, specs.specs);
592 alcSuspendContext(m_context);
594 // OpenAL playback code
597 alGenBuffers(AUD_OPENAL_CYCLE_BUFFERS, sound->buffers);
598 if(alGetError() != AL_NO_ERROR)
599 AUD_THROW(AUD_ERROR_OPENAL);
606 for(int i = 0; i < AUD_OPENAL_CYCLE_BUFFERS; i++)
608 length = m_buffersize;
609 reader->read(length, buf);
610 alBufferData(sound->buffers[i], sound->format, buf,
611 length * AUD_DEVICE_SAMPLE_SIZE(specs),
613 if(alGetError() != AL_NO_ERROR)
614 AUD_THROW(AUD_ERROR_OPENAL);
617 alGenSources(1, &sound->source);
618 if(alGetError() != AL_NO_ERROR)
619 AUD_THROW(AUD_ERROR_OPENAL);
623 alSourceQueueBuffers(sound->source, AUD_OPENAL_CYCLE_BUFFERS,
625 if(alGetError() != AL_NO_ERROR)
626 AUD_THROW(AUD_ERROR_OPENAL);
628 catch(AUD_Exception&)
630 alDeleteSources(1, &sound->source);
634 catch(AUD_Exception&)
636 alDeleteBuffers(AUD_OPENAL_CYCLE_BUFFERS, sound->buffers);
640 catch(AUD_Exception&)
644 alcProcessContext(m_context);
650 m_playingSounds->push_back(sound);
651 alSourcei(sound->source, AL_SOURCE_RELATIVE, 1);
655 alcProcessContext(m_context);
661 bool AUD_OpenALDevice::pause(AUD_Handle* handle)
667 // only songs that are played can be paused
668 for(AUD_HandleIterator i = m_playingSounds->begin();
669 i != m_playingSounds->end(); i++)
673 m_pausedSounds->push_back(*i);
674 alSourcePause((*i)->source);
675 m_playingSounds->erase(i);
686 bool AUD_OpenALDevice::resume(AUD_Handle* handle)
692 // only songs that are paused can be resumed
693 for(AUD_HandleIterator i = m_pausedSounds->begin();
694 i != m_pausedSounds->end(); i++)
698 m_playingSounds->push_back(*i);
700 m_pausedSounds->erase(i);
711 bool AUD_OpenALDevice::stop(AUD_Handle* handle)
713 AUD_OpenALHandle* sound;
719 for(AUD_HandleIterator i = m_playingSounds->begin();
720 i != m_playingSounds->end(); i++)
725 alDeleteSources(1, &sound->source);
726 if(!sound->isBuffered)
728 delete sound->reader;
729 alDeleteBuffers(AUD_OPENAL_CYCLE_BUFFERS, sound->buffers);
732 m_playingSounds->erase(i);
739 for(AUD_HandleIterator i = m_pausedSounds->begin();
740 i != m_pausedSounds->end(); i++)
745 alDeleteSources(1, &sound->source);
746 if(!sound->isBuffered)
748 delete sound->reader;
749 alDeleteBuffers(AUD_OPENAL_CYCLE_BUFFERS, sound->buffers);
752 m_pausedSounds->erase(i);
764 bool AUD_OpenALDevice::getKeep(AUD_Handle* handle)
771 result = ((AUD_OpenALHandle*)handle)->keep;
778 bool AUD_OpenALDevice::setKeep(AUD_Handle* handle, bool keep)
786 ((AUD_OpenALHandle*)handle)->keep = keep;
795 bool AUD_OpenALDevice::seek(AUD_Handle* handle, float position)
803 AUD_OpenALHandle* alhandle = (AUD_OpenALHandle*)handle;
804 if(alhandle->isBuffered)
805 alSourcef(alhandle->source, AL_SEC_OFFSET, position);
808 alhandle->reader->seek((int)(position *
809 alhandle->reader->getSpecs().rate));
810 alhandle->data_end = false;
814 alGetSourcei(alhandle->source, AL_SOURCE_STATE, &info);
816 if(info != AL_PLAYING)
818 if(info == AL_PAUSED)
819 alSourceStop(alhandle->source);
821 alSourcei(alhandle->source, AL_BUFFER, 0);
822 alhandle->current = 0;
825 if((err = alGetError()) == AL_NO_ERROR)
829 AUD_DeviceSpecs specs = m_specs;
830 specs.specs = alhandle->reader->getSpecs();
832 for(int i = 0; i < AUD_OPENAL_CYCLE_BUFFERS; i++)
834 length = m_buffersize;
835 alhandle->reader->read(length, buf);
836 alBufferData(alhandle->buffers[i], alhandle->format,
838 length * AUD_DEVICE_SAMPLE_SIZE(specs),
841 if(alGetError() != AL_NO_ERROR)
845 alSourceQueueBuffers(alhandle->source,
846 AUD_OPENAL_CYCLE_BUFFERS,
850 alSourceRewind(alhandle->source);
860 float AUD_OpenALDevice::getPosition(AUD_Handle* handle)
862 float position = 0.0f;
868 AUD_OpenALHandle* h = (AUD_OpenALHandle*)handle;
869 alGetSourcef(h->source, AL_SEC_OFFSET, &position);
872 AUD_Specs specs = h->reader->getSpecs();
873 position += (h->reader->getPosition() - m_buffersize *
874 AUD_OPENAL_CYCLE_BUFFERS) /
883 AUD_Status AUD_OpenALDevice::getStatus(AUD_Handle* handle)
885 AUD_Status status = AUD_STATUS_INVALID;
889 for(AUD_HandleIterator i = m_playingSounds->begin();
890 i != m_playingSounds->end(); i++)
894 status = AUD_STATUS_PLAYING;
898 if(status == AUD_STATUS_INVALID)
900 for(AUD_HandleIterator i = m_pausedSounds->begin();
901 i != m_pausedSounds->end(); i++)
905 status = AUD_STATUS_PAUSED;
916 void AUD_OpenALDevice::lock()
918 pthread_mutex_lock(&m_mutex);
921 void AUD_OpenALDevice::unlock()
923 pthread_mutex_unlock(&m_mutex);
926 float AUD_OpenALDevice::getVolume() const
929 alGetListenerf(AL_GAIN, &result);
933 void AUD_OpenALDevice::setVolume(float volume)
935 alListenerf(AL_GAIN, volume);
938 float AUD_OpenALDevice::getVolume(AUD_Handle* handle)
941 float result = std::numeric_limits<float>::quiet_NaN();
943 alGetSourcef(((AUD_OpenALHandle*)handle)->source,AL_GAIN, &result);
948 bool AUD_OpenALDevice::setVolume(AUD_Handle* handle, float volume)
951 bool result = isValid(handle);
953 alSourcef(((AUD_OpenALHandle*)handle)->source, AL_GAIN, volume);
958 float AUD_OpenALDevice::getPitch(AUD_Handle* handle)
961 float result = std::numeric_limits<float>::quiet_NaN();
963 alGetSourcef(((AUD_OpenALHandle*)handle)->source,AL_PITCH, &result);
968 bool AUD_OpenALDevice::setPitch(AUD_Handle* handle, float pitch)
971 bool result = isValid(handle);
973 alSourcef(((AUD_OpenALHandle*)handle)->source, AL_PITCH, pitch);
978 /* AUD_XXX Temorary disabled
980 bool AUD_OpenALDevice::bufferFactory(void *value)
983 AUD_IFactory* factory = (AUD_IFactory*) value;
985 // load the factory into an OpenAL buffer
988 // check if the factory is already buffered
990 for(AUD_BFIterator i = m_bufferedFactories->begin();
991 i != m_bufferedFactories->end(); i++)
993 if((*i)->factory == factory)
1003 AUD_IReader* reader = factory->createReader();
1008 AUD_DeviceSpecs specs = m_specs;
1009 specs.specs = reader->getSpecs();
1011 if(m_specs.format != AUD_FORMAT_FLOAT32)
1012 reader = new AUD_ConverterReader(reader, m_specs);
1016 if(!getFormat(format, specs.specs))
1022 // load into a buffer
1024 alcSuspendContext(m_context);
1026 AUD_OpenALBufferedFactory* bf = new AUD_OpenALBufferedFactory;
1027 bf->factory = factory;
1031 alGenBuffers(1, &bf->buffer);
1032 if(alGetError() != AL_NO_ERROR)
1033 AUD_THROW(AUD_ERROR_OPENAL);
1038 int length = reader->getLength();
1040 reader->read(length, buf);
1041 alBufferData(bf->buffer, format, buf,
1042 length * AUD_DEVICE_SAMPLE_SIZE(specs),
1044 if(alGetError() != AL_NO_ERROR)
1045 AUD_THROW(AUD_ERROR_OPENAL);
1047 catch(AUD_Exception&)
1049 alDeleteBuffers(1, &bf->buffer);
1053 catch(AUD_Exception&)
1057 alcProcessContext(m_context);
1062 m_bufferedFactories->push_back(bf);
1064 alcProcessContext(m_context);
1069 // stop all playing and paused buffered sources
1071 alcSuspendContext(m_context);
1073 AUD_OpenALHandle* sound;
1074 AUD_HandleIterator it = m_playingSounds->begin();
1075 while(it != m_playingSounds->end())
1080 if(sound->isBuffered)
1083 alcProcessContext(m_context);
1085 while(!m_bufferedFactories->empty())
1088 &(*(m_bufferedFactories->begin()))->buffer);
1089 delete *m_bufferedFactories->begin();
1090 m_bufferedFactories->erase(m_bufferedFactories->begin());
1098 /******************************************************************************/
1099 /**************************** 3D Device Code **********************************/
1100 /******************************************************************************/
1102 AUD_Vector3 AUD_OpenALDevice::getListenerLocation() const
1105 alGetListenerfv(AL_POSITION, p);
1106 return AUD_Vector3(p[0], p[1], p[2]);
1109 void AUD_OpenALDevice::setListenerLocation(const AUD_Vector3& location)
1111 alListenerfv(AL_POSITION, (ALfloat*)location.get());
1114 AUD_Vector3 AUD_OpenALDevice::getListenerVelocity() const
1117 alGetListenerfv(AL_VELOCITY, v);
1118 return AUD_Vector3(v[0], v[1], v[2]);
1121 void AUD_OpenALDevice::setListenerVelocity(const AUD_Vector3& velocity)
1123 alListenerfv(AL_VELOCITY, (ALfloat*)velocity.get());
1126 AUD_Quaternion AUD_OpenALDevice::getListenerOrientation() const
1128 // AUD_XXX not implemented yet
1129 return AUD_Quaternion(0, 0, 0, 0);
1132 void AUD_OpenALDevice::setListenerOrientation(const AUD_Quaternion& orientation)
1134 ALfloat direction[6];
1135 direction[0] = -2 * (orientation.w() * orientation.y() +
1136 orientation.x() * orientation.z());
1137 direction[1] = 2 * (orientation.x() * orientation.w() -
1138 orientation.z() * orientation.y());
1139 direction[2] = 2 * (orientation.x() * orientation.x() +
1140 orientation.y() * orientation.y()) - 1;
1141 direction[3] = 2 * (orientation.x() * orientation.y() -
1142 orientation.w() * orientation.z());
1143 direction[4] = 1 - 2 * (orientation.x() * orientation.x() +
1144 orientation.z() * orientation.z());
1145 direction[5] = 2 * (orientation.w() * orientation.x() +
1146 orientation.y() * orientation.z());
1147 alListenerfv(AL_ORIENTATION, direction);
1150 float AUD_OpenALDevice::getSpeedOfSound() const
1152 return alGetFloat(AL_SPEED_OF_SOUND);
1155 void AUD_OpenALDevice::setSpeedOfSound(float speed)
1157 alSpeedOfSound(speed);
1160 float AUD_OpenALDevice::getDopplerFactor() const
1162 return alGetFloat(AL_DOPPLER_FACTOR);
1165 void AUD_OpenALDevice::setDopplerFactor(float factor)
1167 alDopplerFactor(factor);
1170 AUD_DistanceModel AUD_OpenALDevice::getDistanceModel() const
1172 switch(alGetInteger(AL_DISTANCE_MODEL))
1174 case AL_INVERSE_DISTANCE:
1175 return AUD_DISTANCE_MODEL_INVERSE;
1176 case AL_INVERSE_DISTANCE_CLAMPED:
1177 return AUD_DISTANCE_MODEL_INVERSE_CLAMPED;
1178 case AL_LINEAR_DISTANCE:
1179 return AUD_DISTANCE_MODEL_LINEAR;
1180 case AL_LINEAR_DISTANCE_CLAMPED:
1181 return AUD_DISTANCE_MODEL_LINEAR_CLAMPED;
1182 case AL_EXPONENT_DISTANCE:
1183 return AUD_DISTANCE_MODEL_EXPONENT;
1184 case AL_EXPONENT_DISTANCE_CLAMPED:
1185 return AUD_DISTANCE_MODEL_EXPONENT_CLAMPED;
1187 return AUD_DISTANCE_MODEL_INVALID;
1191 void AUD_OpenALDevice::setDistanceModel(AUD_DistanceModel model)
1195 case AUD_DISTANCE_MODEL_INVERSE:
1196 alDistanceModel(AL_INVERSE_DISTANCE);
1198 case AUD_DISTANCE_MODEL_INVERSE_CLAMPED:
1199 alDistanceModel(AL_INVERSE_DISTANCE_CLAMPED);
1201 case AUD_DISTANCE_MODEL_LINEAR:
1202 alDistanceModel(AL_LINEAR_DISTANCE);
1204 case AUD_DISTANCE_MODEL_LINEAR_CLAMPED:
1205 alDistanceModel(AL_LINEAR_DISTANCE_CLAMPED);
1207 case AUD_DISTANCE_MODEL_EXPONENT:
1208 alDistanceModel(AL_EXPONENT_DISTANCE);
1210 case AUD_DISTANCE_MODEL_EXPONENT_CLAMPED:
1211 alDistanceModel(AL_EXPONENT_DISTANCE_CLAMPED);
1214 alDistanceModel(AL_NONE);
1218 AUD_Vector3 AUD_OpenALDevice::getSourceLocation(AUD_Handle* handle)
1220 AUD_Vector3 result = AUD_Vector3(0, 0, 0);
1226 alGetSourcefv(((AUD_OpenALHandle*)handle)->source, AL_POSITION, p);
1227 result = AUD_Vector3(p[0], p[1], p[2]);
1234 bool AUD_OpenALDevice::setSourceLocation(AUD_Handle* handle, const AUD_Vector3& location)
1237 bool result = isValid(handle);
1240 alSourcefv(((AUD_OpenALHandle*)handle)->source, AL_POSITION,
1241 (ALfloat*)location.get());
1247 AUD_Vector3 AUD_OpenALDevice::getSourceVelocity(AUD_Handle* handle)
1249 AUD_Vector3 result = AUD_Vector3(0, 0, 0);
1255 alGetSourcefv(((AUD_OpenALHandle*)handle)->source, AL_VELOCITY, v);
1256 result = AUD_Vector3(v[0], v[1], v[2]);
1263 bool AUD_OpenALDevice::setSourceVelocity(AUD_Handle* handle, const AUD_Vector3& velocity)
1266 bool result = isValid(handle);
1269 alSourcefv(((AUD_OpenALHandle*)handle)->source, AL_VELOCITY,
1270 (ALfloat*)velocity.get());
1276 AUD_Quaternion AUD_OpenALDevice::getSourceOrientation(AUD_Handle* handle)
1278 // AUD_XXX not implemented yet
1279 return AUD_Quaternion(0, 0, 0, 0);
1282 bool AUD_OpenALDevice::setSourceOrientation(AUD_Handle* handle, const AUD_Quaternion& orientation)
1285 bool result = isValid(handle);
1289 ALfloat direction[3];
1290 direction[0] = -2 * (orientation.w() * orientation.y() +
1291 orientation.x() * orientation.z());
1292 direction[1] = 2 * (orientation.x() * orientation.w() -
1293 orientation.z() * orientation.y());
1294 direction[2] = 2 * (orientation.x() * orientation.x() +
1295 orientation.y() * orientation.y()) - 1;
1296 alSourcefv(((AUD_OpenALHandle*)handle)->source, AL_DIRECTION,
1304 bool AUD_OpenALDevice::isRelative(AUD_Handle* handle)
1306 int result = std::numeric_limits<float>::quiet_NaN();;
1311 alGetSourcei(((AUD_OpenALHandle*)handle)->source, AL_SOURCE_RELATIVE,
1318 bool AUD_OpenALDevice::setRelative(AUD_Handle* handle, bool relative)
1321 bool result = isValid(handle);
1324 alSourcei(((AUD_OpenALHandle*)handle)->source, AL_SOURCE_RELATIVE,
1331 float AUD_OpenALDevice::getVolumeMaximum(AUD_Handle* handle)
1333 float result = std::numeric_limits<float>::quiet_NaN();;
1338 alGetSourcef(((AUD_OpenALHandle*)handle)->source, AL_MAX_GAIN,
1345 bool AUD_OpenALDevice::setVolumeMaximum(AUD_Handle* handle, float volume)
1348 bool result = isValid(handle);
1352 alSourcef(((AUD_OpenALHandle*)handle)->source, AL_MAX_GAIN,
1359 float AUD_OpenALDevice::getVolumeMinimum(AUD_Handle* handle)
1361 float result = std::numeric_limits<float>::quiet_NaN();;
1366 alGetSourcef(((AUD_OpenALHandle*)handle)->source, AL_MIN_GAIN,
1373 bool AUD_OpenALDevice::setVolumeMinimum(AUD_Handle* handle, float volume)
1376 bool result = isValid(handle);
1379 alSourcef(((AUD_OpenALHandle*)handle)->source, AL_MIN_GAIN,
1386 float AUD_OpenALDevice::getDistanceMaximum(AUD_Handle* handle)
1388 float result = std::numeric_limits<float>::quiet_NaN();;
1393 alGetSourcef(((AUD_OpenALHandle*)handle)->source, AL_MAX_DISTANCE,
1400 bool AUD_OpenALDevice::setDistanceMaximum(AUD_Handle* handle, float distance)
1403 bool result = isValid(handle);
1406 alSourcef(((AUD_OpenALHandle*)handle)->source, AL_MAX_DISTANCE,
1413 float AUD_OpenALDevice::getDistanceReference(AUD_Handle* handle)
1415 float result = std::numeric_limits<float>::quiet_NaN();;
1420 alGetSourcef(((AUD_OpenALHandle*)handle)->source, AL_REFERENCE_DISTANCE,
1427 bool AUD_OpenALDevice::setDistanceReference(AUD_Handle* handle, float distance)
1430 bool result = isValid(handle);
1433 alSourcef(((AUD_OpenALHandle*)handle)->source, AL_REFERENCE_DISTANCE,
1440 float AUD_OpenALDevice::getAttenuation(AUD_Handle* handle)
1442 float result = std::numeric_limits<float>::quiet_NaN();;
1447 alGetSourcef(((AUD_OpenALHandle*)handle)->source, AL_ROLLOFF_FACTOR,
1454 bool AUD_OpenALDevice::setAttenuation(AUD_Handle* handle, float factor)
1457 bool result = isValid(handle);
1460 alSourcef(((AUD_OpenALHandle*)handle)->source, AL_ROLLOFF_FACTOR,
1467 float AUD_OpenALDevice::getConeAngleOuter(AUD_Handle* handle)
1469 float result = std::numeric_limits<float>::quiet_NaN();;
1474 alGetSourcef(((AUD_OpenALHandle*)handle)->source, AL_CONE_OUTER_ANGLE,
1481 bool AUD_OpenALDevice::setConeAngleOuter(AUD_Handle* handle, float angle)
1484 bool result = isValid(handle);
1487 alSourcef(((AUD_OpenALHandle*)handle)->source, AL_CONE_OUTER_ANGLE,
1494 float AUD_OpenALDevice::getConeAngleInner(AUD_Handle* handle)
1496 float result = std::numeric_limits<float>::quiet_NaN();;
1501 alGetSourcef(((AUD_OpenALHandle*)handle)->source, AL_CONE_INNER_ANGLE,
1508 bool AUD_OpenALDevice::setConeAngleInner(AUD_Handle* handle, float angle)
1511 bool result = isValid(handle);
1514 alSourcef(((AUD_OpenALHandle*)handle)->source, AL_CONE_INNER_ANGLE,
1521 float AUD_OpenALDevice::getConeVolumeOuter(AUD_Handle* handle)
1523 float result = std::numeric_limits<float>::quiet_NaN();;
1528 alGetSourcef(((AUD_OpenALHandle*)handle)->source, AL_CONE_OUTER_GAIN,
1535 bool AUD_OpenALDevice::setConeVolumeOuter(AUD_Handle* handle, float volume)
1538 bool result = isValid(handle);
1541 alSourcef(((AUD_OpenALHandle*)handle)->source, AL_CONE_OUTER_GAIN,