aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sound/audiostream.cpp117
-rw-r--r--sound/audiostream.h22
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);
};