static void read_and_decode_spectrum(TwinVQContext *tctx, float *out, enum TwinVQFrameType ftype) { const TwinVQModeTab *mtab = tctx->mtab; TwinVQFrameData *bits = &tctx->bits; int channels = tctx->avctx->channels; int sub = mtab->fmode[ftype].sub; int block_size = mtab->size / sub; float gain[TWINVQ_CHANNELS_MAX * TWINVQ_SUBBLOCKS_MAX]; float ppc_shape[TWINVQ_PPC_SHAPE_LEN_MAX * TWINVQ_CHANNELS_MAX * 4]; int i, j; dequant(tctx, bits->main_coeffs, out, ftype, mtab->fmode[ftype].cb0, mtab->fmode[ftype].cb1, mtab->fmode[ftype].cb_len_read); dec_gain(tctx, ftype, gain); if (ftype == TWINVQ_FT_LONG) { int cb_len_p = (tctx->n_div[3] + mtab->ppc_shape_len * channels - 1) / tctx->n_div[3]; dequant(tctx, bits->ppc_coeffs, ppc_shape, TWINVQ_FT_PPC, mtab->ppc_shape_cb, mtab->ppc_shape_cb + cb_len_p * TWINVQ_PPC_SHAPE_CB_SIZE, cb_len_p); } for (i = 0; i < channels; i++) { float *chunk = out + mtab->size * i; float lsp[TWINVQ_LSP_COEFS_MAX]; for (j = 0; j < sub; j++) { tctx->dec_bark_env(tctx, bits->bark1[i][j], bits->bark_use_hist[i][j], i, tctx->tmp_buf, gain[sub * i + j], ftype); tctx->fdsp.vector_fmul(chunk + block_size * j, chunk + block_size * j, tctx->tmp_buf, block_size); } if (ftype == TWINVQ_FT_LONG) tctx->decode_ppc(tctx, bits->p_coef[i], bits->g_coef[i], ppc_shape + i * mtab->ppc_shape_len, chunk); decode_lsp(tctx, bits->lpc_idx1[i], bits->lpc_idx2[i], bits->lpc_hist_idx[i], lsp, tctx->lsp_hist[i]); dec_lpc_spectrum_inv(tctx, lsp, ftype, tctx->tmp_buf); for (j = 0; j < mtab->fmode[ftype].sub; j++) { tctx->fdsp.vector_fmul(chunk, chunk, tctx->tmp_buf, block_size); chunk += block_size; } } }
void decod_ld8a(struct dec_state_t * state, int parm[], /* (i) : vector of synthesis parameters parm[0] = bad frame indicator (bfi) */ GFLOAT synth[], /* (o) : synthesis speech */ GFLOAT A_t[], /* (o) : decoded LP filter in 2 subframes */ int *T2, /* (o) : decoded pitch lag in 2 subframes */ int *Vad /* (o) : decoded frame type */ ) { GFLOAT *Az; /* Pointer on A_t */ GFLOAT lsp_new[M]; /* Decoded LSP's */ GFLOAT code[L_SUBFR]; /* ACELP codevector */ /* Scalars */ int i, i_subfr; int t0, t0_frac, index; int bfi, bad_pitch; /* for G.729B */ int ftyp; GFLOAT lsfq_mem[MA_NP][M]; /* Test bad frame indicator (bfi) */ bfi = *parm++; /* for G.729B */ ftyp = *parm; if (bfi) { if(state->past_ftyp == 1) ftyp = 1; else ftyp = 0; *parm = ftyp; /* modification introduced in version V1.3 */ } *Vad = ftyp; /* Processing non active frames (SID & not transmitted) */ if(ftyp != 1) { get_freq_prev((const GFLOAT (*)[M]) state->lsp_s.freq_prev, lsfq_mem); dec_cng(&state->cng_s, state->past_ftyp, state->sid_sav, parm, state->exc, state->lsp_old, A_t, &state->seed, lsfq_mem); update_freq_prev(state->lsp_s.freq_prev, (const GFLOAT (*)[M]) lsfq_mem); Az = A_t; for (i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR) { syn_filt(Az, &state->exc[i_subfr], &synth[i_subfr], L_SUBFR, state->mem_syn, 0); copy(&synth[i_subfr+L_SUBFR-M], state->mem_syn, M); Az += MP1; *T2++ = state->old_t0; } state->sharp = SHARPMIN; } else /* Processing active frame */ { state->seed = INIT_SEED; parm++; /* Decode the LSPs */ d_lsp(&state->lsp_s, parm, lsp_new, bfi+state->bad_lsf ); parm += 2; /* Advance synthesis parameters pointer */ /* Note: "bad_lsf" is introduce in case the standard is used with channel protection. */ /* Interpolation of LPC for the 2 subframes */ int_qlpc(state->lsp_old, lsp_new, A_t); /* update the LSFs for the next frame */ copy(lsp_new, state->lsp_old, M); /*------------------------------------------------------------------------* * Loop for every subframe in the analysis frame * *------------------------------------------------------------------------* * The subframe size is L_SUBFR and the loop is repeated L_FRAME/L_SUBFR * * times * * - decode the pitch delay * * - decode algebraic code * * - decode pitch and codebook gains * * - find the excitation and compute synthesis speech * *------------------------------------------------------------------------*/ Az = A_t; /* pointer to interpolated LPC parameters */ for (i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR) { /*-------------------------------------------------* * - Find the adaptive codebook vector. * *--------------------------------------------------*/ index = *parm++; /* pitch index */ if (i_subfr == 0) { i = *parm++; /* get parity check result */ bad_pitch = bfi + i; if( bad_pitch == 0) { dec_lag3(index, PIT_MIN, PIT_MAX, i_subfr, &t0, &t0_frac); state->old_t0 = t0; } else /* Bad frame, or parity error */ { t0 = state->old_t0; t0_frac = 0; state->old_t0++; if( (state->old_t0 - PIT_MAX) > 0) state->old_t0 = PIT_MAX; } } else /* second subframe */ { if( bfi == 0) { dec_lag3(index, PIT_MIN, PIT_MAX, i_subfr, &t0, &t0_frac); state->old_t0 = t0; } else { t0 = state->old_t0; t0_frac = 0; state->old_t0++; if( (state->old_t0 - PIT_MAX) > 0) state->old_t0 = PIT_MAX; } } *T2++ = t0; /*-------------------------------------------------* * - Find the adaptive codebook vector. * *-------------------------------------------------*/ pred_lt_3(&state->exc[i_subfr], t0, t0_frac, L_SUBFR); /*-------------------------------------------------------* * - Decode innovative codebook. * * - Add the fixed-gain pitch contribution to code[]. * *-------------------------------------------------------*/ if(bfi != 0) /* Bad frame */ { parm[0] = random_g729(&state->seed_fer) & (INT16)0x1fff; /* 13 bits random */ parm[1] = random_g729(&state->seed_fer) & (INT16)0x000f; /* 4 bits random */ } decod_ACELP(parm[1], parm[0], code); parm +=2; for (i = t0; i < L_SUBFR; i++) code[i] += state->sharp * code[i-t0]; /*-------------------------------------------------* * - Decode pitch and codebook gains. * *-------------------------------------------------*/ index = *parm++; /* index of energy VQ */ dec_gain(&state->gain_s, index, code, L_SUBFR, bfi, &state->gain_pitch, &state->gain_code); /*-------------------------------------------------------------* * - Update pitch sharpening "sharp" with quantized gain_pitch * *-------------------------------------------------------------*/ state->sharp = state->gain_pitch; if (state->sharp > SHARPMAX) state->sharp = SHARPMAX; if (state->sharp < SHARPMIN) state->sharp = SHARPMIN; /*-------------------------------------------------------* * - Find the total excitation. * * - Find synthesis speech corresponding to exc[]. * *-------------------------------------------------------*/ for (i = 0; i < L_SUBFR; i++) state->exc[i+i_subfr] = state->gain_pitch*state->exc[i+i_subfr] + state->gain_code*code[i]; syn_filt(Az, &state->exc[i_subfr], &synth[i_subfr], L_SUBFR, state->mem_syn, 1); Az += MP1; /* interpolated LPC parameters for next subframe */ } } /*------------* * For G729b *-----------*/ if (bfi == 0) { state->sid_sav = (F)0.0; for (i=0; i<L_FRAME; i++) state->sid_sav += state->exc[i] * state->exc[i]; } state->past_ftyp = ftyp; /*--------------------------------------------------* * Update signal for next frame. * * -> shift to the left by L_FRAME exc[] * *--------------------------------------------------*/ copy(&state->old_exc[L_FRAME], &state->old_exc[0], PIT_MAX+L_INTERPOL); }
/*-------------------------------------------------------------------------- * decod_ld8k - decoder *-------------------------------------------------------------------------- */ void decod_ld8k( int parm[], /* input : synthesis parameters (parm[0] = bfi) */ int voicing, /* input : voicing decision from previous frame */ FLOAT synth[], /* output: synthesized speech */ FLOAT A_t[], /* output: two sets of A(z) coefficients length=2*MP1 */ int *t0_first /* output: integer delay of first subframe */ ) { FLOAT *Az; /* Pointer to A_t (LPC coefficients) */ FLOAT lsp_new[M]; /* LSPs */ FLOAT code[L_SUBFR]; /* algebraic codevector */ /* Scalars */ int i, i_subfr; int t0, t0_frac, index; int bfi; int bad_pitch; /* Test bad frame indicator (bfi) */ bfi = *parm++; /* Decode the LSPs */ d_lsp(parm, lsp_new, bfi); parm += 2; /* Advance synthesis parameters pointer */ /* Interpolation of LPC for the 2 subframes */ int_qlpc(lsp_old, lsp_new, A_t); /* update the LSFs for the next frame */ copy(lsp_new, lsp_old, M); /*------------------------------------------------------------------------* * Loop for every subframe in the analysis frame * *------------------------------------------------------------------------* * The subframe size is L_SUBFR and the loop is repeated L_FRAME/L_SUBFR * * times * * - decode the pitch delay * * - decode algebraic code * * - decode pitch and codebook gains * * - find the excitation and compute synthesis speech * *------------------------------------------------------------------------*/ Az = A_t; /* pointer to interpolated LPC parameters */ for (i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR) { index = *parm++; /* pitch index */ if (i_subfr == 0) { /* if first subframe */ i = *parm++; /* get parity check result */ bad_pitch = bfi+ i; if( bad_pitch == 0) { dec_lag3(index, PIT_MIN, PIT_MAX, i_subfr, &t0, &t0_frac); old_t0 = t0; } else /* Bad frame, or parity error */ { t0 = old_t0; t0_frac = 0; old_t0++; if( old_t0> PIT_MAX) { old_t0 = PIT_MAX; } } *t0_first = t0; /* If first frame */ } else /* second subframe */ { if( bfi == 0) { dec_lag3(index, PIT_MIN, PIT_MAX, i_subfr, &t0, &t0_frac); old_t0 = t0; } else { t0 = old_t0; t0_frac = 0; old_t0++; if( old_t0 >PIT_MAX) { old_t0 = PIT_MAX; } } } /*-------------------------------------------------* * - Find the adaptive codebook vector. * *--------------------------------------------------*/ pred_lt_3(&exc[i_subfr], t0, t0_frac, L_SUBFR); /*-------------------------------------------------------* * - Decode innovative codebook. * * - Add the fixed-gain pitch contribution to code[]. * *-------------------------------------------------------*/ if(bfi != 0) { /* Bad Frame Error Concealment */ parm[0] = (int) (random_g729() & 0x1fff); /* 13 bits random*/ parm[1]= (int) (random_g729() & 0x000f); /* 4 bits random */ } decod_ACELP(parm[1], parm[0], code); parm +=2; for (i = t0; i < L_SUBFR; i++) code[i] += sharp * code[i-t0]; /*-------------------------------------------------* * - Decode pitch and codebook gains. * *-------------------------------------------------*/ index = *parm++; /* index of energy VQ */ dec_gain(index, code, L_SUBFR, bfi, &gain_pitch, &gain_code); /*-------------------------------------------------------------* * - Update pitch sharpening "sharp" with quantized gain_pitch * *-------------------------------------------------------------*/ sharp = gain_pitch; if (sharp > SHARPMAX) sharp = SHARPMAX; if (sharp < SHARPMIN) sharp = SHARPMIN; /*-------------------------------------------------------* * - Find the total excitation. * *-------------------------------------------------------*/ if(bfi != 0 ) { if(voicing == 0) { /* for unvoiced frame */ for (i = 0; i < L_SUBFR; i++) { exc[i+i_subfr] = gain_code*code[i]; } } else { /* for voiced frame */ for (i = 0; i < L_SUBFR; i++) { exc[i+i_subfr] = gain_pitch*exc[i+i_subfr]; } } } else { /* No frame errors */ for (i = 0; i < L_SUBFR; i++) { exc[i+i_subfr] = gain_pitch*exc[i+i_subfr] + gain_code*code[i]; } } /*-------------------------------------------------------* * - Find synthesis speech corresponding to exc[]. * *-------------------------------------------------------*/ syn_filt(Az, &exc[i_subfr], &synth[i_subfr], L_SUBFR, mem_syn, 1); Az += MP1; /* interpolated LPC parameters for next subframe */ } /*--------------------------------------------------* * Update signal for next frame. * * -> shift to the left by L_FRAME exc[] * *--------------------------------------------------*/ copy(&old_exc[L_FRAME], &old_exc[0], PIT_MAX+L_INTERPOL); return; }
void check_cbox() { // use telemetry channel for connection to parameter control box // 2x16 LCD panel for menu and value display // button left/right: change selected gain and display its name on line 1 // and value on line 2 // button up/down: inc/dec selected gain // click: write selected value // perform action when button state changes from none to something else // (called at 20Hz) button_state = debounce_cbox_button(); if (button_state >= 0) { // auto repeat if BUTTON_UP,DOWN,LEFT,RIGHT is held down if (button_state != BUTTON_CLICK) { auto_count++; if (auto_count > 10) { auto_repeat = true; auto_count = 0; } } if (button_state != last_button_state || auto_repeat) { auto_repeat = false; last_button_state = button_state; switch (button_state) { case BUTTON_LEFT: if (menu_item > 0) menu_item--; break; case BUTTON_RIGHT: if (menu_item < MENU_ITEMS_N - 1) menu_item++; break; case BUTTON_UP: inc_gain(menu_item); break; case BUTTON_DOWN: dec_gain(menu_item); break; case BUTTON_CLICK: // toggle between cbox display and telemetry output toggle_cbox_on = 1; break; } } } // toggle cbox on and off to allow enabling telemetry without reflashing if (toggle_cbox_on) { toggle_cbox_on = 0; cbox_on = 1 - cbox_on; if (cbox_on) { // set baud rate for serial LCD and display menu cbox_init(); cbox_display(menu_item); } else { // save gains and init telemetry output storeGains(); init_serial(); } } if (cbox_on && button_state != BUTTON_NONE) cbox_display(menu_item); }