#include #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; iold_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; iexc[-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; iinterp_qlpc[i] = ak[i]; } /* Store the LSPs for interpolation in the next frame */ for (i=0; iold_qlsp[i] = qlsp[i]; return 0; }