28 #ifndef ALC_DEFAULT_ALL_DEVICES_SPECIFIER
29 #define ALC_DEFAULT_ALL_DEVICES_SPECIFIER 0x1012
32 #ifndef ALC_ALL_DEVICES_SPECIFIER
33 #define ALC_ALL_DEVICES_SPECIFIER 0x1013
41 ReMutex OpenALAudioManager::_lock;
42 int OpenALAudioManager::_active_managers = 0;
43 bool OpenALAudioManager::_openal_active =
false;
44 ALCdevice* OpenALAudioManager::_device =
nullptr;
45 ALCcontext* OpenALAudioManager::_context =
nullptr;
56 void al_audio_errcheck(
const char *context) {
57 ALenum result = alGetError();
58 if (result != AL_NO_ERROR) {
59 audio_error(context <<
": " << alGetString(result) );
63 void alc_audio_errcheck(
const char *context,ALCdevice* device) {
64 ALCenum result = alcGetError(device);
65 if (result != ALC_NO_ERROR) {
66 audio_error(context <<
": " << alcGetString(device,result) );
74 audio_debug(
"Create_OpenALAudioManager()");
83 OpenALAudioManager() {
85 if (_managers ==
nullptr) {
86 _managers =
new Managers;
87 _al_sources =
new SourceCache;
90 _managers->insert(
this);
92 _cleanup_required =
true;
93 _active = audio_active;
94 _volume = audio_volume;
97 _cache_limit = audio_cache_limit;
99 _concurrent_sound_limit = 0;
103 _distance_factor = 1;
104 _drop_off_factor = 1;
123 if (_active_managers == 0 || !_openal_active) {
125 string dev_name = select_audio_device();
127 if (!dev_name.empty()) {
129 audio_cat.info() <<
"Using OpenAL device " << dev_name <<
"\n";
130 _device = alcOpenDevice(dev_name.c_str());
132 if (_device ==
nullptr) {
134 <<
"Couldn't open OpenAL device \"" << dev_name <<
"\", falling back to default device\n";
137 audio_cat.info() <<
"Using default OpenAL device\n";
140 if (_device ==
nullptr) {
142 _device = alcOpenDevice(
nullptr);
144 if (_device ==
nullptr && dev_name !=
"OpenAL Soft") {
146 _device = alcOpenDevice(
"OpenAL Soft");
148 if (_device ==
nullptr) {
150 <<
"Couldn't open default OpenAL device\n";
155 if (_device !=
nullptr) {
157 alcGetError(_device);
158 _context = alcCreateContext(_device,
nullptr);
159 alc_audio_errcheck(
"alcCreateContext(_device, NULL)", _device);
160 if (_context !=
nullptr) {
161 _openal_active =
true;
169 nassertv(_active_managers>0);
171 if (!_device || !_context) {
172 audio_error(
"OpenALAudioManager: No open device or context");
175 alcGetError(_device);
176 alcMakeContextCurrent(_context);
177 alc_audio_errcheck(
"alcMakeContextCurrent(_context)", _device);
184 if (audio_cat.is_debug()) {
186 <<
"ALC_DEVICE_SPECIFIER:" << alcGetString(_device, ALC_DEVICE_SPECIFIER) << endl;
190 if (audio_cat.is_debug()) {
191 audio_cat.debug() <<
"AL_RENDERER:" << alGetString(AL_RENDERER) << endl;
192 audio_cat.debug() <<
"AL_VENDOR:" << alGetString(AL_VENDOR) << endl;
193 audio_cat.debug() <<
"AL_VERSION:" << alGetString(AL_VERSION) << endl;
201 ~OpenALAudioManager() {
203 nassertv(_managers !=
nullptr);
204 Managers::iterator mi = _managers->find(
this);
205 nassertv(mi != _managers->end());
206 _managers->erase(mi);
219 if (_managers !=
nullptr) {
220 Managers::iterator mi;
221 for (mi = _managers->begin(); mi != _managers->end(); ++mi) {
226 nassertv(_active_managers == 0);
243 string OpenALAudioManager::
244 select_audio_device() {
245 string selected_device = openal_device;
247 const char *devices =
nullptr;
250 if (alcIsExtensionPresent(
nullptr,
"ALC_ENUMERATE_ALL_EXT") == AL_TRUE) {
251 string default_device = alcGetString(
nullptr, ALC_DEFAULT_ALL_DEVICES_SPECIFIER);
252 devices = (
const char *)alcGetString(
nullptr, ALC_ALL_DEVICES_SPECIFIER);
255 if (audio_cat.is_debug()) {
256 audio_cat.debug() <<
"All OpenAL devices:\n";
260 string device(devices);
261 devices += device.size() + 1;
263 if (audio_cat.is_debug()) {
264 if (device == selected_device) {
265 audio_cat.debug() <<
" " << device <<
" [selected]\n";
266 }
else if (device == default_device) {
267 audio_cat.debug() <<
" " << device <<
" [default]\n";
269 audio_cat.debug() <<
" " << device <<
"\n";
275 audio_cat.debug() <<
"ALC_ENUMERATE_ALL_EXT not supported\n";
280 if (alcIsExtensionPresent(
nullptr,
"ALC_ENUMERATION_EXT") == AL_TRUE) {
281 string default_device = alcGetString(
nullptr, ALC_DEFAULT_DEVICE_SPECIFIER);
282 devices = (
const char *)alcGetString(
nullptr, ALC_DEVICE_SPECIFIER);
285 if (audio_cat.is_debug()) {
286 audio_cat.debug() <<
"OpenAL drivers:\n";
290 string device(devices);
291 devices += device.size() + 1;
293 if (selected_device.empty() && device ==
"OpenAL Soft" &&
294 default_device ==
"Generic Software") {
296 selected_device =
"OpenAL Soft";
299 if (audio_cat.is_debug()) {
300 if (device == selected_device) {
301 audio_cat.debug() <<
" " << device <<
" [selected]\n";
302 }
else if (device == default_device) {
303 audio_cat.debug() <<
" " << device <<
" [default]\n";
305 audio_cat.debug() <<
" " << device <<
"\n";
311 audio_cat.debug() <<
"ALC_ENUMERATION_EXT not supported\n";
314 return selected_device;
321 void OpenALAudioManager::
322 make_current()
const {
331 bool OpenALAudioManager::
334 int channels = source->audio_channels();
335 if ((channels != 1)&&(channels != 2)) {
336 audio_error(
"Currently, only mono and stereo are supported.");
347 bool OpenALAudioManager::
350 if (mode == SM_stream) {
354 if (source->get_source()->get_filename().empty()) {
358 if (source->
ready() != 0x40000000) {
362 if (source->length() > 3600.0) {
366 int channels = source->audio_channels();
367 int samples = (int)(source->length() * source->audio_rate());
368 int bytes = samples * channels * 2;
369 if ((mode == SM_heuristic)&&(bytes > audio_preload_threshold)) {
382 OpenALAudioManager::SoundData *OpenALAudioManager::
390 if (mode != SM_stream) {
391 SampleCache::iterator lsmi=_sample_cache.find(path);
392 if (lsmi != _sample_cache.end()) {
393 SoundData *sd = (*lsmi).second;
394 increment_client_count(sd);
399 if (mode != SM_sample) {
400 ExpirationQueue::iterator exqi;
401 for (exqi=_expiring_streams.begin(); exqi!=_expiring_streams.end(); exqi++) {
402 SoundData *sd = (SoundData*)(*exqi);
403 if (sd->_movie->get_filename() == path) {
404 increment_client_count(sd);
412 if (stream ==
nullptr) {
413 audio_error(
"Cannot open file: "<<path);
417 if (!can_use_audio(stream)) {
418 audio_error(
"File is not in usable format: "<<path);
422 SoundData *sd =
new SoundData();
423 sd->_client_count = 1;
426 sd->_rate = stream->audio_rate();
427 sd->_channels = stream->audio_channels();
428 sd->_length = stream->length();
429 audio_debug(
"Creating: " << sd->_movie->get_filename().get_basename());
430 audio_debug(
" - Rate: " << sd->_rate);
431 audio_debug(
" - Channels: " << sd->_channels);
432 audio_debug(
" - Length: " << sd->_length);
434 if (should_load_audio(stream, mode)) {
435 audio_debug(path.
get_basename() <<
": loading as sample");
439 alGenBuffers(1, &sd->_sample);
440 al_audio_errcheck(
"alGenBuffers");
441 if (sd->_sample == 0) {
442 audio_error(
"Could not create an OpenAL buffer object");
446 int channels = stream->audio_channels();
447 int samples = (int)(stream->length() * stream->audio_rate());
448 int16_t *data =
new int16_t[samples * channels];
449 stream->read_samples(samples, data);
450 alBufferData(sd->_sample,
451 (channels>1) ? AL_FORMAT_STEREO16 : AL_FORMAT_MONO16,
452 data, samples * channels * 2, stream->audio_rate());
454 int err = alGetError();
455 if (err != AL_NO_ERROR) {
456 audio_error(
"could not fill OpenAL buffer object with data");
460 _sample_cache.insert(SampleCache::value_type(path, sd));
462 audio_debug(path.
get_basename() <<
": loading as stream");
463 sd->_stream = stream;
473 get_sound(
MovieAudio *sound,
bool positional,
int mode) {
476 return get_null_sound();
484 return get_null_sound();
487 _all_sounds.insert(oas);
496 get_sound(
const Filename &file_name,
bool positional,
int mode) {
499 return get_null_sound();
507 audio_error(
"get_sound - invalid filename");
519 return get_null_sound();
522 _all_sounds.insert(oas);
540 SampleCache::iterator sci = _sample_cache.find(path);
541 if (sci == _sample_cache.end()) {
542 sci = _sample_cache.find(file_name);
544 if (sci != _sample_cache.end()) {
545 SoundData *sd = (*sci).second;
546 if (sd->_client_count == 0) {
547 _expiring_samples.erase(sd->_expire);
548 _sample_cache.erase(sci);
553 ExpirationQueue::iterator exqi;
554 for (exqi = _expiring_streams.begin(); exqi != _expiring_streams.end();) {
555 SoundData *sd = (SoundData *)(*exqi);
556 if (sd->_client_count == 0) {
557 if (sd->_movie->get_filename() == path ||
558 sd->_movie->get_filename() == file_name) {
559 exqi = _expiring_streams.erase(exqi);
574 discard_excess_cache(0);
584 discard_excess_cache(count);
590 unsigned int OpenALAudioManager::
591 get_cache_limit()
const {
598 void OpenALAudioManager::
601 AllSounds::iterator ai = _all_sounds.find(audioSound);
602 if (ai != _all_sounds.end()) {
603 _all_sounds.erase(ai);
613 if (_volume!=volume) {
617 AllSounds::iterator i=_all_sounds.begin();
618 for (; i!=_all_sounds.end(); ++i) {
619 (**i).set_volume((**i).get_volume());
648 if (_play_rate!=play_rate) {
649 _play_rate = play_rate;
651 AllSounds::iterator i=_all_sounds.begin();
652 for (; i!=_all_sounds.end(); ++i) {
653 (**i).set_play_rate((**i).get_play_rate());
672 if (_active!=active) {
675 AllSounds::iterator i=_all_sounds.begin();
676 for (; i!=_all_sounds.end(); ++i) {
677 (**i).set_active(_active);
685 bool OpenALAudioManager::
702 audio_3d_set_listener_attributes(PN_stdfloat px, PN_stdfloat py, PN_stdfloat pz, PN_stdfloat vx, PN_stdfloat vy, PN_stdfloat vz, PN_stdfloat fx, PN_stdfloat fy, PN_stdfloat fz, PN_stdfloat ux, PN_stdfloat uy, PN_stdfloat uz) {
714 _forward_up[2] = -fy;
718 _forward_up[5] = -uy;
724 alListenerfv(AL_POSITION,_position);
725 al_audio_errcheck(
"alListerfv(AL_POSITION)");
726 alListenerfv(AL_VELOCITY,_velocity);
727 al_audio_errcheck(
"alListerfv(AL_VELOCITY)");
728 alListenerfv(AL_ORIENTATION,_forward_up);
729 al_audio_errcheck(
"alListerfv(AL_ORIENTATION)");
736 audio_3d_get_listener_attributes(PN_stdfloat *px, PN_stdfloat *py, PN_stdfloat *pz, PN_stdfloat *vx, PN_stdfloat *vy, PN_stdfloat *vz, PN_stdfloat *fx, PN_stdfloat *fy, PN_stdfloat *fz, PN_stdfloat *ux, PN_stdfloat *uy, PN_stdfloat *uz) {
746 *fx = _forward_up[0];
747 *fy = -_forward_up[2];
748 *fz = _forward_up[1];
750 *ux = _forward_up[3];
751 *uy = -_forward_up[5];
752 *uz = _forward_up[4];
764 _distance_factor = factor;
770 if (_distance_factor>0) {
771 alSpeedOfSound(343.3*_distance_factor);
772 al_audio_errcheck(
"alSpeedOfSound()");
775 alDopplerFactor(_doppler_factor);
776 al_audio_errcheck(
"alDopplerFactor()");
778 audio_debug(
"can't set speed of sound if distance_factor <=0.0, setting doppler factor to 0.0 instead");
779 alDopplerFactor(0.0);
780 al_audio_errcheck(
"alDopplerFactor()");
783 AllSounds::iterator i=_all_sounds.begin();
784 for (; i!=_all_sounds.end(); ++i) {
785 (**i).set_3d_min_distance((**i).get_3d_min_distance());
786 (**i).set_3d_max_distance((**i).get_3d_max_distance());
795 return _distance_factor;
804 _doppler_factor = factor;
809 alDopplerFactor(_doppler_factor);
810 al_audio_errcheck(
"alDopplerFactor()");
816 PN_stdfloat OpenALAudioManager::
817 audio_3d_get_doppler_factor()
const {
818 return _doppler_factor;
827 _drop_off_factor = factor;
829 AllSounds::iterator i=_all_sounds.begin();
830 for (; i!=_all_sounds.end(); ++i) {
831 (**i).set_3d_drop_off_factor((**i).get_3d_drop_off_factor());
838 PN_stdfloat OpenALAudioManager::
839 audio_3d_get_drop_off_factor()
const {
840 return _drop_off_factor;
848 void OpenALAudioManager::
854 if (audio->_source) {
862 if (_concurrent_sound_limit) {
863 reduce_sounds_playing_to(_concurrent_sound_limit-1);
867 if (_al_sources->empty()) {
870 alGenSources(1,&source);
871 ALenum result = alGetError();
872 if (result!=AL_NO_ERROR) {
873 audio_error(
"alGenSources(): " << alGetString(result) );
876 reduce_sounds_playing_to(_sounds_playing.size()-1);
881 if (!source && !_al_sources->empty()) {
882 source = *(_al_sources->begin());
883 _al_sources->erase(source);
886 audio->_source = source;
889 _sounds_playing.insert(audio);
896 void OpenALAudioManager::
899 if (audio->_source) {
900 _al_sources->insert(audio->_source);
903 _sounds_playing.erase(audio);
909 void OpenALAudioManager::
910 set_concurrent_sound_limit(
unsigned int limit) {
912 _concurrent_sound_limit = limit;
913 reduce_sounds_playing_to(_concurrent_sound_limit);
919 unsigned int OpenALAudioManager::
920 get_concurrent_sound_limit()
const {
921 return _concurrent_sound_limit;
927 void OpenALAudioManager::
928 reduce_sounds_playing_to(
unsigned int count) {
934 int limit = _sounds_playing.size() - count;
935 while (limit-- > 0) {
936 SoundsPlaying::iterator sound = _sounds_playing.begin();
937 nassertv(sound != _sounds_playing.end());
954 reduce_sounds_playing_to(0);
968 SoundsPlaying sounds_finished;
971 SoundsPlaying::iterator i=_sounds_playing.begin();
972 for (; i!=_sounds_playing.end(); ++i) {
974 sound->pull_used_buffers();
975 sound->push_fresh_buffers();
976 sound->restart_stalled_audio();
977 sound->cache_time(rtc);
978 if ((sound->_source == 0)||
979 ((sound->_stream_queued.size() == 0)&&
980 (sound->_loops_completed >= sound->_playing_loops))) {
981 sounds_finished.insert(*i);
985 i=sounds_finished.begin();
986 for (; i!=sounds_finished.end(); ++i) {
996 void OpenALAudioManager::
999 if (!_cleanup_required) {
1005 AllSounds sounds(_all_sounds);
1006 AllSounds::iterator ai;
1007 for (ai = sounds.begin(); ai != sounds.end(); ++ai) {
1013 nassertv(_active_managers > 0);
1016 if (_active_managers == 0) {
1017 if (_openal_active) {
1021 sources =
new ALuint[_al_sources->size()];
1022 for (SourceCache::iterator si = _al_sources->begin(); si!=_al_sources->end(); ++si) {
1027 alDeleteSources(_al_sources->size(),sources);
1028 al_audio_errcheck(
"alDeleteSources()");
1030 _al_sources->clear();
1033 alcGetError(_device);
1034 alcMakeContextCurrent(
nullptr);
1035 alc_audio_errcheck(
"alcMakeContextCurrent(NULL)",_device);
1037 alcDestroyContext(_context);
1038 alc_audio_errcheck(
"alcDestroyContext(_context)",_device);
1042 audio_debug(
"Going to try to close openAL");
1043 alcCloseDevice(_device);
1046 audio_debug(
"openAL Closed");
1049 _openal_active =
false;
1052 _cleanup_required =
false;
1058 OpenALAudioManager::SoundData::
1073 OpenALAudioManager::SoundData::
1077 if (_manager->_is_valid) {
1078 _manager->make_current();
1079 _manager->delete_buffer(_sample);
1089 void OpenALAudioManager::
1090 increment_client_count(SoundData *sd) {
1092 sd->_client_count += 1;
1093 audio_debug(
"Incrementing: " << sd->_movie->get_filename().get_basename() <<
" " << sd->_client_count);
1094 if (sd->_client_count == 1) {
1096 _expiring_samples.erase(sd->_expire);
1098 _expiring_streams.erase(sd->_expire);
1108 void OpenALAudioManager::
1109 decrement_client_count(SoundData *sd) {
1111 sd->_client_count -= 1;
1112 audio_debug(
"Decrementing: " << sd->_movie->get_filename().get_basename() <<
" " << sd->_client_count);
1113 if (sd->_client_count == 0) {
1115 _expiring_samples.push_back(sd);
1116 sd->_expire = _expiring_samples.end();
1119 _expiring_streams.push_back(sd);
1120 sd->_expire = _expiring_streams.end();
1123 discard_excess_cache(_cache_limit);
1131 void OpenALAudioManager::
1132 discard_excess_cache(
int sample_limit) {
1134 int stream_limit = 5;
1136 while (((
int)_expiring_samples.size()) > sample_limit) {
1137 SoundData *sd = (SoundData*)(_expiring_samples.front());
1138 nassertv(sd->_client_count == 0);
1139 nassertv(sd->_expire == _expiring_samples.begin());
1140 _expiring_samples.pop_front();
1141 _sample_cache.erase(_sample_cache.find(sd->_movie->get_filename()));
1142 audio_debug(
"Expiring: " << sd->_movie->get_filename().get_basename());
1146 while (((
int)_expiring_streams.size()) > stream_limit) {
1147 SoundData *sd = (SoundData*)(_expiring_streams.front());
1148 nassertv(sd->_client_count == 0);
1149 nassertv(sd->_expire == _expiring_streams.begin());
1150 _expiring_streams.pop_front();
1151 audio_debug(
"Expiring: " << sd->_movie->get_filename().get_basename());
1164 void OpenALAudioManager::
1165 delete_buffer(ALuint buffer) {
1172 alDeleteBuffers(1, &buffer);
1173 error = alGetError();
1175 if (error == AL_NO_ERROR) {
1178 }
else if (error != AL_INVALID_OPERATION) {
1181 }
else if (tries >= openal_buffer_delete_retries.
get_value()) {
1192 audio_error(
"failed to delete a buffer: " << alGetString(error) );