void Lsp_get_quant( Word16 lspcb1[][M], /* (i) Q13 : first stage LSP codebook */ Word16 lspcb2[][M], /* (i) Q13 : Second stage LSP codebook */ Word16 code0, /* (i) : selected code of first stage */ Word16 code1, /* (i) : selected code of second stage */ Word16 code2, /* (i) : selected code of second stage */ Word16 fg[][M], /* (i) Q15 : MA prediction coef. */ Word16 freq_prev[][M], /* (i) Q13 : previous LSP vector */ Word16 lspq[], /* (o) Q13 : quantized LSP parameters */ Word16 fg_sum[] /* (i) Q15 : present MA prediction coef. */ ) { Word16 j; Word16 buf[M]; /* Q13 */ for ( j = 0 ; j < NC ; j++ ) buf[j] = add( lspcb1[code0][j], lspcb2[code1][j] ); for ( j = NC ; j < M ; j++ ) buf[j] = add( lspcb1[code0][j], lspcb2[code2][j] ); Lsp_expand_1_2(buf, GAP1); Lsp_expand_1_2(buf, GAP2); Lsp_prev_compose(buf, lspq, fg, freq_prev, fg_sum); Lsp_prev_update(buf, freq_prev); Lsp_stability( lspq ); return; }
/* lsf_decode */ void Lsp_get_quant( Word16 lspcb1[][M], /* (i) Q13 : first stage LSP codebook */ Word16 lspcb2[][M], /* (i) Q13 : Second stage LSP codebook */ Word16 code0, /* (i) : selected code of first stage */ Word16 code1, /* (i) : selected code of second stage */ Word16 code2, /* (i) : selected code of second stage */ Word16 fg[][M], /* (i) Q15 : MA prediction coef. */ Word16 freq_prev[][M], /* (i) Q13 : previous LSP vector */ Word16 lspq[], /* (o) Q13 : quantized LSP parameters */ Word16 fg_sum[] /* (i) Q15 : present MA prediction coef. */ ) { static const UWord8 gap[2]={GAP1, GAP2}; Word16 j, i; Word16 buf[M]; /* Q13 */ Word32 diff, acc; for ( j = 0 ; j < NC ; j++ ) { buf[j] = lspcb1[code0][j] + lspcb2[code1][j]; buf[j+NC] = lspcb1[code0][j+NC] + lspcb2[code2][j+NC]; } /* Lsp_expand_1_2 */ for (i = 0; i < 2; ++i) for ( j = 1 ; j < M ; j++ ) { diff = (buf[j-1] - buf[j] + gap[i]) >> 1; if ( diff > 0 ) { buf[j-1] -= diff; buf[j] += diff; } } /* Lsp_prev_compose * compose LSP parameter from elementary LSP with previous LSP. */ for ( i = 0 ; i < M ; i++ ) { acc = buf[i] * fg_sum[i]; for ( j = 0 ; j < MA_NP ; j++ ) acc += freq_prev[j][i] * fg[j][i]; lspq[i] = acc >> 15; } /* Lsp_prev_update */ for ( j = MA_NP-1 ; j > 0 ; j-- ) Copy(freq_prev[j-1], freq_prev[j], M); Copy(buf, freq_prev[0], M); Lsp_stability( lspq ); }
void sid_lsfq_decode(Word16 *index, /* (i) : quantized indices */ Word16 *lspq, /* (o) : quantized lsp vector */ Word16 freq_prev[MA_NP][M] /* (i) : memory of predictor */ ) { Word32 acc0; Word16 i, j, k, lsfq[M], tmpbuf[M]; /* get the lsf error vector */ Copy(lspcb1[PtrTab_1[index[1]]], tmpbuf, M); for (i=0; i<M/2; i++) tmpbuf[i] = add(tmpbuf[i], lspcb2[PtrTab_2[0][index[2]]][i]); for (i=M/2; i<M; i++) tmpbuf[i] = add(tmpbuf[i], lspcb2[PtrTab_2[1][index[2]]][i]); /* guarantee minimum distance of 0.0012 (~10 in Q13) between tmpbuf[j] and tmpbuf[j+1] */ for (j=1; j<M; j++){ acc0 = L_mult(tmpbuf[j-1], 16384); acc0 = L_mac(acc0, tmpbuf[j], -16384); acc0 = L_mac(acc0, 10, 16384); k = extract_h(acc0); if (k > 0){ tmpbuf[j-1] = sub(tmpbuf[j-1], k); tmpbuf[j] = add(tmpbuf[j], k); } } /* compute the quantized lsf vector */ Lsp_prev_compose(tmpbuf, lsfq, noise_fg[index[0]], freq_prev, noise_fg_sum[index[0]]); /* update the prediction memory */ Lsp_prev_update(tmpbuf, freq_prev); /* lsf stability check */ Lsp_stability(lsfq); /* convert lsf to lsp */ Lsf_lsp2(lsfq, lspq, M); }