diff options
author | Joerg Mueller <nexyon@gmail.com> | 2011-07-23 19:59:10 +0400 |
---|---|---|
committer | Joerg Mueller <nexyon@gmail.com> | 2011-07-23 19:59:10 +0400 |
commit | 1193be6eaadc47ef708a521ee883cb12a4650131 (patch) | |
tree | b480289bf6584d0e6038da5750962a144ac2935a /intern/audaspace | |
parent | fd79de0bb3f8b98cdbf973beababec83a2bc399e (diff) |
3D Audio GSoC:
* Reviewed and improved the linear resampler. Now it should work pretty good also for special cases that caused errors previously.
* Fixed a crash in the GE when a sound actuator doesn't have a sound assigned.
* Corrected the OpenAL device's threading code. This is a bugfix for #27913, thanks to Juha Mäki-Kanto for helping to resolve this.
Diffstat (limited to 'intern/audaspace')
-rw-r--r-- | intern/audaspace/OpenAL/AUD_OpenALDevice.cpp | 18 | ||||
-rw-r--r-- | intern/audaspace/OpenAL/AUD_OpenALDevice.h | 2 | ||||
-rw-r--r-- | intern/audaspace/intern/AUD_LinearResampleReader.cpp | 58 |
3 files changed, 46 insertions, 32 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 |