[Scummvm-cvs-logs] CVS: scummvm/sound mixer.cpp,1.105,1.106

Max Horn fingolfin at users.sourceforge.net
Tue Aug 5 14:47:09 CEST 2003


Update of /cvsroot/scummvm/scummvm/sound
In directory sc8-pr-cvs1:/tmp/cvs-serv3430

Modified Files:
	mixer.cpp 
Log Message:
begone, old mixer code

Index: mixer.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sound/mixer.cpp,v
retrieving revision 1.105
retrieving revision 1.106
diff -u -d -r1.105 -r1.106
--- mixer.cpp	5 Aug 2003 18:17:26 -0000	1.105
+++ mixer.cpp	5 Aug 2003 21:46:56 -0000	1.106
@@ -21,15 +21,12 @@
  */
 
 #include "stdafx.h"
-#include "mixer.h"
 #include "common/engine.h"	// for warning/error/debug
 #include "common/file.h"
 #include "common/util.h"
 
-#define NEW_MIXER_CODE
-
-#ifdef NEW_MIXER_CODE
-#include "rate.h"
+#include "sound/mixer.h"
+#include "sound/rate.h"
 
 class Channel {
 protected:
@@ -113,126 +110,6 @@
 #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();
-	virtual bool isMusicChannel() const	= 0;
-};
-
-class ChannelRaw : public Channel {
-	byte *_ptr;
-	byte _flags;
-	uint32 _pos;
-	uint32 _size;
-	uint32 _fpSpeed;
-	uint32 _fpPos;
-	uint32 _realSize, _rate;
-	byte *_loop_ptr;
-	uint32 _loop_size;
-
-public:
-	ChannelRaw(SoundMixer *mixer, PlayingSoundHandle *handle, void *sound, uint32 size, uint rate, byte flags, int id, uint32 loopStart, uint32 loopEnd);
-	~ChannelRaw();
-
-	void mix(int16 *data, uint len);
-	bool isMusicChannel() const		{ return false; }
-};
-
-class ChannelStream : public Channel {
-	byte *_ptr;
-	byte *_endOfData;
-	byte *_endOfBuffer;
-	byte *_pos;
-	uint32 _fpSpeed;
-	uint32 _fpPos;
-	uint32 _bufferSize;
-	uint32 _rate;
-	byte _flags;
-	bool _finished;
-
-public:
-	ChannelStream(SoundMixer *mixer, PlayingSoundHandle *handle, void *sound, uint32 size, uint rate, byte flags, uint32 buffer_size);
-	~ChannelStream();
-
-	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 ChannelMP3Common : public Channel {
-protected:
-	byte *_ptr;
-	struct mad_stream _stream;
-	struct mad_frame _frame;
-	struct mad_synth _synth;
-	uint32 _posInFrame;
-	uint32 _size;
-	bool _initialized;
-
-public:
-	ChannelMP3Common(SoundMixer *mixer, PlayingSoundHandle *handle);
-	~ChannelMP3Common();
-};
-
-class ChannelMP3 : public ChannelMP3Common {
-	uint32 _position;
-
-public:
-	ChannelMP3(SoundMixer *mixer, PlayingSoundHandle *handle, File *file, uint size);
-
-	void mix(int16 *data, uint len);
-	bool isMusicChannel() const		{ return false; }
-};
-
-class ChannelMP3CDMusic : public ChannelMP3Common {
-	uint32 _bufferSize;
-	mad_timer_t _duration;
-	File *_file;
-
-public:
-	ChannelMP3CDMusic(SoundMixer *mixer, PlayingSoundHandle *handle, File *file, mad_timer_t duration);
-
-	void mix(int16 *data, uint len);
-	bool isMusicChannel() const		{ return true; }
-};
-#endif // USE_MAD
-
-#ifdef USE_VORBIS
-class ChannelVorbis : public Channel {
-	OggVorbis_File *_ov_file;
-	int _end_pos;
-	bool _is_cd_track;
-public:
-	ChannelVorbis(SoundMixer *mixer, PlayingSoundHandle *handle, OggVorbis_File *ov_file, int duration, bool is_cd_track);
-	void mix(int16 *data, uint len);
-	bool isMusicChannel() const		{ return _is_cd_track; }
-};
-#endif
-
-#endif
-
 
 void Channel::destroy() {
 	for (int i = 0; i != SoundMixer::NUM_CHANNELS; i++)
@@ -487,7 +364,6 @@
 	_musicVolume = volume;
 }
 
-#ifdef NEW_MIXER_CODE
 
 /* RAW mixer */
 ChannelRaw::ChannelRaw(SoundMixer *mixer, PlayingSoundHandle *handle, void *sound, uint32 size, uint rate, byte flags, int id, uint32 loopStart, uint32 loopEnd)
@@ -595,666 +471,3 @@
 	_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
- * horizontal distance. This is obviously the case for sampled audio.
- */
-class CubicInterpolator {
-protected:
-	int x0, x1, x2, x3;
-	int a, b, c, d;
-
-public:
-	CubicInterpolator(int8 a0, int8 b0, int8 c0) : x0(2 * a0 - b0), x1(a0), x2(b0), x3(c0) {
-		// We use a simple linear interpolation for x0
-		updateCoefficients();
-	}
-
-	inline void feedData() {
-		x0 = x1;
-		x1 = x2;
-		x2 = x3;
-		x3 = 2 * x2 - x1;	// Simple linear interpolation
-		updateCoefficients();
-	}
-
-	inline void feedData(int8 xNew) {
-		x0 = x1;
-		x1 = x2;
-		x2 = x3;
-		x3 = xNew;
-		updateCoefficients();
-	}
-
-	/* t must be a 16.16 fixed point number between 0 and 1 */
-	inline int interpolate(uint32 fpPos) {
-		int result = 0;
-		int t = fpPos >> 8;
-		result = (a * t + b) >> 8;
-		result = (result * t + c) >> 8;
-		result = (result * t + d) >> 8;
-		result = (result / 3 + 1) >> 1;
-
-		return result;
-	}
-
-protected:
-	inline void updateCoefficients() {
-		a = ((-x0 * 2) + (x1 * 5) - (x2 * 4) + x3);
-		b = ((x0 + x2 - (2 * x1)) * 6) << 8;
-		c = ((-4 * x0) + x1 + (x2 * 4) - x3) << 8;
-		d = (x1 * 6) << 8;
-	}
-};
-
-static inline void clamped_add_16(int16& a, int b) {
-	int val = a + b;
-
-	if (val > 32767)
-		a = 32767;
-	else if (val < -32768)
-		a = -32768;
-	else
-		a = val;
-}
-
-static void mix_signed_mono_8(int16 *data, uint &len, byte *&s, uint32 &fp_pos,
-								int fp_speed, int volume, byte *s_end, bool reverse_stereo) {
-	int inc = 1, result;
-	CubicInterpolator interp(*s, *(s + 1), *(s + 2));
-
-	do {
-		do {
-			result = interp.interpolate(fp_pos) * volume;
-
-			clamped_add_16(*data++, result);
-			clamped_add_16(*data++, result);
-
-			fp_pos += fp_speed;
-			inc = fp_pos >> 16;
-			s += inc;
-			len--;
-			fp_pos &= 0x0000FFFF;
-		} while (!inc && len && (s < s_end));
-
-		if (s + 2 < s_end)
-			interp.feedData(*(s + 2));
-		else
-			interp.feedData();
-
-	} while (len && (s < s_end));
-}
-
-static void mix_unsigned_mono_8(int16 *data, uint &len, byte *&s, uint32 &fp_pos,
-											int fp_speed, int volume, byte *s_end, bool reverse_stereo) {
-	int inc = 1, result;
-	CubicInterpolator interp(*s ^ 0x80, *(s + 1) ^ 0x80, *(s + 2) ^ 0x80);
-
-	do {
-		do {
-			result = interp.interpolate(fp_pos) * volume;
-
-			clamped_add_16(*data++, result);
-			clamped_add_16(*data++, result);
-
-			fp_pos += fp_speed;
-			inc = fp_pos >> 16;
-			s += inc;
-			len--;
-			fp_pos &= 0x0000FFFF;
-		} while (!inc && len && (s < s_end));
-
-		if (s + 2 < s_end)
-			interp.feedData(*(s + 2) ^ 0x80);
-		else
-			interp.feedData();
-
-	} while (len && (s < s_end));
-}
-
-static void mix_signed_stereo_8(int16 *data, uint &len, byte *&s, uint32 &fp_pos,
-										int fp_speed, int volume, byte *s_end, bool reverse_stereo) {
-	warning("Mixing stereo signed 8 bit is not supported yet ");
-}
-static void mix_unsigned_stereo_8(int16 *data, uint &len, byte *&s, uint32 &fp_pos,
-										int fp_speed, int volume, byte *s_end, bool reverse_stereo) {
-	int inc = 1;
-	CubicInterpolator	left(*s ^ 0x80, *(s + 2) ^ 0x80, *(s + 4) ^ 0x80);
-	CubicInterpolator	right(*(s + 1) ^ 0x80, *(s + 3) ^ 0x80, *(s + 5) ^ 0x80);
-
-	do {
-		do {
-			if (!reverse_stereo) {
-				clamped_add_16(*data++, left.interpolate(fp_pos) * volume);
-				clamped_add_16(*data++, right.interpolate(fp_pos) * volume);
-			} else {
-				clamped_add_16(*data++, right.interpolate(fp_pos) * volume);
-				clamped_add_16(*data++, left.interpolate(fp_pos) * volume);
-			}
-
-			fp_pos += fp_speed;
-			inc = (fp_pos >> 16) << 1;
-			s += inc;
-			len--;
-			fp_pos &= 0x0000FFFF;
-		} while (!inc && len && (s < s_end));
-
-		if (s + 5 < s_end) {
-			left.feedData(*(s + 4) ^ 0x80);
-			right.feedData(*(s + 5) ^ 0x80);
-		} else {
-			left.feedData();
-			right.feedData();
-		}
-
-	} while (len && (s < s_end));
-}
-static void mix_signed_mono_16(int16 *data, uint &len, byte *&s, uint32 &fp_pos,
-										 int fp_speed, int volume, byte *s_end, bool reverse_stereo) {
-	do {
-		int16 sample = ((int16)READ_BE_UINT16(s) * volume) / 256;
-		fp_pos += fp_speed;
-
-		clamped_add_16(*data++, sample);
-		clamped_add_16(*data++, sample);
-
-		s += (fp_pos >> 16) << 1;
-		fp_pos &= 0x0000FFFF;
-	} while ((--len) && (s < s_end));
-}
-static void mix_unsigned_mono_16(int16 *data, uint &len, byte *&s, uint32 &fp_pos,
-										 int fp_speed, int volume, byte *s_end, bool reverse_stereo) {
-	warning("Mixing mono unsigned 16 bit is not supported yet ");
-}
-static void mix_signed_stereo_16(int16 *data, uint &len, byte *&s, uint32 &fp_pos,
-										 int fp_speed, int volume, byte *s_end, bool reverse_stereo) {
-	do {
-		int16 leftS = ((int16)READ_BE_UINT16(s) * volume) / 256;
-		int16 rightS = ((int16)READ_BE_UINT16(s+2) * volume) / 256;
-		fp_pos += fp_speed;
-
-		if (!reverse_stereo) {
-			clamped_add_16(*data++, leftS);
-			clamped_add_16(*data++, rightS);
-		} else {
-			clamped_add_16(*data++, rightS);
-			clamped_add_16(*data++, leftS);
-		}
-		s += (fp_pos >> 16) << 2;
-		fp_pos &= 0x0000FFFF;
-	} while ((--len) && (s < s_end));
-}
-static void mix_unsigned_stereo_16(int16 *data, uint &len, byte *&s, uint32 &fp_pos,
-											 int fp_speed, int volume, byte *s_end, bool reverse_stereo) {
-	warning("Mixing stereo unsigned 16 bit is not supported yet ");
-}
-
-typedef void MixProc(int16 *data, uint &len, byte *&s,
-                      uint32 &fp_pos, int fp_speed, int volume,
-                      byte *s_end, bool reverse_stereo);
-
-static MixProc *mixer_helper_table[8] = {
-	mix_signed_mono_8, mix_unsigned_mono_8,
-	mix_signed_stereo_8, mix_unsigned_stereo_8,
-	mix_signed_mono_16, mix_unsigned_mono_16,
-	mix_signed_stereo_16, mix_unsigned_stereo_16
-};
-
-static int16 mixer_element_size[] = {
-	1, 1,
-	2, 2,
-	2, 2,
-	4, 4
-};
-
-/* 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;
-	
-	_flags = flags;
-	_pos = 0;
-	_fpPos = 0;
-	_fpSpeed = (1 << 16) * rate / mixer->getOutputRate();
-	_realSize = size;
-
-	// adjust the magnitude to prevent division error
-	while (size & 0xFFFF0000)
-		size >>= 1, rate = (rate >> 1) + 1;
-
-	_rate = rate;
-	_size = size * mixer->getOutputRate() / rate;
-	if (_flags & SoundMixer::FLAG_16BITS)
-		_size = _size >> 1;
-	if (_flags & SoundMixer::FLAG_STEREO)
-		_size = _size >> 1;
-
-	if (flags & SoundMixer::FLAG_LOOP) {
-		_loop_ptr = _ptr;
-		_loop_size = _size;
-	}
-}
-
-ChannelRaw::~ChannelRaw() {
-	if (_flags & SoundMixer::FLAG_AUTOFREE)
-		free(_ptr);
-}
-
-void ChannelRaw::mix(int16 *data, uint len) {
-	byte *s, *end;
-
-	if (len > _size)
-		len = _size;
-	_size -= len;
-
-	s = _ptr + _pos;
-	end = _ptr + _realSize;
-
-	mixer_helper_table[_flags & 0x07] (data, len, s, _fpPos, _fpSpeed, _mixer->getVolume(), end, (_flags & SoundMixer::FLAG_REVERSE_STEREO) ? true : false);
-
-	_pos = s - _ptr;
-
-	if (_size <= 0) {
-		if (_flags & SoundMixer::FLAG_LOOP) {
-			_ptr = _loop_ptr;
-			_size = _loop_size;
-			_pos = 0;
-			_fpPos = 0;
-		} else {
-			destroy();
-		}
-	}
-}
-
-#define WARP_WORKAROUND 50000
-
-ChannelStream::ChannelStream(SoundMixer *mixer, PlayingSoundHandle *handle,
-                             void *sound, uint32 size, uint rate,
-                             byte flags, uint32 buffer_size)
-	: Channel(mixer, handle) {
-	assert(size <= buffer_size);
-
-	_flags = flags;
-	_bufferSize = buffer_size;
-	_ptr = (byte *)malloc(_bufferSize + WARP_WORKAROUND);
-	memcpy(_ptr, sound, size);
-	_endOfData = _ptr + size;
-	_endOfBuffer = _ptr + _bufferSize;
-	_pos = _ptr;
-	_fpPos = 0;
-	_fpSpeed = (1 << 16) * rate / mixer->getOutputRate();
-
-	// adjust the magnitude to prevent division error
-	while (size & 0xFFFF0000)
-		size >>= 1, rate = (rate >> 1) + 1;
-
-	_rate = rate;
-	_finished = false;
-}
-
-ChannelStream::~ChannelStream() {
-	free(_ptr);
-}
-
-void ChannelStream::append(void *data, uint32 len) {
-	if (_endOfData + len > _endOfBuffer) {
-		/* Wrap-around case */
-		uint32 size_to_end_of_buffer = _endOfBuffer - _endOfData;
-		uint32 new_size = len - size_to_end_of_buffer;
-		if ((_endOfData < _pos) || (_ptr + new_size >= _pos)) {
-			debug(2, "Mixer full... Trying to not break too much (A)");
-			return;
-		}
-		memcpy(_endOfData, (byte*)data, size_to_end_of_buffer);
-		memcpy(_ptr, (byte *)data + size_to_end_of_buffer, new_size);
-		_endOfData = _ptr + new_size;
-	} else {
-		if ((_endOfData < _pos) && (_endOfData + len >= _pos)) {
-			debug(2, "Mixer full... Trying to not break too much (B)");
-			return;
-		}
-		memcpy(_endOfData, data, len);
-		_endOfData += len;
-	}
-}
-
-void ChannelStream::mix(int16 *data, uint len) {
-	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
-		// 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();
-		} else {
-			// Since the buffer is empty now, reset the position to the start
-			_pos = _endOfData = _ptr;
-			_fpPos = 0;
-		}
-
-		return;
-	}
-
-	MixProc *mixProc = mixer_helper_table[_flags & 0x07];
-
-	if (_pos < _endOfData) {
-		mixProc(data, len, _pos, _fpPos, _fpSpeed, _mixer->getVolume(), _endOfData, (_flags & SoundMixer::FLAG_REVERSE_STEREO) ? true : false);
-	} else {
-		int wrapOffset = 0;
-		const uint32 outLen = mixer_element_size[_flags & 0x07] * len;
-
-		// see if we will wrap
-		if (_pos + outLen > _endOfBuffer) {
-			wrapOffset = _pos + outLen - _endOfBuffer;
-			debug(2, "using wrap workaround for %d bytes", wrapOffset);
-			assert(wrapOffset <= WARP_WORKAROUND);
-			memcpy(_endOfBuffer, _ptr, wrapOffset);
-		}
-
-		mixProc(data, len, _pos, _fpPos, _fpSpeed, _mixer->getVolume(), _endOfBuffer + wrapOffset, (_flags & SoundMixer::FLAG_REVERSE_STEREO) ? true : false);
-
-		// recover from wrap
-		if (wrapOffset)
-			_pos = _ptr + wrapOffset;
-
-		// shouldn't happen anymore
-		if (len != 0) {
-			//FIXME: what is wrong ?
-			warning("bad play sound in stream (wrap around)");
-			_pos = _ptr;
-			mixProc(data, len, _pos, _fpPos, _fpSpeed, _mixer->getVolume(), _endOfData, (_flags & SoundMixer::FLAG_REVERSE_STEREO) ? true : false);
-		}
-	}
-}
-
-#ifdef USE_MAD
-ChannelMP3Common::ChannelMP3Common(SoundMixer *mixer, PlayingSoundHandle *handle)
-	: Channel(mixer, handle) {
-	mad_stream_init(&_stream);
-#ifdef _WIN32_WCE
-	// Lower sample rate to 11 kHz on WinCE if necessary
-	if (_syst->property(OSystem::PROP_GET_SAMPLE_RATE, 0) != 22050)
-		mad_stream_options(&_stream, MAD_OPTION_HALFSAMPLERATE);
-#endif
-	mad_frame_init(&_frame);
-	mad_synth_init(&_synth);
-
-	_initialized = false;
-}
-
-ChannelMP3Common::~ChannelMP3Common() {
-	free(_ptr);
-	mad_synth_finish(&_synth);
-	mad_frame_finish(&_frame);
-	mad_stream_finish(&_stream);
-}
-
-static inline int scale_sample(mad_fixed_t sample) {
-	/* round */
-	sample += (1L << (MAD_F_FRACBITS - 16));
-
-	/* clip */
-	if (sample > MAD_F_ONE - 1)
-		sample = MAD_F_ONE - 1;
-	else if (sample < -MAD_F_ONE)
-		sample = -MAD_F_ONE;
-
-	/* quantize and scale to not saturate when mixing a lot of channels */
-	return sample >> (MAD_F_FRACBITS + 1 - 16);
-}
-
-ChannelMP3::ChannelMP3(SoundMixer *mixer, PlayingSoundHandle *handle, File *file, uint size)
-	: ChannelMP3Common(mixer, handle) {
-	_posInFrame = 0xFFFFFFFF;
-	_position = 0;
-	_ptr = (byte *)malloc(size + MAD_BUFFER_GUARD);
-
-	_size = file->read(_ptr, size);
-}
-
-void ChannelMP3::mix(int16 *data, uint len) {
-	const int volume = _mixer->getVolume();
-
-	// Exit if all data is used up (this also covers the case were reading from the file failed).
-	if (_position >= _size) {
-		destroy();
-		return;
-	}
-
-	while (1) {
-
-		int16 sample;
-		while ((_posInFrame < _synth.pcm.length) && (len > 0)) {
-			sample = (int16)((scale_sample(_synth.pcm.samples[0][_posInFrame]) * volume) / 256);
-			clamped_add_16(*data++, sample);
-			if (_synth.pcm.channels > 1)
-				sample = (int16)((scale_sample(_synth.pcm.samples[1][_posInFrame]) * volume) / 256);
-			clamped_add_16(*data++, sample);
-			len--;
-			_posInFrame++;
-		}
-		if (len == 0)
-			return;
-
-		if (_position >= _size) {
-			destroy();
-			return;
-		}
-
-		mad_stream_buffer(&_stream, _ptr + _position,
-											_size + MAD_BUFFER_GUARD - _position);
-
-		if (mad_frame_decode(&_frame, &_stream) == -1) {
-			/* End of audio... */
-			if (_stream.error == MAD_ERROR_BUFLEN) {
-				destroy();
-				return;
-			} else if (!MAD_RECOVERABLE(_stream.error)) {
-				error("MAD frame decode error !");
-			}
-		}
-		mad_synth_frame(&_synth, &_frame);
-		_posInFrame = 0;
-		_position = _stream.next_frame - _ptr;
-	}
-}
-
-#define MP3CD_BUFFERING_SIZE 131072
-
-ChannelMP3CDMusic::ChannelMP3CDMusic(SoundMixer *mixer, PlayingSoundHandle *handle, File *file, mad_timer_t duration)
-	: ChannelMP3Common(mixer, handle) {
-	_file = file;
-	_duration = duration;
-	_bufferSize = MP3CD_BUFFERING_SIZE;
-	_ptr = (byte *)malloc(MP3CD_BUFFERING_SIZE);
-}
-
-void ChannelMP3CDMusic::mix(int16 *data, uint len) {
-	mad_timer_t frame_duration;
-	const int volume = _mixer->getMusicVolume();
-
-	if (!_initialized) {
-		// just skipped
-		memset(_ptr, 0, _bufferSize);
-		_size = _file->read(_ptr, _bufferSize);
-		if (_size <= 0) {
-			debug(1, "Failed to read MP3 data during channel initialisation !");
-			destroy();
-			return;
-		}
-		// Resync
-		mad_stream_buffer(&_stream, _ptr, _size);
-		
-		// Skip the first two frames (see ChannelMP3::ChannelMP3 for an explanation)
-		int skip_loop = 2;
-		while (skip_loop != 0) {
-			if (mad_frame_decode(&_frame, &_stream) == 0) {
-				/* Do not decrease duration - see if it's a problem */
-				skip_loop--;
-			} else {
-				if (!MAD_RECOVERABLE(_stream.error)) {
-					debug(1, "Unrecoverable error while skipping !");
-					destroy();
-					return;
-				}
-			}
-		}
-		
-		// FIXME: Fingolfin asks: why is this call to mad_synth_frame
-		// necessary? Or rather, *is* it actually necessary?
-		mad_synth_frame(&_synth, &_frame);
-
-		// We are supposed to be in synch
-		mad_frame_mute(&_frame);
-		mad_synth_mute(&_synth);
-		// Resume decoding
-		if (mad_frame_decode(&_frame, &_stream) == 0) {
-			_posInFrame = 0;
-			_initialized = true;
-		} else {
-			debug(1, "Cannot resume decoding");
-			destroy();
-			return;
-		}
-	}
-
-	while (1) {
-	
-		// TODO: Check _synth.pcm.samplerate and perform rate conversion of appropriate
-		// TODO: Check _synth.pcm.channels to support stereo
-
-		// Get samples, play samples ...
-		int16 sample;
-		while ((_posInFrame < _synth.pcm.length) && (len > 0)) {
-			sample = (int16)((scale_sample(_synth.pcm.samples[0][_posInFrame]) * volume) / 256);
-			clamped_add_16(*data++, sample);
-			if (_synth.pcm.channels > 1)
-				sample = (int16)((scale_sample(_synth.pcm.samples[1][_posInFrame]) * volume) / 256);
-			clamped_add_16(*data++, sample);
-			len--;
-			_posInFrame++;
-		}
-		if (len == 0)
-			return;
-
-		// See if we have finished
-		// May be incorrect to check the size at the end of a frame but I suppose
-		// they are short enough :)
-		frame_duration = _frame.header.duration;
-		mad_timer_negate(&frame_duration);
-		mad_timer_add(&_duration, frame_duration);
-		
-		if (mad_timer_compare(_duration, mad_timer_zero) <= 0) {
-			destroy();
-			return;
-		}
-		if (mad_frame_decode(&_frame, &_stream) == -1) {
-			if (_stream.error == MAD_ERROR_BUFLEN) {
-				int not_decoded;
-
-				if (!_stream.next_frame) {
-					not_decoded = 0;
-					memset(_ptr, 0, _bufferSize + MAD_BUFFER_GUARD);
-				} else {
-					not_decoded = _stream.bufend - _stream.next_frame;
-					memcpy(_ptr, _stream.next_frame, not_decoded);
-				}
-				_size = _file->read(_ptr + not_decoded, _bufferSize - not_decoded);
-				if (_size <= 0) {
-					return;
-				}
-				_stream.error = (enum mad_error)0;
-				// Restream
-				mad_stream_buffer(&_stream, _ptr, _size + not_decoded);
-				if (mad_frame_decode(&_frame, &_stream) == -1) {
-					debug(1, "Error %d decoding after restream !", _stream.error);
-				}
-			} else if (!MAD_RECOVERABLE(_stream.error)) {
-				error("MAD frame decode error in MP3 CDMUSIC !");
-			}
-		}
-		mad_synth_frame(&_synth, &_frame);
-		_posInFrame = 0;
-	}
-}
-#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) {
-	_ov_file = ov_file;
-
-	if (duration)
-		_end_pos = ov_pcm_tell(ov_file) + duration;
-	else
-		_end_pos = 0;
-	_is_cd_track = is_cd_track;
-}
-
-void ChannelVorbis::mix(int16 *data, uint len) {
-	if (_end_pos > 0 && ov_pcm_tell(_ov_file) >= _end_pos) {
-		destroy();
-		return;
-	}
-
-	int channels = ov_info(_ov_file, -1)->channels;
-	uint len_left = len * channels * 2;
-	int16 *samples = new int16[len_left / 2];
-	char *read_pos = (char *) samples;
-	bool eof_flag = false;
-	const int volume = isMusicChannel() ? _mixer->getMusicVolume() : _mixer->getVolume();
-
-	// Read the samples
-	while (len_left > 0) {
-		long result = ov_read(_ov_file, read_pos, len_left,
-#ifndef VORBIS_TREMOR
-#ifdef SCUMM_BIG_ENDIAN
-				      1,
-#else
-				      0,
-#endif
-				      2, 1,
-#endif
-					  NULL);
-		if (result == 0) {
-			eof_flag = true;
-			memset(read_pos, 0, len_left);
-			break;
-		} else if (result == OV_HOLE) {
-			// Possibly recoverable, just warn about it
-			warning("Corrupted data in Vorbis file");
-		} else if (result < 0) {
-			debug(1, "Decode error %d in Vorbis file", result);
-			eof_flag = true;
-			memset(read_pos, 0, len_left);
-			break;
-		} else {
-			len_left -= result;
-			read_pos += result;
-		}
-	}
-
-	// Mix the samples in
-	for (uint i = 0; i < len; i++) {
-		int16 sample = (int16)(samples[i * channels] * volume / 256);
-		clamped_add_16(*data++, sample);
-		if (channels > 1)
-			sample = (int16)(samples[i * channels + 1] * volume / 256);
-		clamped_add_16(*data++, sample);
-	}
-
-	delete [] samples;
-
-	if (eof_flag)
-		destroy();
-}
-#endif // USE_VORBIS
-
-#endif // NEW_MIXER_CODE
-





More information about the Scummvm-git-logs mailing list