protecting openal against multithreaded access too

This commit is contained in:
David Rose 2011-11-08 01:44:33 +00:00
parent 25cb3ae4a5
commit 17611c2d20
3 changed files with 63 additions and 0 deletions

View File

@ -25,11 +25,13 @@
#include "openalAudioSound.h"
#include "virtualFileSystem.h"
#include "movieAudio.h"
#include "reMutexHolder.h"
#include <algorithm>
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) {

View File

@ -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

View File

@ -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;
}