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.
*/