1
0
mirror of https://github.com/rwengine/openrw.git synced 2024-11-22 02:12:45 +01:00

Fix openAL's issue with unqueueing buffers

This commit is contained in:
Filip Gawin 2019-05-19 12:23:56 +02:00
parent 4e068591bd
commit 685b78a6f6
5 changed files with 22 additions and 12 deletions

View File

@ -3,7 +3,7 @@
#include "audio/SoundBuffer.hpp" #include "audio/SoundBuffer.hpp"
Sound::~Sound() { Sound::~Sound() {
if (buffer) { if (buffer && buffer->state == SoundBuffer::State::Playing) {
stop(); stop();
} }
} }

View File

@ -28,12 +28,13 @@ struct SoundBuffer {
void setMaxDistance(float maxDist); void setMaxDistance(float maxDist);
enum class State { enum class State {
Created = 0,
Stopped, Stopped,
Playing Playing
}; };
ALuint source; ALuint source;
State state = State::Stopped; State state = State::Created;
private: private:
ALuint buffer; ALuint buffer;
}; };

View File

@ -18,8 +18,16 @@ SoundBufferStreamed::SoundBufferStreamed() {
} }
SoundBufferStreamed::~SoundBufferStreamed() { SoundBufferStreamed::~SoundBufferStreamed() {
alCheck( std::lock_guard<std::mutex> lock(soundSource->mutex);
alSourceUnqueueBuffers(source, kNrBuffersStreaming, buffers.data()));
if (state == State::Created) { // We should only clear queue
alSourcei(source, AL_BUFFER, 0);
} else {
auto nrBuffersToUnqueue = std::min(kNrBuffersStreaming, buffersUsed);
alCheck(
alSourceUnqueueBuffers(source, nrBuffersToUnqueue, buffers.data()));
}
alCheck(alDeleteBuffers(kNrBuffersStreaming, buffers.data())); alCheck(alDeleteBuffers(kNrBuffersStreaming, buffers.data()));
} }
@ -44,9 +52,10 @@ bool SoundBufferStreamed::bufferData(SoundSource &soundSource) {
static_cast<ALsizei>(sizeOfNextChunk * sizeof(int16_t)), static_cast<ALsizei>(sizeOfNextChunk * sizeof(int16_t)),
soundSource.sampleRate)); soundSource.sampleRate));
streamedData++; streamedData++;
buffersUsed++;
} }
alCheck(alSourceQueueBuffers(source, kNrBuffersStreaming, buffers.data())); alCheck(alSourceQueueBuffers(source, buffersUsed, buffers.data()));
this->soundSource = &soundSource; this->soundSource = &soundSource;
@ -110,6 +119,7 @@ void SoundBufferStreamed::updateBuffers() {
sizeOfNextChunk * sizeof(int16_t), sizeOfNextChunk * sizeof(int16_t),
soundSource->sampleRate)); soundSource->sampleRate));
streamedData++; streamedData++;
buffersUsed++;
alCheck(alSourceQueueBuffers(source, 1, &bufid)); alCheck(alSourceQueueBuffers(source, 1, &bufid));
} }
} }

View File

@ -24,6 +24,7 @@ private:
SoundSource* soundSource = nullptr; SoundSource* soundSource = nullptr;
void updateBuffers(); void updateBuffers();
unsigned int streamedData = 0; unsigned int streamedData = 0;
unsigned int buffersUsed = 0;
std::array<ALuint, kNrBuffersStreaming> buffers; std::array<ALuint, kNrBuffersStreaming> buffers;
std::future<void> bufferingThread; std::future<void> bufferingThread;
}; };

View File

@ -7,9 +7,11 @@ BOOST_AUTO_TEST_SUITE(AudioLoadingTests, DATA_TEST_PREDICATE)
// @todo Shfil119 implement // @todo Shfil119 implement
// This test requires assets // This test requires assets
BOOST_AUTO_TEST_CASE(testBufferIsPlaying) { struct F {
SoundManager manager{Global::get().e}; SoundManager manager{Global::get().e};
};
BOOST_FIXTURE_TEST_CASE(testBufferIsPlaying, F) {
auto audioPath = auto audioPath =
Global::get().e->data->index.findFilePath("audio/A1_a.wav"); Global::get().e->data->index.findFilePath("audio/A1_a.wav");
@ -33,9 +35,7 @@ BOOST_AUTO_TEST_CASE(testBufferIsPlaying) {
BOOST_REQUIRE(sound.isStopped() == true); BOOST_REQUIRE(sound.isStopped() == true);
} }
BOOST_AUTO_TEST_CASE(testDecodingFramesOfMusic) { BOOST_FIXTURE_TEST_CASE(testDecodingFramesOfMusic, F) {
SoundManager manager{Global::get().e};
auto audioPath = auto audioPath =
Global::get().e->data->index.findFilePath("audio/A1_a.wav"); Global::get().e->data->index.findFilePath("audio/A1_a.wav");
@ -45,9 +45,7 @@ BOOST_AUTO_TEST_CASE(testDecodingFramesOfMusic) {
BOOST_REQUIRE(sound.source->decodedFrames > 0); BOOST_REQUIRE(sound.source->decodedFrames > 0);
} }
BOOST_AUTO_TEST_CASE(testDecodingFramesOfSfx) { BOOST_FIXTURE_TEST_CASE(testDecodingFramesOfSfx, F) {
SoundManager manager{Global::get().e};
manager.createSfxInstance(157); // Callahan Bridge fire manager.createSfxInstance(157); // Callahan Bridge fire
auto& sound = manager.getSfxSourceRef(157); auto& sound = manager.getSfxSourceRef(157);