[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