From 1193be6eaadc47ef708a521ee883cb12a4650131 Mon Sep 17 00:00:00 2001 From: Joerg Mueller Date: Sat, 23 Jul 2011 15:59:10 +0000 Subject: =?UTF-8?q?3D=20Audio=20GSoC:=20*=20Reviewed=20and=20improved=20th?= =?UTF-8?q?e=20linear=20resampler.=20Now=20it=20should=20work=20pretty=20g?= =?UTF-8?q?ood=20also=20for=20special=20cases=20that=20caused=20errors=20p?= =?UTF-8?q?reviously.=20*=20Fixed=20a=20crash=20in=20the=20GE=20when=20a?= =?UTF-8?q?=20sound=20actuator=20doesn't=20have=20a=20sound=20assigned.=20?= =?UTF-8?q?*=20Corrected=20the=20OpenAL=20device's=20threading=20code.=20T?= =?UTF-8?q?his=20is=20a=20bugfix=20for=20#27913,=20thanks=20to=20Juha=20M?= =?UTF-8?q?=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 +- .../audaspace/intern/AUD_LinearResampleReader.cpp | 58 ++++++++++++++-------- 3 files changed, 46 insertions(+), 32 deletions(-) (limited to 'intern/audaspace') 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 -- cgit v1.2.3