[xiph-commits] r12151 - trunk/speex/libspeex
jm at svn.xiph.org
jm at svn.xiph.org
Tue Nov 28 06:56:32 PST 2006
Author: jm
Date: 2006-11-28 06:56:27 -0800 (Tue, 28 Nov 2006)
New Revision: 12151
Modified:
trunk/speex/libspeex/filters.c
trunk/speex/libspeex/filters.h
trunk/speex/libspeex/sb_celp.c
trunk/speex/libspeex/sb_celp.h
Log:
Replaced fir_mem_up by qmf_synth which doesn't require intermediate
results. Saved 2.5 kB in the wideband encoder and the same in the decoder.
Modified: trunk/speex/libspeex/filters.c
===================================================================
--- trunk/speex/libspeex/filters.c 2006-11-28 14:22:55 UTC (rev 12150)
+++ trunk/speex/libspeex/filters.c 2006-11-28 14:56:27 UTC (rev 12151)
@@ -650,31 +650,119 @@
a1 = a[j+1];
x1 = xx[N-2+j-i];
- y0 = ADD32(y0,SHR32(MULT16_16(a0, x1),2));
- y1 = ADD32(y1,SHR32(MULT16_16(a1, x1),2));
- y2 = ADD32(y2,SHR32(MULT16_16(a0, x0),2));
- y3 = ADD32(y3,SHR32(MULT16_16(a1, x0),2));
+ y0 = ADD32(y0,MULT16_16(a0, x1));
+ y1 = ADD32(y1,MULT16_16(a1, x1));
+ y2 = ADD32(y2,MULT16_16(a0, x0));
+ y3 = ADD32(y3,MULT16_16(a1, x0));
a0 = a[j+2];
a1 = a[j+3];
x0 = xx[N+j-i];
- y0 = ADD32(y0,SHR32(MULT16_16(a0, x0),2));
- y1 = ADD32(y1,SHR32(MULT16_16(a1, x0),2));
- y2 = ADD32(y2,SHR32(MULT16_16(a0, x1),2));
- y3 = ADD32(y3,SHR32(MULT16_16(a1, x1),2));
+ y0 = ADD32(y0,MULT16_16(a0, x0));
+ y1 = ADD32(y1,MULT16_16(a1, x0));
+ y2 = ADD32(y2,MULT16_16(a0, x1));
+ y3 = ADD32(y3,MULT16_16(a1, x1));
}
- y[i] = y0;
- y[i+1] = y1;
- y[i+2] = y2;
- y[i+3] = y3;
+ y[i] = SHR32(y0,1);
+ y[i+1] = SHR32(y1,1);
+ y[i+2] = SHR32(y2,1);
+ y[i+3] = SHR32(y3,1);
}
for (i = 0; i < M - 1; i += 2)
mem[i+1] = xx[i];
}
+void qmf_synth(const spx_sig_t *x1, const spx_sig_t *x2, const spx_word16_t *a, spx_word16_t *y, int N, int M, spx_word32_t *mem1, spx_word32_t *mem2, char *stack)
+ /* assumptions:
+ all odd x[i] are zero -- well, actually they are left out of the array now
+ N and M are multiples of 4 */
+{
+ int i, j;
+ VARDECL(spx_word16_t *xx1);
+ VARDECL(spx_word16_t *xx2);
+
+ ALLOC(xx1, M+N-1, spx_word16_t);
+ ALLOC(xx2, M+N-1, spx_word16_t);
+
+ for (i = 0; i < N/2; i++)
+ xx1[2*i] = PSHR32(x1[N/2-1-i],SIG_SHIFT);
+ for (i = 0; i < M - 1; i += 2)
+ xx1[N+i] = mem1[i+1];
+ for (i = 0; i < N/2; i++)
+ xx2[2*i] = PSHR32(x2[N/2-1-i],SIG_SHIFT);
+ for (i = 0; i < M - 1; i += 2)
+ xx2[N+i] = mem2[i+1];
+
+ for (i = 0; i < N; i += 4) {
+ spx_sig_t y0, y1, y2, y3;
+ spx_word16_t x10, x20;
+
+ y0 = y1 = y2 = y3 = 0;
+ x10 = xx1[N-4-i];
+ x20 = xx2[N-4-i];
+
+ for (j = 0; j < M; j += 4) {
+ spx_word16_t x11, x21;
+ spx_word16_t a0, a1;
+
+ a0 = a[j];
+ a1 = a[j+1];
+ x11 = xx1[N-2+j-i];
+ x21 = xx2[N-2+j-i];
+
#ifdef FIXED_POINT
+ /* We multiply twice by the same coef to avoid overflows */
+ y0 = MAC16_16(MAC16_16(y0, a0, x11), NEG16(a0), x21);
+ y1 = MAC16_16(MAC16_16(y1, a1, x11), a1, x21);
+ y2 = MAC16_16(MAC16_16(y2, a0, x10), NEG16(a0), x20);
+ y3 = MAC16_16(MAC16_16(y3, a1, x10), a1, x20);
+#else
+ y0 = ADD32(y0,MULT16_16(a0, x11-x21));
+ y1 = ADD32(y1,MULT16_16(a1, x11+x21));
+ y2 = ADD32(y2,MULT16_16(a0, x10-x20));
+ y3 = ADD32(y3,MULT16_16(a1, x10+x20));
+#endif
+ a0 = a[j+2];
+ a1 = a[j+3];
+ x10 = xx1[N+j-i];
+ x20 = xx2[N+j-i];
+
+#ifdef FIXED_POINT
+ /* We multiply twice by the same coef to avoid overflows */
+ y0 = MAC16_16(MAC16_16(y0, a0, x10), NEG16(a0), x20);
+ y1 = MAC16_16(MAC16_16(y1, a1, x10), a1, x20);
+ y2 = MAC16_16(MAC16_16(y2, a0, x11), NEG16(a0), x21);
+ y3 = MAC16_16(MAC16_16(y3, a1, x11), a1, x21);
+#else
+ y0 = ADD32(y0,MULT16_16(a0, x10-x20));
+ y1 = ADD32(y1,MULT16_16(a1, x10+x20));
+ y2 = ADD32(y2,MULT16_16(a0, x11-x21));
+ y3 = ADD32(y3,MULT16_16(a1, x11+x21));
+#endif
+ }
+#ifdef FIXED_POINT
+ y[i] = EXTRACT16(SATURATE32(PSHR32(y0,15),32767));
+ y[i+1] = EXTRACT16(SATURATE32(PSHR32(y1,15),32767));
+ y[i+2] = EXTRACT16(SATURATE32(PSHR32(y2,15),32767));
+ y[i+3] = EXTRACT16(SATURATE32(PSHR32(y3,15),32767));
+#else
+ /* Normalize up explicitly if we're in float */
+ y[i] = 2.*y0;
+ y[i+1] = 2.*y1;
+ y[i+2] = 2.*y2;
+ y[i+3] = 2.*y3;
+#endif
+ }
+
+ for (i = 0; i < M - 1; i += 2)
+ mem1[i+1] = xx1[i];
+ for (i = 0; i < M - 1; i += 2)
+ mem2[i+1] = xx2[i];
+}
+
+#ifdef FIXED_POINT
#if 0
const spx_word16_t shift_filt[3][7] = {{-33, 1043, -4551, 19959, 19959, -4551, 1043},
{-98, 1133, -4425, 29179, 8895, -2328, 444},
Modified: trunk/speex/libspeex/filters.h
===================================================================
--- trunk/speex/libspeex/filters.h 2006-11-28 14:22:55 UTC (rev 12150)
+++ trunk/speex/libspeex/filters.h 2006-11-28 14:56:27 UTC (rev 12151)
@@ -60,8 +60,8 @@
void qmf_decomp(const spx_word16_t *xx, const spx_word16_t *aa, spx_sig_t *, spx_sig_t *y2, int N, int M, spx_word16_t *mem, char *stack);
void fir_mem_up(const spx_sig_t *x, const spx_word16_t *a, spx_sig_t *y, int N, int M, spx_word32_t *mem, char *stack);
+void qmf_synth(const spx_sig_t *x1, const spx_sig_t *x2, const spx_word16_t *a, spx_word16_t *y, int N, int M, spx_word32_t *mem1, spx_word32_t *mem2, char *stack);
-
void filter_mem2(const spx_sig_t *x, const spx_coef_t *num, const spx_coef_t *den, spx_sig_t *y, int N, int ord, spx_mem_t *mem);
void fir_mem2(const spx_sig_t *x, const spx_coef_t *num, spx_sig_t *y, int N, int ord, spx_mem_t *mem);
void iir_mem2(const spx_sig_t *x, const spx_coef_t *den, spx_sig_t *y, int N, int ord, spx_mem_t *mem);
Modified: trunk/speex/libspeex/sb_celp.c
===================================================================
--- trunk/speex/libspeex/sb_celp.c 2006-11-28 14:22:55 UTC (rev 12150)
+++ trunk/speex/libspeex/sb_celp.c 2006-11-28 14:56:27 UTC (rev 12151)
@@ -203,25 +203,6 @@
extern const spx_word16_t lpc_window[];
-static void mix_and_saturate(spx_word32_t *x0, spx_word32_t *x1, spx_word16_t *out, int len)
-{
- int i;
- for (i=0;i<len;i++)
- {
- spx_word32_t tmp;
-#ifdef FIXED_POINT
- tmp=PSHR32(SUB32(x0[i],x1[i]),SIG_SHIFT-1);
-#else
- tmp=2*(x0[i]-x1[i]);
-#endif
- if (tmp>32767)
- out[i] = 32767;
- else if (tmp<-32767)
- out[i] = -32767;
- else
- out[i] = EXTRACT16(tmp);
- }
-}
void *sb_encoder_init(const SpeexMode *m)
{
@@ -269,8 +250,6 @@
st->x0d=(spx_sig_t*)speex_alloc((st->frame_size)*sizeof(spx_sig_t));
st->x1d=(spx_sig_t*)speex_alloc((st->frame_size)*sizeof(spx_sig_t));
st->high=(spx_sig_t*)speex_alloc((st->full_frame_size)*sizeof(spx_sig_t));
- st->y0=(spx_sig_t*)speex_alloc((st->full_frame_size)*sizeof(spx_sig_t));
- st->y1=(spx_sig_t*)speex_alloc((st->full_frame_size)*sizeof(spx_sig_t));
st->h0_mem=(spx_word16_t*)speex_alloc((QMF_ORDER)*sizeof(spx_word16_t));
st->h1_mem=(spx_word16_t*)speex_alloc((QMF_ORDER)*sizeof(spx_word16_t));
@@ -338,8 +317,6 @@
speex_free(st->x0d);
speex_free(st->x1d);
speex_free(st->high);
- speex_free(st->y0);
- speex_free(st->y1);
speex_free(st->h0_mem);
speex_free(st->h1_mem);
@@ -569,11 +546,7 @@
#ifdef RESYNTH
/* Reconstruct the original */
- fir_mem_up(st->x0d, h0, st->y0, st->full_frame_size, QMF_ORDER, st->g0_mem, stack);
- fir_mem_up(st->high, h1, st->y1, st->full_frame_size, QMF_ORDER, st->g1_mem, stack);
-
- for (i=0;i<st->full_frame_size;i++)
- in[i]=SHR(st->y0[i]-st->y1[i], SIG_SHIFT-1);
+ qmf_synth(st->x0d, st->high, h0, in, st->full_frame_size, QMF_ORDER, st->g0_mem, st->g1_mem, stack);
#endif
if (dtx)
@@ -815,11 +788,7 @@
#ifdef RESYNTH
/* Reconstruct the original */
- fir_mem_up(st->x0d, h0, st->y0, st->full_frame_size, QMF_ORDER, st->g0_mem, stack);
- fir_mem_up(st->high, h1, st->y1, st->full_frame_size, QMF_ORDER, st->g1_mem, stack);
-
- for (i=0;i<st->full_frame_size;i++)
- in[i]=SHR(st->y0[i]-st->y1[i], SIG_SHIFT-1);
+ qmf_synth(st->x0d, st->high, h0, in, st->full_frame_size, QMF_ORDER, st->g0_mem, st->g1_mem, stack);
#endif
for (i=0;i<st->lpcSize;i++)
st->old_lsp[i] = st->lsp[i];
@@ -876,8 +845,6 @@
st->x0d = (spx_sig_t*)speex_alloc((st->frame_size)*sizeof(spx_sig_t));
st->x1d = (spx_sig_t*)speex_alloc((st->frame_size)*sizeof(spx_sig_t));
st->high = (spx_sig_t*)speex_alloc((st->full_frame_size)*sizeof(spx_sig_t));
- st->y0 = (spx_sig_t*)speex_alloc((st->full_frame_size)*sizeof(spx_sig_t));
- st->y1 = (spx_sig_t*)speex_alloc((st->full_frame_size)*sizeof(spx_sig_t));
st->g0_mem = (spx_word32_t*)speex_alloc((QMF_ORDER)*sizeof(spx_word32_t));
st->g1_mem = (spx_word32_t*)speex_alloc((QMF_ORDER)*sizeof(spx_word32_t));
@@ -919,8 +886,6 @@
speex_free(st->x0d);
speex_free(st->x1d);
speex_free(st->high);
- speex_free(st->y0);
- speex_free(st->y1);
speex_free(st->g0_mem);
speex_free(st->g1_mem);
speex_free(st->exc);
@@ -969,11 +934,7 @@
/* Reconstruct the original */
- fir_mem_up(st->x0d, h0, st->y0, st->full_frame_size, QMF_ORDER, st->g0_mem, stack);
- fir_mem_up(st->high, h1, st->y1, st->full_frame_size, QMF_ORDER, st->g1_mem, stack);
-
- mix_and_saturate(st->y0, st->y1, out, st->full_frame_size);
-
+ qmf_synth(st->x0d, st->high, h0, out, st->full_frame_size, QMF_ORDER, st->g0_mem, st->g1_mem, stack);
if (dtx)
{
st->submodeID=saved_modeid;
@@ -1067,11 +1028,8 @@
/* Final signal synthesis from excitation */
iir_mem2(st->exc, st->interp_qlpc, st->high, st->frame_size, st->lpcSize, st->mem_sp);
- fir_mem_up(st->x0d, h0, st->y0, st->full_frame_size, QMF_ORDER, st->g0_mem, stack);
- fir_mem_up(st->high, h1, st->y1, st->full_frame_size, QMF_ORDER, st->g1_mem, stack);
+ qmf_synth(st->x0d, st->high, h0, out, st->full_frame_size, QMF_ORDER, st->g0_mem, st->g1_mem, stack);
- mix_and_saturate(st->y0, st->y1, out, st->full_frame_size);
-
return 0;
}
@@ -1236,11 +1194,7 @@
}
- fir_mem_up(st->x0d, h0, st->y0, st->full_frame_size, QMF_ORDER, st->g0_mem, stack);
- fir_mem_up(st->high, h1, st->y1, st->full_frame_size, QMF_ORDER, st->g1_mem, stack);
-
- mix_and_saturate(st->y0, st->y1, out, st->full_frame_size);
-
+ qmf_synth(st->x0d, st->high, h0, out, st->full_frame_size, QMF_ORDER, st->g0_mem, st->g1_mem, stack);
for (i=0;i<st->lpcSize;i++)
st->old_qlsp[i] = st->qlsp[i];
Modified: trunk/speex/libspeex/sb_celp.h
===================================================================
--- trunk/speex/libspeex/sb_celp.h 2006-11-28 14:22:55 UTC (rev 12150)
+++ trunk/speex/libspeex/sb_celp.h 2006-11-28 14:56:27 UTC (rev 12151)
@@ -60,7 +60,6 @@
char *stack; /**< Temporary allocation stack */
spx_sig_t *x0d, *x1d; /**< QMF filter signals*/
spx_sig_t *high; /**< High-band signal (buffer) */
- spx_sig_t *y0, *y1; /**< QMF synthesis signals */
spx_word16_t *h0_mem, *h1_mem;
spx_word32_t *g0_mem, *g1_mem; /**< QMF memories */
@@ -127,7 +126,6 @@
char *stack;
spx_sig_t *x0d, *x1d;
spx_sig_t *high;
- spx_sig_t *y0, *y1;
spx_word32_t *g0_mem, *g1_mem;
spx_sig_t *exc;
More information about the commits
mailing list