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

Max Horn fingolfin at users.sourceforge.net
Sun Jul 27 18:14:19 CEST 2003


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

Modified Files:
	audiostream.h audiostream.cpp rate.cpp rate.h resample.cpp 
Log Message:
use a single converter for both channels (if input data is stereo), for improved efficency; renamed MemoryAudioInputStream -> LinearMemoryStream and use some template voodoo to make the baseclass of Input8bitSignedStream etc. variable; added (commented out) draf of WrappedMemoryStream

Index: audiostream.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sound/audiostream.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- audiostream.h	25 Jul 2003 13:42:05 -0000	1.4
+++ audiostream.h	28 Jul 2003 01:13:31 -0000	1.5
@@ -40,9 +40,10 @@
 	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() = 0;
-	bool eof() { return size() <= 0; }
+//	int16 peek() { assert(size() > 0); return readIntern(); }
+	virtual int size() const = 0;
+	bool eof() const { return size() <= 0; }
+	virtual bool isStereo() const = 0;
 };
 
 class ZeroInputStream : public AudioInputStream {
@@ -52,7 +53,8 @@
 	void advance() { _len--; }
 public:
 	ZeroInputStream(uint len) : _len(len) { }
-	virtual int size() { return _len; }
+	virtual int size() const { return _len; }
+	virtual bool isStereo() const { return false; }
 };
 
 AudioInputStream *makeInputStream(byte _flags, const byte *ptr, uint32 len);

Index: audiostream.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sound/audiostream.cpp,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- audiostream.cpp	25 Jul 2003 13:42:05 -0000	1.1
+++ audiostream.cpp	28 Jul 2003 01:13:31 -0000	1.2
@@ -23,47 +23,79 @@
 #include "mixer.h"
 
 template<int channels, int sampleSize>
-class MemoryAudioInputStream : public AudioInputStream {
+class LinearMemoryStream : public AudioInputStream {
 protected:
 	const byte *_ptr;
 	const byte *_end;
-	void advance() { _ptr += channels * sampleSize; }
+	void advance() { _ptr += sampleSize; }
 public:
-	MemoryAudioInputStream(const byte *ptr, uint len) : _ptr(ptr), _end(ptr+len) { }
-	virtual int size() { return (_end - _ptr) / (channels * sampleSize); }
+	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; }
 };
 
+#if 0
+TODO: Implement a wrapped memory stream, to be used by the ChannelStream class
+(and possibly others?)
 
-template<int channels>
-class Input8bitSignedStream : public MemoryAudioInputStream<channels, 1> {
+template<int channels, int sampleSize>
+class WrappedMemoryStream : public AudioInputStream {
+protected:
+	byte *_bufferStart;
+	byte *_bufferEnd;
+	byte *_pos;
+	byte *_end;
+	
+	void advance() {
+		_ptr += channels * sampleSize;
+		.. TODO: wrap
+	}
+public:
+	WrappedMemoryStream(const byte *ptr, uint len) : _bufferStart(ptr), _bufferEnd(ptr+len) { }
+	virtual int size() const {
+		int size = _end - _pos;
+		if (size < 0)
+			size += _bufferEnd - _bufferStart
+		return size / (channels * sampleSize);
+	}
+	
+	void append(const byte *ptr, uint len) {
+		...
+	}
+};
+#endif
+
+
+template<int channels, class T = class LinearMemoryStream<channels, 1> >
+class Input8bitSignedStream : public T {
 protected:
 	int16 readIntern() { int8 v = (int8)*_ptr; return v << 8; }
 public:
-	Input8bitSignedStream(const byte *ptr, int len) : MemoryAudioInputStream<channels, 1>(ptr, len) { }
+	Input8bitSignedStream(const byte *ptr, int len) : T(ptr, len) { }
 };
 
-template<int channels>
-class Input8bitUnsignedStream : public MemoryAudioInputStream<channels, 1> {
+template<int channels, class T = class LinearMemoryStream<channels, 1> >
+class Input8bitUnsignedStream : public T {
 protected:
 	int16 readIntern() { int8 v = (int8)(*_ptr ^ 0x80); return v << 8; }
 public:
-	Input8bitUnsignedStream(const byte *ptr, int len) : MemoryAudioInputStream<channels, 1>(ptr, len) { }
+	Input8bitUnsignedStream(const byte *ptr, int len) : T(ptr, len) { }
 };
 
-template<int channels>
-class Input16bitSignedStream : public MemoryAudioInputStream<channels, 2> {
+template<int channels, class T = class LinearMemoryStream<channels, 2> >
+class Input16bitSignedStream : public T {
 protected:
 	int16 readIntern() { return (int16)READ_BE_UINT16(_ptr); }
 public:
-	Input16bitSignedStream(const byte *ptr, int len) : MemoryAudioInputStream<channels, 2>(ptr, len) { }
+	Input16bitSignedStream(const byte *ptr, int len) : T(ptr, len) { }
 };
 
-template<int channels>
-class Input16bitUnsignedStream : public MemoryAudioInputStream<channels, 2> {
+template<int channels, class T = class LinearMemoryStream<channels, 2> >
+class Input16bitUnsignedStream : public T {
 protected:
 	int16 readIntern() { return (int16)(READ_BE_UINT16(_ptr) ^ 0x8000); }
 public:
-	Input16bitUnsignedStream(const byte *ptr, int len) : MemoryAudioInputStream<channels, 2>(ptr, len) { }
+	Input16bitUnsignedStream(const byte *ptr, int len) : T(ptr, len) { }
 };
 
 

Index: rate.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sound/rate.cpp,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- rate.cpp	25 Jul 2003 01:05:08 -0000	1.4
+++ rate.cpp	28 Jul 2003 01:13:31 -0000	1.5
@@ -51,7 +51,7 @@
 
 	unsigned long ipos;	 /* position in the input stream (integer) */
 
-	st_sample_t ilast; /* last sample in the input stream */
+	st_sample_t ilast[2]; /* last sample(s) in the input stream (left/right channel) */
 } *rate_t;
 
 /*
@@ -83,7 +83,8 @@
 
 	rate->ipos = 0;
 
-	rate->ilast = 0;
+	rate->ilast[0] = 0;
+	rate->ilast[1] = 0;
 	return (ST_SUCCESS);
 }
 
@@ -91,23 +92,29 @@
  * Processed signed long samples from ibuf to obuf.
  * Return number of samples processed.
  */
+template<int channels>
 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, icur, out;
+	st_sample_t ilast[2], icur[2], out;
 	unsigned long tmp;
+	int i;
 
-	ilast = rate->ilast;
+	assert(channels == 1 || channels == 2);
+
+	for (i = 0; i < channels; i++)
+		ilast[i] = rate->ilast[i];
 
 	ostart = obuf;
 	oend = obuf + *osamp;
 
 	while (obuf < oend && !input.eof()) {
 
-		/* read as many input samples so that ipos > opos */
+		/* read enough input samples so that ipos > opos */
 		while (rate->ipos <= rate->opos) {
-			ilast = input.read();
+			for (i = 0; i < channels; i++)
+				ilast[i] = input.read();
 			rate->ipos++;
 			/* See if we finished the input buffer yet */
 
@@ -115,25 +122,64 @@
 				goto the_end;
 		}
 
-		icur = input.peek();
-
-		/* interpolate */
-		out = ilast + (((icur - ilast) * rate->opos_frac + (1UL << (FRAC_BITS-1))) >> FRAC_BITS);
+		// 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
+			icur[1] = input.read();
+		}
 
-		/* output sample & increment position */
-		out = out * vol / 256;
-		clampedAdd(*obuf++, out);
-		#if 1	// FIXME: Hack to generate stereo output
-		clampedAdd(*obuf++, out);
-		#endif
+		while (rate->ipos > rate->opos) {
+			for (i = 0; i < channels; i++) {
+				// interpolate
+				out = ilast[i] + (((icur[i] - ilast[i]) * 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);
+	
+			// Increment output position
+			tmp = rate->opos_frac + rate->opos_inc_frac;
+			rate->opos = rate->opos + rate->opos_inc + (tmp >> FRAC_BITS);
+			rate->opos_frac = tmp & ((1UL << FRAC_BITS) - 1);
+		}
 
-		tmp = rate->opos_frac + rate->opos_inc_frac;
-		rate->opos = rate->opos + rate->opos_inc + (tmp >> FRAC_BITS);
-		rate->opos_frac = tmp & ((1UL << FRAC_BITS) - 1);
+		// Increment input position again (for the sample we read now)
+		rate->ipos++;
+		for (i = 0; i < channels; i++)
+			ilast[i] = icur[i];
 	}
 
 the_end:
 	*osamp = obuf - ostart;
-	rate->ilast = ilast;
+	for (i = 0; i < channels; i++)
+		rate->ilast[i] = ilast[i];
+	return (ST_SUCCESS);
+}
+
+
+#pragma mark -
+
+
+LinearRateConverter::LinearRateConverter(st_rate_t inrate, st_rate_t outrate) {
+	st_rate_start(&effp, inrate, outrate);
+}
+
+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);
+	else
+		return st_rate_flow<1>(&effp, input, obuf, osamp, vol);
+}
+
+int LinearRateConverter::drain(st_sample_t *obuf, st_size_t *osamp, st_volume_t vol) {
 	return (ST_SUCCESS);
 }

Index: rate.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sound/rate.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- rate.h	24 Jul 2003 21:26:00 -0000	1.3
+++ rate.h	28 Jul 2003 01:13:31 -0000	1.4
@@ -56,17 +56,6 @@
 #define st_fail error
 
 
-// Resample (high quality)
-int st_resample_getopts(eff_t effp, int n, const char **argv);
-int st_resample_start(eff_t effp, st_rate_t inrate, st_rate_t outrate);
-int st_resample_flow(eff_t effp, AudioInputStream &input, st_sample_t *obuf, st_size_t *osamp, st_volume_t vol);
-int st_resample_drain(eff_t effp, st_sample_t *obuf, st_size_t *osamp, st_volume_t vol);
-int st_resample_stop(eff_t effp);
-
-// Rate (linear filter, low quality)
-int st_rate_start(eff_t effp, st_rate_t inrate, st_rate_t outrate);
-int st_rate_flow(eff_t effp, AudioInputStream &input, st_sample_t *obuf, st_size_t *osamp, st_volume_t vol);
-
 class RateConverter {
 protected:
 	eff_struct effp;
@@ -79,40 +68,17 @@
 
 class LinearRateConverter : public RateConverter {
 public:
-	LinearRateConverter(st_rate_t inrate, st_rate_t outrate) {
-		st_rate_start(&effp, inrate, outrate);
-	}
-	virtual int flow(AudioInputStream &input, st_sample_t *obuf, st_size_t *osamp, st_volume_t vol) {
-		return st_rate_flow(&effp, input, obuf, osamp, vol);
-	}
-	virtual int drain(st_sample_t *obuf, st_size_t *osamp, st_volume_t vol) {
-		return (ST_SUCCESS);
-	}
+	LinearRateConverter(st_rate_t inrate, st_rate_t outrate);
+	virtual int flow(AudioInputStream &input, st_sample_t *obuf, st_size_t *osamp, st_volume_t vol);
+	virtual int drain(st_sample_t *obuf, st_size_t *osamp, st_volume_t vol);
 };
 
 class ResampleRateConverter : public RateConverter {
 public:
-	ResampleRateConverter(st_rate_t inrate, st_rate_t outrate, int quality) {
-		// FIXME: quality is for now a nasty hack.
-		// Valid values are 0,1,2,3 (everything else is treated like 0 for now)
-		const char *arg = 0;
-		switch (quality) {
-		case 1: arg = "-qs"; break;
-		case 2: arg = "-q"; break;
-		case 3: arg = "-ql"; break;
-		}
-		st_resample_getopts(&effp, arg ? 1 : 0, &arg);
-		st_resample_start(&effp, inrate, outrate);
-	}
-	~ResampleRateConverter() {
-		st_resample_stop(&effp);
-	}
-	virtual int flow(AudioInputStream &input, st_sample_t *obuf, st_size_t *osamp, st_volume_t vol) {
-		return st_resample_flow(&effp, input, obuf, osamp, vol);
-	}
-	virtual int drain(st_sample_t *obuf, st_size_t *osamp, st_volume_t vol) {
-		return st_resample_drain(&effp, obuf, osamp, vol);
-	}
+	ResampleRateConverter(st_rate_t inrate, st_rate_t outrate, int quality);
+	~ResampleRateConverter();
+	virtual int flow(AudioInputStream &input, st_sample_t *obuf, st_size_t *osamp, st_volume_t vol);
+	virtual int drain(st_sample_t *obuf, st_size_t *osamp, st_volume_t vol);
 };
 
 #endif

Index: resample.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sound/resample.cpp,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- resample.cpp	24 Jul 2003 21:26:00 -0000	1.3
+++ resample.cpp	28 Jul 2003 01:13:31 -0000	1.4
@@ -274,6 +274,16 @@
 	const long obufSize = *osamp;
 #endif
 
+TODO: adjust for the changes made to AudioInputStream; add support for stereo
+initially, could just average the left/right channel -> bad for quality of course,
+but easiest to implement and would get this going again.
+Next step is to duplicate the X/Y buffers... a lot of computations don't care about
+how many channels there are anyway, they could just be ran twice, e.g. SrcEX and SrcUD.
+But better for efficiency would be to rewrite those to deal with 2 channels, too.
+Because esp in SrcEX/SrcUD, only very few computations depend on the input data,
+and dealing with both channels in parallel should only be a little slower than dealing
+with them alone
+
 	// Constrain amount we actually process
 	//fprintf(stderr,"Xp %d, Xread %d\n",r->Xp, r->Xread);
 
@@ -313,7 +323,6 @@
 	
 	// Finally compute the effective number of bytes to process
 	Nproc = last - r->Xoff - r->Xp;
-printf("FOO(3) Nproc %ld\n", Nproc);
 
 	if (Nproc <= 0) {
 		/* fill in starting here next time */
@@ -356,7 +365,7 @@
 
 	/* Copy back portion of input signal that must be re-used */
 	k = r->Xp - r->Xoff;
-	fprintf(stderr,"k %d, last %d\n",k,last);
+	//fprintf(stderr,"k %d, last %d\n",k,last);
 	for (i = 0; i < last - k; i++)
 		r->X[i] = r->X[i + k];
 
@@ -370,7 +379,8 @@
 		int sample = (int)(r->Y[i] * vol / 256);
 		clampedAdd(*obuf++, sample);
 #if 1	// FIXME: Hack to generate stereo output
-		clampedAdd(*obuf++, sample);
+//		clampedAdd(*obuf++, sample);
+		*obuf++;
 #endif
 	}
 
@@ -514,12 +524,12 @@
 	Factor = r->Factor;
 	time = r->Time;
 	dt = 1.0 / Factor;	   /* Output sampling period */
-	fprintf(stderr,"Factor %f, dt %f, ",Factor,dt);
-	fprintf(stderr,"Time %f, ",r->Time);
+	//fprintf(stderr,"Factor %f, dt %f, ",Factor,dt);
+	//fprintf(stderr,"Time %f, ",r->Time);
 	/* (Xh * dhb)>>La is max index into Imp[] */
 	/*fprintf(stderr,"ct=%d\n",ct);*/
-	fprintf(stderr,"ct=%.2f %d\n",(double)r->Nwing*Na/r->dhb, r->Xh);
-	fprintf(stderr,"ct=%ld, T=%.6f, dhb=%6f, dt=%.6f\n", r->Xh, time-floor(time),(double)r->dhb/Na,dt);
+	//fprintf(stderr,"ct=%.2f %d\n",(double)r->Nwing*Na/r->dhb, r->Xh);
+	//fprintf(stderr,"ct=%ld, T=%.6f, dhb=%6f, dt=%.6f\n", r->Xh, time-floor(time),(double)r->dhb/Na,dt);
 	Ystart = Y = r->Y + r->Yposition;
 	n = (int)ceil((double)Nx / dt);
 	while (n--) {
@@ -722,3 +732,33 @@
 		}
 	}
 }
+
+
+#pragma mark -
+
+
+ResampleRateConverter::ResampleRateConverter(st_rate_t inrate, st_rate_t outrate, int quality) {
+	// FIXME: quality is for now a nasty hack.
+	// Valid values are 0,1,2,3 (everything else is treated like 0 for now)
+	const char *arg = 0;
+	switch (quality) {
+	case 1: arg = "-qs"; break;
+	case 2: arg = "-q"; break;
+	case 3: arg = "-ql"; break;
+	}
+	st_resample_getopts(&effp, arg ? 1 : 0, &arg);
+	st_resample_start(&effp, inrate, outrate);
+}
+
+ResampleRateConverter::~ResampleRateConverter() {
+	st_resample_stop(&effp);
+}
+
+int ResampleRateConverter::flow(AudioInputStream &input, st_sample_t *obuf, st_size_t *osamp, st_volume_t vol) {
+	return st_resample_flow(&effp, input, obuf, osamp, vol);
+}
+
+int ResampleRateConverter::drain(st_sample_t *obuf, st_size_t *osamp, st_volume_t vol) {
+	return st_resample_drain(&effp, obuf, osamp, vol);
+}
+





More information about the Scummvm-git-logs mailing list