From 0e2c667fa86dceef5ec263949e5464d12cf6c4ec Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 12 Feb 2017 08:05:33 -0500 Subject: TITANIC: Simplify implementation of CAudioBuffer --- engines/titanic/sound/audio_buffer.cpp | 61 +++++++++++----------------- engines/titanic/sound/audio_buffer.h | 59 ++++++++++++--------------- engines/titanic/sound/music_room_handler.cpp | 17 ++++---- engines/titanic/sound/wave_file.cpp | 11 +++-- 4 files changed, 63 insertions(+), 85 deletions(-) diff --git a/engines/titanic/sound/audio_buffer.cpp b/engines/titanic/sound/audio_buffer.cpp index 029e7f0d9c..1f0693181a 100644 --- a/engines/titanic/sound/audio_buffer.cpp +++ b/engines/titanic/sound/audio_buffer.cpp @@ -21,62 +21,49 @@ */ #include "titanic/sound/audio_buffer.h" +#include "common/algorithm.h" namespace Titanic { -CAudioBuffer::CAudioBuffer(int bufferSize) : _flag(true), _disabled(false) { - _buffer.resize(bufferSize); - reset(); -} - -CAudioBuffer::~CAudioBuffer() { - _buffer.clear(); +CAudioBuffer::CAudioBuffer(int maxSize) : _finished(false) { + _data.resize(maxSize); } void CAudioBuffer::reset() { - _flag = true; - _readBytesLeft = _writeBytesLeft = _buffer.size() / 2; + _frontP = _backP = &_data[0]; } -byte *CAudioBuffer::getBegin() { - return _flag ? &_buffer[_buffer.size() / 2] : &_buffer[0]; -} +void CAudioBuffer::push(int16 value) { + assert(!full()); + compact(); -byte *CAudioBuffer::getEnd() { - return _flag ? &_buffer[0] : &_buffer[_buffer.size() / 2]; + *_backP++ = value; } -int16 *CAudioBuffer::getReadPtr() { - byte *ptr = getBegin(); - return (int16 *)(ptr + (_buffer.size() / 2 - _readBytesLeft)); -} +void CAudioBuffer::push(int16 *values, int count) { + compact(); + assert(freeSize() >= count); -int16 *CAudioBuffer::getWritePtr() { - byte *ptr = getEnd(); - return (int16 *)(ptr + (_buffer.size() / 2 - _writeBytesLeft)); + Common::copy(values, values + count, _backP); + _backP += count; } -void CAudioBuffer::advanceRead(int size) { - _readBytesLeft -= size; - if (_readBytesLeft < 0) { - _readBytesLeft = 0; - } else if (size && !_writeBytesLeft) { - reverse(); - } +int16 CAudioBuffer::pop() { + assert(!empty()); + return *_frontP++; } -void CAudioBuffer::advanceWrite(int size) { - _writeBytesLeft -= size; - if (_writeBytesLeft < 0) { - _writeBytesLeft = 0; - } else if (size && !_readBytesLeft) { - reverse(); +void CAudioBuffer::compact() { + if (_frontP != &_data[0]) { + Common::copy(_frontP, _backP, &_data[0]); + _backP -= _frontP - &_data[0]; + _frontP = &_data[0]; } } -void CAudioBuffer::reverse() { - _flag = !_flag; - _readBytesLeft = _writeBytesLeft = _buffer.size() / 2; +int CAudioBuffer::freeSize() { + compact(); + return &_data[0] + _data.size() - _backP; } void CAudioBuffer::enterCriticalSection() { diff --git a/engines/titanic/sound/audio_buffer.h b/engines/titanic/sound/audio_buffer.h index 54dd807250..8d27667e93 100644 --- a/engines/titanic/sound/audio_buffer.h +++ b/engines/titanic/sound/audio_buffer.h @@ -31,30 +31,18 @@ namespace Titanic { class CAudioBuffer { private: Common::Mutex _mutex; -private: - /** - * Gets the beginning of stored audio data - */ - byte *getBegin(); - - /** - * Gets the end of the stored audio data - */ - byte *getEnd(); + Common::Array _data; + int16 *_frontP, *_backP; /** - * Reverses the audio buffer + * Reclaims any space at the start of the array resulting from + * having read values off the font */ - void reverse(); + void compact(); public: - Common::Array _buffer; - int _readBytesLeft; - int _writeBytesLeft; - bool _flag; - bool _disabled; + bool _finished; public: - CAudioBuffer(int bufferSize); - ~CAudioBuffer(); + CAudioBuffer(int maxSize); /** * Resets the audio buffer @@ -62,36 +50,39 @@ public: void reset(); /** - * Gets a pointer to the start of previously written data + * Returns true if the buffer is empty */ - int16 *getReadPtr(); + bool empty() const { return _data.empty(); } /** - * Returns the number of bytes that can be read + * Returns the number of 16-bit entries in the buffer */ - int getBytesToRead() const { return _readBytesLeft; } + int size() const { return _backP - _frontP; } /** - * Advances the read index + * Returns true if the buffer is full */ - void advanceRead(int size); + bool full() const { return (_backP - _frontP) == (int)_data.size(); } /** - * Gets a pointer to the remainder of the audio buffer that - * can be written to + * Returns the number of entries free in the buffer */ - int16 *getWritePtr(); + int freeSize(); /** - * Returns how many bytes can be written before hitting the - * end of the audio buffer + * Adds a value to the buffer */ - int getWriteBytesLeft() const { return _writeBytesLeft; } - + void push(int16 value); + + /** + * Adds a value to the buffer + */ + void push(int16 *values, int count); + /** - * Advances the write pointer by the specified number of bytes + * Removes a value from the buffer */ - void advanceWrite(int size); + int16 pop(); /** * Enters a critical section diff --git a/engines/titanic/sound/music_room_handler.cpp b/engines/titanic/sound/music_room_handler.cpp index e50384e0f8..d464a1d95d 100644 --- a/engines/titanic/sound/music_room_handler.cpp +++ b/engines/titanic/sound/music_room_handler.cpp @@ -40,7 +40,7 @@ CMusicRoomHandler::CMusicRoomHandler(CProjectItem *project, CSoundManager *sound Common::fill(&_array5[0], &_array5[4], 0.0); Common::fill(&_position[0], &_position[4], 0); - _audioBuffer = new CAudioBuffer(176400); + _audioBuffer = new CAudioBuffer(88200); } CMusicRoomHandler::~CMusicRoomHandler() { @@ -96,7 +96,6 @@ void CMusicRoomHandler::setup(int volume) { update(); _waveFile = _soundManager->loadMusic(_audioBuffer, DisposeAfterUse::NO); - _audioBuffer->advanceRead(_audioBuffer->getBytesToRead()); update(); } @@ -203,14 +202,15 @@ bool CMusicRoomHandler::update() { void CMusicRoomHandler::updateAudio() { _audioBuffer->enterCriticalSection(); - int size = _audioBuffer->getWriteBytesLeft(); + + int size = _audioBuffer->freeSize(); int count; int16 *ptr; if (size > 0) { - // Null out the destination write area - int16 *audioPtr = _audioBuffer->getWritePtr(); - Common::fill(audioPtr, audioPtr + size / sizeof(uint16), 0); + // Create a temporary buffer for merging the instruments into + int16 *audioData = new int16[size]; + Common::fill(audioData, audioData + size, 0); for (MusicInstrument instrument = BELLS; instrument <= BASS; instrument = (MusicInstrument)((int)instrument + 1)) { @@ -218,7 +218,7 @@ void CMusicRoomHandler::updateAudio() { // Iterate through each of the four instruments and do an additive // read that will merge their data onto the output buffer - for (count = size, ptr = audioPtr; count > 0; ) { + for (count = size, ptr = audioData; count > 0; ) { int amount = musicWave->read(ptr, count); if (amount > 0) { count -= amount; @@ -230,7 +230,8 @@ void CMusicRoomHandler::updateAudio() { } } - _audioBuffer->advanceWrite(size); + _audioBuffer->push(audioData, size); + delete[] audioData; } _audioBuffer->leaveCriticalSection(); diff --git a/engines/titanic/sound/wave_file.cpp b/engines/titanic/sound/wave_file.cpp index a4cd9d3e3f..b094adbafe 100644 --- a/engines/titanic/sound/wave_file.cpp +++ b/engines/titanic/sound/wave_file.cpp @@ -49,18 +49,17 @@ public: int AudioBufferStream::readBuffer(int16 *buffer, const int numSamples) { _audioBuffer->enterCriticalSection(); - int samplesToRead = MIN((const int)numSamples, (const int)(_audioBuffer->getBytesToRead() / sizeof(uint16))); - - const int16 *src = _audioBuffer->getReadPtr(); - Common::copy(src, src + samplesToRead, buffer); - _audioBuffer->advanceRead(samplesToRead * 2); + int samplesToRead = MIN((const int)numSamples, (const int)_audioBuffer->size()); + + for (int idx = 0; idx < samplesToRead; ++idx) + *buffer++ = _audioBuffer->pop(); _audioBuffer->leaveCriticalSection(); return samplesToRead; } bool AudioBufferStream::endOfData() const { - return _audioBuffer->_disabled; + return _audioBuffer->_finished; } /*------------------------------------------------------------------------*/ -- cgit v1.2.3