aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sound/decoders/raw.cpp110
-rw-r--r--sound/decoders/raw.h11
2 files changed, 60 insertions, 61 deletions
diff --git a/sound/decoders/raw.cpp b/sound/decoders/raw.cpp
index ecdde10250..cf114a25cc 100644
--- a/sound/decoders/raw.cpp
+++ b/sound/decoders/raw.cpp
@@ -138,71 +138,59 @@ class RawDiskStream : public SeekableAudioStream {
#endif
protected:
- byte* _buffer; ///< Streaming buffer
- const byte *_ptr; ///< Pointer to current position in stream buffer
- const int _rate; ///< Sample rate of stream
-
- Timestamp _playtime; ///< Calculated total play time
- Common::SeekableReadStream *_stream; ///< Stream to read data from
- int32 _filePos; ///< Current position in stream
- int32 _diskLeft; ///< Samples left in stream in current block not yet read to buffer
- int32 _bufferLeft; ///< Samples left in buffer in current block
- const DisposeAfterUse::Flag _disposeAfterUse; ///< Indicates whether the stream object should be deleted when this RawDiskStream is destructed
-
- RawDiskStreamAudioBlock *_audioBlock; ///< Audio block list
- const int _audioBlockCount; ///< Number of blocks in _audioBlock
- int _currentBlock; ///< Current audio block number
+ byte *_buffer; ///< Streaming buffer
+ const byte *_ptr; ///< Pointer to current position in stream buffer
+ const int _rate; ///< Sample rate of stream
+
+ Timestamp _playtime; ///< Calculated total play time
+ Common::SeekableReadStream *_stream; ///< Stream to read data from
+ int32 _filePos; ///< Current position in stream
+ int32 _diskLeft; ///< Samples left in stream in current block not yet read to buffer
+ int32 _bufferLeft; ///< Samples left in buffer in current block
+ const DisposeAfterUse::Flag _disposeAfterUse; ///< Indicates whether the stream object should be deleted when this RawDiskStream is destructed
+
+ const RawStreamBlockList _blocks; ///< Audio block list
+ RawStreamBlockList::const_iterator _curBlock; ///< Current audio block number
public:
- RawDiskStream(int rate, DisposeAfterUse::Flag disposeStream, Common::SeekableReadStream *stream, RawDiskStreamAudioBlock *block, uint numBlocks)
- : _rate(rate), _playtime(0, rate), _stream(stream), _disposeAfterUse(disposeStream),
- _audioBlockCount(numBlocks) {
+ RawDiskStream(int rate, DisposeAfterUse::Flag disposeStream, Common::SeekableReadStream *stream, const RawStreamBlockList &blocks)
+ : _rate(rate), _playtime(0, rate), _stream(stream), _disposeAfterUse(disposeStream), _blocks(blocks), _curBlock(blocks.begin()) {
- assert(numBlocks > 0);
+ assert(_blocks.size() > 0);
// Allocate streaming buffer
- if (is16Bit) {
+ if (is16Bit)
_buffer = (byte *)malloc(BUFFER_SIZE * sizeof(int16));
- } else {
+ else
_buffer = (byte *)malloc(BUFFER_SIZE * sizeof(byte));
- }
_ptr = _buffer;
_bufferLeft = 0;
- // Copy audio block data to our buffer
- // TODO: Replace this with a Common::Array or Common::List to
- // make it a little friendlier.
- _audioBlock = new RawDiskStreamAudioBlock[numBlocks];
- memcpy(_audioBlock, block, numBlocks * sizeof(RawDiskStreamAudioBlock));
-
// Set current buffer state, playing first block
- _currentBlock = 0;
- _filePos = _audioBlock[_currentBlock].pos;
- _diskLeft = _audioBlock[_currentBlock].len;
+ _filePos = _curBlock->pos;
+ _diskLeft = _curBlock->len;
// Add up length of all blocks in order to caluclate total play time
- int len = 0;
- for (int r = 0; r < _audioBlockCount; r++) {
- len += _audioBlock[r].len;
- }
+ int32 len = 0;
+ for (RawStreamBlockList::const_iterator i = _blocks.begin(); i != _blocks.end(); ++i)
+ len += i->len;
_playtime = Timestamp(0, len / (is16Bit ? 2 : 1) / (stereo ? 2 : 1), rate);
}
virtual ~RawDiskStream() {
- if (_disposeAfterUse == DisposeAfterUse::YES) {
+ if (_disposeAfterUse == DisposeAfterUse::YES)
delete _stream;
- }
- delete[] _audioBlock;
free(_buffer);
}
+
int readBuffer(int16 *buffer, const int numSamples);
- bool isStereo() const { return stereo; }
- bool endOfData() const { return (_currentBlock == _audioBlockCount - 1) && (_diskLeft == 0) && (_bufferLeft == 0); }
+ bool isStereo() const { return stereo; }
+ bool endOfData() const { return (_curBlock == _blocks.end()) && (_diskLeft == 0) && (_bufferLeft == 0); }
- int getRate() const { return _rate; }
+ int getRate() const { return _rate; }
Timestamp getLength() const { return _playtime; }
bool seek(const Timestamp &where);
@@ -215,7 +203,7 @@ int RawDiskStream<stereo, is16Bit, isUnsigned, isLE>::readBuffer(int16 *buffer,
int samples = numSamples;
- while (samples > 0 && ((_diskLeft > 0 || _bufferLeft > 0) || (_currentBlock != _audioBlockCount - 1)) ) {
+ while (samples > 0 && ((_diskLeft > 0 || _bufferLeft > 0) || _curBlock != _blocks.end())) {
// Output samples in the buffer to the output
int len = MIN<int>(samples, _bufferLeft);
samples -= len;
@@ -228,16 +216,18 @@ int RawDiskStream<stereo, is16Bit, isUnsigned, isLE>::readBuffer(int16 *buffer,
}
// Have we now finished this block? If so, read the next block
- if ((_bufferLeft == 0) && (_diskLeft == 0) && (_currentBlock != _audioBlockCount - 1)) {
+ if ((_bufferLeft == 0) && (_diskLeft == 0) && _curBlock != _blocks.end()) {
// Next block
- _currentBlock++;
+ ++_curBlock;
- _filePos = _audioBlock[_currentBlock].pos;
- _diskLeft = _audioBlock[_currentBlock].len;
+ if (_curBlock != _blocks.end()) {
+ _filePos = _curBlock->pos;
+ _diskLeft = _curBlock->len;
+ }
}
// Now read more data from disk if there is more to be read
- if ((_bufferLeft == 0) && (_diskLeft > 0)) {
+ if (_bufferLeft == 0 && _diskLeft > 0) {
int32 readAmount = MIN(_diskLeft, BUFFER_SIZE);
_stream->seek(_filePos, SEEK_SET);
@@ -259,9 +249,8 @@ int RawDiskStream<stereo, is16Bit, isUnsigned, isLE>::readBuffer(int16 *buffer,
// In case calling code relies on the position of this stream staying
// constant, I restore the location if I've changed it. This is probably
// not necessary.
- if (restoreFilePosition) {
+ if (restoreFilePosition)
_stream->seek(oldPos, SEEK_SET);
- }
return numSamples - samples;
}
@@ -272,28 +261,26 @@ bool RawDiskStream<stereo, is16Bit, isUnsigned, isLE>::seek(const Timestamp &whe
uint32 curSample = 0;
// Search for the disk block in which the specific sample is placed
- _currentBlock = 0;
- while (_currentBlock < _audioBlockCount) {
- uint32 nextBlockSample = curSample + _audioBlock[_currentBlock].len;
+ for (_curBlock = _blocks.begin(); _curBlock != _blocks.end(); ++_curBlock) {
+ uint32 nextBlockSample = curSample + _curBlock->len;
if (nextBlockSample > seekSample)
break;
curSample = nextBlockSample;
- ++_currentBlock;
}
_filePos = 0;
_diskLeft = 0;
_bufferLeft = 0;
- if (_currentBlock == _audioBlockCount) {
- return ((seekSample - curSample) == (uint32)_audioBlock[_currentBlock - 1].len);
+ if (_curBlock == _blocks.end()) {
+ return ((seekSample - curSample) == (uint32)_curBlock->len);
} else {
const uint32 offset = seekSample - curSample;
- _filePos = _audioBlock[_currentBlock].pos + offset * (is16Bit ? 2 : 1);
- _diskLeft = _audioBlock[_currentBlock].len - offset;
+ _filePos = _curBlock->pos + offset * (is16Bit ? 2 : 1);
+ _diskLeft = _curBlock->len - offset;
return true;
}
@@ -388,11 +375,11 @@ AudioStream *makeRawMemoryStream_OLD(const byte *ptr, uint32 len,
#define MAKE_LINEAR_DISK(STEREO, UNSIGNED) \
if (is16Bit) { \
if (isLE) \
- return new RawDiskStream<STEREO, true, UNSIGNED, true>(rate, disposeStream, stream, block, numBlocks); \
+ return new RawDiskStream<STEREO, true, UNSIGNED, true>(rate, disposeStream, stream, blocks); \
else \
- return new RawDiskStream<STEREO, true, UNSIGNED, false>(rate, disposeStream, stream, block, numBlocks); \
+ return new RawDiskStream<STEREO, true, UNSIGNED, false>(rate, disposeStream, stream, blocks); \
} else \
- return new RawDiskStream<STEREO, false, UNSIGNED, false>(rate, disposeStream, stream, block, numBlocks)
+ return new RawDiskStream<STEREO, false, UNSIGNED, false>(rate, disposeStream, stream, blocks)
SeekableAudioStream *makeRawDiskStream(Common::SeekableReadStream *stream, RawDiskStreamAudioBlock *block, int numBlocks,
@@ -402,6 +389,11 @@ SeekableAudioStream *makeRawDiskStream(Common::SeekableReadStream *stream, RawDi
const bool isUnsigned = (flags & Audio::FLAG_UNSIGNED) != 0;
const bool isLE = (flags & Audio::FLAG_LITTLE_ENDIAN) != 0;
+ assert(numBlocks > 0);
+ RawStreamBlockList blocks;
+ for (int i = 0; i < numBlocks; ++i)
+ blocks.push_back(block[i]);
+
if (isStereo) {
if (isUnsigned) {
MAKE_LINEAR_DISK(true, true);
diff --git a/sound/decoders/raw.h b/sound/decoders/raw.h
index f4de982d62..4136c9953e 100644
--- a/sound/decoders/raw.h
+++ b/sound/decoders/raw.h
@@ -29,6 +29,8 @@
#include "common/scummsys.h"
#include "common/types.h"
+#include "common/list.h"
+
namespace Common { class SeekableReadStream; }
@@ -105,11 +107,16 @@ AudioStream *makeRawMemoryStream_OLD(const byte *ptr, uint32 len,
* Struct used to define the audio data to be played by a RawDiskStream.
*/
struct RawDiskStreamAudioBlock {
- int32 pos; ///< Position in stream of the block
- int32 len; ///< Length of the block (in samples)
+ int32 pos; ///< Position in stream of the block (in bytes of course!)
+ int32 len; ///< Length of the block (in samples)
};
/**
+ * List containing all blocks of a raw stream.
+ */
+typedef Common::List<RawDiskStreamAudioBlock> RawStreamBlockList;
+
+/**
* Creates a audio stream, which plays from given stream.
*
* @param stream Stream to play from