diff options
author | Tobias Gunkel | 2011-12-21 10:10:42 +0100 |
---|---|---|
committer | Tobias Gunkel | 2011-12-22 12:08:28 +0100 |
commit | f7a869ccc5c22212768c43f258a7fbf7dddb758f (patch) | |
tree | b0afdff0275cd05d0d4d3e7577e98d8fc22bb872 /engines/scumm | |
parent | 3a9f2c5f5bb817b4acbe279aedae938679634257 (diff) | |
download | scummvm-rg350-f7a869ccc5c22212768c43f258a7fbf7dddb758f.tar.gz scummvm-rg350-f7a869ccc5c22212768c43f258a7fbf7dddb758f.tar.bz2 scummvm-rg350-f7a869ccc5c22212768c43f258a7fbf7dddb758f.zip |
SCUMM: Optimize player_appleII sample buffer
The AppleII sound player works in two phases: writing samples to the
sample buffer (sample
generation) or reading samples from the buffer and passing it to ScummVM's
output callback.
The sample buffer is read completely in the reading phase so the entries
of the already read samples of the buffer can be reused again during the
next write phase.
Diffstat (limited to 'engines/scumm')
-rw-r--r-- | engines/scumm/player_appleII.h | 84 |
1 files changed, 50 insertions, 34 deletions
diff --git a/engines/scumm/player_appleII.h b/engines/scumm/player_appleII.h index f0b148ef86..1f53b6a8dc 100644 --- a/engines/scumm/player_appleII.h +++ b/engines/scumm/player_appleII.h @@ -35,13 +35,20 @@ namespace Scumm { class ScummEngine; -class DynamicMemoryStream { +/* + * Optimized for use with periodical read/write phases when the buffer + * is filled in a write phase and completely read in a read phase. + * The growing strategy is optimized for repeated small (e.g. 2 bytes) + * single writes resulting in large buffers + * (avg.: 4KB, max: 18KB @ 16bit/22.050kHz (MM sound21)). + */ +class SampleBuffer { public: - DynamicMemoryStream() : _data(0) { + SampleBuffer() : _data(0) { clear(); } - ~DynamicMemoryStream() { + ~SampleBuffer() { free(_data); } @@ -49,50 +56,61 @@ public: free(_data); _data = 0; _capacity = 0; - _size = 0; - _ptr = 0; - _pos = 0; + _writePos = 0; _readPos = 0; } - void ensureCapacity(uint32 new_len) { - if (new_len <= _capacity) + void ensureFree(uint32 needed) { + // if data was read completely, reset read/write pos to front + if ((_writePos != 0) && (_writePos == _readPos)) { + _writePos = 0; + _readPos = 0; + } + + // check for enough space at end of buffer + uint32 freeEndCnt = _capacity - _writePos; + if (needed <= freeEndCnt) return; - byte *old_data = _data; + uint32 avail = availableSize(); + + // check for enough space at beginning and end of buffer + if (needed <= _readPos + freeEndCnt) { + // move unread data to front of buffer + memmove(_data, _data + _readPos, avail); + _writePos = avail; + _readPos = 0; + } else { // needs a grow + byte *old_data = _data; + uint32 new_len = avail + needed; - _capacity *= 2; - if (_capacity < new_len + 2048) _capacity = new_len + 2048; - _data = (byte *)malloc(_capacity); - _ptr = _data + _pos; - - if (old_data) { - // Copy old data - memcpy(_data, old_data, _size); - free(old_data); + _data = (byte *)malloc(_capacity); + + if (old_data) { + // copy old unread data to front of new buffer + memcpy(_data, old_data + _readPos, avail); + free(old_data); + _writePos = avail; + _readPos = 0; + } } - - _size = new_len; } uint32 availableSize() const { - if (_readPos >= _size) + if (_readPos >= _writePos) return 0; - return _size - _readPos; + return _writePos - _readPos; } virtual uint32 write(const void *dataPtr, uint32 dataSize) { - ensureCapacity(_pos + dataSize); - memcpy(_ptr, dataPtr, dataSize); - _ptr += dataSize; - _pos += dataSize; - if (_pos > _size) - _size = _pos; + ensureFree(dataSize); + memcpy(_data + _writePos, dataPtr, dataSize); + _writePos += dataSize; return dataSize; } - uint32 read(byte *dataPtr, uint32 dataSize) const { + uint32 read(byte *dataPtr, uint32 dataSize) { uint32 avail = availableSize(); if (avail == 0) return 0; @@ -104,12 +122,10 @@ public: } private: - mutable uint32 _readPos; + uint32 _writePos; + uint32 _readPos; uint32 _capacity; - uint32 _size; - byte *_ptr; byte *_data; - uint32 _pos; }; // CPU_CLOCK according to AppleWin @@ -214,7 +230,7 @@ private: int _sampleCyclesSumFP; /* (fixed precision) */ int _volume; /* 0 - 256 */ static const int _maxVolume = 256; - DynamicMemoryStream _buffer; + SampleBuffer _buffer; }; class AppleII_SoundFunction; |