diff options
author | Max Horn | 2003-08-01 16:32:11 +0000 |
---|---|---|
committer | Max Horn | 2003-08-01 16:32:11 +0000 |
commit | 1cfa9d90298f826e2485883ce4b90a09cd8a9329 (patch) | |
tree | f5767238462fec424a72fcc4ee477018324e7713 | |
parent | 252b8ed4b92fe0906b1162b4155d94185987553a (diff) | |
download | scummvm-rg350-1cfa9d90298f826e2485883ce4b90a09cd8a9329.tar.gz scummvm-rg350-1cfa9d90298f826e2485883ce4b90a09cd8a9329.tar.bz2 scummvm-rg350-1cfa9d90298f826e2485883ce4b90a09cd8a9329.zip |
let the input stream handle the looping (by pretending to be of infinite size -> this fixes a problem which cause 'gaps' at loop turn-over points)
svn-id: r9379
-rw-r--r-- | sound/audiostream.cpp | 38 | ||||
-rw-r--r-- | sound/audiostream.h | 7 | ||||
-rw-r--r-- | sound/mixer.cpp | 49 |
3 files changed, 42 insertions, 52 deletions
diff --git a/sound/audiostream.cpp b/sound/audiostream.cpp index b6ac2d08a1..8428de2d78 100644 --- a/sound/audiostream.cpp +++ b/sound/audiostream.cpp @@ -40,14 +40,20 @@ static inline int16 readSample(const byte *ptr) { template<bool stereo, bool is16Bit, bool isUnsigned> -class LinearMemoryStream : public LinearAudioInputStream { +class LinearMemoryStream : public AudioInputStream { protected: const byte *_ptr; const byte *_end; + const byte *_loopPtr; + const byte *_loopEnd; public: - LinearMemoryStream(const byte *ptr, uint len) - : _ptr(ptr), _end(ptr+len) { + LinearMemoryStream(const byte *ptr, uint len, uint loopOffset, uint loopLen) + : _ptr(ptr), _end(ptr+len), _loopPtr(0), _loopEnd(0) { + if (loopLen) { + _loopPtr = _ptr + loopOffset; + _loopEnd = _loopPtr + loopLen; + } if (stereo) // Stereo requires even sized data assert(len % 2 == 0); } @@ -55,6 +61,10 @@ public: assert(_ptr < _end); int16 val = readSample<is16Bit, isUnsigned>(_ptr); _ptr += (is16Bit ? 2 : 1); + if (_loopPtr && _ptr == _end) { + _ptr = _loopPtr; + _end = _loopEnd; + } return val; } bool eof() const { @@ -63,12 +73,6 @@ public: bool isStereo() const { return stereo; } - void reset(const byte *data, uint32 len) { - _ptr = data; - _end = data + len; - if (stereo) // Stereo requires even sized data - assert(len % 2 == 0); - } }; @@ -419,17 +423,17 @@ void VorbisInputStream::refill() { template<bool stereo> -static LinearAudioInputStream *makeLinearInputStream(const byte *ptr, uint32 len, bool is16Bit, bool isUnsigned) { +static AudioInputStream *makeLinearInputStream(const byte *ptr, uint32 len, bool is16Bit, bool isUnsigned, uint loopOffset, uint loopLen) { if (isUnsigned) { if (is16Bit) - return new LinearMemoryStream<stereo, true, true>(ptr, len); + return new LinearMemoryStream<stereo, true, true>(ptr, len, loopOffset, loopLen); else - return new LinearMemoryStream<stereo, false, true>(ptr, len); + return new LinearMemoryStream<stereo, false, true>(ptr, len, loopOffset, loopLen); } else { if (is16Bit) - return new LinearMemoryStream<stereo, true, false>(ptr, len); + return new LinearMemoryStream<stereo, true, false>(ptr, len, loopOffset, loopLen); else - return new LinearMemoryStream<stereo, false, false>(ptr, len); + return new LinearMemoryStream<stereo, false, false>(ptr, len, loopOffset, loopLen); } } @@ -450,13 +454,13 @@ static WrappedAudioInputStream *makeWrappedInputStream(uint32 len, bool is16Bit, } -LinearAudioInputStream *makeLinearInputStream(byte _flags, const byte *ptr, uint32 len) { +AudioInputStream *makeLinearInputStream(byte _flags, const byte *ptr, uint32 len, uint loopOffset, uint loopLen) { const bool is16Bit = (_flags & SoundMixer::FLAG_16BITS) != 0; const bool isUnsigned = (_flags & SoundMixer::FLAG_UNSIGNED) != 0; if (_flags & SoundMixer::FLAG_STEREO) { - return makeLinearInputStream<true>(ptr, len, is16Bit, isUnsigned); + return makeLinearInputStream<true>(ptr, len, is16Bit, isUnsigned, loopOffset, loopLen); } else { - return makeLinearInputStream<false>(ptr, len, is16Bit, isUnsigned); + return makeLinearInputStream<false>(ptr, len, is16Bit, isUnsigned, loopOffset, loopLen); } } diff --git a/sound/audiostream.h b/sound/audiostream.h index 04c0c4fc9f..722006e625 100644 --- a/sound/audiostream.h +++ b/sound/audiostream.h @@ -53,11 +53,6 @@ public: virtual bool eof() const = 0; }; -class LinearAudioInputStream : public AudioInputStream { -public: - virtual void reset(const byte *data, uint32 len) = 0; -}; - class WrappedAudioInputStream : public AudioInputStream { public: virtual void append(const byte *data, uint32 len) = 0; @@ -123,7 +118,7 @@ public: -LinearAudioInputStream *makeLinearInputStream(byte _flags, const byte *ptr, uint32 len); +AudioInputStream *makeLinearInputStream(byte _flags, const byte *ptr, uint32 len, uint loopOffset, uint loopLen); WrappedAudioInputStream *makeWrappedInputStream(byte _flags, uint32 len); diff --git a/sound/mixer.cpp b/sound/mixer.cpp index 0171d1bb26..6cb4823f2c 100644 --- a/sound/mixer.cpp +++ b/sound/mixer.cpp @@ -67,16 +67,16 @@ class ChannelRaw : public Channel { byte _flags; #ifdef SOX_HACK RateConverter *_converter; - LinearAudioInputStream *_input; + AudioInputStream *_input; #else uint32 _pos; uint32 _size; uint32 _fpSpeed; uint32 _fpPos; uint32 _realSize, _rate; -#endif byte *_loop_ptr; uint32 _loop_size; +#endif public: ChannelRaw(SoundMixer *mixer, PlayingSoundHandle *handle, void *sound, uint32 size, uint rate, byte flags, int id, uint32 loopStart, uint32 loopEnd); @@ -660,7 +660,16 @@ ChannelRaw::ChannelRaw(SoundMixer *mixer, PlayingSoundHandle *handle, void *soun #ifdef SOX_HACK // Create the input stream - _input = makeLinearInputStream(flags, _ptr, size); + if (flags & SoundMixer::FLAG_LOOP) { + if (loopEnd == 0) { + _input = makeLinearInputStream(flags, _ptr, size, 0, size); + } else { + assert(loopStart < loopEnd && loopEnd <= size); + _input = makeLinearInputStream(flags, _ptr, size, loopStart, loopEnd - loopStart); + } + } else { + _input = makeLinearInputStream(flags, _ptr, size, 0, 0); + } // TODO: add support for SoundMixer::FLAG_REVERSE_STEREO // Get a rate converter instance @@ -669,19 +678,6 @@ ChannelRaw::ChannelRaw(SoundMixer *mixer, PlayingSoundHandle *handle, void *soun ((flags & SoundMixer::FLAG_16BITS) ? 16 : 8), ((flags & SoundMixer::FLAG_UNSIGNED) ? "unsigned" : "signed")); - if (flags & SoundMixer::FLAG_LOOP) { - if (loopEnd == 0) { - _loop_ptr = _ptr; - _loop_size = size; - } else { - assert(loopStart < loopEnd && loopEnd <= size); - _loop_ptr = _ptr + loopStart; - _loop_size = loopEnd - loopStart; - } - } else { - _loop_ptr = 0; - _loop_size = 0; - } #else _pos = 0; _fpPos = 0; @@ -722,18 +718,13 @@ void ChannelRaw::mix(int16 *data, uint len) { if (_input->eof()) { // TODO: call drain method - // Loop if requested - if (_loop_ptr) { - _input->reset(_loop_ptr, _loop_size); - } else { - destroy(); - return; - } + destroy(); + return; } const int volume = _mixer->getVolume(); - uint tmpLen = len; - _converter->flow(*_input, data, (st_size_t *) &tmpLen, volume); + st_size_t tmpLen = len; + _converter->flow(*_input, data, &tmpLen, volume); #else byte *s, *end; @@ -856,8 +847,8 @@ void ChannelStream::mix(int16 *data, uint len) { } const int volume = _mixer->getVolume(); - uint tmpLen = len; - _converter->flow(*_input, data, (st_size_t *) &tmpLen, volume); + st_size_t tmpLen = len; + _converter->flow(*_input, data, &tmpLen, volume); #else if (_pos == _endOfData) { // Normally, the stream stays around even if all its data is used up. @@ -1043,7 +1034,7 @@ void ChannelMP3CDMusic::mix(int16 *data, uint len) { } const int volume = _mixer->getVolume(); - uint tmpLen = len; + st_size_t tmpLen = len; _converter->flow(*_input, data, &tmpLen, volume); #else mad_timer_t frame_duration; @@ -1205,7 +1196,7 @@ void ChannelVorbis::mix(int16 *data, uint len) { } const int volume = _mixer->getVolume(); - uint tmpLen = len; + st_size_t tmpLen = len; _converter->flow(*_input, data, &tmpLen, volume); #else if (_end_pos > 0 && ov_pcm_tell(_ov_file) >= _end_pos) { |