[Scummvm-cvs-logs] CVS: scummvm/sound rate.h,1.5,1.6 rate.cpp,1.6,1.7 audiostream.cpp,1.2,1.3 audiostream.h,1.5,1.6

Max Horn fingolfin at users.sourceforge.net
Mon Jul 28 04:14:02 CEST 2003


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

Modified Files:
	rate.h rate.cpp audiostream.cpp audiostream.h 
Log Message:
instead of 'int channels', use 'bool stereo' (less extensible, but then I don't think we'll ever support 5.1 sound :-)); fixed a bug in st_rate_flow where it sometimes would overflow the output buffer; made CopyRateConverter a template, too, increasing efficency

Index: rate.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sound/rate.h,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- rate.h	28 Jul 2003 01:50:46 -0000	1.5
+++ rate.h	28 Jul 2003 11:13:01 -0000	1.6
@@ -81,15 +81,17 @@
 	virtual int drain(st_sample_t *obuf, st_size_t *osamp, st_volume_t vol);
 };
 
+template<bool stereo>
 class CopyRateConverter : public RateConverter {
 public:
 	virtual int flow(AudioInputStream &input, st_sample_t *obuf, st_size_t *osamp, st_volume_t vol) {
 		int16 tmp;
 		st_size_t len = *osamp;
+		assert(input.isStereo() == stereo);
 		while (!input.eof() && len--) {
 			tmp = input.read() * vol / 256;
 			clampedAdd(*obuf++, tmp);
-			if (input.isStereo())
+			if (stereo)
 				tmp = input.read() * vol / 256;
 			clampedAdd(*obuf++, tmp);
 		}

Index: rate.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sound/rate.cpp,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- rate.cpp	28 Jul 2003 01:50:46 -0000	1.6
+++ rate.cpp	28 Jul 2003 11:13:01 -0000	1.7
@@ -92,29 +92,36 @@
  * Processed signed long samples from ibuf to obuf.
  * Return number of samples processed.
  */
-template<int channels>
+template<bool stereo>
 int st_rate_flow(eff_t effp, AudioInputStream &input, st_sample_t *obuf, st_size_t *osamp, st_volume_t vol)
 {
 	rate_t rate = (rate_t) effp->priv;
 	st_sample_t *ostart, *oend;
 	st_sample_t ilast[2], icur[2], out;
 	unsigned long tmp;
-	int i;
-
-	assert(channels == 1 || channels == 2);
 
-	for (i = 0; i < channels; i++)
-		ilast[i] = rate->ilast[i];
+	ilast[0] = rate->ilast[0];
+	if (stereo)
+		ilast[1] = rate->ilast[1];
 
 	ostart = obuf;
 	oend = obuf + *osamp * 2;
 
+	if (stereo)
+		assert(input.size() % 2 == 0);	// Stereo code assumes even number of input samples
+	
+	// If the input position exceeds the output position, then we aborted the
+	// previous conversion run because the output buffer was full. Resume!
+	if (rate->ipos > rate->opos)
+		goto resume;
+
 	while (obuf < oend && !input.eof()) {
 
 		/* read enough input samples so that ipos > opos */
 		while (rate->ipos <= rate->opos) {
-			for (i = 0; i < channels; i++)
-				ilast[i] = input.read();
+			ilast[0] = input.read();
+			if (stereo)
+				ilast[1] = input.read();
 			rate->ipos++;
 			/* See if we finished the input buffer yet */
 
@@ -124,27 +131,31 @@
 
 		// read the input sample(s)
 		icur[0] = input.read();
-		if (channels == 2) {
-			if (input.eof())
-				goto the_end;	// Shouldn't happen if data comes pair-wise
+		if (stereo)
 			icur[1] = input.read();
-		}
 
-		while (rate->ipos > rate->opos) {
-			for (i = 0; i < channels; i++) {
+resume:
+		// Loop as long as the outpos trails behind, and as long as there is
+		// still space in the output buffer.
+		while (rate->ipos > rate->opos && obuf < oend) {
+
+			// interpolate
+			out = ilast[0] + (((icur[0] - ilast[0]) * rate->opos_frac + (1UL << (FRAC_BITS-1))) >> FRAC_BITS);
+			// adjust volume
+			out = out * vol / 256;
+	
+			// output left channel sample
+			clampedAdd(*obuf++, out);
+			
+			if (stereo) {
 				// interpolate
-				out = ilast[i] + (((icur[i] - ilast[i]) * rate->opos_frac + (1UL << (FRAC_BITS-1))) >> FRAC_BITS);
-		
+				out = ilast[1] + (((icur[1] - ilast[1]) * rate->opos_frac + (1UL << (FRAC_BITS-1))) >> FRAC_BITS);
 				// adjust volume
 				out = out * vol / 256;
-		
-				// output left channel sample
-				clampedAdd(*obuf++, out);
 			}
 	
-			// For mono input, repeat the sample to produce stereo output
-			if (channels == 1)
-				clampedAdd(*obuf++, out);
+			// output right channel sample
+			clampedAdd(*obuf++, out);
 	
 			// Increment output position
 			tmp = rate->opos_frac + rate->opos_inc_frac;
@@ -154,14 +165,16 @@
 
 		// Increment input position again (for the sample we read now)
 		rate->ipos++;
-		for (i = 0; i < channels; i++)
-			ilast[i] = icur[i];
+		ilast[0] = icur[0];
+		if (stereo)
+			ilast[1] = icur[1];
 	}
 
 the_end:
 	*osamp = (obuf - ostart) / 2;
-	for (i = 0; i < channels; i++)
-		rate->ilast[i] = ilast[i];
+	rate->ilast[0] = ilast[0];
+	if (stereo)
+		rate->ilast[1] = ilast[1];
 	return (ST_SUCCESS);
 }
 
@@ -175,9 +188,9 @@
 
 int LinearRateConverter::flow(AudioInputStream &input, st_sample_t *obuf, st_size_t *osamp, st_volume_t vol) {
 	if (input.isStereo())
-		return st_rate_flow<2>(&effp, input, obuf, osamp, vol);
+		return st_rate_flow<true>(&effp, input, obuf, osamp, vol);
 	else
-		return st_rate_flow<1>(&effp, input, obuf, osamp, vol);
+		return st_rate_flow<false>(&effp, input, obuf, osamp, vol);
 }
 
 int LinearRateConverter::drain(st_sample_t *obuf, st_size_t *osamp, st_volume_t vol) {

Index: audiostream.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sound/audiostream.cpp,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- audiostream.cpp	28 Jul 2003 01:13:31 -0000	1.2
+++ audiostream.cpp	28 Jul 2003 11:13:01 -0000	1.3
@@ -22,7 +22,7 @@
 #include "audiostream.h"
 #include "mixer.h"
 
-template<int channels, int sampleSize>
+template<bool stereo, int sampleSize>
 class LinearMemoryStream : public AudioInputStream {
 protected:
 	const byte *_ptr;
@@ -31,14 +31,14 @@
 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 channels == 2; }
+	virtual bool isStereo() const { return stereo; }
 };
 
 #if 0
 TODO: Implement a wrapped memory stream, to be used by the ChannelStream class
 (and possibly others?)
 
-template<int channels, int sampleSize>
+template<bool stereo, int sampleSize>
 class WrappedMemoryStream : public AudioInputStream {
 protected:
 	byte *_bufferStart;
@@ -47,7 +47,7 @@
 	byte *_end;
 	
 	void advance() {
-		_ptr += channels * sampleSize;
+		_ptr += sampleSize;
 		.. TODO: wrap
 	}
 public:
@@ -56,7 +56,7 @@
 		int size = _end - _pos;
 		if (size < 0)
 			size += _bufferEnd - _bufferStart
-		return size / (channels * sampleSize);
+		return size / sampleSize;
 	}
 	
 	void append(const byte *ptr, uint len) {
@@ -66,7 +66,7 @@
 #endif
 
 
-template<int channels, class T = class LinearMemoryStream<channels, 1> >
+template<bool stereo, class T = class LinearMemoryStream<stereo, 1> >
 class Input8bitSignedStream : public T {
 protected:
 	int16 readIntern() { int8 v = (int8)*_ptr; return v << 8; }
@@ -74,7 +74,7 @@
 	Input8bitSignedStream(const byte *ptr, int len) : T(ptr, len) { }
 };
 
-template<int channels, class T = class LinearMemoryStream<channels, 1> >
+template<bool stereo, class T = class LinearMemoryStream<stereo, 1> >
 class Input8bitUnsignedStream : public T {
 protected:
 	int16 readIntern() { int8 v = (int8)(*_ptr ^ 0x80); return v << 8; }
@@ -82,7 +82,7 @@
 	Input8bitUnsignedStream(const byte *ptr, int len) : T(ptr, len) { }
 };
 
-template<int channels, class T = class LinearMemoryStream<channels, 2> >
+template<bool stereo, class T = class LinearMemoryStream<stereo, 2> >
 class Input16bitSignedStream : public T {
 protected:
 	int16 readIntern() { return (int16)READ_BE_UINT16(_ptr); }
@@ -90,7 +90,7 @@
 	Input16bitSignedStream(const byte *ptr, int len) : T(ptr, len) { }
 };
 
-template<int channels, class T = class LinearMemoryStream<channels, 2> >
+template<bool stereo, class T = class LinearMemoryStream<stereo, 2> >
 class Input16bitUnsignedStream : public T {
 protected:
 	int16 readIntern() { return (int16)(READ_BE_UINT16(_ptr) ^ 0x8000); }
@@ -99,25 +99,25 @@
 };
 
 
-template<int channels>
+template<bool stereo>
 static AudioInputStream *makeInputStream(const byte *ptr, uint32 len, bool isUnsigned, bool is16Bit) {
 	if (isUnsigned) {
 		if (is16Bit)
-			return new Input16bitUnsignedStream<channels>(ptr, len);
+			return new Input16bitUnsignedStream<stereo>(ptr, len);
 		else
-			return new Input8bitUnsignedStream<channels>(ptr, len);
+			return new Input8bitUnsignedStream<stereo>(ptr, len);
 	} else {
 		if (is16Bit)
-			return new Input16bitSignedStream<channels>(ptr, len);
+			return new Input16bitSignedStream<stereo>(ptr, len);
 		else
-			return new Input8bitSignedStream<channels>(ptr, len);
+			return new Input8bitSignedStream<stereo>(ptr, len);
 	}
 }
 
 
 AudioInputStream *makeInputStream(byte _flags, const byte *ptr, uint32 len) {
 	if (_flags & SoundMixer::FLAG_STEREO)
-		return makeInputStream<2>(ptr, len, _flags & SoundMixer::FLAG_UNSIGNED, _flags & SoundMixer::FLAG_16BITS);
+		return makeInputStream<true>(ptr, len, _flags & SoundMixer::FLAG_UNSIGNED, _flags & SoundMixer::FLAG_16BITS);
 	else
-		return makeInputStream<1>(ptr, len, _flags & SoundMixer::FLAG_UNSIGNED, _flags & SoundMixer::FLAG_16BITS);
+		return makeInputStream<false>(ptr, len, _flags & SoundMixer::FLAG_UNSIGNED, _flags & SoundMixer::FLAG_16BITS);
 }

Index: audiostream.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sound/audiostream.h,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- audiostream.h	28 Jul 2003 01:13:31 -0000	1.5
+++ audiostream.h	28 Jul 2003 11:13:01 -0000	1.6
@@ -40,7 +40,6 @@
 	virtual void advance() = 0;
 public:
 	int16 read() { assert(size() > 0); int16 val = readIntern(); advance(); return val; }
-//	int16 peek() { assert(size() > 0); return readIntern(); }
 	virtual int size() const = 0;
 	bool eof() const { return size() <= 0; }
 	virtual bool isStereo() const = 0;





More information about the Scummvm-git-logs mailing list