diff options
Diffstat (limited to 'sound')
-rw-r--r-- | sound/audiostream.cpp | 63 | ||||
-rw-r--r-- | sound/audiostream.h | 23 | ||||
-rw-r--r-- | sound/mixer.cpp | 86 |
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 |