123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182 |
- #include <math.h>
- #include "nb_celp.h"
- #include "lsp.h"
- #include "ltp.h"
- #include "quant_lsp.h"
- #include "cb_search.h"
- #include "filters.h"
- #include "os_support.h"
- #ifndef NULL
- #define NULL 0
- #endif
- #define LSP_MARGIN .002f
- #define SIG_SCALING 1.f
- #define NB_DEC_BUFFER (NB_FRAME_SIZE+2*NB_PITCH_END+NB_SUBFRAME_SIZE+12)
- #define NB_ORDER 10
- #define NB_FRAME_SIZE 160
- #define NB_SUBFRAME_SIZE 40
- #define NB_NB_SUBFRAMES 4
- #define NB_PITCH_START 17
- #define NB_PITCH_END 144
- struct speex_decode_state {
- float excBuf[NB_DEC_BUFFER]; /**< Excitation buffer */
- float *exc; /**< Start of excitation frame */
- float old_qlsp[10]; /**< Quantized LSPs for previous frame */
- float interp_qlpc[10]; /**< Interpolated quantized LPCs */
- float mem_sp[10]; /**< Filter memory for synthesis signal */
- int first; /**< Is this the first frame? */
- };
- static const float exc_gain_quant_scal1[2] = {0.70469f, 1.05127f};
- struct speex_decode_state *nb_decoder_init(void)
- {
- struct speex_decode_state *st;
- st = malloc(sizeof(*st));
- if (!st)
- return NULL;
- memset(st, 0, sizeof(*st));
- st->first = 1;
- return st;
- }
- void nb_decoder_destroy(struct speex_decode_state *state)
- {
- if (state)
- free(state);
- }
- /* basic decoder using mode3 only */
- int nb_decode(struct speex_decode_state *st, SpeexBits *bits, float *out)
- {
- int i, sub, wideband, mode, qe;
- float ol_gain;
- float innov[NB_SUBFRAME_SIZE];
- float exc32[NB_SUBFRAME_SIZE];
- float qlsp[NB_ORDER], interp_qlsp[NB_ORDER];
- float ak[NB_ORDER];
- if (!bits)
- return -1;
- st->exc = st->excBuf + 2*NB_PITCH_END + NB_SUBFRAME_SIZE + 6;
- /* Decode Sub-modes */
- do {
- if (speex_bits_remaining(bits) < 5)
- return -1;
- wideband = speex_bits_unpack_unsigned(bits, 1);
- if (wideband) {
- printf("wideband not supported\n");
- return -2;
- }
- mode = speex_bits_unpack_unsigned(bits, 4);
- if (mode == 15)
- return -1;
- } while (mode > 8);
- if (mode != 3) {
- printf("only mode 3 supported\n");
- return -2;
- }
- /* Shift all buffers by one frame */
- SPEEX_MOVE(st->excBuf, st->excBuf+NB_FRAME_SIZE,
- 2*NB_PITCH_END + NB_SUBFRAME_SIZE + 12);
- /* Unquantize LSPs */
- lsp_unquant_lbr(qlsp, NB_ORDER, bits);
- /* Handle first frame */
- if (st->first) {
- st->first = 0;
- for (i=0; i<NB_ORDER; i++)
- st->old_qlsp[i] = qlsp[i];
- }
- /* Get global excitation gain */
- qe = speex_bits_unpack_unsigned(bits, 5);
- ol_gain = SIG_SCALING*exp(qe/3.5);
- /* Loop on subframes */
- for (sub=0; sub<4; sub++) {
- int offset, q_energy;
- float *exc, *sp;
- float ener;
- offset = NB_SUBFRAME_SIZE*sub;
- exc = st->exc + offset;
- sp = out + offset;
- SPEEX_MEMSET(exc, 0, NB_SUBFRAME_SIZE);
- /* Adaptive codebook contribution */
- pitch_unquant_3tap(exc, exc32, NB_PITCH_START,
- NB_SUBFRAME_SIZE, bits, 0);
- sanitize_values32(exc32, -32000, 32000, NB_SUBFRAME_SIZE);
- /* Unquantize the innovation */
- SPEEX_MEMSET(innov, 0, NB_SUBFRAME_SIZE);
- /* Decode sub-frame gain correction */
- q_energy = speex_bits_unpack_unsigned(bits, 1);
- ener = exc_gain_quant_scal1[q_energy] * ol_gain;
- /* Fixed codebook contribution */
- split_cb_shape_sign_unquant(innov, bits);
- /* De-normalize innovation and update excitation */
- signal_mul(innov, innov, ener, NB_SUBFRAME_SIZE);
- for (i=0; i<NB_SUBFRAME_SIZE; i++) {
- exc[i] = exc32[i] + innov[i];
- }
- }
- SPEEX_COPY(out, &st->exc[-NB_SUBFRAME_SIZE], NB_FRAME_SIZE);
- /* Loop on subframes */
- for (sub=0; sub<4; sub++) {
- const int offset = NB_SUBFRAME_SIZE*sub;
- float *sp, *exc;
- sp = out + offset;
- exc = st->exc + offset;
- /* LSP interpolation (quantized and unquantized) */
- lsp_interpolate(st->old_qlsp, qlsp, interp_qlsp, NB_ORDER,
- sub, NB_NB_SUBFRAMES, LSP_MARGIN);
- /* Compute interpolated LPCs (unquantized) */
- lsp_to_lpc(interp_qlsp, ak, NB_ORDER);
- iir_mem16(sp, st->interp_qlpc, sp, NB_SUBFRAME_SIZE,
- NB_ORDER, st->mem_sp);
- /* Save for interpolation in next frame */
- for (i=0; i<NB_ORDER; i++)
- st->interp_qlpc[i] = ak[i];
- }
- /* Store the LSPs for interpolation in the next frame */
- for (i=0; i<NB_ORDER; i++)
- st->old_qlsp[i] = qlsp[i];
- return 0;
- }
|