aboutsummaryrefslogtreecommitdiff
path: root/sound
diff options
context:
space:
mode:
Diffstat (limited to 'sound')
-rw-r--r--sound/audiostream.cpp63
-rw-r--r--sound/audiostream.h23
-rw-r--r--sound/mixer.cpp86
3 files changed, 75 insertions, 97 deletions
diff --git a/sound/audiostream.cpp b/sound/audiostream.cpp
index 6a74cbc42c..a0dfcbbfcb 100644
--- a/sound/audiostream.cpp
+++ b/sound/audiostream.cpp
@@ -50,11 +50,12 @@ protected:
const byte *_end;
const byte *_loopPtr;
const byte *_loopEnd;
+ const int _rate;
inline bool eosIntern() const { return _ptr >= _end; };
public:
- LinearMemoryStream(const byte *ptr, uint len, uint loopOffset, uint loopLen)
- : _ptr(ptr), _end(ptr+len), _loopPtr(0), _loopEnd(0) {
+ LinearMemoryStream(int rate, const byte *ptr, uint len, uint loopOffset, uint loopLen)
+ : _ptr(ptr), _end(ptr+len), _loopPtr(0), _loopEnd(0), _rate(rate) {
// Verify the buffer sizes are sane
if (is16Bit && stereo)
@@ -81,8 +82,10 @@ public:
}
return val;
}
- bool eos() const { return eosIntern(); }
bool isStereo() const { return stereo; }
+ bool eos() const { return eosIntern(); }
+
+ int getRate() const { return _rate; }
};
template<bool stereo, bool is16Bit, bool isUnsigned, bool isLE>
@@ -119,16 +122,19 @@ protected:
byte *_pos;
byte *_end;
bool _finalized;
+ const int _rate;
inline bool eosIntern() const { return _end == _pos; };
public:
- WrappedMemoryStream(uint bufferSize);
+ WrappedMemoryStream(int rate, uint bufferSize);
~WrappedMemoryStream() { free(_bufferStart); }
int readBuffer(int16 *buffer, const int numSamples);
int16 read();
- bool eos() const { return _finalized; }
bool isStereo() const { return stereo; }
+ bool eos() const { return _finalized; }
+
+ int getRate() const { return _rate; }
void append(const byte *data, uint32 len);
void finish() { _finalized = true; }
@@ -136,7 +142,8 @@ public:
template<bool stereo, bool is16Bit, bool isUnsigned>
-WrappedMemoryStream<stereo, is16Bit, isUnsigned>::WrappedMemoryStream(uint bufferSize) {
+WrappedMemoryStream<stereo, is16Bit, isUnsigned>::WrappedMemoryStream(int rate, uint bufferSize)
+ : _rate(rate) {
// Verify the buffer size is sane
if (is16Bit && stereo)
@@ -225,7 +232,7 @@ void WrappedMemoryStream<stereo, is16Bit, isUnsigned>::append(const byte *data,
#ifdef USE_MAD
-class MP3InputStream : public MusicStream {
+class MP3InputStream : public AudioInputStream {
struct mad_stream _stream;
struct mad_frame _frame;
struct mad_synth _synth;
@@ -449,7 +456,7 @@ int MP3InputStream::readBuffer(int16 *buffer, const int numSamples) {
return samples;
}
-MusicStream *makeMP3Stream(File *file, mad_timer_t duration, uint size) {
+AudioInputStream *makeMP3Stream(File *file, mad_timer_t duration, uint size) {
return new MP3InputStream(file, duration, size);
}
@@ -463,7 +470,7 @@ MusicStream *makeMP3Stream(File *file, mad_timer_t duration, uint size) {
#ifdef USE_VORBIS
-class VorbisInputStream : public MusicStream {
+class VorbisInputStream : public AudioInputStream {
OggVorbis_File *_ov_file;
int _end_pos;
int _numChannels;
@@ -572,7 +579,7 @@ void VorbisInputStream::refill() {
_bufferEnd = (int16 *)read_pos;
}
-MusicStream *makeVorbisStream(OggVorbis_File *file, int duration) {
+AudioInputStream *makeVorbisStream(OggVorbis_File *file, int duration) {
return new VorbisInputStream(file, duration);
}
@@ -585,58 +592,58 @@ MusicStream *makeVorbisStream(OggVorbis_File *file, int duration) {
template<bool stereo>
-static AudioInputStream *makeLinearInputStream(const byte *ptr, uint32 len, bool is16Bit, bool isUnsigned, bool isLE, uint loopOffset, uint loopLen) {
+static AudioInputStream *makeLinearInputStream(int rate, const byte *ptr, uint32 len, bool is16Bit, bool isUnsigned, bool isLE, uint loopOffset, uint loopLen) {
if (isUnsigned) {
if (is16Bit) {
if (isLE)
- return new LinearMemoryStream<stereo, true, true, true>(ptr, len, loopOffset, loopLen);
+ return new LinearMemoryStream<stereo, true, true, true>(rate, ptr, len, loopOffset, loopLen);
else
- return new LinearMemoryStream<stereo, true, true, false>(ptr, len, loopOffset, loopLen);
+ return new LinearMemoryStream<stereo, true, true, false>(rate, ptr, len, loopOffset, loopLen);
} else
- return new LinearMemoryStream<stereo, false, true, false>(ptr, len, loopOffset, loopLen);
+ return new LinearMemoryStream<stereo, false, true, false>(rate, ptr, len, loopOffset, loopLen);
} else {
if (is16Bit) {
if (isLE)
- return new LinearMemoryStream<stereo, true, false, true>(ptr, len, loopOffset, loopLen);
+ return new LinearMemoryStream<stereo, true, false, true>(rate, ptr, len, loopOffset, loopLen);
else
- return new LinearMemoryStream<stereo, true, false, false>(ptr, len, loopOffset, loopLen);
+ return new LinearMemoryStream<stereo, true, false, false>(rate, ptr, len, loopOffset, loopLen);
} else
- return new LinearMemoryStream<stereo, false, false, false>(ptr, len, loopOffset, loopLen);
+ return new LinearMemoryStream<stereo, false, false, false>(rate, ptr, len, loopOffset, loopLen);
}
}
template<bool stereo>
-static WrappedAudioInputStream *makeWrappedInputStream(uint32 len, bool is16Bit, bool isUnsigned) {
+static WrappedAudioInputStream *makeWrappedInputStream(int rate, uint32 len, bool is16Bit, bool isUnsigned) {
if (isUnsigned) {
if (is16Bit)
- return new WrappedMemoryStream<stereo, true, true>(len);
+ return new WrappedMemoryStream<stereo, true, true>(rate, len);
else
- return new WrappedMemoryStream<stereo, false, true>(len);
+ return new WrappedMemoryStream<stereo, false, true>(rate, len);
} else {
if (is16Bit)
- return new WrappedMemoryStream<stereo, true, false>(len);
+ return new WrappedMemoryStream<stereo, true, false>(rate, len);
else
- return new WrappedMemoryStream<stereo, false, false>(len);
+ return new WrappedMemoryStream<stereo, false, false>(rate, len);
}
}
-AudioInputStream *makeLinearInputStream(byte _flags, const byte *ptr, uint32 len, uint loopOffset, uint loopLen) {
+AudioInputStream *makeLinearInputStream(int rate, 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;
const bool isLE = (_flags & SoundMixer::FLAG_LITTLE_ENDIAN) != 0;
if (_flags & SoundMixer::FLAG_STEREO) {
- return makeLinearInputStream<true>(ptr, len, is16Bit, isUnsigned, isLE, loopOffset, loopLen);
+ return makeLinearInputStream<true>(rate, ptr, len, is16Bit, isUnsigned, isLE, loopOffset, loopLen);
} else {
- return makeLinearInputStream<false>(ptr, len, is16Bit, isUnsigned, isLE, loopOffset, loopLen);
+ return makeLinearInputStream<false>(rate, ptr, len, is16Bit, isUnsigned, isLE, loopOffset, loopLen);
}
}
-WrappedAudioInputStream *makeWrappedInputStream(byte _flags, uint32 len) {
+WrappedAudioInputStream *makeWrappedInputStream(int rate, byte _flags, uint32 len) {
const bool is16Bit = (_flags & SoundMixer::FLAG_16BITS) != 0;
const bool isUnsigned = (_flags & SoundMixer::FLAG_UNSIGNED) != 0;
if (_flags & SoundMixer::FLAG_STEREO) {
- return makeWrappedInputStream<true>(len, is16Bit, isUnsigned);
+ return makeWrappedInputStream<true>(rate, len, is16Bit, isUnsigned);
} else {
- return makeWrappedInputStream<false>(len, is16Bit, isUnsigned);
+ return makeWrappedInputStream<false>(rate, len, is16Bit, isUnsigned);
}
}
diff --git a/sound/audiostream.h b/sound/audiostream.h
index 5e8455cc5a..ef702d3259 100644
--- a/sound/audiostream.h
+++ b/sound/audiostream.h
@@ -68,16 +68,17 @@ public:
return samples;
}
- /** Read a singel (16 bit signed) sample from the stream. */
+ /** Read a single (16 bit signed) sample from the stream. */
virtual int16 read() = 0;
/** Is this a stereo stream? */
virtual bool isStereo() const = 0;
- /* End of stream reached? */
+ /** End of stream reached? */
virtual bool eos() const = 0;
- virtual int getRate() const { return -1; }
+ /** Sample rate of the stream. */
+ virtual int getRate() const = 0;
};
class WrappedAudioInputStream : public AudioInputStream {
@@ -101,23 +102,19 @@ public:
int size() const { return _len; }
bool isStereo() const { return false; }
bool eos() const { return _len <= 0; }
+
+ int getRate() const { return -1; }
};
-class MusicStream : public AudioInputStream {
-public:
- virtual int getRate() const = 0;
-};
-
-
-AudioInputStream *makeLinearInputStream(byte _flags, const byte *ptr, uint32 len, uint loopOffset, uint loopLen);
-WrappedAudioInputStream *makeWrappedInputStream(byte _flags, uint32 len);
+AudioInputStream *makeLinearInputStream(int rate, byte _flags, const byte *ptr, uint32 len, uint loopOffset, uint loopLen);
+WrappedAudioInputStream *makeWrappedInputStream(int rate, byte _flags, uint32 len);
#ifdef USE_MAD
-MusicStream *makeMP3Stream(File *file, mad_timer_t duration, uint size = 0);
+AudioInputStream *makeMP3Stream(File *file, mad_timer_t duration, uint size = 0);
#endif
#ifdef USE_VORBIS
-MusicStream *makeVorbisStream(OggVorbis_File *file, int duration);
+AudioInputStream *makeVorbisStream(OggVorbis_File *file, int duration);
#endif
diff --git a/sound/mixer.cpp b/sound/mixer.cpp
index df2a25036c..96720f0aa1 100644
--- a/sound/mixer.cpp
+++ b/sound/mixer.cpp
@@ -57,6 +57,15 @@ public:
: _mixer(mixer), _handle(handle), _isMusic(isMusic), _volume(volume), _pan(pan), _paused(false), _converter(0), _input(0), _id(-1) {
assert(mixer);
}
+
+ Channel(SoundMixer *mixer, PlayingSoundHandle *handle, AudioInputStream *input, bool isMusic, byte volume, int8 pan, bool reverseStereo = false)
+ : _mixer(mixer), _handle(handle), _isMusic(isMusic), _volume(volume), _pan(pan), _paused(false), _converter(0), _input(input), _id(-1) {
+ assert(mixer);
+ assert(input);
+
+ // Get a rate converter instance
+ _converter = makeRateConverter(_input->getRate(), mixer->getOutputRate(), _input->isStereo(), reverseStereo);
+ }
virtual ~Channel();
void destroy();
virtual void mix(int16 *data, uint len);
@@ -96,22 +105,6 @@ public:
void finish();
};
-#ifdef USE_MAD
-class ChannelMP3 : public Channel {
-public:
- ChannelMP3(SoundMixer *mixer, PlayingSoundHandle *handle, File *file, uint size, byte volume, int8 pan);
- ChannelMP3(SoundMixer *mixer, PlayingSoundHandle *handle, File *file, mad_timer_t duration, byte volume, int8 pan);
-};
-#endif // USE_MAD
-
-#ifdef USE_VORBIS
-class ChannelVorbis : public Channel {
-public:
- ChannelVorbis(SoundMixer *mixer, PlayingSoundHandle *handle, OggVorbis_File *ov_file, int duration, bool isMusic, byte volume, int8 pan);
-};
-#endif // USE_VORBIS
-
-
#pragma mark -
#pragma mark --- SoundMixer ---
#pragma mark -
@@ -255,18 +248,30 @@ int SoundMixer::playRaw(PlayingSoundHandle *handle, void *sound, uint32 size, ui
#ifdef USE_MAD
int SoundMixer::playMP3(PlayingSoundHandle *handle, File *file, uint32 size, byte volume, int8 pan) {
Common::StackLock lock(_mutex);
- return insertChannel(handle, new ChannelMP3(this, handle, file, size, volume, pan));
+
+ // Create the input stream
+ AudioInputStream *input = makeMP3Stream(file, mad_timer_zero, size);
+ Channel *chan = new Channel(this, handle, input, false, volume, pan);
+ return insertChannel(handle, chan);
}
int SoundMixer::playMP3CDTrack(PlayingSoundHandle *handle, File *file, mad_timer_t duration, byte volume, int8 pan) {
Common::StackLock lock(_mutex);
- return insertChannel(handle, new ChannelMP3(this, handle, file, duration, volume, pan));
+
+ // Create the input stream
+ AudioInputStream *input = makeMP3Stream(file, duration, 0);
+ Channel *chan = new Channel(this, handle, input, true, volume, pan);
+ return insertChannel(handle, chan);
}
#endif
#ifdef USE_VORBIS
int SoundMixer::playVorbis(PlayingSoundHandle *handle, OggVorbis_File *ov_file, int duration, bool is_cd_track, byte volume, int8 pan) {
Common::StackLock lock(_mutex);
- return insertChannel(handle, new ChannelVorbis(this, handle, ov_file, duration, is_cd_track, volume, pan));
+
+ // Create the input stream
+ AudioInputStream *input = makeVorbisStream(ov_file, duration);
+ Channel *chan = new Channel(this, handle, input, is_cd_track, volume, pan);
+ return insertChannel(handle, chan);
}
#endif
@@ -509,20 +514,20 @@ ChannelRaw::ChannelRaw(SoundMixer *mixer, PlayingSoundHandle *handle, void *soun
// Create the input stream
if (flags & SoundMixer::FLAG_LOOP) {
if (loopEnd == 0) {
- _input = makeLinearInputStream(flags, _ptr, size, 0, size);
+ _input = makeLinearInputStream(rate, flags, _ptr, size, 0, size);
} else {
assert(loopStart < loopEnd && loopEnd <= size);
- _input = makeLinearInputStream(flags, _ptr, size, loopStart, loopEnd - loopStart);
+ _input = makeLinearInputStream(rate, flags, _ptr, size, loopStart, loopEnd - loopStart);
}
} else {
- _input = makeLinearInputStream(flags, _ptr, size, 0, 0);
+ _input = makeLinearInputStream(rate, flags, _ptr, size, 0, 0);
}
if (!(flags & SoundMixer::FLAG_AUTOFREE))
_ptr = 0;
// Get a rate converter instance
- _converter = makeRateConverter(rate, mixer->getOutputRate(), _input->isStereo(), (flags & SoundMixer::FLAG_REVERSE_STEREO) != 0);
+ _converter = makeRateConverter(_input->getRate(), mixer->getOutputRate(), _input->isStereo(), (flags & SoundMixer::FLAG_REVERSE_STEREO) != 0);
}
ChannelRaw::~ChannelRaw() {
@@ -536,13 +541,13 @@ ChannelStream::ChannelStream(SoundMixer *mixer, PlayingSoundHandle *handle,
assert(size <= buffer_size);
// Create the input stream
- _input = makeWrappedInputStream(flags, buffer_size);
+ _input = makeWrappedInputStream(rate, flags, buffer_size);
// Append the initial data
append(sound, size);
// Get a rate converter instance
- _converter = makeRateConverter(rate, mixer->getOutputRate(), _input->isStereo(), (flags & SoundMixer::FLAG_REVERSE_STEREO) != 0);
+ _converter = makeRateConverter(_input->getRate(), mixer->getOutputRate(), _input->isStereo(), (flags & SoundMixer::FLAG_REVERSE_STEREO) != 0);
}
void ChannelStream::finish() {
@@ -552,34 +557,3 @@ void ChannelStream::finish() {
void ChannelStream::append(void *data, uint32 len) {
((WrappedAudioInputStream *)_input)->append((const byte *)data, len);
}
-
-#ifdef USE_MAD
-ChannelMP3::ChannelMP3(SoundMixer *mixer, PlayingSoundHandle *handle, File *file, uint size, byte volume, int8 pan)
- : Channel(mixer, handle, false, volume, pan) {
- // Create the input stream
- _input = makeMP3Stream(file, mad_timer_zero, size);
-
- // Get a rate converter instance
- _converter = makeRateConverter(_input->getRate(), mixer->getOutputRate(), _input->isStereo());
-}
-
-ChannelMP3::ChannelMP3(SoundMixer *mixer, PlayingSoundHandle *handle, File *file, mad_timer_t duration, byte volume, int8 pan)
- : Channel(mixer, handle, true, volume, pan) {
- // Create the input stream
- _input = makeMP3Stream(file, duration, 0);
-
- // Get a rate converter instance
- _converter = makeRateConverter(_input->getRate(), mixer->getOutputRate(), _input->isStereo());
-}
-#endif // USE_MAD
-
-#ifdef USE_VORBIS
-ChannelVorbis::ChannelVorbis(SoundMixer *mixer, PlayingSoundHandle *handle, OggVorbis_File *ov_file, int duration, bool isMusic, byte volume, int8 pan)
- : Channel(mixer, handle, isMusic, volume, pan) {
- // Create the input stream
- _input = makeVorbisStream(ov_file, duration);
-
- // Get a rate converter instance
- _converter = makeRateConverter(_input->getRate(), mixer->getOutputRate(), _input->isStereo());
-}
-#endif // USE_VORBIS