aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMax Horn2003-08-01 16:32:11 +0000
committerMax Horn2003-08-01 16:32:11 +0000
commit1cfa9d90298f826e2485883ce4b90a09cd8a9329 (patch)
treef5767238462fec424a72fcc4ee477018324e7713
parent252b8ed4b92fe0906b1162b4155d94185987553a (diff)
downloadscummvm-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.cpp38
-rw-r--r--sound/audiostream.h7
-rw-r--r--sound/mixer.cpp49
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) {