aboutsummaryrefslogtreecommitdiff
path: root/sound
diff options
context:
space:
mode:
authorJohannes Schickel2010-01-07 16:08:41 +0000
committerJohannes Schickel2010-01-07 16:08:41 +0000
commit2e9bae44c5f80fe18aa0545b6c868682c380497c (patch)
tree50b97e4d1ab49e7ece8ecf9902d3e7df89eb8a52 /sound
parent8c03fffbf0c246b77b5d60604405aa898c58e6ea (diff)
downloadscummvm-rg350-2e9bae44c5f80fe18aa0545b6c868682c380497c.tar.gz
scummvm-rg350-2e9bae44c5f80fe18aa0545b6c868682c380497c.tar.bz2
scummvm-rg350-2e9bae44c5f80fe18aa0545b6c868682c380497c.zip
Let ADPCM streams subclass RewindableAudioStreams and thus allow them to be looped with the new looping code.
svn-id: r47127
Diffstat (limited to 'sound')
-rw-r--r--sound/adpcm.cpp34
-rw-r--r--sound/adpcm.h36
-rw-r--r--sound/wave.cpp19
3 files changed, 47 insertions, 42 deletions
diff --git a/sound/adpcm.cpp b/sound/adpcm.cpp
index 68ce9fafb0..ef8bb50c98 100644
--- a/sound/adpcm.cpp
+++ b/sound/adpcm.cpp
@@ -31,7 +31,7 @@
namespace Audio {
-class ADPCMInputStream : public AudioStream {
+class ADPCMInputStream : public RewindableAudioStream {
private:
Common::SeekableReadStream *_stream;
bool _disposeAfterUse;
@@ -45,8 +45,6 @@ private:
uint16 _chunkData;
int _blockLen;
int _rate;
- uint _numLoops;
- uint _curLoop;
struct ADPCMChannelStatus {
byte predictor;
@@ -84,7 +82,7 @@ private:
int16 decodeTinsel(int16, double);
public:
- ADPCMInputStream(Common::SeekableReadStream *stream, bool disposeAfterUse, uint32 size, typesADPCM type, int rate, int channels = 2, uint32 blockAlign = 0, uint numLoops = 1);
+ ADPCMInputStream(Common::SeekableReadStream *stream, bool disposeAfterUse, uint32 size, typesADPCM type, int rate, int channels, uint32 blockAlign);
~ADPCMInputStream();
int readBuffer(int16 *buffer, const int numSamples);
@@ -102,6 +100,8 @@ public:
bool endOfData() const { return (_stream->eos() || _stream->pos() >= _endpos); }
bool isStereo() const { return _channels == 2; }
int getRate() const { return _rate; }
+
+ bool rewind();
};
// Routines to convert 12 bit linear samples to the
@@ -114,8 +114,8 @@ public:
// In addition, also MS IMA ADPCM is supported. See
// <http://wiki.multimedia.cx/index.php?title=Microsoft_IMA_ADPCM>.
-ADPCMInputStream::ADPCMInputStream(Common::SeekableReadStream *stream, bool disposeAfterUse, uint32 size, typesADPCM type, int rate, int channels, uint32 blockAlign, uint numLoops)
- : _stream(stream), _disposeAfterUse(disposeAfterUse), _channels(channels), _type(type), _blockAlign(blockAlign), _rate(rate), _numLoops(numLoops) {
+ADPCMInputStream::ADPCMInputStream(Common::SeekableReadStream *stream, bool disposeAfterUse, uint32 size, typesADPCM type, int rate, int channels, uint32 blockAlign)
+ : _stream(stream), _disposeAfterUse(disposeAfterUse), _channels(channels), _type(type), _blockAlign(blockAlign), _rate(rate) {
if (type == kADPCMMSIma && blockAlign == 0)
error("ADPCMInputStream(): blockAlign isn't specified for MS IMA ADPCM");
@@ -138,7 +138,6 @@ ADPCMInputStream::ADPCMInputStream(Common::SeekableReadStream *stream, bool disp
_startpos = stream->pos();
_endpos = _startpos + size;
- _curLoop = 0;
reset();
}
@@ -156,6 +155,13 @@ void ADPCMInputStream::reset() {
_chunkPos = 0;
}
+bool ADPCMInputStream::rewind() {
+ // TODO: Error checking.
+ reset();
+ _stream->seek(_startpos);
+ return true;
+}
+
int ADPCMInputStream::readBuffer(int16 *buffer, const int numSamples) {
int samplesDecoded = 0;
switch (_type) {
@@ -191,16 +197,6 @@ int ADPCMInputStream::readBuffer(int16 *buffer, const int numSamples) {
break;
}
- // Loop if necessary
- if (samplesDecoded < numSamples || _stream->pos() == _endpos) {
- _curLoop++;
- if (_numLoops == 0 || _curLoop < _numLoops) {
- reset();
- _stream->seek(_startpos);
- return samplesDecoded + readBuffer(buffer + samplesDecoded, numSamples - samplesDecoded);
- }
- }
-
return samplesDecoded;
}
@@ -624,8 +620,8 @@ int16 ADPCMInputStream::decodeTinsel(int16 code, double eVal) {
return (int16) CLIP<double>(sample, -32768.0, 32767.0);
}
-AudioStream *makeADPCMStream(Common::SeekableReadStream *stream, bool disposeAfterUse, uint32 size, typesADPCM type, int rate, int channels, uint32 blockAlign, uint numLoops) {
- return new ADPCMInputStream(stream, disposeAfterUse, size, type, rate, channels, blockAlign, numLoops);
+RewindableAudioStream *makeADPCMStream(Common::SeekableReadStream *stream, bool disposeAfterUse, uint32 size, typesADPCM type, int rate, int channels, uint32 blockAlign) {
+ return new ADPCMInputStream(stream, disposeAfterUse, size, type, rate, channels, blockAlign);
}
} // End of namespace Audio
diff --git a/sound/adpcm.h b/sound/adpcm.h
index 48d003ae78..46ccb582c3 100644
--- a/sound/adpcm.h
+++ b/sound/adpcm.h
@@ -42,6 +42,7 @@
namespace Audio {
class AudioStream;
+class RewindableAudioStream;
// There are several types of ADPCM encoding, only some are supported here
// For all the different encodings, refer to:
@@ -61,27 +62,24 @@ enum typesADPCM {
/**
* Takes an input stream containing ADPCM compressed sound data and creates
- * an AudioStream from that.
+ * an RewindableAudioStream from that.
*
- * @param stream the SeekableReadStream from which to read the ADPCM data
- * @param disposeAfterUse whether to delete the stream after use
- * @param size how many bytes to read from the stream (0 = all)
- * @param type the compression type used
- * @param rate the sampling rate (default = 22050)
- * @param channels the number of channels (default = 2)
- * @param blockAlign block alignment ??? (default = 0)
- * @param numLoop how many types the sounds should loop, 0 for infinite loop (default = 1)
- * @return a new AudioStream, or NULL, if an error occured
+ * @param stream the SeekableReadStream from which to read the ADPCM data
+ * @param disposeAfterUse whether to delete the stream after use
+ * @param size how many bytes to read from the stream (0 = all)
+ * @param type the compression type used
+ * @param rate the sampling rate
+ * @param channels the number of channels
+ * @param blockAlign block alignment ???
+ * @return a new RewindableAudioStream, or NULL, if an error occured
*/
-AudioStream *makeADPCMStream(
- Common::SeekableReadStream *stream,
- bool disposeAfterUse,
- uint32 size,
- typesADPCM type,
- int rate = 22050,
- int channels = 2,
- uint32 blockAlign = 0,
- uint numLoops = 1);
+RewindableAudioStream *makeADPCMStream(
+ Common::SeekableReadStream *stream,
+ bool disposeAfterUse,
+ uint32 size, typesADPCM type,
+ int rate = 22050,
+ int channels = 2,
+ uint32 blockAlign = 0);
} // End of namespace Audio
diff --git a/sound/wave.cpp b/sound/wave.cpp
index 49189f3ea3..67aa7daa54 100644
--- a/sound/wave.cpp
+++ b/sound/wave.cpp
@@ -173,10 +173,21 @@ AudioStream *makeWAVStream(Common::SeekableReadStream *stream, bool disposeAfter
return 0;
}
- if (type == 17) // MS IMA ADPCM
- return makeADPCMStream(stream, disposeAfterUse, size, Audio::kADPCMMSIma, rate, (flags & Audio::Mixer::FLAG_STEREO) ? 2 : 1, blockAlign, loop ? 0 : 1);
- else if (type == 2) // MS ADPCM
- return makeADPCMStream(stream, disposeAfterUse, size, Audio::kADPCMMS, rate, (flags & Audio::Mixer::FLAG_STEREO) ? 2 : 1, blockAlign, loop ? 0 : 1);
+ if (type == 17) { // MS IMA ADPCM
+ RewindableAudioStream *adpcm = makeADPCMStream(stream, disposeAfterUse, size, Audio::kADPCMMSIma, rate, (flags & Audio::Mixer::FLAG_STEREO) ? 2 : 1, blockAlign);
+
+ if (loop)
+ return new LoopingAudioStream(adpcm, 0);
+ else
+ return adpcm;
+ } else if (type == 2) { // MS ADPCM
+ RewindableAudioStream *adpcm = makeADPCMStream(stream, disposeAfterUse, size, Audio::kADPCMMS, rate, (flags & Audio::Mixer::FLAG_STEREO) ? 2 : 1, blockAlign);
+
+ if (loop)
+ return new LoopingAudioStream(adpcm, 0);
+ else
+ return adpcm;
+ }
// Raw PCM. Just read everything at once.
// TODO: More elegant would be to wrap the stream.