[Scummvm-cvs-logs] SF.net SVN: scummvm: [27760] scummvm/trunk

fingolfin at users.sourceforge.net fingolfin at users.sourceforge.net
Thu Jun 28 21:35:48 CEST 2007


Revision: 27760
          http://scummvm.svn.sourceforge.net/scummvm/?rev=27760&view=rev
Author:   fingolfin
Date:     2007-06-28 12:35:48 -0700 (Thu, 28 Jun 2007)

Log Message:
-----------
Moved some fixed point code to its own header file; simplified the LinearRateConverter code a bit; corrected some comments; split makeRateConverter into two funcs (one of them being a template func), for easier maintenance

Modified Paths:
--------------
    scummvm/trunk/sound/rate.cpp

Added Paths:
-----------
    scummvm/trunk/common/frac.h

Added: scummvm/trunk/common/frac.h
===================================================================
--- scummvm/trunk/common/frac.h	                        (rev 0)
+++ scummvm/trunk/common/frac.h	2007-06-28 19:35:48 UTC (rev 27760)
@@ -0,0 +1,51 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef COMMON_FRAC_H
+#define COMMON_FRAC_H
+
+#include "common/scummsys.h"
+
+/**
+ * The precision of the fractional (fixed point) type we define below.
+ * Normally you should never have to modify this value.
+ */
+enum {
+	FRAC_BITS = 16,
+	FRAC_LO_MASK = ((1L << FRAC_BITS) - 1),
+	FRAC_HI_MASK = ((1L << FRAC_BITS) - 1) << FRAC_BITS,
+
+	FRAC_ONE = (1L << FRAC_BITS),		// 1.0
+	FRAC_HALF = (1L << (FRAC_BITS-1))	// 0.5
+};
+
+/**
+ * Fixed-point fractions, used by the sound rate converter and other code.
+ */
+typedef int32 frac_t;
+
+inline frac_t  intToFrac(int16 value) { return value << FRAC_BITS; }
+
+#endif


Property changes on: scummvm/trunk/common/frac.h
___________________________________________________________________
Name: svn:mime-type
   + text/plain
Name: svn:keywords
   + Date Rev Author URL Id
Name: svn:eol-style
   + native

Modified: scummvm/trunk/sound/rate.cpp
===================================================================
--- scummvm/trunk/sound/rate.cpp	2007-06-28 17:42:57 UTC (rev 27759)
+++ scummvm/trunk/sound/rate.cpp	2007-06-28 19:35:48 UTC (rev 27760)
@@ -35,15 +35,11 @@
 #include "sound/audiostream.h"
 #include "sound/rate.h"
 #include "sound/mixer.h"
+#include "common/frac.h"
 #include "common/util.h"
 
 namespace Audio {
 
-/**
- * The precision of the fractional computations used by the rate converter.
- * Normally you should never have to modify this value.
- */
-#define FRAC_BITS 16
 
 /**
  * The size of the intermediate input cache. Bigger values may increase
@@ -88,12 +84,8 @@
  */
 template<bool stereo, bool reverseStereo>
 SimpleRateConverter<stereo, reverseStereo>::SimpleRateConverter(st_rate_t inrate, st_rate_t outrate) {
-	if (inrate == outrate) {
-		error("Input and Output rates must be different to use rate effect");
-	}
-
 	if ((inrate % outrate) != 0) {
-		error("Input rate must be a multiple of Output rate to use rate effect");
+		error("Input rate must be a multiple of output rate to use rate effect");
 	}
 
 	if (inrate >= 65536 || outrate >= 65536) {
@@ -174,10 +166,10 @@
 	int inLen;
 
 	/** fractional position of the output stream in input stream unit */
-	long opos, opos_frac;
+	frac_t opos;
 
 	/** fractional position increment in the output stream */
-	long opos_inc, opos_inc_frac;
+	frac_t opos_inc;
 
 	/** last sample(s) in the input stream (left/right channel) */
 	st_sample_t ilast0, ilast1;
@@ -198,25 +190,15 @@
  */
 template<bool stereo, bool reverseStereo>
 LinearRateConverter<stereo, reverseStereo>::LinearRateConverter(st_rate_t inrate, st_rate_t outrate) {
-	unsigned long incr;
-
-	if (inrate == outrate) {
-		error("Input and Output rates must be different to use rate effect");
-	}
-
 	if (inrate >= 65536 || outrate >= 65536) {
 		error("rate effect can only handle rates < 65536");
 	}
 
-	opos_frac = 0;
-	opos = 1;
+	opos = FRAC_ONE;
 
 	/* increment */
-	incr = (inrate << FRAC_BITS) / outrate;
+	opos_inc = (inrate << FRAC_BITS) / outrate;
 
-	opos_inc_frac = incr & ((1UL << FRAC_BITS) - 1);
-	opos_inc = incr >> FRAC_BITS;
-
 	ilast0 = ilast1 = 0;
 	icur0 = icur1 = 0;
 
@@ -236,7 +218,7 @@
 
 	while (obuf < oend) {
 
-		// read enough input samples so that opos <= 0
+		// read enough input samples so that opos < 0
 		while (0 <= opos) {
 			// Check if we have to refill the buffer
 			if (inLen == 0) {
@@ -252,7 +234,7 @@
 				ilast1 = icur1;
 				icur1 = *inPtr++;
 			}
-			opos--;
+			opos -= FRAC_ONE;
 		}
 
 		// Loop as long as the outpos trails behind, and as long as there is
@@ -260,9 +242,10 @@
 		while (0 > opos && obuf < oend) {
 			// interpolate
 			st_sample_t out0, out1;
-			out0 = (st_sample_t)(ilast0 + (((icur0 - ilast0) * opos_frac + (1UL << (FRAC_BITS-1))) >> FRAC_BITS));
+			const frac_t scale = (opos & FRAC_LO_MASK);
+			out0 = (st_sample_t)(ilast0 + (((icur0 - ilast0) * scale + FRAC_HALF) >> FRAC_BITS));
 			out1 = (stereo ?
-						  (st_sample_t)(ilast1 + (((icur1 - ilast1) * opos_frac + (1UL << (FRAC_BITS-1))) >> FRAC_BITS)) :
+						  (st_sample_t)(ilast1 + (((icur1 - ilast1) * scale + FRAC_HALF) >> FRAC_BITS)) :
 						  out0);
 
 			// output left channel
@@ -274,9 +257,7 @@
 			obuf += 2;
 
 			// Increment output position
-			long tmp = opos_frac + opos_inc_frac;
-			opos += opos_inc + (tmp >> FRAC_BITS);
-			opos_frac = tmp & ((1UL << FRAC_BITS) - 1);
+			opos += opos_inc;
 		}
 	}
 	return ST_SUCCESS;
@@ -344,38 +325,30 @@
 
 #pragma mark -
 
-
-/**
- * Create and return a RateConverter object for the specified input and output rates.
- */
-RateConverter *makeRateConverter(st_rate_t inrate, st_rate_t outrate, bool stereo, bool reverseStereo) {
+template<bool stereo, bool reverseStereo>
+RateConverter *makeRateConverter(st_rate_t inrate, st_rate_t outrate) {
 	if (inrate != outrate) {
 		if ((inrate % outrate) == 0) {
-			if (stereo) {
-				if (reverseStereo)
-					return new SimpleRateConverter<true, true>(inrate, outrate);
-				else
-					return new SimpleRateConverter<true, false>(inrate, outrate);
-			} else
-				return new SimpleRateConverter<false, false>(inrate, outrate);
+			return new SimpleRateConverter<stereo, reverseStereo>(inrate, outrate);
 		} else {
-			if (stereo) {
-				if (reverseStereo)
-					return new LinearRateConverter<true, true>(inrate, outrate);
-				else
-					return new LinearRateConverter<true, false>(inrate, outrate);
-			} else
-				return new LinearRateConverter<false, false>(inrate, outrate);
-		 }
+			return new LinearRateConverter<stereo, reverseStereo>(inrate, outrate);
+		}
 	} else {
-		if (stereo) {
-			if (reverseStereo)
-				return new CopyRateConverter<true, true>();
-			else
-				return new CopyRateConverter<true, false>();
-		} else
-			return new CopyRateConverter<false, false>();
+		return new CopyRateConverter<stereo, reverseStereo>();
 	}
 }
 
+/**
+ * Create and return a RateConverter object for the specified input and output rates.
+ */
+RateConverter *makeRateConverter(st_rate_t inrate, st_rate_t outrate, bool stereo, bool reverseStereo) {
+	if (stereo) {
+		if (reverseStereo)
+			return makeRateConverter<true, true>(inrate, outrate);
+		else
+			return makeRateConverter<true, false>(inrate, outrate);
+	} else
+		return makeRateConverter<false, false>(inrate, outrate);
+}
+
 } // End of namespace Audio


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list