diff options
Diffstat (limited to 'sound')
-rw-r--r-- | sound/audiostream.cpp | 14 | ||||
-rw-r--r-- | sound/audiostream.h | 7 | ||||
-rw-r--r-- | sound/mixer.cpp | 42 | ||||
-rw-r--r-- | sound/mixer.h | 3 | ||||
-rw-r--r-- | sound/rate.h | 2 |
5 files changed, 52 insertions, 16 deletions
diff --git a/sound/audiostream.cpp b/sound/audiostream.cpp index 133333503b..b6ac2d08a1 100644 --- a/sound/audiostream.cpp +++ b/sound/audiostream.cpp @@ -40,7 +40,7 @@ static inline int16 readSample(const byte *ptr) { template<bool stereo, bool is16Bit, bool isUnsigned> -class LinearMemoryStream : public AudioInputStream { +class LinearMemoryStream : public LinearAudioInputStream { protected: const byte *_ptr; const byte *_end; @@ -58,11 +58,17 @@ public: return val; } bool eof() const { - return _end <= _ptr; + return _ptr >= _end; } 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); + } }; @@ -413,7 +419,7 @@ void VorbisInputStream::refill() { template<bool stereo> -static AudioInputStream *makeLinearInputStream(const byte *ptr, uint32 len, bool is16Bit, bool isUnsigned) { +static LinearAudioInputStream *makeLinearInputStream(const byte *ptr, uint32 len, bool is16Bit, bool isUnsigned) { if (isUnsigned) { if (is16Bit) return new LinearMemoryStream<stereo, true, true>(ptr, len); @@ -444,7 +450,7 @@ static WrappedAudioInputStream *makeWrappedInputStream(uint32 len, bool is16Bit, } -AudioInputStream *makeLinearInputStream(byte _flags, const byte *ptr, uint32 len) { +LinearAudioInputStream *makeLinearInputStream(byte _flags, const byte *ptr, uint32 len) { const bool is16Bit = (_flags & SoundMixer::FLAG_16BITS) != 0; const bool isUnsigned = (_flags & SoundMixer::FLAG_UNSIGNED) != 0; if (_flags & SoundMixer::FLAG_STEREO) { diff --git a/sound/audiostream.h b/sound/audiostream.h index 6611018c3d..04c0c4fc9f 100644 --- a/sound/audiostream.h +++ b/sound/audiostream.h @@ -53,6 +53,11 @@ 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; @@ -118,7 +123,7 @@ public: -AudioInputStream *makeLinearInputStream(byte _flags, const byte *ptr, uint32 len); +LinearAudioInputStream *makeLinearInputStream(byte _flags, const byte *ptr, uint32 len); WrappedAudioInputStream *makeWrappedInputStream(byte _flags, uint32 len); diff --git a/sound/mixer.cpp b/sound/mixer.cpp index aa297896a6..0171d1bb26 100644 --- a/sound/mixer.cpp +++ b/sound/mixer.cpp @@ -67,19 +67,19 @@ class ChannelRaw : public Channel { byte _flags; #ifdef SOX_HACK RateConverter *_converter; - AudioInputStream *_input; + LinearAudioInputStream *_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); + ChannelRaw(SoundMixer *mixer, PlayingSoundHandle *handle, void *sound, uint32 size, uint rate, byte flags, int id, uint32 loopStart, uint32 loopEnd); ~ChannelRaw(); void mix(int16 *data, uint len); @@ -272,7 +272,7 @@ int SoundMixer::insertChannel(PlayingSoundHandle *handle, Channel *chan) { return index; } -int SoundMixer::playRaw(PlayingSoundHandle *handle, void *sound, uint32 size, uint rate, byte flags, int id) { +int SoundMixer::playRaw(PlayingSoundHandle *handle, void *sound, uint32 size, uint rate, byte flags, int id, uint32 loopStart, uint32 loopEnd) { StackLock lock(_mutex); // Prevent duplicate sounds @@ -282,7 +282,7 @@ int SoundMixer::playRaw(PlayingSoundHandle *handle, void *sound, uint32 size, ui return -1; } - return insertChannel(handle, new ChannelRaw(this, handle, sound, size, rate, flags, id)); + return insertChannel(handle, new ChannelRaw(this, handle, sound, size, rate, flags, id, loopStart, loopEnd)); } #ifdef USE_MAD @@ -651,7 +651,7 @@ static int16 mixer_element_size[] = { #endif /* RAW mixer */ -ChannelRaw::ChannelRaw(SoundMixer *mixer, PlayingSoundHandle *handle, void *sound, uint32 size, uint rate, byte flags, int id) +ChannelRaw::ChannelRaw(SoundMixer *mixer, PlayingSoundHandle *handle, void *sound, uint32 size, uint rate, byte flags, int id, uint32 loopStart, uint32 loopEnd) : Channel(mixer, handle) { _id = id; _ptr = (byte *)sound; @@ -665,6 +665,23 @@ ChannelRaw::ChannelRaw(SoundMixer *mixer, PlayingSoundHandle *handle, void *soun // Get a rate converter instance _converter = makeRateConverter(rate, mixer->getOutputRate(), _input->isStereo()); + printf(" data has %d bits and is %s\n", + ((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; @@ -705,9 +722,13 @@ void ChannelRaw::mix(int16 *data, uint len) { if (_input->eof()) { // TODO: call drain method - // TODO: Looping - destroy(); - return; + // Loop if requested + if (_loop_ptr) { + _input->reset(_loop_ptr, _loop_size); + } else { + destroy(); + return; + } } const int volume = _mixer->getVolume(); @@ -756,6 +777,9 @@ ChannelStream::ChannelStream(SoundMixer *mixer, PlayingSoundHandle *handle, void // Get a rate converter instance _converter = makeRateConverter(rate, mixer->getOutputRate(), _input->isStereo()); + printf(" data has %d bits and is %s\n", + ((flags & SoundMixer::FLAG_16BITS) ? 16 : 8), + ((flags & SoundMixer::FLAG_UNSIGNED) ? "unsigned" : "signed")); #else _flags = flags; _bufferSize = buffer_size; diff --git a/sound/mixer.h b/sound/mixer.h index ff156b5a08..e6060268e2 100644 --- a/sound/mixer.h +++ b/sound/mixer.h @@ -82,7 +82,8 @@ public: ~SoundMixer(); // start playing a raw sound - int playRaw(PlayingSoundHandle *handle, void *sound, uint32 size, uint rate, byte flags, int id = -1); + int playRaw(PlayingSoundHandle *handle, void *sound, uint32 size, uint rate, byte flags, + int id = -1, uint32 loopStart = 0, uint32 loopEnd = 0); #ifdef USE_MAD int playMP3(PlayingSoundHandle *handle, File *file, uint32 size); int playMP3CDTrack(PlayingSoundHandle *handle, File *file, mad_timer_t duration); diff --git a/sound/rate.h b/sound/rate.h index 31f90dc5f8..7a84526e2b 100644 --- a/sound/rate.h +++ b/sound/rate.h @@ -94,7 +94,7 @@ public: }; static inline RateConverter *makeRateConverter(st_rate_t inrate, st_rate_t outrate, bool stereo) { -// printf("makeRateConverter: inrate %d, outrate %d\n", inrate, outrate); +printf("makeRateConverter: inrate %d, outrate %d, %s\n", inrate, outrate, (stereo ? "stereo" : "mono")); if (inrate != outrate) { return new LinearRateConverter(inrate, outrate); //return new ResampleRateConverter(inrate, outrate, 1); |