aboutsummaryrefslogtreecommitdiff
path: root/sound/mixer.cpp
diff options
context:
space:
mode:
authorMax Horn2003-08-05 02:05:37 +0000
committerMax Horn2003-08-05 02:05:37 +0000
commit1eaf41eda40f1777a5e99c19a027ea025cbaeb4c (patch)
tree66c67f0f994ee3f64c2fee33269d7d21d6a9ad24 /sound/mixer.cpp
parent2bc604081e4ef7ac8cf39cdde3a89dd494fbb6e1 (diff)
downloadscummvm-rg350-1eaf41eda40f1777a5e99c19a027ea025cbaeb4c.tar.gz
scummvm-rg350-1eaf41eda40f1777a5e99c19a027ea025cbaeb4c.tar.bz2
scummvm-rg350-1eaf41eda40f1777a5e99c19a027ea025cbaeb4c.zip
more cleanup (like the previous two, I just moved around code, to clearly separate the old and the new mixer code)
svn-id: r9479
Diffstat (limited to 'sound/mixer.cpp')
-rw-r--r--sound/mixer.cpp345
1 files changed, 190 insertions, 155 deletions
diff --git a/sound/mixer.cpp b/sound/mixer.cpp
index fbeef67d6d..1cd63ea5b2 100644
--- a/sound/mixer.cpp
+++ b/sound/mixer.cpp
@@ -30,31 +30,22 @@
#ifdef NEW_MIXER_CODE
#include "rate.h"
-#endif
class Channel {
protected:
SoundMixer *_mixer;
PlayingSoundHandle *_handle;
-#ifdef NEW_MIXER_CODE
RateConverter *_converter;
AudioInputStream *_input;
-#endif
public:
int _id;
Channel(SoundMixer *mixer, PlayingSoundHandle *handle)
- : _mixer(mixer), _handle(handle),
-#ifdef NEW_MIXER_CODE
- _converter(0), _input(0),
-#endif
- _id(-1) {
+ : _mixer(mixer), _handle(handle), _converter(0), _input(0), _id(-1) {
assert(mixer);
}
virtual ~Channel() {
-#ifdef NEW_MIXER_CODE
delete _converter;
delete _input;
-#endif
if (_handle)
*_handle = 0;
}
@@ -63,7 +54,6 @@ public:
10 means that the buffer contains twice 10 sample, each
16 bits, for a total of 40 bytes.
*/
-#ifdef NEW_MIXER_CODE
virtual void mix(int16 *data, uint len) {
assert(_input);
assert(_converter);
@@ -77,9 +67,79 @@ public:
const int volume = isMusicChannel() ? _mixer->getMusicVolume() : _mixer->getVolume();
_converter->flow(*_input, data, len, volume);
}
-#else
- virtual void mix(int16 *data, uint len) = 0;
+ void destroy() {
+ for (int i = 0; i != SoundMixer::NUM_CHANNELS; i++)
+ if (_mixer->_channels[i] == this)
+ _mixer->_channels[i] = 0;
+ delete this;
+ }
+ virtual bool isMusicChannel() const = 0;
+};
+
+class ChannelRaw : public Channel {
+ byte *_ptr;
+public:
+ ChannelRaw(SoundMixer *mixer, PlayingSoundHandle *handle, void *sound, uint32 size, uint rate, byte flags, int id, uint32 loopStart, uint32 loopEnd);
+ ~ChannelRaw();
+ bool isMusicChannel() const { return false; }
+};
+
+class ChannelStream : public Channel {
+ bool _finished;
+public:
+ ChannelStream(SoundMixer *mixer, PlayingSoundHandle *handle, void *sound, uint32 size, uint rate, byte flags, uint32 buffer_size);
+ void mix(int16 *data, uint len);
+ void append(void *sound, uint32 size);
+ bool isMusicChannel() const { return true; }
+ void finish() { _finished = true; }
+};
+
+#ifdef USE_MAD
+class ChannelMP3 : public Channel {
+public:
+ ChannelMP3(SoundMixer *mixer, PlayingSoundHandle *handle, File *file, uint size);
+ bool isMusicChannel() const { return false; }
+};
+
+class ChannelMP3CDMusic : public Channel {
+public:
+ ChannelMP3CDMusic(SoundMixer *mixer, PlayingSoundHandle *handle, File *file, mad_timer_t duration);
+ bool isMusicChannel() const { return true; }
+};
+#endif // USE_MAD
+
+#ifdef USE_VORBIS
+class ChannelVorbis : public Channel {
+ bool _is_cd_track;
+public:
+ ChannelVorbis(SoundMixer *mixer, PlayingSoundHandle *handle, OggVorbis_File *ov_file, int duration, bool is_cd_track);
+ bool isMusicChannel() const { return _is_cd_track; }
+};
#endif
+
+
+#else // NEW_MIXER_CODE
+
+class Channel {
+protected:
+ SoundMixer *_mixer;
+ PlayingSoundHandle *_handle;
+public:
+ int _id;
+ Channel(SoundMixer *mixer, PlayingSoundHandle *handle)
+ : _mixer(mixer), _handle(handle), _id(-1) {
+ assert(mixer);
+ }
+ virtual ~Channel() {
+ if (_handle)
+ *_handle = 0;
+ }
+
+ /* len indicates the number of sample *pairs*. So a value of
+ 10 means that the buffer contains twice 10 sample, each
+ 16 bits, for a total of 40 bytes.
+ */
+ virtual void mix(int16 *data, uint len) = 0;
void destroy() {
for (int i = 0; i != SoundMixer::NUM_CHANNELS; i++)
if (_mixer->_channels[i] == this)
@@ -91,7 +151,6 @@ public:
class ChannelRaw : public Channel {
byte *_ptr;
-#ifndef NEW_MIXER_CODE
byte _flags;
uint32 _pos;
uint32 _size;
@@ -100,20 +159,16 @@ class ChannelRaw : public Channel {
uint32 _realSize, _rate;
byte *_loop_ptr;
uint32 _loop_size;
-#endif
public:
ChannelRaw(SoundMixer *mixer, PlayingSoundHandle *handle, void *sound, uint32 size, uint rate, byte flags, int id, uint32 loopStart, uint32 loopEnd);
~ChannelRaw();
-#ifndef NEW_MIXER_CODE
void mix(int16 *data, uint len);
-#endif
bool isMusicChannel() const { return false; }
};
class ChannelStream : public Channel {
-#ifndef NEW_MIXER_CODE
byte *_ptr;
byte *_endOfData;
byte *_endOfBuffer;
@@ -123,7 +178,6 @@ class ChannelStream : public Channel {
uint32 _bufferSize;
uint32 _rate;
byte _flags;
-#endif
bool _finished;
public:
@@ -136,24 +190,7 @@ public:
void finish() { _finished = true; }
};
-
#ifdef USE_MAD
-
-#ifdef NEW_MIXER_CODE
-
-class ChannelMP3 : public Channel {
-public:
- ChannelMP3(SoundMixer *mixer, PlayingSoundHandle *handle, File *file, uint size);
- bool isMusicChannel() const { return false; }
-};
-
-class ChannelMP3CDMusic : public Channel {
-public:
- ChannelMP3CDMusic(SoundMixer *mixer, PlayingSoundHandle *handle, File *file, mad_timer_t duration);
- bool isMusicChannel() const { return true; }
-};
-
-#else // NEW_MIXER_CODE
class ChannelMP3Common : public Channel {
protected:
byte *_ptr;
@@ -190,29 +227,22 @@ public:
void mix(int16 *data, uint len);
bool isMusicChannel() const { return true; }
};
-#endif // NEW_MIXER_CODE
-
#endif // USE_MAD
-
#ifdef USE_VORBIS
class ChannelVorbis : public Channel {
-#ifndef NEW_MIXER_CODE
OggVorbis_File *_ov_file;
int _end_pos;
-#endif
bool _is_cd_track;
-
public:
ChannelVorbis(SoundMixer *mixer, PlayingSoundHandle *handle, OggVorbis_File *ov_file, int duration, bool is_cd_track);
-
-#ifndef NEW_MIXER_CODE
void mix(int16 *data, uint len);
-#endif
bool isMusicChannel() const { return _is_cd_track; }
};
#endif
+#endif
+
SoundMixer::SoundMixer() {
_syst = 0;
@@ -460,8 +490,116 @@ void SoundMixer::setMusicVolume(int volume) {
}
#ifdef NEW_MIXER_CODE
-#define clamped_add_16(a, b) clampedAdd(a, b)
-#else
+
+/* RAW mixer */
+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;
+
+ // Create the input stream
+ if (flags & SoundMixer::FLAG_LOOP) {
+ if (loopEnd == 0) {
+ _input = makeLinearInputStream(flags, _ptr, size, 0, size);
+ } else {
+ assert(loopStart < loopEnd && loopEnd <= size);
+ _input = makeLinearInputStream(flags, _ptr, size, loopStart, loopEnd - loopStart);
+ }
+ } else {
+ _input = makeLinearInputStream(flags, _ptr, size, 0, 0);
+ }
+
+ // Get a rate converter instance
+ _converter = makeRateConverter(rate, mixer->getOutputRate(), _input->isStereo(), (flags & SoundMixer::FLAG_REVERSE_STEREO) != 0);
+
+ if (!(flags & SoundMixer::FLAG_AUTOFREE))
+ _ptr = 0;
+}
+
+ChannelRaw::~ChannelRaw() {
+ free(_ptr);
+}
+
+ChannelStream::ChannelStream(SoundMixer *mixer, PlayingSoundHandle *handle,
+ void *sound, uint32 size, uint rate,
+ byte flags, uint32 buffer_size)
+ : Channel(mixer, handle) {
+ assert(size <= buffer_size);
+
+ // Create the input stream
+ _input = makeWrappedInputStream(flags, buffer_size);
+
+ // Append the initial data
+ ((WrappedAudioInputStream *)_input)->append((const byte *)sound, size);
+
+ // Get a rate converter instance
+ _converter = makeRateConverter(rate, mixer->getOutputRate(), _input->isStereo(), (flags & SoundMixer::FLAG_REVERSE_STEREO) != 0);
+
+ _finished = false;
+}
+
+void ChannelStream::append(void *data, uint32 len) {
+ ((WrappedAudioInputStream *)_input)->append((const byte *)data, len);
+}
+
+void ChannelStream::mix(int16 *data, uint len) {
+ assert(_input);
+ assert(_converter);
+
+ if (_input->eos()) {
+ // TODO: call drain method
+
+ // Normally, the stream stays around even if all its data is used up.
+ // This is in case more data is streamed into it. To make the stream
+ // go away, one can either stop() it (which takes effect immediately,
+ // ignoring any remaining sound data), or finish() it, which means
+ // it will finish playing before it terminates itself.
+ if (_finished) {
+ destroy();
+ }
+
+ return;
+ }
+
+ const int volume = _mixer->getVolume(); // FIXME: Shouldn't this be music volume instead??
+// const int volume = isMusicChannel() ? _mixer->getMusicVolume() : _mixer->getVolume();
+ _converter->flow(*_input, data, len, volume);
+}
+
+#ifdef USE_MAD
+ChannelMP3::ChannelMP3(SoundMixer *mixer, PlayingSoundHandle *handle, File *file, uint size)
+ : Channel(mixer, handle) {
+ // Create the input stream
+ _input = makeMP3Stream(file, mad_timer_zero, size);
+
+ // Get a rate converter instance
+ _converter = makeRateConverter(_input->getRate(), mixer->getOutputRate(), _input->isStereo());
+}
+
+ChannelMP3CDMusic::ChannelMP3CDMusic(SoundMixer *mixer, PlayingSoundHandle *handle, File *file, mad_timer_t duration)
+ : Channel(mixer, handle) {
+ // 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 is_cd_track)
+ : Channel(mixer, handle) {
+ // Create the input stream
+ _input = makeVorbisStream(ov_file, duration);
+
+ // Get a rate converter instance
+ _converter = makeRateConverter(_input->getRate(), mixer->getOutputRate(), _input->isStereo());
+ _is_cd_track = is_cd_track;
+}
+#endif // USE_VORBIS
+
+#else // NEW_MIXER_CODE
+
/*
* Class that performs cubic interpolation on integer data.
* It is expected that the data is equidistant, i.e. all have the same
@@ -674,7 +812,6 @@ static int16 mixer_element_size[] = {
2, 2,
4, 4
};
-#endif
/* RAW mixer */
ChannelRaw::ChannelRaw(SoundMixer *mixer, PlayingSoundHandle *handle, void *sound, uint32 size, uint rate, byte flags, int id, uint32 loopStart, uint32 loopEnd)
@@ -682,25 +819,6 @@ ChannelRaw::ChannelRaw(SoundMixer *mixer, PlayingSoundHandle *handle, void *soun
_id = id;
_ptr = (byte *)sound;
-#ifdef NEW_MIXER_CODE
- // Create the input stream
- if (flags & SoundMixer::FLAG_LOOP) {
- if (loopEnd == 0) {
- _input = makeLinearInputStream(flags, _ptr, size, 0, size);
- } else {
- assert(loopStart < loopEnd && loopEnd <= size);
- _input = makeLinearInputStream(flags, _ptr, size, loopStart, loopEnd - loopStart);
- }
- } else {
- _input = makeLinearInputStream(flags, _ptr, size, 0, 0);
- }
-
- // Get a rate converter instance
- _converter = makeRateConverter(rate, mixer->getOutputRate(), _input->isStereo(), (flags & SoundMixer::FLAG_REVERSE_STEREO) != 0);
-
- if (!(flags & SoundMixer::FLAG_AUTOFREE))
- _ptr = 0;
-#else
_flags = flags;
_pos = 0;
_fpPos = 0;
@@ -722,19 +840,13 @@ ChannelRaw::ChannelRaw(SoundMixer *mixer, PlayingSoundHandle *handle, void *soun
_loop_ptr = _ptr;
_loop_size = _size;
}
-#endif
}
ChannelRaw::~ChannelRaw() {
-#ifdef NEW_MIXER_CODE
- free(_ptr);
-#else
if (_flags & SoundMixer::FLAG_AUTOFREE)
free(_ptr);
-#endif
}
-#ifndef NEW_MIXER_CODE
void ChannelRaw::mix(int16 *data, uint len) {
byte *s, *end;
@@ -760,26 +872,15 @@ void ChannelRaw::mix(int16 *data, uint len) {
}
}
}
-#endif
#define WARP_WORKAROUND 50000
-ChannelStream::ChannelStream(SoundMixer *mixer, PlayingSoundHandle *handle, void *sound, uint32 size, uint rate,
- byte flags, uint32 buffer_size)
+ChannelStream::ChannelStream(SoundMixer *mixer, PlayingSoundHandle *handle,
+ void *sound, uint32 size, uint rate,
+ byte flags, uint32 buffer_size)
: Channel(mixer, handle) {
assert(size <= buffer_size);
-#ifdef NEW_MIXER_CODE
-
- // Create the input stream
- _input = makeWrappedInputStream(flags, buffer_size);
-
- // Append the initial data
- ((WrappedAudioInputStream *)_input)->append((const byte *)sound, size);
-
- // Get a rate converter instance
- _converter = makeRateConverter(rate, mixer->getOutputRate(), _input->isStereo(), (flags & SoundMixer::FLAG_REVERSE_STEREO) != 0);
-#else
_flags = flags;
_bufferSize = buffer_size;
_ptr = (byte *)malloc(_bufferSize + WARP_WORKAROUND);
@@ -795,20 +896,14 @@ ChannelStream::ChannelStream(SoundMixer *mixer, PlayingSoundHandle *handle, void
size >>= 1, rate = (rate >> 1) + 1;
_rate = rate;
-#endif
_finished = false;
}
ChannelStream::~ChannelStream() {
-#ifndef NEW_MIXER_CODE
free(_ptr);
-#endif
}
void ChannelStream::append(void *data, uint32 len) {
-#ifdef NEW_MIXER_CODE
- ((WrappedAudioInputStream *)_input)->append((const byte *)data, len);
-#else
if (_endOfData + len > _endOfBuffer) {
/* Wrap-around case */
uint32 size_to_end_of_buffer = _endOfBuffer - _endOfData;
@@ -828,33 +923,9 @@ void ChannelStream::append(void *data, uint32 len) {
memcpy(_endOfData, data, len);
_endOfData += len;
}
-#endif
}
void ChannelStream::mix(int16 *data, uint len) {
-#ifdef NEW_MIXER_CODE
- assert(_input);
- assert(_converter);
-
- if (_input->eos()) {
- // TODO: call drain method
-
- // Normally, the stream stays around even if all its data is used up.
- // This is in case more data is streamed into it. To make the stream
- // go away, one can either stop() it (which takes effect immediately,
- // ignoring any remaining sound data), or finish() it, which means
- // it will finish playing before it terminates itself.
- if (_finished) {
- destroy();
- }
-
- return;
- }
-
- const int volume = _mixer->getVolume(); // FIXME: Shouldn't this be music volume instead??
-// const int volume = isMusicChannel() ? _mixer->getMusicVolume() : _mixer->getVolume();
- _converter->flow(*_input, data, len, volume);
-#else
if (_pos == _endOfData) {
// Normally, the stream stays around even if all its data is used up.
// This is in case more data is streamed into it. To make the stream
@@ -902,32 +973,9 @@ void ChannelStream::mix(int16 *data, uint len) {
mixProc(data, len, _pos, _fpPos, _fpSpeed, _mixer->getVolume(), _endOfData, (_flags & SoundMixer::FLAG_REVERSE_STEREO) ? true : false);
}
}
-#endif
}
#ifdef USE_MAD
-
-#ifdef NEW_MIXER_CODE
-ChannelMP3::ChannelMP3(SoundMixer *mixer, PlayingSoundHandle *handle, File *file, uint size)
- : Channel(mixer, handle) {
- // Create the input stream
- _input = makeMP3Stream(file, mad_timer_zero, size);
-
- // Get a rate converter instance
- _converter = makeRateConverter(_input->getRate(), mixer->getOutputRate(), _input->isStereo());
-}
-
-ChannelMP3CDMusic::ChannelMP3CDMusic(SoundMixer *mixer, PlayingSoundHandle *handle, File *file, mad_timer_t duration)
- : Channel(mixer, handle) {
- // Create the input stream
- _input = makeMP3Stream(file, duration, 0);
-
- // Get a rate converter instance
- _converter = makeRateConverter(_input->getRate(), mixer->getOutputRate(), _input->isStereo());
-}
-
-#else // NEW_MIXER_CODE
-
ChannelMP3Common::ChannelMP3Common(SoundMixer *mixer, PlayingSoundHandle *handle)
: Channel(mixer, handle) {
mad_stream_init(&_stream);
@@ -1137,23 +1185,9 @@ void ChannelMP3CDMusic::mix(int16 *data, uint len) {
_posInFrame = 0;
}
}
-#endif // NEW_MIXER_CODE
-
#endif // USE_MAD
#ifdef USE_VORBIS
-
-#ifdef NEW_MIXER_CODE
-ChannelVorbis::ChannelVorbis(SoundMixer *mixer, PlayingSoundHandle *handle, OggVorbis_File *ov_file, int duration, bool is_cd_track)
- : Channel(mixer, handle) {
- // Create the input stream
- _input = makeVorbisStream(ov_file, duration);
-
- // Get a rate converter instance
- _converter = makeRateConverter(_input->getRate(), mixer->getOutputRate(), _input->isStereo());
- _is_cd_track = is_cd_track;
-}
-#else // NEW_MIXER_CODE
ChannelVorbis::ChannelVorbis(SoundMixer *mixer, PlayingSoundHandle *handle, OggVorbis_File *ov_file, int duration, bool is_cd_track)
: Channel(mixer, handle) {
_ov_file = ov_file;
@@ -1222,6 +1256,7 @@ void ChannelVorbis::mix(int16 *data, uint len) {
if (eof_flag)
destroy();
}
+#endif // USE_VORBIS
+
#endif // NEW_MIXER_CODE
-#endif // USE_VORBIS