From 1193be6eaadc47ef708a521ee883cb12a4650131 Mon Sep 17 00:00:00 2001 From: Joerg Mueller Date: Sat, 23 Jul 2011 15:59:10 +0000 Subject: [PATCH] =?UTF-8?q?3D=20Audio=20GSoC:=20*=20Reviewed=20and=20impro?= =?UTF-8?q?ved=20the=20linear=20resampler.=20Now=20it=20should=20work=20pr?= =?UTF-8?q?etty=20good=20also=20for=20special=20cases=20that=20caused=20er?= =?UTF-8?q?rors=20previously.=20*=20Fixed=20a=20crash=20in=20the=20GE=20wh?= =?UTF-8?q?en=20a=20sound=20actuator=20doesn't=20have=20a=20sound=20assign?= =?UTF-8?q?ed.=20*=20Corrected=20the=20OpenAL=20device's=20threading=20cod?= =?UTF-8?q?e.=20This=20is=20a=20bugfix=20for=20#27913,=20thanks=20to=20Juh?= =?UTF-8?q?a=20M=C3=A4ki-Kanto=20for=20helping=20to=20resolve=20this.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- intern/audaspace/OpenAL/AUD_OpenALDevice.cpp | 18 +++--- intern/audaspace/OpenAL/AUD_OpenALDevice.h | 2 +- .../intern/AUD_LinearResampleReader.cpp | 58 ++++++++++++------- source/gameengine/Ketsji/KX_SoundActuator.cpp | 16 +++-- 4 files changed, 58 insertions(+), 36 deletions(-) diff --git a/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp b/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp index 65b1d3f3b64..684ad50792b 100644 --- a/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp +++ b/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp @@ -775,12 +775,15 @@ void* AUD_openalRunThread(void* device) return NULL; } -void AUD_OpenALDevice::start() +void AUD_OpenALDevice::start(bool join) { lock(); if(!m_playing) { + if(join) + pthread_join(m_thread, NULL); + pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); @@ -943,8 +946,8 @@ void AUD_OpenALDevice::updateStreams() // stop thread if(m_playingSounds.empty() || (cerr != ALC_NO_ERROR)) { - unlock(); m_playing = false; + unlock(); pthread_exit(NULL); } @@ -1023,6 +1026,8 @@ AUD_OpenALDevice::AUD_OpenALDevice(AUD_DeviceSpecs specs, int buffersize) pthread_mutex_init(&m_mutex, &attr); pthread_mutexattr_destroy(&attr); + + start(false); } AUD_OpenALDevice::~AUD_OpenALDevice() @@ -1048,13 +1053,8 @@ AUD_OpenALDevice::~AUD_OpenALDevice() alcProcessContext(m_context); // wait for the thread to stop - if(m_playing) - { - unlock(); - pthread_join(m_thread, NULL); - } - else - unlock(); + unlock(); + pthread_join(m_thread, NULL); //delete m_bufferedFactories; diff --git a/intern/audaspace/OpenAL/AUD_OpenALDevice.h b/intern/audaspace/OpenAL/AUD_OpenALDevice.h index ea4f9ca1ea8..3ba761bad5a 100644 --- a/intern/audaspace/OpenAL/AUD_OpenALDevice.h +++ b/intern/audaspace/OpenAL/AUD_OpenALDevice.h @@ -207,7 +207,7 @@ private: /** * Starts the streaming thread. */ - void start(); + void start(bool join = true); /** * Gets the format according to the specs. diff --git a/intern/audaspace/intern/AUD_LinearResampleReader.cpp b/intern/audaspace/intern/AUD_LinearResampleReader.cpp index c33017e912a..db050b5a9b7 100644 --- a/intern/audaspace/intern/AUD_LinearResampleReader.cpp +++ b/intern/audaspace/intern/AUD_LinearResampleReader.cpp @@ -63,7 +63,7 @@ int AUD_LinearResampleReader::getLength() const int AUD_LinearResampleReader::getPosition() const { - return floor((m_reader->getPosition() + (m_cache_ok ? m_cache_pos - 2 : 0)) + return floor((m_reader->getPosition() + (m_cache_ok ? m_cache_pos - 1 : 0)) * m_rate / m_reader->getSpecs().rate); } @@ -76,6 +76,9 @@ AUD_Specs AUD_LinearResampleReader::getSpecs() const void AUD_LinearResampleReader::read(int& length, bool& eos, sample_t* buffer) { + if(length == 0) + return; + AUD_Specs specs = m_reader->getSpecs(); int samplesize = AUD_SAMPLE_SIZE(specs); @@ -85,13 +88,6 @@ void AUD_LinearResampleReader::read(int& length, bool& eos, sample_t* buffer) sample_t low, high; eos = false; - if(factor == 1 && (!m_cache_ok || m_cache_pos == 0)) - { - // can read directly! - m_reader->read(length, eos, buffer); - return; - } - // check for channels changed if(specs.channels != m_channels) @@ -101,47 +97,65 @@ void AUD_LinearResampleReader::read(int& length, bool& eos, sample_t* buffer) m_cache_ok = false; } + if(factor == 1 && (!m_cache_ok || m_cache_pos == 1)) + { + // can read directly! + m_reader->read(length, eos, buffer); + + if(length > 0) + { + memcpy(m_cache.getBuffer() + m_channels, buffer + m_channels * (length - 1), samplesize); + m_cache_pos = 1; + m_cache_ok = true; + } + + return; + } + int len; sample_t* buf; if(m_cache_ok) { - int need = ceil(length / factor - (1 - m_cache_pos)); + int need = ceil(length / factor + m_cache_pos) - 1; len = need; - m_buffer.assureSize((len + 3) * samplesize); + m_buffer.assureSize((len + 2) * samplesize); buf = m_buffer.getBuffer(); memcpy(buf, m_cache.getBuffer(), 2 * samplesize); m_reader->read(len, eos, buf + 2 * m_channels); if(len < need) - length = floor((len + (1 - m_cache_pos)) * factor); + length = floor((len + 1 - m_cache_pos) * factor); } else { - int need = ceil(length / factor) + 1; + m_cache_pos = 1 - 1 / factor; + + int need = ceil(length / factor + m_cache_pos); len = need; m_buffer.assureSize((len + 1) * samplesize); buf = m_buffer.getBuffer(); - m_reader->read(len, eos, buf); + memset(buf, 0, samplesize); + m_reader->read(len, eos, buf + m_channels); + + if(len == 0) + { + length = 0; + return; + } if(len < need) { - if(eos) - { - length = floor(len * factor); - memset(buf + len * m_channels, 0, samplesize); - } - else - length = ceil((len - 1) * factor); + length = floor((len - m_cache_pos) * factor); } + m_cache_ok = true; - m_cache_pos = 0; } for(int channel = 0; channel < m_channels; channel++) @@ -159,7 +173,7 @@ void AUD_LinearResampleReader::read(int& length, bool& eos, sample_t* buffer) if(floor(spos) == spos) { - memcpy(m_cache.getBuffer(), buf + int(floor(spos - 1)) * m_channels, 2 * samplesize); + memcpy(m_cache.getBuffer() + m_channels, buf + int(floor(spos)) * m_channels, samplesize); m_cache_pos = 1; } else diff --git a/source/gameengine/Ketsji/KX_SoundActuator.cpp b/source/gameengine/Ketsji/KX_SoundActuator.cpp index 0e7b00aeb24..0f2597c336f 100644 --- a/source/gameengine/Ketsji/KX_SoundActuator.cpp +++ b/source/gameengine/Ketsji/KX_SoundActuator.cpp @@ -57,7 +57,10 @@ KX_SoundActuator::KX_SoundActuator(SCA_IObject* gameobj, KX_SOUNDACT_TYPE type)//, : SCA_IActuator(gameobj, KX_ACT_SOUND) { - m_sound = AUD_copy(sound); + if(sound) + m_sound = AUD_copy(sound); + else + m_sound = NULL; m_volume = volume; m_pitch = pitch; m_is3d = is3d; @@ -73,7 +76,8 @@ KX_SoundActuator::~KX_SoundActuator() { if(m_handle) AUD_stop(m_handle); - AUD_unload(m_sound); + if(m_sound) + AUD_unload(m_sound); } void KX_SoundActuator::play() @@ -421,7 +425,10 @@ PyObject* KX_SoundActuator::pyattr_get_pitch(void *self, const struct KX_PYATTRI PyObject* KX_SoundActuator::pyattr_get_sound(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef) { KX_SoundActuator * actuator = static_cast (self); - return AUD_getPythonFactory(actuator->m_sound); + if(actuator->m_sound) + return AUD_getPythonFactory(actuator->m_sound); + else + Py_RETURN_NONE; } int KX_SoundActuator::pyattr_set_3d_property(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value) @@ -535,7 +542,8 @@ int KX_SoundActuator::pyattr_set_sound(void *self, const struct KX_PYATTRIBUTE_D AUD_Sound* snd = AUD_getPythonSound(sound); if(snd) { - AUD_unload(actuator->m_sound); + if(actuator->m_sound) + AUD_unload(actuator->m_sound); actuator->m_sound = snd; return PY_SET_ATTR_SUCCESS; }