[Scummvm-cvs-logs] CVS: scummvm/sound mixer.cpp,1.76,1.77 module.mk,1.9,1.10
Max Horn
fingolfin at users.sourceforge.net
Mon Jul 28 13:43:28 CEST 2003
Update of /cvsroot/scummvm/scummvm/sound
In directory sc8-pr-cvs1:/tmp/cvs-serv26760
Modified Files:
mixer.cpp module.mk
Log Message:
experimental new rate conversion code (use SOX_HACK to en-/disable it); note that right now only the linear filter works, the high quality resample in resample.cpp is in flux; right now the top priority for me is to get MP3/Vorbis resampling working
Index: mixer.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sound/mixer.cpp,v
retrieving revision 1.76
retrieving revision 1.77
diff -u -d -r1.76 -r1.77
--- mixer.cpp 28 Jul 2003 20:25:09 -0000 1.76
+++ mixer.cpp 28 Jul 2003 20:42:54 -0000 1.77
@@ -26,6 +26,12 @@
#include "common/file.h"
#include "common/util.h"
+//#define SOX_HACK
+
+#ifdef SOX_HACK
+#include "rate.h"
+#endif
+
class Channel {
protected:
SoundMixer *_mixer;
@@ -59,6 +65,10 @@
class ChannelRaw : public Channel {
byte *_ptr;
byte _flags;
+#ifdef SOX_HACK
+ RateConverter *_converter;
+ AudioInputStream *_input;
+#else
uint32 _pos;
uint32 _size;
uint32 _fpSpeed;
@@ -66,6 +76,7 @@
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);
@@ -78,6 +89,10 @@
};
class ChannelStream : public Channel {
+#ifdef SOX_HACK
+ RateConverter *_converter;
+ WrappedAudioInputStream *_input;
+#else
byte *_ptr;
byte *_endOfData;
byte *_endOfBuffer;
@@ -87,6 +102,7 @@
uint32 _bufferSize;
uint32 _rate;
byte _flags;
+#endif
bool _finished;
public:
@@ -421,6 +437,9 @@
_musicVolume = volume;
}
+#ifdef SOX_HACK
+#define clamped_add_16(a, b) clampedAdd(a, b)
+#else
/*
* Class that performs cubic interpolation on integer data.
* It is expected that the data is equidistant, i.e. all have the same
@@ -633,6 +652,7 @@
2, 2,
4, 4
};
+#endif
bool Channel::isActive() {
error("isActive should never be called on a non-MP3 mixer ");
@@ -646,6 +666,28 @@
_ptr = (byte *)sound;
_flags = flags;
+printf("ChannelRaw: flags 0x%x, input rate %d, output rate %d, size %d\n", flags, rate, mixer->getOutputRate(), size);
+//hexdump(_ptr, size);
+//puts("\n");
+
+#ifdef SOX_HACK
+
+ // Create the input stream
+ _input = makeLinearInputStream(flags, _ptr, size);
+ // TODO: add support for SoundMixer::FLAG_REVERSE_STEREO
+
+ // If rate conversion is necessary, create a converter
+// printf("inrate %d, outrate %d\n", rate, mixer->getOutputRate());
+ if (rate != mixer->getOutputRate()) {
+ _converter = new LinearRateConverter(rate, mixer->getOutputRate());
+ //_converter = new ResampleRateConverter(rate, mixer->getOutputRate(), 1);
+ } else {
+ if (flags & SoundMixer::FLAG_STEREO)
+ _converter = new CopyRateConverter<true>();
+ else
+ _converter = new CopyRateConverter<false>();
+ }
+#else
_pos = 0;
_fpPos = 0;
_fpSpeed = (1 << 16) * rate / mixer->getOutputRate();
@@ -666,14 +708,32 @@
_loop_ptr = _ptr;
_loop_size = _size;
}
+#endif
}
ChannelRaw::~ChannelRaw() {
+#ifdef SOX_HACK
+ delete _converter;
+ delete _input;
+#endif
if (_flags & SoundMixer::FLAG_AUTOFREE)
free(_ptr);
}
void ChannelRaw::mix(int16 *data, uint len) {
+#ifdef SOX_HACK
+ const int volume = _mixer->getVolume();
+ uint tmpLen = len;
+ if (_input->eof()) {
+ // TODO: call drain method
+ // TODO: Looping
+ destroy();
+ }
+
+ assert(_converter);
+ _converter->flow(*_input, data, &tmpLen, volume);
+
+#else
byte *s, *end;
if (len > _size)
@@ -697,6 +757,7 @@
destroy();
}
}
+#endif
}
#define WARP_WORKAROUND 50000
@@ -705,6 +766,30 @@
byte flags, uint32 buffer_size)
: Channel(mixer, handle) {
assert(size <= buffer_size);
+
+printf("ChannelStream: flags 0x%x, input rate %d, output rate %d, size %d\n", flags, rate, mixer->getOutputRate(), size);
+//hexdump(_ptr, size);
+//puts("\n");
+
+#ifdef SOX_HACK
+
+ // Create the input stream
+ _input = makeWrappedInputStream(flags, buffer_size);
+ _input->append((const byte *)sound, size);
+ // TODO: add support for SoundMixer::FLAG_REVERSE_STEREO
+
+ // If rate conversion is necessary, create a converter
+// printf("inrate %d, outrate %d\n", rate, mixer->getOutputRate());
+ if (rate != mixer->getOutputRate()) {
+ _converter = new LinearRateConverter(rate, mixer->getOutputRate());
+ //_converter = new ResampleRateConverter(rate, mixer->getOutputRate(), 1);
+ } else {
+ if (flags & SoundMixer::FLAG_STEREO)
+ _converter = new CopyRateConverter<true>();
+ else
+ _converter = new CopyRateConverter<false>();
+ }
+#else
_flags = flags;
_bufferSize = buffer_size;
_ptr = (byte *)malloc(_bufferSize + WARP_WORKAROUND);
@@ -714,21 +799,29 @@
_pos = _ptr;
_fpPos = 0;
_fpSpeed = (1 << 16) * rate / mixer->getOutputRate();
- _finished = false;
// adjust the magnitude to prevent division error
while (size & 0xFFFF0000)
size >>= 1, rate = (rate >> 1) + 1;
_rate = rate;
+#endif
+ _finished = false;
}
ChannelStream::~ChannelStream() {
+#ifdef SOX_HACK
+ delete _converter;
+ delete _input;
+#else
free(_ptr);
+#endif
}
void ChannelStream::append(void *data, uint32 len) {
-
+#ifdef SOX_HACK
+ _input->append((const byte *)data, len);
+#else
if (_endOfData + len > _endOfBuffer) {
/* Wrap-around case */
uint32 size_to_end_of_buffer = _endOfBuffer - _endOfData;
@@ -748,10 +841,32 @@
memcpy(_endOfData, data, len);
_endOfData += len;
}
+#endif
}
void ChannelStream::mix(int16 *data, uint len) {
+#ifdef SOX_HACK
+ const int volume = _mixer->getVolume();
+ uint tmpLen = len;
+
+ if (_input->eof()) {
+ // 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;
+ }
+
+ assert(_converter);
+ _converter->flow(*_input, data, &tmpLen, 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
@@ -799,6 +914,7 @@
mixProc(data, len, _pos, _fpPos, _fpSpeed, _mixer->getVolume(), _endOfData, (_flags & SoundMixer::FLAG_REVERSE_STEREO) ? true : false);
}
}
+#endif
}
#ifdef USE_MAD
@@ -1014,7 +1130,7 @@
// Restream
mad_stream_buffer(&_stream, _ptr, _size + not_decoded);
if (mad_frame_decode(&_frame, &_stream) == -1) {
- debug(1, "Error decoding after restream %d !", _stream.error);
+ debug(1, "Error %d decoding after restream !", _stream.error);
}
} else if (!MAD_RECOVERABLE(_stream.error)) {
error("MAD frame decode error in MP3 CDMUSIC !");
Index: module.mk
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sound/module.mk,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -d -r1.9 -r1.10
--- module.mk 19 May 2003 18:47:50 -0000 1.9
+++ module.mk 28 Jul 2003 20:42:54 -0000 1.10
@@ -1,12 +1,15 @@
MODULE := sound
MODULE_OBJS = \
+ sound/audiostream.o \
sound/fmopl.o \
sound/midiparser.o \
sound/midiparser_smf.o \
sound/midiparser_xmidi.o \
sound/mixer.o \
- sound/mpu401.o
+ sound/mpu401.o \
+ sound/rate.o
+# sound/resample.o
# Include common rules
include common.rules
More information about the Scummvm-git-logs
mailing list