shithub: sox

Download patch

ref: 82a7fd4ef9e66dffe17bc376db6ade45ed478a5e
parent: f31c7d7278764124164294fee84c4c9c00a9ab50
author: cbagwell <cbagwell>
date: Sun Jan 28 22:09:32 EST 2007

Reverting gsm library back to upstream version.

--- a/src/libgsm/add.c
+++ b/src/libgsm/add.c
@@ -4,6 +4,8 @@
  * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
  */
 
+/* $Header: /cvsroot/sox/sox/src/libgsm/Attic/add.c,v 1.5 2007/01/29 03:09:32 cbagwell Exp $ */
+
 /*
  *  See private.h for the more commonly used macro versions.
  */
@@ -35,6 +37,63 @@
 	else return SASR( (longword)a * (longword)b, 15 );
 }
 
+word gsm_mult_r (word a, word b)
+{
+	if (b == MIN_WORD && a == MIN_WORD) return MAX_WORD;
+	else {
+		longword prod = (longword)a * (longword)b + 16384;
+		prod >>= 15;
+		return prod & 0xFFFF;
+	}
+}
+
+word gsm_abs (word a)
+{
+	return a < 0 ? (a == MIN_WORD ? MAX_WORD : -a) : a;
+}
+
+longword gsm_L_mult (word a, word b)
+{
+	assert( a != MIN_WORD || b != MIN_WORD );
+	return ((longword)a * (longword)b) << 1;
+}
+
+longword gsm_L_add (longword a, longword b)
+{
+	if (a < 0) {
+		if (b >= 0) return a + b;
+		else {
+			ulongword A = (ulongword)-(a + 1) + (ulongword)-(b + 1);
+			return A >= MAX_LONGWORD ? MIN_LONGWORD :-(longword)A-2;
+		}
+	}
+	else if (b <= 0) return a + b;
+	else {
+		ulongword A = (ulongword)a + (ulongword)b;
+		return A > MAX_LONGWORD ? MAX_LONGWORD : A;
+	}
+}
+
+longword gsm_L_sub (longword a, longword b)
+{
+	if (a >= 0) {
+		if (b >= 0) return a - b;
+		else {
+			/* a>=0, b<0 */
+
+			ulongword A = (ulongword)a + -(b + 1);
+			return A >= MAX_LONGWORD ? MAX_LONGWORD : (A + 1);
+		}
+	}
+	else if (b <= 0) return a - b;
+	else {
+		/* a<0, b>0 */  
+
+		ulongword A = (ulongword)-(a + 1) + b;
+		return A >= MAX_LONGWORD ? MIN_LONGWORD : -(longword)A - 1;
+	}
+}
+
 static unsigned char const bitoff[ 256 ] = {
 	 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
 	 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
@@ -90,6 +149,14 @@
 		  :  23 + bitoff[ 0xFF & a ] );
 }
 
+longword gsm_L_asl (longword a, int n)
+{
+	if (n >= 32) return 0;
+	if (n <= -32) return -(a < 0);
+	if (n < 0) return gsm_L_asr(a, -n);
+	return a << n;
+}
+
 word gsm_asl (word a, int n)
 {
 	if (n >= 16) return 0;
@@ -98,12 +165,32 @@
 	return a << n;
 }
 
+longword gsm_L_asr (longword a, int n)
+{
+	if (n >= 32) return -(a < 0);
+	if (n <= -32) return 0;
+	if (n < 0) return a << -n;
+
+#	ifdef	SASR
+		return a >> n;
+#	else
+		if (a >= 0) return a >> n;
+		else return -(longword)( -(ulongword)a >> n );
+#	endif
+}
+
 word gsm_asr (word a, int n)
 {
 	if (n >= 16) return -(a < 0);
 	if (n <= -16) return 0;
 	if (n < 0) return a << -n;
-        return SASR(a, n);
+
+#	ifdef	SASR
+		return a >> n;
+#	else
+		if (a >= 0) return a >> n;
+		else return -(word)( -(uword)a >> n );
+#	endif
 }
 
 /* 
--- a/src/libgsm/code.c
+++ b/src/libgsm/code.c
@@ -4,6 +4,8 @@
  * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
  */
 
+/* $Header: /cvsroot/sox/sox/src/libgsm/Attic/code.c,v 1.4 2007/01/29 03:09:32 cbagwell Exp $ */
+
 #include	<stdlib.h>
 #include	<string.h>
 
@@ -54,19 +56,21 @@
 	word	so[160];
 
 	Gsm_Preprocess			(S, s, so);
-	Gsm_LPC_Analysis		(so, LARc);
+	Gsm_LPC_Analysis		(S, so, LARc);
 	Gsm_Short_Term_Analysis_Filter	(S, LARc, so);
 
 	for (k = 0; k <= 3; k++, xMc += 13) {
 
-		Gsm_Long_Term_Predictor	(so+k*40, /* d      [0..39] IN	*/
+		Gsm_Long_Term_Predictor	( S,
+					 so+k*40, /* d      [0..39] IN	*/
 					 dp,	  /* dp  [-120..-1] IN	*/
-					 e + 5,	  /* e      [0..39] OUT	*/
-					 dpp,	  /* dpp    [0..39] OUT */
+					e + 5,	  /* e      [0..39] OUT	*/
+					dpp,	  /* dpp    [0..39] OUT */
 					 Nc++,
 					 bc++);
 
-		Gsm_RPE_Encoding	( e + 5,	/* e	  ][0..39][ IN/OUT */
+		Gsm_RPE_Encoding	( S,
+					e + 5,	/* e	  ][0..39][ IN/OUT */
 					  xmaxc++, Mc++, xMc );
 		/*
 		 * Gsm_Update_of_reconstructed_short_time_residual_signal
--- a/src/libgsm/decode.c
+++ b/src/libgsm/decode.c
@@ -4,6 +4,8 @@
  * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
  */
 
+/* $Header: /cvsroot/sox/sox/src/libgsm/Attic/decode.c,v 1.4 2007/01/29 03:09:32 cbagwell Exp $ */
+
 #include <stdio.h>
 
 #include	"private.h"
@@ -49,7 +51,7 @@
 
 	for (j=0; j <= 3; j++, xmaxcr++, bcr++, Ncr++, Mcr++, xMcr += 13) {
 
-		Gsm_RPE_Decoding( *xmaxcr, *Mcr, xMcr, erp );
+		Gsm_RPE_Decoding( S, *xmaxcr, *Mcr, xMcr, erp );
 		Gsm_Long_Term_Synthesis_Filtering( S, *Ncr, *bcr, erp, drp );
 
 		for (k = 0; k <= 39; k++) wt[ j * 40 + k ] =  drp[ k ];
--- a/src/libgsm/gsm.3
+++ b/src/libgsm/gsm.3
@@ -103,4 +103,3 @@
 Please direct bug reports to jutta@cs.tu-berlin.de and cabo@cs.tu-berlin.de.
 .SH "SEE ALSO"
 toast(1), gsm_print(3), gsm_explode(3), gsm_option(3)
-http://www.cs.tu-berlin.de/~jutta/toast.html
--- a/src/libgsm/gsm.h
+++ b/src/libgsm/gsm.h
@@ -4,10 +4,34 @@
  * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
  */
 
+/*$Header: /cvsroot/sox/sox/src/libgsm/Attic/gsm.h,v 1.5 2007/01/29 03:09:32 cbagwell Exp $*/
+
 #ifndef	GSM_H
 #define	GSM_H
 
+#ifdef __cplusplus
+#	define	NeedFunctionPrototypes	1
+#endif
 
+#if __STDC__
+#	define	NeedFunctionPrototypes	1
+#endif
+
+#ifdef _NO_PROTO
+#	undef	NeedFunctionPrototypes
+#endif
+
+#ifdef NeedFunctionPrototypes
+#   include	<stdio.h>		/* for FILE * 	*/
+#endif
+
+#undef GSM_P
+#if NeedFunctionPrototypes
+#	define	GSM_P( protos )	protos
+#else
+#	define  GSM_P( protos )	( /* protos */ )
+#endif
+
 /*
  *	Interface
  */
@@ -24,16 +48,20 @@
 #define	GSM_MAJOR		1
 
 #define	GSM_OPT_VERBOSE		1
+#define	GSM_OPT_FAST		2
+#define	GSM_OPT_LTP_CUT		3
 #define	GSM_OPT_WAV49		4
 #define	GSM_OPT_FRAME_INDEX	5
 #define	GSM_OPT_FRAME_CHAIN	6
 
-extern gsm  gsm_create(void);
-extern void gsm_destroy(gsm);	
+extern gsm  gsm_create 	GSM_P((void));
+extern void gsm_destroy GSM_P((gsm));	
 
-extern int  gsm_option(gsm, int, int *);
+extern int  gsm_option  GSM_P((gsm, int, int *));
 
-extern void gsm_encode(gsm, gsm_signal *, gsm_byte  *);
-extern int  gsm_decode(gsm, gsm_byte   *, gsm_signal *);
+extern void gsm_encode  GSM_P((gsm, gsm_signal *, gsm_byte  *));
+extern int  gsm_decode  GSM_P((gsm, gsm_byte   *, gsm_signal *));
+
+#undef	GSM_P
 
 #endif	/* GSM_H */
--- a/src/libgsm/gsm_create.c
+++ b/src/libgsm/gsm_create.c
@@ -4,6 +4,8 @@
  * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
  */
 
+static char const	ident[] = "$Header: /cvsroot/sox/sox/src/libgsm/Attic/gsm_create.c,v 1.5 2007/01/29 03:09:32 cbagwell Exp $";
+
 #include <string.h>
 #include <stdlib.h>
 #include <stdio.h>
@@ -13,10 +15,13 @@
 
 gsm gsm_create ()
 {
-	gsm r = (gsm)calloc(1, sizeof(struct gsm_state));
+	gsm  r;
 
-        if (r)
-          r->nrp = 40;
+	r = (gsm)malloc(sizeof(struct gsm_state));
+	if (!r) return r;
+
+	memset((char *)r, 0, sizeof(*r));
+	r->nrp = 40;
 
 	return r;
 }
--- a/src/libgsm/gsm_decode.c
+++ b/src/libgsm/gsm_decode.c
@@ -4,6 +4,8 @@
  * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
  */
 
+/* $Header: /cvsroot/sox/sox/src/libgsm/Attic/gsm_decode.c,v 1.4 2007/01/29 03:09:32 cbagwell Exp $ */
+
 #include "private.h"
 
 #include "gsm.h"
@@ -12,6 +14,7 @@
 {
 	word  	LARc[8], Nc[4], Mc[4], bc[4], xmaxc[4], xmc[13*4];
 
+#ifdef WAV49
 	if (s->wav_fmt) {
 
 		uword sr = 0;
@@ -244,6 +247,7 @@
 		}
 	}
 	else
+#endif
 	{
 		/* GSM_MAGIC  = (*c >> 4) & 0xF; */
 
--- a/src/libgsm/gsm_destroy.c
+++ b/src/libgsm/gsm_destroy.c
@@ -4,11 +4,13 @@
  * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
  */
 
+/* $Header: /cvsroot/sox/sox/src/libgsm/Attic/gsm_destroy.c,v 1.3 2007/01/29 03:09:33 cbagwell Exp $ */
+
 #include "gsm.h"
 
-#include <stdlib.h>
+#	include	<stdlib.h>
 
 void gsm_destroy (gsm S)
 {
-  free((char *)S);
+	if (S) free((char *)S);
 }
--- a/src/libgsm/gsm_encode.c
+++ b/src/libgsm/gsm_encode.c
@@ -4,6 +4,8 @@
  * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
  */
 
+/* $Header: /cvsroot/sox/sox/src/libgsm/Attic/gsm_encode.c,v 1.4 2007/01/29 03:09:33 cbagwell Exp $ */
+
 #include "private.h"
 #include "gsm.h"
 
@@ -100,6 +102,8 @@
 		xmc[51]		3
 	*/
 
+#ifdef WAV49
+
 	if (s->wav_fmt) {
 		s->frame_index = !s->frame_index;
 		if (s->frame_index) {
@@ -338,6 +342,7 @@
 
 	else
 
+#endif	/* WAV49 */
 	{
 
 		*c++ =   ((GSM_MAGIC & 0xF) << 4)		/* 1 */
--- a/src/libgsm/gsm_option.3
+++ b/src/libgsm/gsm_option.3
@@ -48,6 +48,32 @@
 .in-5
 .sp
 .PP
+.I GSM_OPT_FAST
+Faster compression algorithm.
+.br
+.in+5
+This implementation offers a not strictly standard-compliant, but
+faster compression algorithm that is compatible with the regular
+method and does not noticably degrade audio quality.
+.br
+The value passed to 
+.br
+.nf
+	gsm_option(handle, GSM_OPT_FAST, & value)
+.fi
+.br 
+functions as a boolean flag; if it is zero, the regular algorithm
+will be used, if not, the faster version will be used.
+.br
+The availability of this option depends on the hardware used;
+if it is not available, gsm_option will return -1 on an attempt
+to set or query it.
+.br
+This option can be set any time during encoding or decoding.
+.in-5
+.ne 5
+.sp
+.PP
 .I GSM_OPT_LTP_CUT
 Enable, disable, or query the LTP cut-off optimization.
 .br
--- a/src/libgsm/gsm_option.c
+++ b/src/libgsm/gsm_option.c
@@ -4,6 +4,8 @@
  * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
  */
 
+/* $Header: /cvsroot/sox/sox/src/libgsm/Attic/gsm_option.c,v 1.4 2007/01/29 03:09:33 cbagwell Exp $ */
+
 #include "private.h"
 
 #include "gsm.h"
@@ -13,24 +15,50 @@
 	int 	result = -1;
 
 	switch (opt) {
+	case GSM_OPT_LTP_CUT:
+#ifdef 	LTP_CUT
+		result = r->ltp_cut;
+		if (val) r->ltp_cut = *val;
+#endif
+		break;
+
 	case GSM_OPT_VERBOSE:
+#ifndef	NDEBUG
 		result = r->verbose;
 		if (val) r->verbose = *val;
+#endif
 		break;
 
+	case GSM_OPT_FAST:
+
+#if	defined(FAST) && defined(USE_FLOAT_MUL)
+		result = r->fast;
+		if (val) r->fast = !!*val;
+#endif
+		break;
+
 	case GSM_OPT_FRAME_CHAIN:
+
+#ifdef WAV49
 		result = r->frame_chain;
 		if (val) r->frame_chain = *val;
+#endif
 		break;
 
 	case GSM_OPT_FRAME_INDEX:
+
+#ifdef WAV49
 		result = r->frame_index;
 		if (val) r->frame_index = *val;
+#endif
 		break;
 
 	case GSM_OPT_WAV49:
+
+#ifdef WAV49 
 		result = r->wav_fmt;
 		if (val) r->wav_fmt = !!*val;
+#endif
 		break;
 
 	default:
--- a/src/libgsm/long_term.c
+++ b/src/libgsm/long_term.c
@@ -4,6 +4,8 @@
  * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
  */
 
+/* $Header: /cvsroot/sox/sox/src/libgsm/Attic/long_term.c,v 1.6 2007/01/29 03:09:33 cbagwell Exp $ */
+
 #include <stdio.h>
 #include <assert.h>
 
@@ -28,6 +30,128 @@
  * performed to avoid overflow.
  */
 
+ /* The next procedure exists in six versions.  First two integer
+  * version (if USE_FLOAT_MUL is not defined); then four floating
+  * point versions, twice with proper scaling (USE_FLOAT_MUL defined),
+  * once without (USE_FLOAT_MUL and FAST defined, and fast run-time
+  * option used).  Every pair has first a Cut version (see the -C
+  * option to toast or the LTP_CUT option to gsm_option()), then the
+  * uncut one.  (For a detailed explanation of why this is altogether
+  * a bad idea, see Henry Spencer and Geoff Collyer, ``#ifdef Considered
+  * Harmful''.)
+  */
+
+#ifndef  USE_FLOAT_MUL
+
+#ifdef	LTP_CUT
+
+static void Cut_Calculation_of_the_LTP_parameters (
+
+	struct gsm_state * st,
+
+	register word	* d,		/* [0..39]	IN	*/
+	register word	* dp,		/* [-120..-1]	IN	*/
+	word		* bc_out,	/* 		OUT	*/
+	word		* Nc_out	/* 		OUT	*/
+)
+{
+	register int  	k, lambda;
+	word		Nc, bc;
+	word		wt[40];
+
+	longword	L_result;
+	longword	L_max, L_power;
+	word		R, S, dmax, scal, best_k;
+	word		ltp_cut;
+
+	register word	temp, wt_k;
+
+	/*  Search of the optimum scaling of d[0..39].
+	 */
+	dmax = 0;
+	for (k = 0; k <= 39; k++) {
+		temp = d[k];
+		temp = GSM_ABS( temp );
+		if (temp > dmax) {
+			dmax = temp;
+			best_k = k;
+		}
+	}
+	temp = 0;
+	if (dmax == 0) scal = 0;
+	else {
+		assert(dmax > 0);
+		temp = gsm_norm( (longword)dmax << 16 );
+	}
+	if (temp > 6) scal = 0;
+	else scal = 6 - temp;
+	assert(scal >= 0);
+
+	/* Search for the maximum cross-correlation and coding of the LTP lag
+	 */
+	L_max = 0;
+	Nc    = 40;	/* index for the maximum cross-correlation */
+	wt_k  = SASR(d[best_k], scal);
+
+	for (lambda = 40; lambda <= 120; lambda++) {
+		L_result = (longword)wt_k * dp[best_k - lambda];
+		if (L_result > L_max) {
+			Nc    = lambda;
+			L_max = L_result;
+		}
+	}
+	*Nc_out = Nc;
+	L_max <<= 1;
+
+	/*  Rescaling of L_max
+	 */
+	assert(scal <= 100 && scal >= -100);
+	L_max = L_max >> (6 - scal);	/* sub(6, scal) */
+
+	assert( Nc <= 120 && Nc >= 40);
+
+	/*   Compute the power of the reconstructed short term residual
+	 *   signal dp[..]
+	 */
+	L_power = 0;
+	for (k = 0; k <= 39; k++) {
+
+		register longword L_temp;
+
+		L_temp   = SASR( dp[k - Nc], 3 );
+		L_power += L_temp * L_temp;
+	}
+	L_power <<= 1;	/* from L_MULT */
+
+	/*  Normalization of L_max and L_power
+	 */
+
+	if (L_max <= 0)  {
+		*bc_out = 0;
+		return;
+	}
+	if (L_max >= L_power) {
+		*bc_out = 3;
+		return;
+	}
+
+	temp = gsm_norm( L_power );
+
+	R = SASR( L_max   << temp, 16 );
+	S = SASR( L_power << temp, 16 );
+
+	/*  Coding of the LTP gain
+	 */
+
+	/*  Table 4.3a must be used to obtain the level DLB[i] for the
+	 *  quantization of the LTP gain b to get the coded version bc.
+	 */
+	for (bc = 0; bc <= 2; bc++) if (R <= gsm_mult(S, gsm_DLB[bc])) break;
+	*bc_out = bc;
+}
+
+#endif 	/* LTP_CUT */
+
 static void Calculation_of_the_LTP_parameters (
 	register word	* d,		/* [0..39]	IN	*/
 	register word	* dp,		/* [-120..-1]	IN	*/
@@ -161,7 +285,548 @@
 	*bc_out = bc;
 }
 
+#else	/* USE_FLOAT_MUL */
 
+#ifdef	LTP_CUT
+
+static void Cut_Calculation_of_the_LTP_parameters (
+	struct gsm_state * st,		/*              IN 	*/
+	register word	* d,		/* [0..39]	IN	*/
+	register word	* dp,		/* [-120..-1]	IN	*/
+	word		* bc_out,	/* 		OUT	*/
+	word		* Nc_out	/* 		OUT	*/
+)
+{
+	register int  	k, lambda;
+	word		Nc, bc;
+	word		ltp_cut;
+
+	float		wt_float[40];
+	float		dp_float_base[120], * dp_float = dp_float_base + 120;
+
+	longword	L_max, L_power;
+	word		R, S, dmax, scal;
+	register word	temp;
+
+	/*  Search of the optimum scaling of d[0..39].
+	 */
+	dmax = 0;
+
+	for (k = 0; k <= 39; k++) {
+		temp = d[k];
+		temp = GSM_ABS( temp );
+		if (temp > dmax) dmax = temp;
+	}
+
+	temp = 0;
+	if (dmax == 0) scal = 0;
+	else {
+		assert(dmax > 0);
+		temp = gsm_norm( (longword)dmax << 16 );
+	}
+
+	if (temp > 6) scal = 0;
+	else scal = 6 - temp;
+
+	assert(scal >= 0);
+	ltp_cut = (longword)SASR(dmax, scal) * st->ltp_cut / 100; 
+
+
+	/*  Initialization of a working array wt
+	 */
+
+	for (k = 0; k < 40; k++) {
+		register word w = SASR( d[k], scal );
+		if (w < 0 ? w > -ltp_cut : w < ltp_cut) {
+			wt_float[k] = 0.0;
+		}
+		else {
+			wt_float[k] =  w;
+		}
+	}
+	for (k = -120; k <  0; k++) dp_float[k] =  dp[k];
+
+	/* Search for the maximum cross-correlation and coding of the LTP lag
+	 */
+	L_max = 0;
+	Nc    = 40;	/* index for the maximum cross-correlation */
+
+	for (lambda = 40; lambda <= 120; lambda += 9) {
+
+		/*  Calculate L_result for l = lambda .. lambda + 9.
+		 */
+		register float *lp = dp_float - lambda;
+
+		register float	W;
+		register float	a = lp[-8], b = lp[-7], c = lp[-6],
+				d = lp[-5], e = lp[-4], f = lp[-3],
+				g = lp[-2], h = lp[-1];
+		register float  E; 
+		register float  S0 = 0, S1 = 0, S2 = 0, S3 = 0, S4 = 0,
+				S5 = 0, S6 = 0, S7 = 0, S8 = 0;
+
+#		undef STEP
+#		define	STEP(K, a, b, c, d, e, f, g, h) \
+			if ((W = wt_float[K]) != 0.0) {	\
+			E = W * a; S8 += E;		\
+			E = W * b; S7 += E;		\
+			E = W * c; S6 += E;		\
+			E = W * d; S5 += E;		\
+			E = W * e; S4 += E;		\
+			E = W * f; S3 += E;		\
+			E = W * g; S2 += E;		\
+			E = W * h; S1 += E;		\
+			a  = lp[K];			\
+			E = W * a; S0 += E; } else (a = lp[K])
+
+#		define	STEP_A(K)	STEP(K, a, b, c, d, e, f, g, h)
+#		define	STEP_B(K)	STEP(K, b, c, d, e, f, g, h, a)
+#		define	STEP_C(K)	STEP(K, c, d, e, f, g, h, a, b)
+#		define	STEP_D(K)	STEP(K, d, e, f, g, h, a, b, c)
+#		define	STEP_E(K)	STEP(K, e, f, g, h, a, b, c, d)
+#		define	STEP_F(K)	STEP(K, f, g, h, a, b, c, d, e)
+#		define	STEP_G(K)	STEP(K, g, h, a, b, c, d, e, f)
+#		define	STEP_H(K)	STEP(K, h, a, b, c, d, e, f, g)
+
+		STEP_A( 0); STEP_B( 1); STEP_C( 2); STEP_D( 3);
+		STEP_E( 4); STEP_F( 5); STEP_G( 6); STEP_H( 7);
+
+		STEP_A( 8); STEP_B( 9); STEP_C(10); STEP_D(11);
+		STEP_E(12); STEP_F(13); STEP_G(14); STEP_H(15);
+
+		STEP_A(16); STEP_B(17); STEP_C(18); STEP_D(19);
+		STEP_E(20); STEP_F(21); STEP_G(22); STEP_H(23);
+
+		STEP_A(24); STEP_B(25); STEP_C(26); STEP_D(27);
+		STEP_E(28); STEP_F(29); STEP_G(30); STEP_H(31);
+
+		STEP_A(32); STEP_B(33); STEP_C(34); STEP_D(35);
+		STEP_E(36); STEP_F(37); STEP_G(38); STEP_H(39);
+
+		if (S0 > L_max) { L_max = S0; Nc = lambda;     }
+		if (S1 > L_max) { L_max = S1; Nc = lambda + 1; }
+		if (S2 > L_max) { L_max = S2; Nc = lambda + 2; }
+		if (S3 > L_max) { L_max = S3; Nc = lambda + 3; }
+		if (S4 > L_max) { L_max = S4; Nc = lambda + 4; }
+		if (S5 > L_max) { L_max = S5; Nc = lambda + 5; }
+		if (S6 > L_max) { L_max = S6; Nc = lambda + 6; }
+		if (S7 > L_max) { L_max = S7; Nc = lambda + 7; }
+		if (S8 > L_max) { L_max = S8; Nc = lambda + 8; }
+
+	}
+	*Nc_out = Nc;
+
+	L_max <<= 1;
+
+	/*  Rescaling of L_max
+	 */
+	assert(scal <= 100 && scal >=  -100);
+	L_max = L_max >> (6 - scal);	/* sub(6, scal) */
+
+	assert( Nc <= 120 && Nc >= 40);
+
+	/*   Compute the power of the reconstructed short term residual
+	 *   signal dp[..]
+	 */
+	L_power = 0;
+	for (k = 0; k <= 39; k++) {
+
+		register longword L_temp;
+
+		L_temp   = SASR( dp[k - Nc], 3 );
+		L_power += L_temp * L_temp;
+	}
+	L_power <<= 1;	/* from L_MULT */
+
+	/*  Normalization of L_max and L_power
+	 */
+
+	if (L_max <= 0)  {
+		*bc_out = 0;
+		return;
+	}
+	if (L_max >= L_power) {
+		*bc_out = 3;
+		return;
+	}
+
+	temp = gsm_norm( L_power );
+
+	R = SASR( L_max   << temp, 16 );
+	S = SASR( L_power << temp, 16 );
+
+	/*  Coding of the LTP gain
+	 */
+
+	/*  Table 4.3a must be used to obtain the level DLB[i] for the
+	 *  quantization of the LTP gain b to get the coded version bc.
+	 */
+	for (bc = 0; bc <= 2; bc++) if (R <= gsm_mult(S, gsm_DLB[bc])) break;
+	*bc_out = bc;
+}
+
+#endif /* LTP_CUT */
+
+static void Calculation_of_the_LTP_parameters (
+	register word	* d,		/* [0..39]	IN	*/
+	register word	* dp,		/* [-120..-1]	IN	*/
+	word		* bc_out,	/* 		OUT	*/
+	word		* Nc_out	/* 		OUT	*/
+)
+{
+	register int  	k, lambda;
+	word		Nc, bc;
+
+	float		wt_float[40];
+	float		dp_float_base[120], * dp_float = dp_float_base + 120;
+
+	longword	L_max, L_power;
+	word		R, S, dmax, scal;
+	register word	temp;
+
+	/*  Search of the optimum scaling of d[0..39].
+	 */
+	dmax = 0;
+
+	for (k = 0; k <= 39; k++) {
+		temp = d[k];
+		temp = GSM_ABS( temp );
+		if (temp > dmax) dmax = temp;
+	}
+
+	temp = 0;
+	if (dmax == 0) scal = 0;
+	else {
+		assert(dmax > 0);
+		temp = gsm_norm( (longword)dmax << 16 );
+	}
+
+	if (temp > 6) scal = 0;
+	else scal = 6 - temp;
+
+	assert(scal >= 0);
+
+	/*  Initialization of a working array wt
+	 */
+
+	for (k =    0; k < 40; k++) wt_float[k] =  SASR( d[k], scal );
+	for (k = -120; k <  0; k++) dp_float[k] =  dp[k];
+
+	/* Search for the maximum cross-correlation and coding of the LTP lag
+	 */
+	L_max = 0;
+	Nc    = 40;	/* index for the maximum cross-correlation */
+
+	for (lambda = 40; lambda <= 120; lambda += 9) {
+
+		/*  Calculate L_result for l = lambda .. lambda + 9.
+		 */
+		register float *lp = dp_float - lambda;
+
+		register float	W;
+		register float	a = lp[-8], b = lp[-7], c = lp[-6],
+				d = lp[-5], e = lp[-4], f = lp[-3],
+				g = lp[-2], h = lp[-1];
+		register float  E; 
+		register float  S0 = 0, S1 = 0, S2 = 0, S3 = 0, S4 = 0,
+				S5 = 0, S6 = 0, S7 = 0, S8 = 0;
+
+#		undef STEP
+#		define	STEP(K, a, b, c, d, e, f, g, h) \
+			W = wt_float[K];		\
+			E = W * a; S8 += E;		\
+			E = W * b; S7 += E;		\
+			E = W * c; S6 += E;		\
+			E = W * d; S5 += E;		\
+			E = W * e; S4 += E;		\
+			E = W * f; S3 += E;		\
+			E = W * g; S2 += E;		\
+			E = W * h; S1 += E;		\
+			a  = lp[K];			\
+			E = W * a; S0 += E
+
+#		define	STEP_A(K)	STEP(K, a, b, c, d, e, f, g, h)
+#		define	STEP_B(K)	STEP(K, b, c, d, e, f, g, h, a)
+#		define	STEP_C(K)	STEP(K, c, d, e, f, g, h, a, b)
+#		define	STEP_D(K)	STEP(K, d, e, f, g, h, a, b, c)
+#		define	STEP_E(K)	STEP(K, e, f, g, h, a, b, c, d)
+#		define	STEP_F(K)	STEP(K, f, g, h, a, b, c, d, e)
+#		define	STEP_G(K)	STEP(K, g, h, a, b, c, d, e, f)
+#		define	STEP_H(K)	STEP(K, h, a, b, c, d, e, f, g)
+
+		STEP_A( 0); STEP_B( 1); STEP_C( 2); STEP_D( 3);
+		STEP_E( 4); STEP_F( 5); STEP_G( 6); STEP_H( 7);
+
+		STEP_A( 8); STEP_B( 9); STEP_C(10); STEP_D(11);
+		STEP_E(12); STEP_F(13); STEP_G(14); STEP_H(15);
+
+		STEP_A(16); STEP_B(17); STEP_C(18); STEP_D(19);
+		STEP_E(20); STEP_F(21); STEP_G(22); STEP_H(23);
+
+		STEP_A(24); STEP_B(25); STEP_C(26); STEP_D(27);
+		STEP_E(28); STEP_F(29); STEP_G(30); STEP_H(31);
+
+		STEP_A(32); STEP_B(33); STEP_C(34); STEP_D(35);
+		STEP_E(36); STEP_F(37); STEP_G(38); STEP_H(39);
+
+		if (S0 > L_max) { L_max = S0; Nc = lambda;     }
+		if (S1 > L_max) { L_max = S1; Nc = lambda + 1; }
+		if (S2 > L_max) { L_max = S2; Nc = lambda + 2; }
+		if (S3 > L_max) { L_max = S3; Nc = lambda + 3; }
+		if (S4 > L_max) { L_max = S4; Nc = lambda + 4; }
+		if (S5 > L_max) { L_max = S5; Nc = lambda + 5; }
+		if (S6 > L_max) { L_max = S6; Nc = lambda + 6; }
+		if (S7 > L_max) { L_max = S7; Nc = lambda + 7; }
+		if (S8 > L_max) { L_max = S8; Nc = lambda + 8; }
+	}
+	*Nc_out = Nc;
+
+	L_max <<= 1;
+
+	/*  Rescaling of L_max
+	 */
+	assert(scal <= 100 && scal >=  -100);
+	L_max = L_max >> (6 - scal);	/* sub(6, scal) */
+
+	assert( Nc <= 120 && Nc >= 40);
+
+	/*   Compute the power of the reconstructed short term residual
+	 *   signal dp[..]
+	 */
+	L_power = 0;
+	for (k = 0; k <= 39; k++) {
+
+		register longword L_temp;
+
+		L_temp   = SASR( dp[k - Nc], 3 );
+		L_power += L_temp * L_temp;
+	}
+	L_power <<= 1;	/* from L_MULT */
+
+	/*  Normalization of L_max and L_power
+	 */
+
+	if (L_max <= 0)  {
+		*bc_out = 0;
+		return;
+	}
+	if (L_max >= L_power) {
+		*bc_out = 3;
+		return;
+	}
+
+	temp = gsm_norm( L_power );
+
+	R = SASR( L_max   << temp, 16 );
+	S = SASR( L_power << temp, 16 );
+
+	/*  Coding of the LTP gain
+	 */
+
+	/*  Table 4.3a must be used to obtain the level DLB[i] for the
+	 *  quantization of the LTP gain b to get the coded version bc.
+	 */
+	for (bc = 0; bc <= 2; bc++) if (R <= gsm_mult(S, gsm_DLB[bc])) break;
+	*bc_out = bc;
+}
+
+#ifdef	FAST
+#ifdef	LTP_CUT
+
+static void Cut_Fast_Calculation_of_the_LTP_parameters (
+	struct gsm_state * st,		/*              IN	*/
+	register word	* d,		/* [0..39]	IN	*/
+	register word	* dp,		/* [-120..-1]	IN	*/
+	word		* bc_out,	/* 		OUT	*/
+	word		* Nc_out	/* 		OUT	*/
+)
+{
+	register int  	k, lambda;
+	register float	wt_float;
+	word		Nc, bc;
+	word		wt_max, best_k, ltp_cut;
+
+	float		dp_float_base[120], * dp_float = dp_float_base + 120;
+
+	register float	L_result, L_max, L_power;
+
+	wt_max = 0;
+
+	for (k = 0; k < 40; ++k) {
+		if      ( d[k] > wt_max) wt_max =  d[best_k = k];
+		else if (-d[k] > wt_max) wt_max = -d[best_k = k];
+	}
+
+	assert(wt_max >= 0);
+	wt_float = (float)wt_max;
+
+	for (k = -120; k < 0; ++k) dp_float[k] = (float)dp[k];
+
+	/* Search for the maximum cross-correlation and coding of the LTP lag
+	 */
+	L_max = 0;
+	Nc    = 40;	/* index for the maximum cross-correlation */
+
+	for (lambda = 40; lambda <= 120; lambda++) {
+		L_result = wt_float * dp_float[best_k - lambda];
+		if (L_result > L_max) {
+			Nc    = lambda;
+			L_max = L_result;
+		}
+	}
+
+	*Nc_out = Nc;
+	if (L_max <= 0.)  {
+		*bc_out = 0;
+		return;
+	}
+
+	/*  Compute the power of the reconstructed short term residual
+	 *  signal dp[..]
+	 */
+	dp_float -= Nc;
+	L_power = 0;
+	for (k = 0; k < 40; ++k) {
+		register float f = dp_float[k];
+		L_power += f * f;
+	}
+
+	if (L_max >= L_power) {
+		*bc_out = 3;
+		return;
+	}
+
+	/*  Coding of the LTP gain
+	 *  Table 4.3a must be used to obtain the level DLB[i] for the
+	 *  quantization of the LTP gain b to get the coded version bc.
+	 */
+	lambda = L_max / L_power * 32768.;
+	for (bc = 0; bc <= 2; ++bc) if (lambda <= gsm_DLB[bc]) break;
+	*bc_out = bc;
+}
+
+#endif /* LTP_CUT */
+
+static void Fast_Calculation_of_the_LTP_parameters (
+	register word	* d,		/* [0..39]	IN	*/
+	register word	* dp,		/* [-120..-1]	IN	*/
+	word		* bc_out,	/* 		OUT	*/
+	word		* Nc_out	/* 		OUT	*/
+)
+{
+	register int  	k, lambda;
+	word		Nc, bc;
+
+	float		wt_float[40];
+	float		dp_float_base[120], * dp_float = dp_float_base + 120;
+
+	register float	L_max, L_power;
+
+	for (k = 0; k < 40; ++k) wt_float[k] = (float)d[k];
+	for (k = -120; k < 0; ++k) dp_float[k] = (float)dp[k];
+
+	/* Search for the maximum cross-correlation and coding of the LTP lag
+	 */
+	L_max = 0;
+	Nc    = 40;	/* index for the maximum cross-correlation */
+
+	for (lambda = 40; lambda <= 120; lambda += 9) {
+
+		/*  Calculate L_result for l = lambda .. lambda + 9.
+		 */
+		register float *lp = dp_float - lambda;
+
+		register float	W;
+		register float	a = lp[-8], b = lp[-7], c = lp[-6],
+				d = lp[-5], e = lp[-4], f = lp[-3],
+				g = lp[-2], h = lp[-1];
+		register float  E; 
+		register float  S0 = 0, S1 = 0, S2 = 0, S3 = 0, S4 = 0,
+				S5 = 0, S6 = 0, S7 = 0, S8 = 0;
+
+#		undef STEP
+#		define	STEP(K, a, b, c, d, e, f, g, h) \
+			W = wt_float[K];		\
+			E = W * a; S8 += E;		\
+			E = W * b; S7 += E;		\
+			E = W * c; S6 += E;		\
+			E = W * d; S5 += E;		\
+			E = W * e; S4 += E;		\
+			E = W * f; S3 += E;		\
+			E = W * g; S2 += E;		\
+			E = W * h; S1 += E;		\
+			a  = lp[K];			\
+			E = W * a; S0 += E
+
+#		define	STEP_A(K)	STEP(K, a, b, c, d, e, f, g, h)
+#		define	STEP_B(K)	STEP(K, b, c, d, e, f, g, h, a)
+#		define	STEP_C(K)	STEP(K, c, d, e, f, g, h, a, b)
+#		define	STEP_D(K)	STEP(K, d, e, f, g, h, a, b, c)
+#		define	STEP_E(K)	STEP(K, e, f, g, h, a, b, c, d)
+#		define	STEP_F(K)	STEP(K, f, g, h, a, b, c, d, e)
+#		define	STEP_G(K)	STEP(K, g, h, a, b, c, d, e, f)
+#		define	STEP_H(K)	STEP(K, h, a, b, c, d, e, f, g)
+
+		STEP_A( 0); STEP_B( 1); STEP_C( 2); STEP_D( 3);
+		STEP_E( 4); STEP_F( 5); STEP_G( 6); STEP_H( 7);
+
+		STEP_A( 8); STEP_B( 9); STEP_C(10); STEP_D(11);
+		STEP_E(12); STEP_F(13); STEP_G(14); STEP_H(15);
+
+		STEP_A(16); STEP_B(17); STEP_C(18); STEP_D(19);
+		STEP_E(20); STEP_F(21); STEP_G(22); STEP_H(23);
+
+		STEP_A(24); STEP_B(25); STEP_C(26); STEP_D(27);
+		STEP_E(28); STEP_F(29); STEP_G(30); STEP_H(31);
+
+		STEP_A(32); STEP_B(33); STEP_C(34); STEP_D(35);
+		STEP_E(36); STEP_F(37); STEP_G(38); STEP_H(39);
+
+		if (S0 > L_max) { L_max = S0; Nc = lambda;     }
+		if (S1 > L_max) { L_max = S1; Nc = lambda + 1; }
+		if (S2 > L_max) { L_max = S2; Nc = lambda + 2; }
+		if (S3 > L_max) { L_max = S3; Nc = lambda + 3; }
+		if (S4 > L_max) { L_max = S4; Nc = lambda + 4; }
+		if (S5 > L_max) { L_max = S5; Nc = lambda + 5; }
+		if (S6 > L_max) { L_max = S6; Nc = lambda + 6; }
+		if (S7 > L_max) { L_max = S7; Nc = lambda + 7; }
+		if (S8 > L_max) { L_max = S8; Nc = lambda + 8; }
+	}
+	*Nc_out = Nc;
+
+	if (L_max <= 0.)  {
+		*bc_out = 0;
+		return;
+	}
+
+	/*  Compute the power of the reconstructed short term residual
+	 *  signal dp[..]
+	 */
+	dp_float -= Nc;
+	L_power = 0;
+	for (k = 0; k < 40; ++k) {
+		register float f = dp_float[k];
+		L_power += f * f;
+	}
+
+	if (L_max >= L_power) {
+		*bc_out = 3;
+		return;
+	}
+
+	/*  Coding of the LTP gain
+	 *  Table 4.3a must be used to obtain the level DLB[i] for the
+	 *  quantization of the LTP gain b to get the coded version bc.
+	 */
+	lambda = L_max / L_power * 32768.;
+	for (bc = 0; bc <= 2; ++bc) if (lambda <= gsm_DLB[bc]) break;
+	*bc_out = bc;
+}
+
+#endif	/* FAST 	 */
+#endif	/* USE_FLOAT_MUL */
+
+
 /* 4.2.12 */
 
 static void Long_term_analysis_filtering (
@@ -198,6 +863,9 @@
 }
 
 void Gsm_Long_Term_Predictor ( 	/* 4x for 160 samples */
+
+	struct gsm_state	* S,
+
 	word	* d,	/* [0..39]   residual signal	IN	*/
 	word	* dp,	/* [-120..-1] d'		IN	*/
 
@@ -210,7 +878,23 @@
 	assert( d  ); assert( dp ); assert( e  );
 	assert( dpp); assert( Nc ); assert( bc );
 
-        Calculation_of_the_LTP_parameters(d, dp, bc, Nc);
+#if defined(FAST) && defined(USE_FLOAT_MUL)
+	if (S->fast) 
+#if   defined (LTP_CUT)
+		if (S->ltp_cut)
+			Cut_Fast_Calculation_of_the_LTP_parameters(S,
+				d, dp, bc, Nc);
+		else
+#endif /* LTP_CUT */
+			Fast_Calculation_of_the_LTP_parameters(d, dp, bc, Nc );
+	else 
+#endif /* FAST & USE_FLOAT_MUL */
+#ifdef LTP_CUT
+		if (S->ltp_cut)
+			Cut_Calculation_of_the_LTP_parameters(S, d, dp, bc, Nc);
+		else
+#endif
+			Calculation_of_the_LTP_parameters(d, dp, bc, Nc);
 
 	Long_term_analysis_filtering( *bc, *Nc, dp, d, dpp, e );
 }
--- a/src/libgsm/lpc.c
+++ b/src/libgsm/lpc.c
@@ -4,6 +4,8 @@
  * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
  */
 
+/* $Header: /cvsroot/sox/sox/src/libgsm/Attic/lpc.c,v 1.6 2007/01/29 03:09:33 cbagwell Exp $ */
+
 #include <stdio.h>
 #include <assert.h>
 
@@ -30,6 +32,10 @@
 
 	word		temp, smax, scalauto;
 
+#ifdef	USE_FLOAT_MUL
+	float		float_s[160];
+#endif
+
 	/*  Dynamic scaling of the array  s[0..159]
 	 */
 
@@ -54,10 +60,18 @@
 
 	if (scalauto > 0) {
 
+# ifdef USE_FLOAT_MUL
 #   define SCALE(n)	\
 	case n: for (k = 0; k <= 159; k++) \
+			float_s[k] = (float)	\
+				(s[k] = GSM_MULT_R(s[k], 16384 >> (n-1)));\
+		break;
+# else 
+#   define SCALE(n)	\
+	case n: for (k = 0; k <= 159; k++) \
 			s[k] = GSM_MULT_R( s[k], 16384 >> (n-1) );\
 		break;
+# endif /* USE_FLOAT_MUL */
 
 		switch (scalauto) {
 		SCALE(1)
@@ -67,14 +81,24 @@
 		}
 # undef	SCALE
 	}
+# ifdef	USE_FLOAT_MUL
+	else for (k = 0; k <= 159; k++) float_s[k] = (float) s[k];
+# endif
 
 	/*  Compute the L_ACF[..].
 	 */
 	{
+# ifdef	USE_FLOAT_MUL
+		register float * sp = float_s;
+		register float   sl = *sp;
+
+#		define STEP(k)	 L_ACF[k] += (longword)(sl * sp[ -(k) ]);
+# else
 		word  * sp = s;
 		word    sl = *sp;
 
 #		define STEP(k)	 L_ACF[k] += ((longword)sl * sp[ -(k) ]);
+# endif
 
 #	define NEXTI	 sl = *++sp
 
@@ -117,6 +141,34 @@
 	}
 }
 
+#if defined(USE_FLOAT_MUL) && defined(FAST)
+
+static void Fast_Autocorrelation (
+	word * s,		/* [0..159]	IN/OUT  */
+ 	longword * L_ACF)	/* [0..8]	OUT     */
+{
+	register int	k, i;
+	float f_L_ACF[9];
+	float scale;
+
+	float          s_f[160];
+	register float *sf = s_f;
+
+	for (i = 0; i < 160; ++i) sf[i] = s[i];
+	for (k = 0; k <= 8; k++) {
+		register float L_temp2 = 0;
+		register float *sfl = sf - k;
+		for (i = k; i < 160; ++i) L_temp2 += sf[i] * sfl[i];
+		f_L_ACF[k] = L_temp2;
+	}
+	scale = MAX_LONGWORD / f_L_ACF[0];
+
+	for (k = 0; k <= 8; k++) {
+		L_ACF[k] = f_L_ACF[k] * scale;
+	}
+}
+#endif	/* defined (USE_FLOAT_MUL) && defined (FAST) */
+
 /* 4.2.5 */
 
 static void Reflection_coefficients (
@@ -269,11 +321,16 @@
 }
 
 void Gsm_LPC_Analysis (
+	struct gsm_state *S,
 	word 		 * s,		/* 0..159 signals	IN/OUT	*/
         word 		 * LARc)	/* 0..7   LARc's	OUT	*/
 {
 	longword	L_ACF[9];
 
+#if defined(USE_FLOAT_MUL) && defined(FAST)
+	if (S->fast) Fast_Autocorrelation (s,	  L_ACF );
+	else
+#endif
 	Autocorrelation			  (s,	  L_ACF	);
 	Reflection_coefficients		  (L_ACF, LARc	);
 	Transformation_to_Log_Area_Ratios (LARc);
--- a/src/libgsm/preprocess.c
+++ b/src/libgsm/preprocess.c
@@ -4,6 +4,8 @@
  * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
  */
 
+/* $Header: /cvsroot/sox/sox/src/libgsm/Attic/preprocess.c,v 1.4 2007/01/29 03:09:33 cbagwell Exp $ */
+
 #include	<stdio.h>
 #include	<assert.h>
 
@@ -90,7 +92,7 @@
 
 		L_s2  += GSM_MULT_R( lsp, 32735 );
 		L_temp = (longword)msp * 32735; /* GSM_L_MULT(msp,32735) >> 1;*/
-                L_z2   = GSM_L_ADD( L_temp, L_s2 );
+		L_z2   = GSM_L_ADD( L_temp, L_s2 );
 
 		/*    Compute sof[k] with rounding
 		 */
--- a/src/libgsm/private.h
+++ b/src/libgsm/private.h
@@ -4,6 +4,8 @@
  * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
  */
 
+/*$Header: /cvsroot/sox/sox/src/libgsm/Attic/private.h,v 1.8 2007/01/29 03:09:33 cbagwell Exp $*/
+
 #ifndef	PRIVATE_H
 #define	PRIVATE_H
 
@@ -30,7 +32,8 @@
 	word		v[9];		/* short_term.c, synthesis	*/
 	word		msr;		/* decoder.c,	Postprocessing	*/
 
-	char		verbose;
+	char		verbose;	/* only used if !NDEBUG		*/
+	char		fast;		/* only used if FAST		*/
 
 	char		wav_fmt;	/* only used if WAV49 defined	*/
 	unsigned char	frame_index;	/*            odd/even chaining	*/
@@ -44,23 +47,36 @@
 #define	MIN_LONGWORD	(-2147483647 - 1)
 #define	MAX_LONGWORD	  2147483647
 
-#define	SASR(x, by)	(((x) >> (by)) | (-((x) < 0) << (by)))
+#ifdef	SASR		/* flag: >> is a signed arithmetic shift right */
+#undef	SASR
+#define	SASR(x, by)	((x) >> (by))
+#else
+#define	SASR(x, by)	((x) >= 0 ? (x) >> (by) : (~(-((x) + 1) >> (by))))
+#endif	/* SASR */
 
 /*
  *	Prototypes from add.c
  */
 extern word	gsm_mult 	(word a, word b);
+extern longword gsm_L_mult 	(word a, word b);
+extern word	gsm_mult_r	(word a, word b);
 
 extern word	gsm_div  	(word num, word denum);
 
 extern word	gsm_add 	( word a, word b );
+extern longword gsm_L_add 	( longword a, longword b );
 
 extern word	gsm_sub 	(word a, word b);
+extern longword gsm_L_sub 	(longword a, longword b);
 
+extern word	gsm_abs 	(word a);
+
 extern word	gsm_norm 	( longword a );
 
+extern longword gsm_L_asl  	(longword a, int n);
 extern word	gsm_asl 	(word a, int n);
 
+extern longword gsm_L_asr  	(longword a, int n);
 extern word	gsm_asr  	(word a, int n);
 
 /*
@@ -86,8 +102,15 @@
 		   >= MAX_LONGWORD ? MIN_LONGWORD : -(longword)utmp-2 )   \
 	: ((b) <= 0 ? (a) + (b)   \
 	          : (utmp = (ulongword)(a) + (ulongword)(b)) >= MAX_LONGWORD \
-		    ? MAX_LONGWORD : (longword)utmp))
+		    ? MAX_LONGWORD : utmp))
 
+/*
+ * # define GSM_ADD(a, b)	\
+ * 	((ltmp = (longword)(a) + (longword)(b)) >= MAX_WORD \
+ * 	? MAX_WORD : ltmp <= MIN_WORD ? MIN_WORD : ltmp)
+ */
+/* Nonportable, but faster: */
+
 #define	GSM_ADD(a, b)	\
 	((ulongword)((ltmp = (longword)(a) + (longword)(b)) - MIN_WORD) > \
 		MAX_WORD - MIN_WORD ? (ltmp > 0 ? MAX_WORD : MIN_WORD) : ltmp)
@@ -98,6 +121,20 @@
 
 # define GSM_ABS(a)	((a) < 0 ? ((a) == MIN_WORD ? MAX_WORD : -(a)) : (a))
 
+/* Use these if necessary:
+
+# define GSM_MULT_R(a, b)	gsm_mult_r(a, b)
+# define GSM_MULT(a, b)		gsm_mult(a, b)
+# define GSM_L_MULT(a, b)	gsm_L_mult(a, b)
+
+# define GSM_L_ADD(a, b)	gsm_L_add(a, b)
+# define GSM_ADD(a, b)		gsm_add(a, b)
+# define GSM_SUB(a, b)		gsm_sub(a, b)
+
+# define GSM_ABS(a)		gsm_abs(a)
+
+*/
+
 /*
  *  More prototypes from implementations..
  */
@@ -112,6 +149,7 @@
 		word	* xMc	/* [13*4] normalized RPE samples OUT	*/);
 
 extern void Gsm_Long_Term_Predictor (		/* 4x for 160 samples */
+		struct gsm_state * S,
 		word	* d,	/* [0..39]   residual signal	IN	*/
 		word	* dp,	/* [-120..-1] d'		IN	*/
 		word	* e,	/* [0..40] 			OUT	*/
@@ -120,6 +158,7 @@
 		word	* bc	/* gain factor			OUT	*/);
 
 extern void Gsm_LPC_Analysis (
+		struct gsm_state * S,
 		word * s,	 /* 0..159 signals	IN/OUT	*/
 	        word * LARc);   /* 0..7   LARc's	OUT	*/
 
@@ -165,6 +204,7 @@
 		word	* drp); 	/* [-120..-1] IN, [0..40] OUT 	*/
 
 void Gsm_RPE_Decoding (
+	struct gsm_state *S,
 		word xmaxcr,
 		word Mcr,
 		word * xMcr,  /* [0..12], 3 bits             IN      */
@@ -171,6 +211,7 @@
 		word * erp); /* [0..39]                     OUT     */
 
 void Gsm_RPE_Encoding (
+		struct gsm_state * S,
 		word    * e,            /* -5..-1][0..39][40..44     IN/OUT  */
 		word    * xmaxc,        /*                              OUT */
 		word    * Mc,           /*                              OUT */
@@ -190,6 +231,8 @@
 /*
  *  Tables from table.c
  */
+#ifndef	GSM_TABLE_C
+
 extern word gsm_A[8], gsm_B[8], gsm_MIC[8], gsm_MAC[8];
 extern word gsm_INVA[8];
 extern word gsm_DLB[4], gsm_QLB[4];
@@ -197,12 +240,25 @@
 extern word gsm_NRFAC[8];
 extern word gsm_FAC[8];
 
+#endif	/* GSM_TABLE_C */
+
 /*
  *  Debugging
  */
-extern void  gsm_debug_words     (char * name, int, int, word *);
-extern void  gsm_debug_longwords (char * name, int, int, longword *);
-extern void  gsm_debug_longword  (char * name, longword);
-extern void  gsm_debug_word      (char * name, word);
+#ifdef NDEBUG
+
+#	define	gsm_debug_words(a, b, c, d)		/* nil */
+#	define	gsm_debug_longwords(a, b, c, d)		/* nil */
+#	define	gsm_debug_word(a, b)			/* nil */
+#	define	gsm_debug_longword(a, b)		/* nil */
+
+#else	/* !NDEBUG => DEBUG */
+
+	extern void  gsm_debug_words     (char * name, int, int, word *);
+	extern void  gsm_debug_longwords (char * name, int, int, longword *);
+	extern void  gsm_debug_longword  (char * name, longword);
+	extern void  gsm_debug_word      (char * name, word);
+
+#endif /* !NDEBUG */
 
 #endif	/* PRIVATE_H */
--- a/src/libgsm/rpe.c
+++ b/src/libgsm/rpe.c
@@ -4,6 +4,8 @@
  * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
  */
 
+/* $Header: /cvsroot/sox/sox/src/libgsm/Attic/rpe.c,v 1.5 2007/01/29 03:09:33 cbagwell Exp $ */
+
 #include <stdio.h>
 #include <assert.h>
 
@@ -64,6 +66,19 @@
 		 *  Do you?
 		 */
 
+#ifdef	STUPID_COMPILER
+		L_result += STEP(	0, 	-134 ) ;
+		L_result += STEP(	1, 	-374 )  ;
+	               /* + STEP(	2, 	0    )  */
+		L_result += STEP(	3, 	2054 ) ;
+		L_result += STEP(	4, 	5741 ) ;
+		L_result += STEP(	5, 	8192 ) ;
+		L_result += STEP(	6, 	5741 ) ;
+		L_result += STEP(	7, 	2054 ) ;
+	 	       /* + STEP(	8, 	0    )  */
+		L_result += STEP(	9, 	-374 ) ;
+		L_result += STEP(	10, 	-134 ) ;
+#else
 		L_result +=
 		  STEP(	0, 	-134 ) 
 		+ STEP(	1, 	-374 ) 
@@ -77,6 +92,7 @@
 		+ STEP(	9, 	-374 ) 
 		+ STEP(10, 	-134 )
 		;
+#endif
 
 		/* L_result = GSM_L_ADD( L_result, L_result ); (* scaling(x2) *)
 		 * L_result = GSM_L_ADD( L_result, L_result ); (* scaling(x4) *)
@@ -430,6 +446,9 @@
 #endif	/* Has been inlined in code.c */
 
 void Gsm_RPE_Encoding (
+
+	struct gsm_state * S,
+
 	word	* e,		/* -5..-1][0..39][40..44	IN/OUT  */
 	word	* xmaxc,	/* 				OUT */
 	word	* Mc,		/* 			  	OUT */
@@ -450,6 +469,8 @@
 }
 
 void Gsm_RPE_Decoding (
+	struct gsm_state	* S,
+
 	word 		xmaxcr,
 	word		Mcr,
 	word		* xMcr,  /* [0..12], 3 bits 		IN	*/
--- a/src/libgsm/short_term.c
+++ b/src/libgsm/short_term.c
@@ -4,6 +4,8 @@
  * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
  */
 
+/* $Header: /cvsroot/sox/sox/src/libgsm/Attic/short_term.c,v 1.4 2007/01/29 03:09:33 cbagwell Exp $ */
+
 #include <stdio.h>
 #include <assert.h>
 
@@ -220,6 +222,45 @@
 	}
 }
 
+#if defined(USE_FLOAT_MUL) && defined(FAST)
+
+static void Fast_Short_term_analysis_filtering (
+	struct gsm_state * S,
+	register word	* rp,	/* [0..7]	IN	*/
+	register int 	k_n, 	/*   k_end - k_start	*/
+	register word	* s	/* [0..n-1]	IN/OUT	*/
+)
+{
+	register word		* u = S->u;
+	register int		i;
+
+	float 	  uf[8],
+		 rpf[8];
+
+	register float scalef = 3.0517578125e-5;
+	register float		sav, di, temp;
+
+	for (i = 0; i < 8; ++i) {
+		uf[i]  = u[i];
+		rpf[i] = rp[i] * scalef;
+	}
+	for (; k_n--; s++) {
+		sav = di = *s;
+		for (i = 0; i < 8; ++i) {
+			register float rpfi = rpf[i];
+			register float ufi  = uf[i];
+
+			uf[i] = sav;
+			temp  = rpfi * di + ufi;
+			di   += rpfi * ufi;
+			sav   = temp;
+		}
+		*s = di;
+	}
+	for (i = 0; i < 8; ++i) u[i] = uf[i];
+}
+#endif /* ! (defined (USE_FLOAT_MUL) && defined (FAST)) */
+
 static void Short_term_synthesis_filtering (
 	struct gsm_state * S,
 	register word	* rrp,	/* [0..7]	IN	*/
@@ -261,6 +302,46 @@
 	}
 }
 
+
+#if defined(FAST) && defined(USE_FLOAT_MUL)
+
+static void Fast_Short_term_synthesis_filtering (
+	struct gsm_state * S,
+	register word	* rrp,	/* [0..7]	IN	*/
+	register int	k,	/* k_end - k_start	*/
+	register word	* wt,	/* [0..k-1]	IN	*/
+	register word	* sr	/* [0..k-1]	OUT	*/
+)
+{
+	register word		* v = S->v;
+	register int		i;
+
+	float va[9], rrpa[8];
+	register float scalef = 3.0517578125e-5, temp;
+
+	for (i = 0; i < 8; ++i) {
+		va[i]   = v[i];
+		rrpa[i] = (float)rrp[i] * scalef;
+	}
+	while (k--) {
+		register float sri = *wt++;
+		for (i = 8; i--;) {
+			sri -= rrpa[i] * va[i];
+			if     (sri < -32768.) sri = -32768.;
+			else if (sri > 32767.) sri =  32767.;
+
+			temp = va[i] + rrpa[i] * sri;
+			if     (temp < -32768.) temp = -32768.;
+			else if (temp > 32767.) temp =  32767.;
+			va[i+1] = temp;
+		}
+		*sr++ = va[0] = sri;
+	}
+	for (i = 0; i < 9; ++i) v[i] = va[i];
+}
+
+#endif /* defined(FAST) && defined(USE_FLOAT_MUL) */
+
 void Gsm_Short_Term_Analysis_Filter (
 
 	struct gsm_state * S,
@@ -275,8 +356,15 @@
 	word		LARp[8];
 
 #undef	FILTER
-#define	FILTER	Short_term_analysis_filtering
+#if 	defined(FAST) && defined(USE_FLOAT_MUL)
+# 	define	FILTER 	(* (S->fast			\
+			   ? Fast_Short_term_analysis_filtering	\
+		    	   : Short_term_analysis_filtering	))
 
+#else
+# 	define	FILTER	Short_term_analysis_filtering
+#endif
+
 	Decoding_of_the_coded_Log_Area_Ratios( LARc, LARpp_j );
 
 	Coefficients_0_12(  LARpp_j_1, LARpp_j, LARp );
@@ -311,7 +399,14 @@
 	word		LARp[8];
 
 #undef	FILTER
-#define	FILTER	Short_term_synthesis_filtering
+#if 	defined(FAST) && defined(USE_FLOAT_MUL)
+
+# 	define	FILTER 	(* (S->fast			\
+			   ? Fast_Short_term_synthesis_filtering	\
+		    	   : Short_term_synthesis_filtering	))
+#else
+#	define	FILTER	Short_term_synthesis_filtering
+#endif
 
 	Decoding_of_the_coded_Log_Area_Ratios( LARcr, LARpp_j );
 
--- a/src/libgsm/table.c
+++ b/src/libgsm/table.c
@@ -4,6 +4,8 @@
  * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
  */
 
+/* $Header: /cvsroot/sox/sox/src/libgsm/Attic/table.c,v 1.3 2007/01/29 03:09:33 cbagwell Exp $ */
+
 /*  Most of these tables are inlined at their point of use.
  */