diff options
author | jmvalin <jmvalin@0101bb08-14d6-0310-b084-bc0e0c8e3800> | 2002-04-03 02:58:12 +0400 |
---|---|---|
committer | jmvalin <jmvalin@0101bb08-14d6-0310-b084-bc0e0c8e3800> | 2002-04-03 02:58:12 +0400 |
commit | 957df90f3ac5daed1c3dcc97267d6aa4e72eb2fd (patch) | |
tree | 95bac9206a6065cf337c808e6152af8a6f720eb6 /libspeex | |
parent | 0860601ab57b07e75e0a0c7d95560cd9c7ab8eb3 (diff) |
Adding sub-band CELP (SB-CELP) -like encoding. Still incomplete.
git-svn-id: http://svn.xiph.org/trunk/speex@3214 0101bb08-14d6-0310-b084-bc0e0c8e3800
Diffstat (limited to 'libspeex')
-rw-r--r-- | libspeex/Makefile.am | 11 | ||||
-rw-r--r-- | libspeex/filters.c | 15 | ||||
-rw-r--r-- | libspeex/filters.h | 3 | ||||
-rw-r--r-- | libspeex/modes.c | 36 | ||||
-rw-r--r-- | libspeex/modes.h | 1 | ||||
-rw-r--r-- | libspeex/sb_celp.c | 125 | ||||
-rw-r--r-- | libspeex/sb_celp.h | 48 | ||||
-rw-r--r-- | libspeex/testenc.c | 2 | ||||
-rw-r--r-- | libspeex/testenc_wb.c | 2 |
9 files changed, 238 insertions, 5 deletions
diff --git a/libspeex/Makefile.am b/libspeex/Makefile.am index ce1d49b..810c796 100644 --- a/libspeex/Makefile.am +++ b/libspeex/Makefile.am @@ -1,6 +1,6 @@ ## Process this file with automake to produce Makefile.in. -*-Makefile-*- -# $Id: Makefile.am,v 1.17 2002/03/22 05:03:30 jmvalin Exp $ +# $Id: Makefile.am,v 1.18 2002/04/02 22:58:12 jmvalin Exp $ # Disable automatic dependency tracking if using other tools than gcc and gmake #AUTOMAKE_OPTIONS = no-dependencies @@ -9,6 +9,7 @@ lib_LTLIBRARIES = libspeex.la # Sources for compilation in the library libspeex_la_SOURCES = speex.c \ + sb_celp.c \ lpc.c \ ltp.c \ lsp.c \ @@ -33,7 +34,8 @@ libspeex_la_SOURCES = speex.c \ include_HEADERS = speex.h \ bits.h \ - modes.h + modes.h \ + sb_celp.h noinst_HEADERS = lsp.h \ lpc.h \ @@ -49,7 +51,7 @@ noinst_HEADERS = lsp.h \ libspeex_la_LDFLAGS = -release $(LT_RELEASE) -bin_PROGRAMS = testenc testdec testenc_wb +bin_PROGRAMS = testenc testdec testenc_wb testenc_sb testenc_SOURCES = testenc.c testenc_LDADD = libspeex.la @@ -60,3 +62,6 @@ testdec_LDADD = libspeex.la testenc_wb_SOURCES = testenc_wb.c testenc_wb_LDADD = libspeex.la +testenc_sb_SOURCES = testenc_sb.c +testenc_sb_LDADD = libspeex.la + diff --git a/libspeex/filters.c b/libspeex/filters.c index 325b450..1ba9c20 100644 --- a/libspeex/filters.c +++ b/libspeex/filters.c @@ -115,3 +115,18 @@ float xcorr(float *x, float *y, int len) sum += x[i]*y[i]; return sum; } + +void fir_mem(float *x, float *a, float *y, int N, int M, float *mem) +{ + int i,j; + for (i=0;i<N;i++) + { + y[i]=0; + for (j=0;j<=min(M-1,i);j++) + y[i] += a[j]*x[i-j]; + for (j=i+1;j<=M-1;j++) + y[i] += a[j]*mem[j-i-1]; + } + for (i=0;i<M-1;i++) + mem[i]=x[N-i-1]; +} diff --git a/libspeex/filters.h b/libspeex/filters.h index 81515b9..b9d856d 100644 --- a/libspeex/filters.h +++ b/libspeex/filters.h @@ -44,4 +44,7 @@ void residue_mem(float *x, float *a, float *y, int N, int ord, float *mem); /* Cross correlation */ float xcorr(float *x, float *y, int len); +/* FIR filter */ +void fir_mem(float *x, float *a, float *y, int N, int M, float *mem); + #endif diff --git a/libspeex/modes.c b/libspeex/modes.c index bda2229..87e7cf7 100644 --- a/libspeex/modes.c +++ b/libspeex/modes.c @@ -69,6 +69,15 @@ mpulse_params mpulse_nb = { 10 }; + +mpulse_params mpulse_sb = { + 24, /*nb_pulse*/ + 4, /*nb_tracks*/ + 2.2, /*gain_coef*/ + 20 +}; + + mpulse_params mpulse_wb = { 24, /*nb_pulse*/ 4, /*nb_tracks*/ @@ -182,3 +191,30 @@ SpeexMode mp_wb_mode = { mpulse_unquant, &mpulse_wb }; + + +SpeexMode mp_sb_mode = { + 160, /*frameSize*/ + 40, /*subframeSize*/ + 320, /*windowSize*/ + 10, /*lpcSize*/ + 640, /*bufSize*/ + 17, /*pitchStart*/ + 144, /*pitchEnd*/ + 0.9, /*gamma1*/ + 0.6, /*gamma2*/ + .005, /*lag_factor*/ + 1.0001, /*lpc_floor*/ + 0.0, /*preemph*/ + /*LSP quantization*/ + lsp_quant_nb, + lsp_unquant_nb, + /*Pitch quantization*/ + pitch_search_3tap, + pitch_unquant_3tap, + <p_params_nb, + /*Innovation quantization*/ + mpulse_search, + mpulse_unquant, + &mpulse_sb +}; diff --git a/libspeex/modes.h b/libspeex/modes.h index a0314fe..b3dd0e9 100644 --- a/libspeex/modes.h +++ b/libspeex/modes.h @@ -78,5 +78,6 @@ extern SpeexMode nb_mode; extern SpeexMode wb_mode; extern SpeexMode mp_nb_mode; extern SpeexMode mp_wb_mode; +extern SpeexMode mp_sb_mode; #endif diff --git a/libspeex/sb_celp.c b/libspeex/sb_celp.c new file mode 100644 index 0000000..f5e97b6 --- /dev/null +++ b/libspeex/sb_celp.c @@ -0,0 +1,125 @@ +/* Copyright (C) 2002 Jean-Marc Valin + File: speex.c + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#include "speex.h" +#include "sb_celp.h" +#include "stdlib.h" +#include "filters.h" + +static float h0[32] = { + 0.0006910579, -0.001403793, + -0.001268303, 0.004234195, + 0.001414246, -0.009458318, + -0.0001303859, 0.01798145, + -0.004187483, -0.03123862, + 0.01456844, 0.05294745, + -0.03934878, -0.09980243, + 0.1285579, 0.4664053, + 0.4664053, 0.1285579, + -0.09980243, -0.03934878, + 0.05294745, 0.01456844, + -0.03123862, -0.004187483, + 0.01798145, -0.0001303859, + -0.009458318, 0.001414246, + 0.004234195, -0.001268303, + -0.001403793, 0.0006910579 +}; + +static float h1[32] = { + 0.0006910579, 0.001403793, + -0.001268303, -0.004234195, + 0.001414246, 0.009458318, + -0.0001303859, -0.01798145, + -0.004187483, 0.03123862, + 0.01456844, -0.05294745, + -0.03934878, 0.09980243, + 0.1285579, -0.4664053, + 0.4664053, -0.1285579, + -0.09980243, 0.03934878, + 0.05294745, -0.01456844, + -0.03123862, 0.004187483, + 0.01798145, 0.0001303859, + -0.009458318, -0.001414246, + 0.004234195, 0.001268303, + -0.001403793, -0.0006910579 +}; + +void sb_encoder_init(SBEncState *st, SpeexMode *mode) +{ + encoder_init(&st->st_low, mode); + st->frame_size = 2*st->st_low.frameSize; + st->x0=calloc(st->frame_size, sizeof(float)); + st->x1=calloc(st->frame_size, sizeof(float)); + st->x0d=calloc(st->frame_size>>1, sizeof(float)); + st->x1d=calloc(st->frame_size>>1, sizeof(float)); + st->high=calloc(st->frame_size, sizeof(float)); + st->y0=calloc(st->frame_size, sizeof(float)); + st->y1=calloc(st->frame_size, sizeof(float)); + + st->h0_mem=calloc(32, sizeof(float)); + st->h1_mem=calloc(32, sizeof(float)); + st->g0_mem=calloc(32, sizeof(float)); + st->g1_mem=calloc(32, sizeof(float)); +} + +void sb_encoder_destroy(SBEncState *st) +{ + encoder_destroy(&st->st_low); + free(st->x0); + free(st->x0d); + free(st->x1); + free(st->x1d); + free(st->high); + free(st->y0); + free(st->y1); + free(st->h0_mem); + free(st->h1_mem); + free(st->g0_mem); + free(st->g1_mem); +} + + +void sb_encode(SBEncState *st, float *in, FrameBits *bits) +{ + int i; + fir_mem(in, h0, st->x0, st->frame_size, 32, st->h0_mem); + fir_mem(in, h1, st->x1, st->frame_size, 32, st->h1_mem); + for (i=0;i<st->frame_size>>1;i++) + { + st->x0d[i]=st->x0[i<<1]; + st->x1d[i]=st->x1[i<<1]; + } + encode(&st->st_low, st->x0d, bits); + for (i=0;i<st->frame_size>>1;i++) + { + st->high[i]=st->high[(st->frame_size>>1)+i]; + st->high[(st->frame_size>>1)+i]=st->x1d[i]; + } + for (i=0;i<st->frame_size>>1;i++) + { + st->x0[(i<<1)]=st->x0d[i]; + st->x1[(i<<1)]=st->high[i]; + st->x0[(i<<1)+1]=0; + st->x1[(i<<1)+1]=0; + } + fir_mem(st->x0, h0, st->y0, st->frame_size, 32, st->g0_mem); + fir_mem(st->x1, h1, st->y1, st->frame_size, 32, st->g1_mem); + for (i=0;i<st->frame_size;i++) + in[i]=2*(st->y0[i]-st->y1[i]); +} diff --git a/libspeex/sb_celp.h b/libspeex/sb_celp.h new file mode 100644 index 0000000..2a0b1a0 --- /dev/null +++ b/libspeex/sb_celp.h @@ -0,0 +1,48 @@ +/* Copyright (C) 2002 Jean-Marc Valin + File: speex.h + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#ifndef SB_CELP_H +#define SB_CELP_H + +#include "modes.h" +#include "bits.h" +#include "speex.h" + +/**Structure representing the full state of the encoder*/ +typedef struct SBEncState { + EncState st_low; + int frame_size; + float *x0, *x0d, *x1, *x1d; + float *high; + float *y0, *y1; + float *h0_mem, *h1_mem, *g0_mem, *g1_mem; +} SBEncState; + + +/**Initializes encoder state*/ +void sb_encoder_init(SBEncState *st, SpeexMode *mode); + +/**De-allocates encoder state resources*/ +void sb_encoder_destroy(SBEncState *st); + +/**Encodes one frame*/ +void sb_encode(SBEncState *st, float *in, FrameBits *bits); + + +#endif diff --git a/libspeex/testenc.c b/libspeex/testenc.c index 3399861..80a43eb 100644 --- a/libspeex/testenc.c +++ b/libspeex/testenc.c @@ -59,7 +59,7 @@ int main(int argc, char **argv) } frame_bits_rewind(&bits); - decode(&dec, &bits, input); + /*decode(&dec, &bits, input);*/ /* Save the bits here */ frame_bits_reset(&bits); diff --git a/libspeex/testenc_wb.c b/libspeex/testenc_wb.c index 588735e..f3f3430 100644 --- a/libspeex/testenc_wb.c +++ b/libspeex/testenc_wb.c @@ -59,7 +59,7 @@ int main(int argc, char **argv) } frame_bits_rewind(&bits); - decode(&dec, &bits, input); + /*decode(&dec, &bits, input);*/ /* Save the bits here */ frame_bits_reset(&bits); |