From 91f5f1687cc40f1385c62655973c3dd65266e250 Mon Sep 17 00:00:00 2001 From: Max Horn Date: Fri, 26 Dec 2003 01:32:29 +0000 Subject: logic fix: we must do wrap around *before* read, not after. otherwise eosIntern will in some border cases return wrong results; some cleanup svn-id: r11932 --- sound/audiostream.cpp | 36 ++++++++++++++++++------------------ sound/audiostream.h | 2 +- sound/mixer.cpp | 10 ++++------ sound/rate.cpp | 2 ++ 4 files changed, 25 insertions(+), 25 deletions(-) diff --git a/sound/audiostream.cpp b/sound/audiostream.cpp index f3bf3552f9..0e86bc00d7 100644 --- a/sound/audiostream.cpp +++ b/sound/audiostream.cpp @@ -177,17 +177,15 @@ WrappedMemoryStream::WrappedMemoryStream(int rate, template inline int16 WrappedMemoryStream::read() { - if (eosIntern()) { - // If the stream contains no more data, it is silent... - return 0; - } - int16 val = READSAMPLE(is16Bit, isUnsigned, _pos); - _pos += (is16Bit ? 2 : 1); + assert(!eosIntern()); // Wrap around? if (_pos >= _bufferEnd) _pos = _pos - (_bufferEnd - _bufferStart); + int16 val = READSAMPLE(is16Bit, isUnsigned, _pos); + _pos += (is16Bit ? 2 : 1); + return val; } @@ -195,6 +193,10 @@ template int WrappedMemoryStream::readBuffer(int16 *buffer, const int numSamples) { int samples = 0; while (samples < numSamples && !eosIntern()) { + // Wrap around? + if (_pos >= _bufferEnd) + _pos = _pos - (_bufferEnd - _bufferStart); + const byte *endMarker = (_pos > _end) ? _bufferEnd : _end; const int len = MIN(numSamples, samples + (int)(endMarker - _pos) / (is16Bit ? 2 : 1)); while (samples < len) { @@ -202,9 +204,6 @@ int WrappedMemoryStream::readBuffer(int16 *buffer, _pos += (is16Bit ? 2 : 1); samples++; } - // Wrap around? - if (_pos >= _bufferEnd) - _pos = _pos - (_bufferEnd - _bufferStart); } return samples; } @@ -226,7 +225,7 @@ void WrappedMemoryStream::append(const byte *data, uint32 size_to_end_of_buffer = _bufferEnd - _end; len -= size_to_end_of_buffer; if ((_end < _pos) || (_bufferStart + len >= _pos)) { - debug(2, "WrappedMemoryStream: buffer overflow (A)"); + warning("WrappedMemoryStream: buffer overflow (A)"); return; } memcpy(_end, data, size_to_end_of_buffer); @@ -234,7 +233,7 @@ void WrappedMemoryStream::append(const byte *data, _end = _bufferStart + len; } else { if ((_end < _pos) && (_end + len >= _pos)) { - debug(2, "WrappedMemoryStream: buffer overflow (B)"); + warning("WrappedMemoryStream: buffer overflow (B)"); return; } memcpy(_end, data, len); @@ -319,17 +318,18 @@ public: #define MAKE_LINEAR(STEREO, UNSIGNED) \ if (is16Bit) { \ if (isLE) \ - return new LinearMemoryStream(rate, ptr, len, loopOffset, loopLen, autoFreeMemory); \ + return new LinearMemoryStream(rate, ptr, len, loopOffset, loopLen, autoFree); \ else \ - return new LinearMemoryStream(rate, ptr, len, loopOffset, loopLen, autoFreeMemory); \ + return new LinearMemoryStream(rate, ptr, len, loopOffset, loopLen, autoFree); \ } else \ - return new LinearMemoryStream(rate, ptr, len, loopOffset, loopLen, autoFreeMemory) + return new LinearMemoryStream(rate, ptr, len, loopOffset, loopLen, autoFree) -AudioInputStream *makeLinearInputStream(int rate, byte _flags, const byte *ptr, uint32 len, uint loopOffset, uint loopLen, bool autoFreeMemory) { - const bool isStereo = (_flags & SoundMixer::FLAG_STEREO) != 0; - const bool is16Bit = (_flags & SoundMixer::FLAG_16BITS) != 0; +AudioInputStream *makeLinearInputStream(int rate, byte _flags, const byte *ptr, uint32 len, uint loopOffset, uint loopLen) { + const bool isStereo = (_flags & SoundMixer::FLAG_STEREO) != 0; + const bool is16Bit = (_flags & SoundMixer::FLAG_16BITS) != 0; const bool isUnsigned = (_flags & SoundMixer::FLAG_UNSIGNED) != 0; - const bool isLE = (_flags & SoundMixer::FLAG_LITTLE_ENDIAN) != 0; + const bool isLE = (_flags & SoundMixer::FLAG_LITTLE_ENDIAN) != 0; + const bool autoFree = (_flags & SoundMixer::FLAG_AUTOFREE) != 0; if (isStereo) { if (isUnsigned) { diff --git a/sound/audiostream.h b/sound/audiostream.h index 86d6c1be66..e31c3ac505 100644 --- a/sound/audiostream.h +++ b/sound/audiostream.h @@ -100,7 +100,7 @@ public: int getRate() const { return -1; } }; -AudioInputStream *makeLinearInputStream(int rate, byte _flags, const byte *ptr, uint32 len, uint loopOffset, uint loopLen, bool autoFreeMemory = false); +AudioInputStream *makeLinearInputStream(int rate, byte _flags, const byte *ptr, uint32 len, uint loopOffset, uint loopLen); WrappedAudioInputStream *makeWrappedInputStream(int rate, byte _flags, uint32 len); #endif diff --git a/sound/mixer.cpp b/sound/mixer.cpp index 1549424720..815aa9d347 100644 --- a/sound/mixer.cpp +++ b/sound/mixer.cpp @@ -219,13 +219,11 @@ void SoundMixer::insertChannel(PlayingSoundHandle *handle, Channel *chan) { void SoundMixer::playRaw(PlayingSoundHandle *handle, void *sound, uint32 size, uint rate, byte flags, int id, byte volume, int8 pan, uint32 loopStart, uint32 loopEnd) { Common::StackLock lock(_mutex); - const bool autoFreeMemory = (flags & SoundMixer::FLAG_AUTOFREE) != 0; - // Prevent duplicate sounds if (id != -1) { for (int i = 0; i != NUM_CHANNELS; i++) if (_channels[i] != 0 && _channels[i]->getId() == id) { - if (autoFreeMemory) + if ((flags & SoundMixer::FLAG_AUTOFREE) != 0) free(sound); return; } @@ -235,13 +233,13 @@ void SoundMixer::playRaw(PlayingSoundHandle *handle, void *sound, uint32 size, u AudioInputStream *input; if (flags & SoundMixer::FLAG_LOOP) { if (loopEnd == 0) { - input = makeLinearInputStream(rate, flags, (byte *)sound, size, 0, size, autoFreeMemory); + input = makeLinearInputStream(rate, flags, (byte *)sound, size, 0, size); } else { assert(loopStart < loopEnd && loopEnd <= size); - input = makeLinearInputStream(rate, flags, (byte *)sound, size, loopStart, loopEnd - loopStart, autoFreeMemory); + input = makeLinearInputStream(rate, flags, (byte *)sound, size, loopStart, loopEnd - loopStart); } } else { - input = makeLinearInputStream(rate, flags, (byte *)sound, size, 0, 0, autoFreeMemory); + input = makeLinearInputStream(rate, flags, (byte *)sound, size, 0, 0); } // Create the channel diff --git a/sound/rate.cpp b/sound/rate.cpp index a30837248e..45046cb80b 100644 --- a/sound/rate.cpp +++ b/sound/rate.cpp @@ -192,6 +192,8 @@ the_end: /** * Simple audio rate converter for the case that the inrate equals the outrate. + * @todo This is inefficient, it would be better if this used readBuffer() + * instead of read(). */ template class CopyRateConverter : public RateConverter { -- cgit v1.2.3