diff options
-rw-r--r-- | sound/audiostream.cpp | 117 | ||||
-rw-r--r-- | sound/audiostream.h | 22 |
2 files changed, 74 insertions, 65 deletions
diff --git a/sound/audiostream.cpp b/sound/audiostream.cpp index 6fbf2acb1a..15ef73ff91 100644 --- a/sound/audiostream.cpp +++ b/sound/audiostream.cpp @@ -22,47 +22,89 @@ #include "audiostream.h" #include "mixer.h" -template<bool stereo, int sampleSize> + +template<bool is16Bit, bool isUnsigned> +static inline int16 readSample(const byte *ptr) { + if (is16Bit) { + if (isUnsigned) + return (int16)(READ_BE_UINT16(ptr) ^ 0x8000); + else + return (int16)READ_BE_UINT16(ptr); + } else { + if (isUnsigned) + return (int8)(*ptr ^ 0x80) << 8; + else + return (int8)*ptr << 8; + } +} + +#pragma mark - +#pragma mark --- WrappedMemoryStream --- +#pragma mark - + + +template<bool stereo, bool is16Bit, bool isUnsigned> class LinearMemoryStream : public AudioInputStream { protected: const byte *_ptr; const byte *_end; - void advance() { _ptr += sampleSize; } + public: - LinearMemoryStream(const byte *ptr, uint len) : _ptr(ptr), _end(ptr+len) { } - virtual int size() const { return (_end - _ptr) / sampleSize; } - virtual bool isStereo() const { return stereo; } + LinearMemoryStream(const byte *ptr, uint len) + : _ptr(ptr), _end(ptr+len) { + if (stereo) // Stereo requires even sized data + assert(len % 2 == 0); + } + int16 read() { + assert(_ptr < _end); + int16 val = readSample<is16Bit, isUnsigned>(_ptr); + _ptr += (is16Bit ? 2 : 1); + return val; + } + int size() const { + return (_end - _ptr) / (is16Bit ? 2 : 1); + } + bool isStereo() const { + return stereo; + } }; #pragma mark - +#pragma mark --- WrappedMemoryStream --- +#pragma mark - -template<bool stereo, int sampleSize> -WrappedMemoryStream<stereo, sampleSize>::WrappedMemoryStream(const byte *buffer, uint bufferSize) - : _bufferStart(buffer), _bufferEnd(buffer+bufferSize) { +template<bool stereo, bool is16Bit, bool isUnsigned> +WrappedMemoryStream<stereo, is16Bit, isUnsigned>::WrappedMemoryStream(const byte *buffer, uint bufferSize) + : _bufferStart(buffer), _bufferEnd(buffer+bufferSize), _pos(buffer), _end(buffer) { if (stereo) // Stereo requires an even sized buffer assert(bufferSize % 2 == 0); } -template<bool stereo, int sampleSize> -void WrappedMemoryStream<stereo, sampleSize>::advance() { - _pos += sampleSize; +template<bool stereo, bool is16Bit, bool isUnsigned> +int16 WrappedMemoryStream<stereo, is16Bit, isUnsigned>::read() { + assert(_pos != _end); + int16 val = readSample<is16Bit, isUnsigned>(_ptr); + _pos += (is16Bit ? 2 : 1); + // Wrap around? if (_pos >= _bufferEnd) _pos = _pos - (_bufferEnd - _bufferStart); + + return val; } -template<bool stereo, int sampleSize> -int WrappedMemoryStream<stereo, sampleSize>::size() const { +template<bool stereo, bool is16Bit, bool isUnsigned> +int WrappedMemoryStream<stereo, is16Bit, isUnsigned>::size() const { int len = _end - _pos; if (len < 0) len += (_bufferEnd - _bufferStart); - return len / sampleSize; + return len / (is16Bit ? 2 : 1); } -template<bool stereo, int sampleSize> -void WrappedMemoryStream<stereo, sampleSize>::append(const byte *data, uint32 len) { +template<bool stereo, bool is16Bit, bool isUnsigned> +void WrappedMemoryStream<stereo, is16Bit, isUnsigned>::append(const byte *data, uint32 len) { if (_end + len > _bufferEnd) { // Wrap-around case uint32 size_to_end_of_buffer = _bufferEnd - _end; @@ -86,53 +128,22 @@ void WrappedMemoryStream<stereo, sampleSize>::append(const byte *data, uint32 le #pragma mark - - - -template<bool stereo, class T = class LinearMemoryStream<stereo, 1> > -class Input8bitSignedStream : public T { -protected: - int16 readIntern() { int8 v = (int8)*_ptr; return v << 8; } -public: - Input8bitSignedStream(const byte *ptr, int len) : T(ptr, len) { } -}; - -template<bool stereo, class T = class LinearMemoryStream<stereo, 1> > -class Input8bitUnsignedStream : public T { -protected: - int16 readIntern() { int8 v = (int8)(*_ptr ^ 0x80); return v << 8; } -public: - Input8bitUnsignedStream(const byte *ptr, int len) : T(ptr, len) { } -}; - -template<bool stereo, class T = class LinearMemoryStream<stereo, 2> > -class Input16bitSignedStream : public T { -protected: - int16 readIntern() { return (int16)READ_BE_UINT16(_ptr); } -public: - Input16bitSignedStream(const byte *ptr, int len) : T(ptr, len) { } -}; - -template<bool stereo, class T = class LinearMemoryStream<stereo, 2> > -class Input16bitUnsignedStream : public T { -protected: - int16 readIntern() { return (int16)(READ_BE_UINT16(_ptr) ^ 0x8000); } -public: - Input16bitUnsignedStream(const byte *ptr, int len) : T(ptr, len) { } -}; +#pragma mark --- Input stream factories --- +#pragma mark - template<bool stereo> static AudioInputStream *makeInputStream(const byte *ptr, uint32 len, bool isUnsigned, bool is16Bit) { if (isUnsigned) { if (is16Bit) - return new Input16bitUnsignedStream<stereo>(ptr, len); + return new LinearMemoryStream<stereo, true, true>(ptr, len); else - return new Input8bitUnsignedStream<stereo>(ptr, len); + return new LinearMemoryStream<stereo, false, true>(ptr, len); } else { if (is16Bit) - return new Input16bitSignedStream<stereo>(ptr, len); + return new LinearMemoryStream<stereo, true, false>(ptr, len); else - return new Input8bitSignedStream<stereo>(ptr, len); + return new LinearMemoryStream<stereo, false, false>(ptr, len); } } diff --git a/sound/audiostream.h b/sound/audiostream.h index d0ac9d46c4..344664e276 100644 --- a/sound/audiostream.h +++ b/sound/audiostream.h @@ -35,29 +35,26 @@ * Generic input stream for the resampling code. */ class AudioInputStream { -protected: - virtual int16 readIntern() = 0; - virtual void advance() = 0; public: - int16 read() { assert(size() > 0); int16 val = readIntern(); advance(); return val; } + virtual int16 read() = 0; virtual int size() const = 0; - bool eof() const { return size() <= 0; } virtual bool isStereo() const = 0; + + bool eof() const { return size() <= 0; } }; class ZeroInputStream : public AudioInputStream { protected: int _len; - int16 readIntern() { return 0; } - void advance() { _len--; } public: ZeroInputStream(uint len) : _len(len) { } - virtual int size() const { return _len; } - virtual bool isStereo() const { return false; } + int16 read() { assert(_len > 0); _len--; return 0; } + int size() const { return _len; } + bool isStereo() const { return false; } }; // Wrapped memory stream, to be used by the ChannelStream class (and possibly others?) -template<bool stereo, int sampleSize> +template<bool stereo, bool is16Bit, bool isUnsigned> class WrappedMemoryStream : public AudioInputStream { protected: byte *_bufferStart; @@ -65,10 +62,11 @@ protected: byte *_pos; byte *_end; - void advance(); public: WrappedMemoryStream(const byte *buffer, uint bufferSize); - virtual int size() const; + int16 read(); + int size() const; + void append(const byte *data, uint32 len); }; |