Skip to content
Permalink
Browse files

TITANIC: Implementing audio buffer audio stream

  • Loading branch information...
dreammaster committed Feb 11, 2017
1 parent 173e9c0 commit 9ab1ad60bf9f83479a85ba961938db7edb1317e0
@@ -46,14 +46,14 @@ byte *CAudioBuffer::getEnd() {
return _flag ? &_buffer[0] : &_buffer[_buffer.size() / 2];
}

uint16 *CAudioBuffer::getReadPtr() {
int16 *CAudioBuffer::getReadPtr() {
byte *ptr = getBegin();
return (uint16 *)(ptr + (_buffer.size() / 2 - _readBytesLeft));
return (int16 *)(ptr + (_buffer.size() / 2 - _readBytesLeft));
}

uint16 *CAudioBuffer::getWritePtr() {
int16 *CAudioBuffer::getWritePtr() {
byte *ptr = getEnd();
return (uint16 *)(ptr + (_buffer.size() / 2 - _writeBytesLeft));
return (int16 *)(ptr + (_buffer.size() / 2 - _writeBytesLeft));
}

void CAudioBuffer::advanceRead(int size) {
@@ -64,7 +64,7 @@ class CAudioBuffer {
/**
* Gets a pointer to the start of previously written data
*/
uint16 *getReadPtr();
int16 *getReadPtr();

/**
* Returns the number of bytes that can be read
@@ -80,7 +80,7 @@ class CAudioBuffer {
* Gets a pointer to the remainder of the audio buffer that
* can be written to
*/
uint16 *getWritePtr();
int16 *getWritePtr();

/**
* Returns how many bytes can be written before hitting the
@@ -205,11 +205,11 @@ void CMusicRoomHandler::updateAudio() {
_audioBuffer->enterCriticalSection();
int size = _audioBuffer->getWriteBytesLeft();
int count;
uint16 *ptr;
int16 *ptr;

if (size > 0) {
// Null out the destination write area
uint16 *audioPtr = _audioBuffer->getWritePtr();
int16 *audioPtr = _audioBuffer->getWritePtr();
Common::fill(audioPtr, audioPtr + size / sizeof(uint16), 0);

for (int instrIdx = 0; instrIdx < 4; ++instrIdx) {
@@ -269,7 +269,7 @@ void CMusicWave::setSize(uint total) {
_count = 0;
}

int CMusicWave::read(uint16 *ptr, uint size) {
int CMusicWave::read(int16 *ptr, uint size) {
if (!_size)
return 0;

@@ -278,17 +278,17 @@ int CMusicWave::read(uint16 *ptr, uint size) {

if (_waveIndex != -1) {
// Lock the specified wave file for access
const uint16 *data = _items[_waveIndex]._waveFile->lock();
const int16 *data = _items[_waveIndex]._waveFile->lock();
assert(data);
const uint16 *src = data;
const int16 *src = data;

// Loop through merging data from the wave file into the dest buffer
for (uint idx = 0; idx < (size / sizeof(uint16)); ++idx, _readPos += _readIncrement) {
for (uint idx = 0; idx < (size / sizeof(int16)); ++idx, _readPos += _readIncrement) {
uint srcPos = _readPos >> 8;
if (srcPos >= _count)
break;

uint16 val = READ_LE_UINT16(src + srcPos);
int16 val = READ_LE_UINT16(src + srcPos);
*ptr++ += val;
}

@@ -120,7 +120,7 @@ class CMusicWave {
* If there is any wave file currently specified, reads it in
* and merges it into the supplied buffer
*/
int read(uint16 *ptr, uint size);
int read(int16 *ptr, uint size);

/**
* Figure out which wave file to use next
@@ -29,6 +29,40 @@

namespace Titanic {

/**
* This creates a ScummVM audio stream around a CAudioBuffer buffer,
* allowing for streaming audio output for the music room music
*/
class AudioBufferStream : public Audio::SeekableAudioStream {
private:
CAudioBuffer *_audioBuffer;
public:
AudioBufferStream(CAudioBuffer *audioBuffer) : _audioBuffer(audioBuffer) {}

virtual int readBuffer(int16 *buffer, const int numSamples);
virtual bool isStereo() const { return false; }
virtual bool endOfData() const;
virtual int getRate() const { return 22050; }
virtual Audio::Timestamp getLength() const { return Audio::Timestamp(); }
virtual bool seek(const Audio::Timestamp &where) { return false; }
};

int AudioBufferStream::readBuffer(int16 *buffer, const int numSamples) {
int samplesToRead = MIN((const uint)numSamples, _audioBuffer->getBytesToRead() / sizeof(uint16));

const int16 *src = _audioBuffer->getReadPtr();
Common::copy(src, src + samplesToRead, buffer);
_audioBuffer->advanceRead(samplesToRead * 2);

return samplesToRead;
}

bool AudioBufferStream::endOfData() const {
return _audioBuffer->_disabled;
}

/*------------------------------------------------------------------------*/

CWaveFile::CWaveFile() : _soundManager(nullptr), _audioStream(nullptr),
_waveData(nullptr), _waveSize(0), _dataSize(0), _headerSize(0),
_rate(0), _flags(0), _soundType(Audio::Mixer::kPlainSoundType) {
@@ -43,8 +77,6 @@ CWaveFile::CWaveFile(QSoundManager *owner) : _soundManager(owner), _audioStream(

void CWaveFile::setup() {
_loadMode = LOADMODE_SCUMMVM;
_field4 = 0;
_field14 = 1;
_dataSize = 0;
_audioBuffer = nullptr;
_disposeAudioBuffer = DisposeAfterUse::NO;
@@ -53,7 +85,7 @@ void CWaveFile::setup() {

CWaveFile::~CWaveFile() {
if (_audioStream) {
_soundManager->soundFreed(_soundHandle);
//_soundManager->soundFreed(_soundHandle);
delete _audioStream;
}

@@ -127,8 +159,8 @@ bool CWaveFile::loadMusic(CAudioBuffer *buffer, DisposeAfterUse::Flag disposeAft
_audioBuffer = buffer;
_disposeAudioBuffer = disposeAfterUse;
_loadMode = LOADMODE_AUDIO_BUFFER;
_field14 = 0;

_audioStream = new AudioBufferStream(_audioBuffer);
return true;
}

@@ -164,19 +196,19 @@ void CWaveFile::reset() {
audioStream()->rewind();
}

const uint16 *CWaveFile::lock() {
const int16 *CWaveFile::lock() {
switch (_loadMode) {
case LOADMODE_SCUMMVM:
assert(_waveData && _rate == 22050);
assert(_flags == (Audio::FLAG_LITTLE_ENDIAN | Audio::FLAG_16BITS));
return (uint16 *)(_waveData + _headerSize);
return (const int16 *)(_waveData + _headerSize);

default:
return nullptr;
}
}

void CWaveFile::unlock(const uint16 *ptr) {
void CWaveFile::unlock(const int16 *ptr) {
// No implementation needed in ScummVM
}

@@ -45,7 +45,6 @@ class CWaveFile {
byte _flags;
QSoundManager *_soundManager;
Audio::SeekableAudioStream *_audioStream;
Audio::SoundHandle _soundHandle;
private:
/**
* Handles setup of fields shared by the constructors
@@ -60,8 +59,6 @@ class CWaveFile {
Audio::Mixer::SoundType _soundType;

LoadMode _loadMode;
int _field4;
int _field14;
CAudioBuffer *_audioBuffer;
DisposeAfterUse::Flag _disposeAudioBuffer;
int _channel;
@@ -127,12 +124,12 @@ class CWaveFile {
/**
* Lock sound data for access
*/
const uint16 *lock();
const int16 *lock();

/**
* Unlock sound data after a prior call to lock
*/
void unlock(const uint16 *ptr);
void unlock(const int16 *ptr);
};

} // End of namespace Titanic

0 comments on commit 9ab1ad6

Please sign in to comment.
You can’t perform that action at this time.