diff --git a/panda/src/audiotraits/openalAudioManager.cxx b/panda/src/audiotraits/openalAudioManager.cxx index 3b71b38841..7cf0ea2af7 100644 --- a/panda/src/audiotraits/openalAudioManager.cxx +++ b/panda/src/audiotraits/openalAudioManager.cxx @@ -25,11 +25,13 @@ #include "openalAudioSound.h" #include "virtualFileSystem.h" #include "movieAudio.h" +#include "reMutexHolder.h" #include TypeHandle OpenALAudioManager::_type_handle; +ReMutex OpenALAudioManager::_lock; int OpenALAudioManager::_active_managers = 0; bool OpenALAudioManager::_openal_active = false; ALCdevice* OpenALAudioManager::_device = NULL; @@ -78,6 +80,7 @@ AudioManager *Create_OpenALAudioManager() { //////////////////////////////////////////////////////////////////// OpenALAudioManager:: OpenALAudioManager() { + ReMutexHolder holder(_lock); if (_managers == (Managers *)NULL) { _managers = new Managers; _al_sources = new SourceCache; @@ -164,6 +167,7 @@ OpenALAudioManager() { //////////////////////////////////////////////////////////////////// OpenALAudioManager:: ~OpenALAudioManager() { + ReMutexHolder holder(_lock); nassertv(_managers != (Managers *)NULL); Managers::iterator mi = _managers->find(this); nassertv(mi != _managers->end()); @@ -182,6 +186,7 @@ OpenALAudioManager:: //////////////////////////////////////////////////////////////////// void OpenALAudioManager:: shutdown() { + ReMutexHolder holder(_lock); if (_managers != (Managers *)NULL) { Managers::iterator mi; for (mi = _managers->begin(); mi != _managers->end(); ++mi) { @@ -226,6 +231,7 @@ make_current() const { //////////////////////////////////////////////////////////////////// bool OpenALAudioManager:: can_use_audio(MovieAudioCursor *source) { + ReMutexHolder holder(_lock); int channels = source->audio_channels(); if ((channels != 1)&&(channels != 2)) { audio_error("Currently, only mono and stereo are supported."); @@ -244,6 +250,7 @@ can_use_audio(MovieAudioCursor *source) { //////////////////////////////////////////////////////////////////// bool OpenALAudioManager:: should_load_audio(MovieAudioCursor *source, int mode) { + ReMutexHolder holder(_lock); if (mode == SM_stream) { // If the user asked for streaming, give him streaming. return false; @@ -280,6 +287,7 @@ should_load_audio(MovieAudioCursor *source, int mode) { //////////////////////////////////////////////////////////////////// OpenALAudioManager::SoundData *OpenALAudioManager:: get_sound_data(MovieAudio *movie, int mode) { + ReMutexHolder holder(_lock); const Filename &path = movie->get_filename(); // Search for an already-cached sample or an already-opened stream. @@ -370,6 +378,7 @@ get_sound_data(MovieAudio *movie, int mode) { //////////////////////////////////////////////////////////////////// PT(AudioSound) OpenALAudioManager:: get_sound(MovieAudio *sound, bool positional, int mode) { + ReMutexHolder holder(_lock); if(!is_valid()) { return get_null_sound(); } @@ -388,6 +397,7 @@ get_sound(MovieAudio *sound, bool positional, int mode) { //////////////////////////////////////////////////////////////////// PT(AudioSound) OpenALAudioManager:: get_sound(const string &file_name, bool positional, int mode) { + ReMutexHolder holder(_lock); if(!is_valid()) { return get_null_sound(); } @@ -420,6 +430,7 @@ get_sound(const string &file_name, bool positional, int mode) { //////////////////////////////////////////////////////////////////// void OpenALAudioManager:: uncache_sound(const string& file_name) { + ReMutexHolder holder(_lock); assert(is_valid()); Filename path = file_name; @@ -444,6 +455,7 @@ uncache_sound(const string& file_name) { //////////////////////////////////////////////////////////////////// void OpenALAudioManager:: clear_cache() { + ReMutexHolder holder(_lock); discard_excess_cache(0); } @@ -454,6 +466,7 @@ clear_cache() { //////////////////////////////////////////////////////////////////// void OpenALAudioManager:: set_cache_limit(unsigned int count) { + ReMutexHolder holder(_lock); _cache_limit=count; discard_excess_cache(count); } @@ -475,6 +488,7 @@ get_cache_limit() const { //////////////////////////////////////////////////////////////////// void OpenALAudioManager:: release_sound(OpenALAudioSound* audioSound) { + ReMutexHolder holder(_lock); AllSounds::iterator ai = _all_sounds.find(audioSound); if (ai != _all_sounds.end()) { _all_sounds.erase(ai); @@ -488,6 +502,7 @@ release_sound(OpenALAudioSound* audioSound) { // Sets listener gain //////////////////////////////////////////////////////////////////// void OpenALAudioManager::set_volume(PN_stdfloat volume) { + ReMutexHolder holder(_lock); if (_volume!=volume) { _volume = volume; @@ -526,6 +541,7 @@ get_volume() const { //////////////////////////////////////////////////////////////////// void OpenALAudioManager:: set_play_rate(PN_stdfloat play_rate) { + ReMutexHolder holder(_lock); if (_play_rate!=play_rate) { _play_rate = play_rate; // Tell our AudioSounds to adjust: @@ -554,6 +570,7 @@ get_play_rate() const { //////////////////////////////////////////////////////////////////// void OpenALAudioManager:: set_active(bool active) { + ReMutexHolder holder(_lock); if (_active!=active) { _active=active; // Tell our AudioSounds to adjust: @@ -591,6 +608,7 @@ get_active() const { //////////////////////////////////////////////////////////////////// void OpenALAudioManager:: 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) { + ReMutexHolder holder(_lock); _position[0] = px; _position[1] = pz; _position[2] = -py; @@ -626,6 +644,7 @@ audio_3d_set_listener_attributes(PN_stdfloat px, PN_stdfloat py, PN_stdfloat pz, //////////////////////////////////////////////////////////////////// void OpenALAudioManager:: 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) { + ReMutexHolder holder(_lock); *px = _position[0]; *py = -_position[2]; *pz = _position[1]; @@ -655,6 +674,7 @@ audio_3d_get_listener_attributes(PN_stdfloat *px, PN_stdfloat *py, PN_stdfloat * //////////////////////////////////////////////////////////////////// void OpenALAudioManager:: audio_3d_set_distance_factor(PN_stdfloat factor) { + ReMutexHolder holder(_lock); _distance_factor = factor; make_current(); @@ -698,6 +718,7 @@ audio_3d_get_distance_factor() const { //////////////////////////////////////////////////////////////////// void OpenALAudioManager:: audio_3d_set_doppler_factor(PN_stdfloat factor) { + ReMutexHolder holder(_lock); _doppler_factor = factor; make_current(); @@ -725,6 +746,7 @@ audio_3d_get_doppler_factor() const { //////////////////////////////////////////////////////////////////// void OpenALAudioManager:: audio_3d_set_drop_off_factor(PN_stdfloat factor) { + ReMutexHolder holder(_lock); _drop_off_factor = factor; AllSounds::iterator i=_all_sounds.begin(); @@ -753,6 +775,7 @@ audio_3d_get_drop_off_factor() const { //////////////////////////////////////////////////////////////////// void OpenALAudioManager:: starting_sound(OpenALAudioSound* audio) { + ReMutexHolder holder(_lock); ALuint source=0; // If the sound already has a source, we don't need to do anything. @@ -801,6 +824,7 @@ starting_sound(OpenALAudioSound* audio) { //////////////////////////////////////////////////////////////////// void OpenALAudioManager:: stopping_sound(OpenALAudioSound* audio) { + ReMutexHolder holder(_lock); if (audio->_source) { _al_sources->insert(audio->_source); audio->_source = 0; @@ -815,6 +839,7 @@ stopping_sound(OpenALAudioSound* audio) { //////////////////////////////////////////////////////////////////// void OpenALAudioManager:: set_concurrent_sound_limit(unsigned int limit) { + ReMutexHolder holder(_lock); _concurrent_sound_limit = limit; reduce_sounds_playing_to(_concurrent_sound_limit); } @@ -836,6 +861,7 @@ get_concurrent_sound_limit() const { //////////////////////////////////////////////////////////////////// void OpenALAudioManager:: reduce_sounds_playing_to(unsigned int count) { + ReMutexHolder holder(_lock); // first give all sounds that have finished a chance to stop, so that these get stopped first update(); @@ -861,6 +887,7 @@ reduce_sounds_playing_to(unsigned int count) { //////////////////////////////////////////////////////////////////// void OpenALAudioManager:: stop_all_sounds() { + ReMutexHolder holder(_lock); reduce_sounds_playing_to(0); } @@ -871,6 +898,7 @@ stop_all_sounds() { //////////////////////////////////////////////////////////////////// void OpenALAudioManager:: update() { + ReMutexHolder holder(_lock); // See if any of our playing sounds have ended // we must first collect a seperate list of finished sounds and then @@ -910,6 +938,7 @@ update() { //////////////////////////////////////////////////////////////////// void OpenALAudioManager:: cleanup() { + ReMutexHolder holder(_lock); if (!_cleanup_required) { return; } @@ -991,6 +1020,7 @@ SoundData() : //////////////////////////////////////////////////////////////////// OpenALAudioManager::SoundData:: ~SoundData() { + ReMutexHolder holder(OpenALAudioManager::_lock); if (_sample != 0) { if (_manager->_is_valid) { _manager->make_current(); @@ -1009,6 +1039,7 @@ OpenALAudioManager::SoundData:: //////////////////////////////////////////////////////////////////// void OpenALAudioManager:: increment_client_count(SoundData *sd) { + ReMutexHolder holder(_lock); sd->_client_count += 1; audio_debug("Incrementing: " << sd->_movie->get_filename().get_basename() << " " << sd->_client_count); if (sd->_client_count == 1) { @@ -1031,6 +1062,7 @@ increment_client_count(SoundData *sd) { //////////////////////////////////////////////////////////////////// void OpenALAudioManager:: decrement_client_count(SoundData *sd) { + ReMutexHolder holder(_lock); sd->_client_count -= 1; audio_debug("Decrementing: " << sd->_movie->get_filename().get_basename() << " " << sd->_client_count); if (sd->_client_count == 0) { @@ -1055,6 +1087,7 @@ decrement_client_count(SoundData *sd) { //////////////////////////////////////////////////////////////////// void OpenALAudioManager:: discard_excess_cache(int sample_limit) { + ReMutexHolder holder(_lock); int stream_limit = 5; while (((int)_expiring_samples.size()) > sample_limit) { diff --git a/panda/src/audiotraits/openalAudioManager.h b/panda/src/audiotraits/openalAudioManager.h index e7d14f22c9..2a95aba405 100644 --- a/panda/src/audiotraits/openalAudioManager.h +++ b/panda/src/audiotraits/openalAudioManager.h @@ -25,6 +25,7 @@ #include "pmap.h" #include "pset.h" #include "movieAudioCursor.h" +#include "reMutex.h" // OSX uses the OpenAL framework #ifdef IS_OSX @@ -135,6 +136,8 @@ private: void cleanup(); private: + // This global lock protects all access to OpenAL library interfaces. + static ReMutex _lock; // An expiration queue is a list of SoundData // that are no longer being used. They are kept diff --git a/panda/src/audiotraits/openalAudioSound.cxx b/panda/src/audiotraits/openalAudioSound.cxx index 9de51fa971..54799c4114 100644 --- a/panda/src/audiotraits/openalAudioSound.cxx +++ b/panda/src/audiotraits/openalAudioSound.cxx @@ -74,6 +74,8 @@ OpenALAudioSound(OpenALAudioManager* manager, _velocity[1] = 0.0f; _velocity[2] = 0.0f; + ReMutexHolder holder(OpenALAudioManager::_lock); + require_sound_data(); if (_manager == NULL) { return; @@ -107,6 +109,7 @@ OpenALAudioSound:: //////////////////////////////////////////////////////////////////// void OpenALAudioSound:: cleanup() { + ReMutexHolder holder(OpenALAudioManager::_lock); if (_manager == 0) { return; } @@ -128,6 +131,7 @@ cleanup() { //////////////////////////////////////////////////////////////////// void OpenALAudioSound:: play() { + ReMutexHolder holder(OpenALAudioManager::_lock); if (_manager == 0) return; PN_stdfloat px,py,pz,vx,vy,vz; @@ -202,6 +206,7 @@ play() { //////////////////////////////////////////////////////////////////// void OpenALAudioSound:: stop() { + ReMutexHolder holder(OpenALAudioManager::_lock); if (_manager==0) return; if (_source) { @@ -233,6 +238,7 @@ stop() { //////////////////////////////////////////////////////////////////// void OpenALAudioSound:: finished() { + ReMutexHolder holder(OpenALAudioManager::_lock); stop(); _current_time = _length; if (!_finished_event.empty()) { @@ -247,6 +253,7 @@ finished() { //////////////////////////////////////////////////////////////////// void OpenALAudioSound:: set_loop(bool loop) { + ReMutexHolder holder(OpenALAudioManager::_lock); set_loop_count((loop)?0:1); } @@ -267,6 +274,7 @@ get_loop() const { //////////////////////////////////////////////////////////////////// void OpenALAudioSound:: set_loop_count(unsigned long loop_count) { + ReMutexHolder holder(OpenALAudioManager::_lock); if (_manager==0) return; if (loop_count >= 1000000000) { @@ -298,6 +306,7 @@ get_loop_count() const { //////////////////////////////////////////////////////////////////// void OpenALAudioSound:: restart_stalled_audio() { + ReMutexHolder holder(OpenALAudioManager::_lock); ALenum status; if (_stream_queued.size() == 0) { return; @@ -316,6 +325,7 @@ restart_stalled_audio() { //////////////////////////////////////////////////////////////////// void OpenALAudioSound:: queue_buffer(ALuint buffer, int samples, int loop_index, double time_offset) { + ReMutexHolder holder(OpenALAudioManager::_lock); // Now push the buffer into the stream queue. alGetError(); alSourceQueueBuffers(_source,1,&buffer); @@ -340,6 +350,7 @@ queue_buffer(ALuint buffer, int samples, int loop_index, double time_offset) { //////////////////////////////////////////////////////////////////// ALuint OpenALAudioSound:: make_buffer(int samples, int channels, int rate, unsigned char *data) { + ReMutexHolder holder(OpenALAudioManager::_lock); // Allocate a buffer to hold the data. alGetError(); @@ -373,6 +384,7 @@ make_buffer(int samples, int channels, int rate, unsigned char *data) { //////////////////////////////////////////////////////////////////// int OpenALAudioSound:: read_stream_data(int bytelen, unsigned char *buffer) { + ReMutexHolder holder(OpenALAudioManager::_lock); MovieAudioCursor *cursor = _sd->_stream; double length = cursor->length(); @@ -427,6 +439,7 @@ read_stream_data(int bytelen, unsigned char *buffer) { //////////////////////////////////////////////////////////////////// void OpenALAudioSound:: correct_calibrated_clock(double rtc, double t) { + ReMutexHolder holder(OpenALAudioManager::_lock); double cc = (rtc - _calibrated_clock_base) * _calibrated_clock_scale; double diff = cc-t; _calibrated_clock_decavg = (_calibrated_clock_decavg * 0.95) + (diff * 0.05); @@ -459,6 +472,7 @@ correct_calibrated_clock(double rtc, double t) { //////////////////////////////////////////////////////////////////// void OpenALAudioSound:: pull_used_buffers() { + ReMutexHolder holder(OpenALAudioManager::_lock); while (_stream_queued.size()) { ALuint buffer = 0; alGetError(); @@ -493,6 +507,7 @@ pull_used_buffers() { //////////////////////////////////////////////////////////////////// void OpenALAudioSound:: push_fresh_buffers() { + ReMutexHolder holder(OpenALAudioManager::_lock); static unsigned char data[65536]; if (_sd->_sample) { @@ -536,6 +551,7 @@ push_fresh_buffers() { //////////////////////////////////////////////////////////////////// void OpenALAudioSound:: set_time(PN_stdfloat time) { + ReMutexHolder holder(OpenALAudioManager::_lock); _start_time = time; } @@ -546,6 +562,7 @@ set_time(PN_stdfloat time) { //////////////////////////////////////////////////////////////////// PN_stdfloat OpenALAudioSound:: get_time() const { + ReMutexHolder holder(OpenALAudioManager::_lock); if (_manager == 0) { return 0.0; } @@ -559,6 +576,7 @@ get_time() const { //////////////////////////////////////////////////////////////////// void OpenALAudioSound:: cache_time(double rtc) { + ReMutexHolder holder(OpenALAudioManager::_lock); assert(_source != 0); double t=get_calibrated_clock(rtc); double max = _length * _playing_loops; @@ -577,6 +595,7 @@ cache_time(double rtc) { //////////////////////////////////////////////////////////////////// void OpenALAudioSound:: set_volume(PN_stdfloat volume) { + ReMutexHolder holder(OpenALAudioManager::_lock); _volume=volume; if (_source) { @@ -630,6 +649,7 @@ get_balance() const { //////////////////////////////////////////////////////////////////// void OpenALAudioSound:: set_play_rate(PN_stdfloat play_rate) { + ReMutexHolder holder(OpenALAudioManager::_lock); _play_rate = play_rate; if (_source) { alSourcef(_source, AL_PITCH, play_rate); @@ -674,6 +694,7 @@ length() const { //////////////////////////////////////////////////////////////////// void OpenALAudioSound:: set_3d_attributes(PN_stdfloat px, PN_stdfloat py, PN_stdfloat pz, PN_stdfloat vx, PN_stdfloat vy, PN_stdfloat vz) { + ReMutexHolder holder(OpenALAudioManager::_lock); _location[0] = px; _location[1] = pz; _location[2] = -py; @@ -701,6 +722,7 @@ set_3d_attributes(PN_stdfloat px, PN_stdfloat py, PN_stdfloat pz, PN_stdfloat vx //////////////////////////////////////////////////////////////////// void OpenALAudioSound:: get_3d_attributes(PN_stdfloat *px, PN_stdfloat *py, PN_stdfloat *pz, PN_stdfloat *vx, PN_stdfloat *vy, PN_stdfloat *vz) { + ReMutexHolder holder(OpenALAudioManager::_lock); *px = _location[0]; *py = -_location[2]; *pz = _location[1]; @@ -718,6 +740,7 @@ get_3d_attributes(PN_stdfloat *px, PN_stdfloat *py, PN_stdfloat *pz, PN_stdfloat //////////////////////////////////////////////////////////////////// void OpenALAudioSound:: set_3d_min_distance(PN_stdfloat dist) { + ReMutexHolder holder(OpenALAudioManager::_lock); _min_dist = dist; if (_source) { @@ -746,6 +769,7 @@ get_3d_min_distance() const { //////////////////////////////////////////////////////////////////// void OpenALAudioSound:: set_3d_max_distance(PN_stdfloat dist) { + ReMutexHolder holder(OpenALAudioManager::_lock); _max_dist = dist; if (_source) { @@ -775,6 +799,7 @@ get_3d_max_distance() const { //////////////////////////////////////////////////////////////////// void OpenALAudioSound:: set_3d_drop_off_factor(PN_stdfloat factor) { + ReMutexHolder holder(OpenALAudioManager::_lock); _drop_off_factor = factor; if (_source) { @@ -807,6 +832,7 @@ get_3d_drop_off_factor() const { //////////////////////////////////////////////////////////////////// void OpenALAudioSound:: set_active(bool active) { + ReMutexHolder holder(OpenALAudioManager::_lock); if (_active!=active) { _active=active; if (_active) { @@ -880,6 +906,7 @@ get_name() const { //////////////////////////////////////////////////////////////////// AudioSound::SoundStatus OpenALAudioSound:: status() const { + ReMutexHolder holder(OpenALAudioManager::_lock); if (_source==0) { return AudioSound::READY; }