/*------------------------------------------------------------------------* * POSTFILTER.C * *------------------------------------------------------------------------* * Performs adaptive postfiltering on the synthesis speech * * This file contains all functions related to the post filter. * *------------------------------------------------------------------------*/ /*****************************************************************************/ /* string.h v8.1.4 */ /* */ /* Copyright (c) 1993-2017 Texas Instruments Incorporated */ /* http://www.ti.com/ */ /* */ /* Redistribution and use in source and binary forms, with or without */ /* modification, are permitted provided that the following conditions */ /* are met: */ /* */ /* Redistributions of source code must retain the above copyright */ /* notice, this list of conditions and the following disclaimer. */ /* */ /* Redistributions in binary form must reproduce the above copyright */ /* notice, this list of conditions and the following disclaimer in */ /* the documentation and/or other materials provided with the */ /* distribution. */ /* */ /* Neither the name of Texas Instruments Incorporated nor the names */ /* of its contributors may be used to endorse or promote products */ /* derived from this software without specific prior written */ /* permission. */ /* */ /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */ /* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ /* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */ /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */ /* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */ /* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */ /* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* */ /*****************************************************************************/ #pragma diag_push #pragma CHECK_MISRA("-6.3") /* standard types required for standard headers */ #pragma CHECK_MISRA("-19.1") /* #includes required for implementation */ #pragma CHECK_MISRA("-20.1") /* standard headers must define standard names */ #pragma CHECK_MISRA("-20.2") /* standard headers must define standard names */ typedef unsigned size_t; /*****************************************************************************/ /* linkage.h v8.1.4 */ /* */ /* Copyright (c) 1998-2017 Texas Instruments Incorporated */ /* http://www.ti.com/ */ /* */ /* Redistribution and use in source and binary forms, with or without */ /* modification, are permitted provided that the following conditions */ /* are met: */ /* */ /* Redistributions of source code must retain the above copyright */ /* notice, this list of conditions and the following disclaimer. */ /* */ /* Redistributions in binary form must reproduce the above copyright */ /* notice, this list of conditions and the following disclaimer in */ /* the documentation and/or other materials provided with the */ /* distribution. */ /* */ /* Neither the name of Texas Instruments Incorporated nor the names */ /* of its contributors may be used to endorse or promote products */ /* derived from this software without specific prior written */ /* permission. */ /* */ /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */ /* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ /* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */ /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */ /* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */ /* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */ /* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* */ /*****************************************************************************/ #pragma diag_push #pragma CHECK_MISRA("-19.4") /* macros required for implementation */ /*--------------------------------------------------------------------------*/ /* Define _CODE_ACCESS ==> how to call RTS functions */ /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ /* Define _DATA_ACCESS ==> how to access RTS global or static data */ /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ /* Define _DATA_ACCESS_NEAR ==> some C6000 RTS data must always be near */ /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ /* Define _IDECL ==> how inline functions are declared */ /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ /* If compiling with non-TI compiler (e.g. GCC), nullify any TI-specific */ /* language extensions. */ /*--------------------------------------------------------------------------*/ #pragma diag_pop #pragma diag_push #pragma CHECK_MISRA("-19.4") /* macros required for implementation */ #pragma diag_pop static __inline size_t strlen(const char *string); static __inline char *strcpy(char *dest, const char *src); static __inline char *strncpy(char *dest, const char *src, size_t n); static __inline char *strcat(char *string1, const char *string2); static __inline char *strncat(char *dest, const char *src, size_t n); static __inline char *strchr(const char *string, int c); static __inline char *strrchr(const char *string, int c); static __inline int strcmp(const char *string1, const char *string2); static __inline int strncmp(const char *string1, const char *string2, size_t n); int strcoll(const char *string1, const char *_string2); size_t strxfrm(char *to, const char *from, size_t n); char *strpbrk(const char *string, const char *chs); size_t strspn(const char *string, const char *chs); size_t strcspn(const char *string, const char *chs); char *strstr(const char *string1, const char *string2); char *strtok(char *str1, const char *str2); char *strerror(int _errno); char *strdup(const char *string); void *memmove(void *s1, const void *s2, size_t n); #pragma diag_push #pragma CHECK_MISRA("-16.4") /* false positives due to builtin declarations */ void *memcpy(void *s1, const void *s2, size_t n); #pragma diag_pop static __inline int memcmp(const void *cs, const void *ct, size_t n); static __inline void *memchr(const void *cs, int c, size_t n); void *memset(void *mem, int ch, size_t length); #pragma diag_push #pragma CHECK_MISRA("-19.4") /* macros required for implementation */ #pragma diag_pop #pragma diag_push /* functions */ /* MISRA exceptions to avoid changing inline versions of the functions that would be linked in instead of included inline at different mf levels */ /* these functions are very well-tested, stable, and efficient; it would introduce a high risk to implement new, separate MISRA versions just for the inline headers */ #pragma CHECK_MISRA("-5.7") /* keep names intact */ #pragma CHECK_MISRA("-6.1") /* false positive on use of char type */ #pragma CHECK_MISRA("-8.5") /* need to define inline functions */ #pragma CHECK_MISRA("-10.1") /* use implicit casts */ #pragma CHECK_MISRA("-10.3") /* need casts */ #pragma CHECK_MISRA("-11.5") /* casting away const required for standard impl */ #pragma CHECK_MISRA("-12.1") /* avoid changing expressions */ #pragma CHECK_MISRA("-12.2") /* avoid changing expressions */ #pragma CHECK_MISRA("-12.4") /* avoid changing expressions */ #pragma CHECK_MISRA("-12.5") /* avoid changing expressions */ #pragma CHECK_MISRA("-12.6") /* avoid changing expressions */ #pragma CHECK_MISRA("-12.13") /* ++/-- needed for reasonable implementation */ #pragma CHECK_MISRA("-13.1") /* avoid changing expressions */ #pragma CHECK_MISRA("-14.7") /* use multiple return points */ #pragma CHECK_MISRA("-14.8") /* use non-compound statements */ #pragma CHECK_MISRA("-14.9") /* use non-compound statements */ #pragma CHECK_MISRA("-17.4") /* pointer arithmetic needed for reasonable impl */ #pragma CHECK_MISRA("-17.6") /* false positive returning pointer-typed param */ static __inline size_t strlen(const char *string) { size_t n = (size_t)-1; const char *s = string; do n++; while (*s++); return n; } static __inline char *strcpy(register char *dest, register const char *src) { register char *d = dest; register const char *s = src; while (*d++ = *s++); return dest; } static __inline char *strncpy(register char *dest, register const char *src, register size_t n) { if (n) { register char *d = dest; register const char *s = src; while ((*d++ = *s++) && --n); /* COPY STRING */ if (n-- > 1) do *d++ = '\0'; while (--n); /* TERMINATION PADDING */ } return dest; } static __inline char *strcat(char *string1, const char *string2) { char *s1 = string1; const char *s2 = string2; while (*s1) s1++; /* FIND END OF STRING */ while (*s1++ = *s2++); /* APPEND SECOND STRING */ return string1; } static __inline char *strncat(char *dest, const char *src, register size_t n) { if (n) { char *d = dest; const char *s = src; while (*d) d++; /* FIND END OF STRING */ while (n--) if (!(*d++ = *s++)) return dest; /* APPEND SECOND STRING */ *d = 0; } return dest; } static __inline char *strchr(const char *string, int c) { char tch, ch = c; const char *s = string; for (;;) { if ((tch = *s) == ch) return (char *) s; if (!tch) return (char *) 0; s++; } } static __inline char *strrchr(const char *string, int c) { char tch, ch = c; char *result = 0; const char *s = string; for (;;) { if ((tch = *s) == ch) result = (char *) s; if (!tch) break; s++; } return result; } static __inline int strcmp(register const char *string1, register const char *string2) { register int c1, res; for (;;) { c1 = (unsigned char)*string1++; res = c1 - (unsigned char)*string2++; if (c1 == 0 || res != 0) break; } return res; } static __inline int strncmp(const char *string1, const char *string2, size_t n) { if (n) { const char *s1 = string1; const char *s2 = string2; unsigned char cp; int result; do if (result = (unsigned char)*s1++ - (cp = (unsigned char)*s2++)) return result; while (cp && --n); } return 0; } static __inline int memcmp(const void *cs, const void *ct, size_t n) { if (n) { const unsigned char *mem1 = (unsigned char *)cs; const unsigned char *mem2 = (unsigned char *)ct; int cp1, cp2; while ((cp1 = *mem1++) == (cp2 = *mem2++) && --n); return cp1 - cp2; } return 0; } static __inline void *memchr(const void *cs, int c, size_t n) { if (n) { const unsigned char *mem = (unsigned char *)cs; unsigned char ch = c; do if ( *mem == ch ) return (void *)mem; else mem++; while (--n); } return 0; } #pragma diag_pop #pragma diag_push /* using declarations must occur outside header guard to support including both C and C++-wrapped version of header; see _CPP_STYLE_HEADER check */ /* this code is for C++ mode only and thus also not relevant for MISRA */ #pragma CHECK_MISRA("-19.15") #pragma diag_pop // Types definitions typedef short Word16; typedef int Word32; typedef int Flag; /*___________________________________________________________________________ | | | Operators prototypes | |___________________________________________________________________________| */ Word16 sature(Word32 L_var1, Flag overflow_carry[]); /* Limit to 16 bits, 1 */ Word32 L_mult(Word16 var1, Word16 var2, Flag overflow_carry[]); /* Long mult, 1 */ Word32 L_msu(Word32 L_var3, Word16 var1, Word16 var2, Flag overflow_carry[]); /* Msu, 1 */ Word32 L_sub(Word32 L_var1, Word32 L_var2, Flag overflow_carry[]); /* Long sub, 2 */ Word32 L_shl(Word32 L_var1, Word16 var2, Flag overflow_carry[]); /* Long shift left, 2 */ Word16 shl(Word16 var1, Word16 var2, Flag overflow_carry[]); /* Short shift left, 1 */ Word16 shr(Word16 var1, Word16 var2, Flag overflow_carry[]); /* Short shift right, 1 */ Word32 L_mac(Word32 L_var3, Word16 var1, Word16 var2, Flag overflow_carry[]); /* Mac, 1 */ Word32 L_macNs(Word32 L_var3, Word16 var1, Word16 var2, Flag overflow_carry[]);/* Mac without sat, 1*/ Word32 L_msuNs(Word32 L_var3, Word16 var1, Word16 var2, Flag overflow_carry[]);/* Msu without sat, 1*/ Word32 L_add(Word32 L_var1, Word32 L_var2, Flag overflow_carry[]); /* Long add, 2 */ Word32 L_add_c(Word32 L_var1, Word32 L_var2, Flag overflow_carry[]); /*Long add with c, 2 */ Word32 L_sub_c(Word32 L_var1, Word32 L_var2, Flag overflow_carry[]); /*Long sub with c, 2 */ Word16 shr_r(Word16 var1, Word16 var2, Flag overflow_carry[]);/* Shift right with round, 2 */ Word16 mac_r(Word32 L_var3, Word16 var1, Word16 var2, Flag overflow_carry[]);/* Mac with rounding, 2*/ Word16 msu_r(Word32 L_var3, Word16 var1, Word16 var2, Flag overflow_carry[]);/* Msu with rounding, 2*/ Word32 L_shr_r(Word32 L_var1, Word16 var2, Flag overflow_carry[]);/* Long shift right with round, 3*/ Word32 L_sat(Word32 L_var1, Flag overflow_carry[]); /* Long saturation, 4 */ Word16 div_s(Word16 var1, Word16 var2, Flag overflow_carry[]); /* Short division, 18 */ /* ITU-T G.729A Speech Coder ANSI-C Source Code Version 1.1 Last modified: September 1996 Copyright (c) 1996, AT&T, France Telecom, NTT, Universite de Sherbrooke All rights reserved. */ /*---------------------------------------------------------------* * LD8A.H * * ~~~~~~ * * Function prototypes and constants use for G.729A 8kb/s coder. * * * *---------------------------------------------------------------*/ /*--------------------------------------------------------------------------* * Codec constant parameters (coder, decoder, and postfilter) * *--------------------------------------------------------------------------*/ /*-------------------------------* * Mathematic functions. * *-------------------------------*/ Word32 Inv_sqrt( /* (o) Q30 : output value (range: 0<=val<1) */ Word32 L_x, /* (i) Q0 : input value (range: 0<=val<=7fffffff) */ Flag overflow_carry[] ); void Log2( Word32 L_x, /* (i) Q0 : input value */ Word16 *exponent, /* (o) Q0 : Integer part of Log2. (range: 0<=val<=30) */ Word16 *fraction, /* (o) Q15: Fractionnal part of Log2. (range: 0<=val<1) */ Flag overflow_carry[] ); Word32 Pow2( /* (o) Q0 : result (range: 0<=val<=0x7fffffff) */ Word16 exponent, /* (i) Q0 : Integer part. (range: 0<=val<=30) */ Word16 fraction, /* (i) Q15 : Fractionnal part. (range: 0.0<=val<1.0) */ Flag overflow_carry[] ); /*----------------------------------* * Main coder and decoder functions * *----------------------------------*/ /*-------------------------------* * LPC analysis and filtering. * *-------------------------------*/ void Lag_window( Word16 m, /* (i) : LPC order */ Word16 r_h[], /* (i/o) : Autocorrelations (msb) */ Word16 r_l[], /* (i/o) : Autocorrelations (lsb) */ Flag overflow_carry[] ); void Lsp_Az( Word16 lsp[], /* (i) Q15 : line spectral frequencies */ Word16 a[], /* (o) Q12 : predictor coefficients (order = 10) */ Flag overflow_carry[] ); void Lsf_lsp( Word16 lsf[], /* (i) Q15 : lsf[m] normalized (range: 0.0<=val<=0.5) */ Word16 lsp[], /* (o) Q15 : lsp[m] (range: -1<=val<1) */ Word16 m /* (i) : LPC order */ ); void Lsp_lsf( Word16 lsp[], /* (i) Q15 : lsp[m] (range: -1<=val<1) */ Word16 lsf[], /* (o) Q15 : lsf[m] normalized (range: 0.0<=val<=0.5) */ Word16 m /* (i) : LPC order */ ); void Int_qlpc( Word16 lsp_old[], /* input : LSP vector of past frame */ Word16 lsp_new[], /* input : LSP vector of present frame */ Word16 Az[], /* output: interpolated Az() for the 2 subframes */ Flag overflow_carry[] ); void Weight_Az( Word16 a[], /* (i) Q12 : a[m+1] LPC coefficients */ Word16 gamma, /* (i) Q15 : Spectral expansion factor. */ Word16 m, /* (i) : LPC order. */ Word16 ap[], /* (o) Q12 : Spectral expanded LPC coefficients */ Flag overflow_carry[] ); void Residu( Word16 a[], /* (i) Q12 : prediction coefficients */ Word16 x[], /* (i) : speech (values x[-m..-1] are needed (m=10) */ Word16 y[], /* (o) : residual signal */ Word16 lg, /* (i) : size of filtering */ Flag overflow_carry[] ); void Syn_filt( Word16 a[], /* (i) Q12 : a[m+1] prediction coefficients (m=10) */ Word16 x[], /* (i) : input signal */ Word16 y[], /* (o) : output signal */ Word16 lg, /* (i) : size of filtering */ Word16 mem[], /* (i/o) : memory associated with this filtering. */ Word16 update, /* (i) : 0=no update, 1=update of memory. */ Flag overflow_carry[] ); void Convolve( Word16 x[], /* (i) : input vector */ Word16 h[], /* (i) Q12 : impulse response */ Word16 y[], /* (o) : output vector */ Word16 L /* (i) : vector size */ ); /*--------------------------------------------------------------------------* * LTP constant parameters * *--------------------------------------------------------------------------*/ /*-----------------------* * Pitch functions. * *-----------------------*/ Word16 Pitch_ol_fast( /* output: open loop pitch lag */ Word16 signal[], /* input : signal used to compute the open loop pitch */ /* signal[-pit_max] to signal[-1] should be known */ Word16 pit_max, /* input : maximum pitch lag */ Word16 L_frame, /* input : length of frame to compute pitch */ Flag overflow_carry[] ); Word16 Pitch_fr3_fast(/* (o) : pitch period. */ Word16 exc[], /* (i) : excitation buffer */ Word16 xn[], /* (i) : target vector */ Word16 h[], /* (i) Q12 : impulse response of filters. */ Word16 L_subfr, /* (i) : Length of subframe */ Word16 t0_min, /* (i) : minimum value in the searched range. */ Word16 t0_max, /* (i) : maximum value in the searched range. */ Word16 i_subfr, /* (i) : indicator for first subframe. */ Word16 *pit_frac, /* (o) : chosen fraction. */ Flag overflow_carry[] ); Word16 G_pitch( /* (o) Q14 : Gain of pitch lag saturated to 1.2 */ Word16 xn[], /* (i) : Pitch target. */ Word16 y1[], /* (i) : Filtered adaptive codebook. */ Word16 g_coeff[], /* (i) : Correlations need for gain quantization. */ Word16 L_subfr, /* (i) : Length of subframe. */ Flag overflow_carry[] ); Word16 Enc_lag3( /* output: Return index of encoding */ Word16 T0, /* input : Pitch delay */ Word16 T0_frac, /* input : Fractional pitch delay */ Word16 *T0_min, /* in/out: Minimum search delay */ Word16 *T0_max, /* in/out: Maximum search delay */ Word16 pit_min, /* input : Minimum pitch delay */ Word16 pit_max, /* input : Maximum pitch delay */ Word16 pit_flag, /* input : Flag for 1st subframe */ Flag overflow_carry[] ); void Dec_lag3( /* output: return integer pitch lag */ Word16 index, /* input : received pitch index */ Word16 pit_min, /* input : minimum pitch lag */ Word16 pit_max, /* input : maximum pitch lag */ Word16 i_subfr, /* input : subframe flag */ Word16 *T0, /* output: integer part of pitch lag */ Word16 *T0_frac, /* output: fractional part of pitch lag */ Flag overflow_carry[] ); Word16 Interpol_3( /* (o) : interpolated value */ Word16 *x, /* (i) : input vector */ Word16 frac /* (i) : fraction */ ); void Pred_lt_3( Word16 exc[], /* in/out: excitation buffer */ Word16 T0, /* input : integer pitch lag */ Word16 frac, /* input : fraction of lag */ Word16 L_subfr, /* input : subframe size */ Flag overflow_carry[] ); Word16 Parity_Pitch( /* output: parity bit (XOR of 6 MSB bits) */ Word16 pitch_index, /* input : index for which parity to compute */ Flag overflow_carry[] ); Word16 Check_Parity_Pitch( /* output: 0 = no error, 1= error */ Word16 pitch_index, /* input : index of parameter */ Word16 parity, /* input : parity bit */ Flag overflow_carry[] ); void Cor_h_X( Word16 h[], /* (i) Q12 :Impulse response of filters */ Word16 X[], /* (i) :Target vector */ Word16 D[], /* (o) :Correlations between h[] and D[] */ /* Normalized to 13 bits */ Flag overflow_carry[] ); /*-----------------------* * Innovative codebook. * *-----------------------*/ /* The following constants are Q15 fractions. These fractions is used to keep maximum precision on "alp" sum */ Word16 ACELP_Code_A( /* (o) :index of pulses positions */ Word16 x[], /* (i) :Target vector */ Word16 h[], /* (i) Q12 :Inpulse response of filters */ Word16 T0, /* (i) :Pitch lag */ Word16 pitch_sharp, /* (i) Q14 :Last quantized pitch gain */ Word16 code[], /* (o) Q13 :Innovative codebook */ Word16 y[], /* (o) Q12 :Filtered innovative codebook */ Word16 *sign, /* (o) :Signs of 4 pulses */ Flag overflow_carry[] ); void Decod_ACELP( Word16 sign, /* (i) : signs of 4 pulses. */ Word16 index, /* (i) : Positions of the 4 pulses. */ Word16 cod[], /* (o) Q13 : algebraic (fixed) codebook excitation */ Flag overflow_carry[] ); /*--------------------------------------------------------------------------* * LSP constant parameters * *--------------------------------------------------------------------------*/ /*-------------------------------* * LSP VQ functions. * *-------------------------------*/ void Lsf_lsp2( Word16 lsf[], /* (i) Q13 : lsf[m] (range: 0.0<=val normalized */ Flag overflow_carry[] ); void Lsp_expand_1( Word16 buf[], /* Q13 */ Word16 gap, /* Q13 */ Flag overflow_carry[] ); void Lsp_expand_2( Word16 buf[], /* Q13 */ Word16 gap, /* Q13 */ Flag overflow_carry[] ); void Lsp_expand_1_2( Word16 buf[], /* Q13 */ Word16 gap, /* Q13 */ Flag overflow_carry[] ); void Lsp_get_quant( Word16 lspcb1[][10], /* Q13 */ Word16 lspcb2[][10], /* Q13 */ Word16 code0, Word16 code1, Word16 code2, Word16 fg[][10], /* Q15 */ Word16 freq_prev[][10], /* Q13 */ Word16 lspq[], /* Q13 */ Word16 fg_sum[], /* Q15 */ Flag overflow_carry[] ); void Lsp_get_tdist( Word16 wegt[], /* normalized */ Word16 buf[], /* Q13 */ Word32 *L_tdist, /* Q27 */ Word16 rbuf[], /* Q13 */ Word16 fg_sum[], /* Q15 */ Flag overflow_carry[] ); void Lsp_last_select( Word32 L_tdist[], /* Q27 */ Word16 *mode_index, Flag overflow_carry[] ); void Lsp_pre_select( Word16 rbuf[], /* Q13 */ Word16 lspcb1[][10], /* Q13 */ Word16 *cand, Flag overflow_carry[] ); void Lsp_select_1( Word16 rbuf[], /* Q13 */ Word16 lspcb1[], /* Q13 */ Word16 wegt[], /* normalized */ Word16 lspcb2[][10], /* Q13 */ Word16 *index, Flag overflow_carry[] ); void Lsp_select_2( Word16 rbuf[], /* Q13 */ Word16 lspcb1[], /* Q13 */ Word16 wegt[], /* normalized */ Word16 lspcb2[][10], /* Q13 */ Word16 *index, Flag overflow_carry[] ); void Lsp_stability( Word16 buf[], /* Q13 */ Flag overflow_carry[] ); void Relspwed( Word16 lsp[], /* Q13 */ Word16 wegt[], /* normalized */ Word16 lspq[], /* Q13 */ Word16 lspcb1[][10], /* Q13 */ Word16 lspcb2[][10], /* Q13 */ Word16 fg[2][4][10], /* Q15 */ Word16 freq_prev[4][10], /* Q13 */ Word16 fg_sum[2][10], /* Q15 */ Word16 fg_sum_inv[2][10], /* Q12 */ Word16 code_ana[], Flag overflow_carry[] ); void Lsp_prev_compose( Word16 lsp_ele[], /* Q13 */ Word16 lsp[], /* Q13 */ Word16 fg[][10], /* Q15 */ Word16 freq_prev[][10], /* Q13 */ Word16 fg_sum[], /* Q15 */ Flag overflow_carry[] ); void Lsp_prev_extract( Word16 lsp[10], /* Q13 */ Word16 lsp_ele[10], /* Q13 */ Word16 fg[4][10], /* Q15 */ Word16 freq_prev[4][10], /* Q13 */ Word16 fg_sum_inv[10], /* Q12 */ Flag overflow_carry[] ); void Lsp_prev_update( Word16 lsp_ele[10], /* Q13 */ Word16 freq_prev[4][10] /* Q13 */ ); /*-------------------------------* * gain VQ constants. * *-------------------------------*/ /*--------------------------------------------------------------------------* * gain VQ functions. * *--------------------------------------------------------------------------*/ void Gain_predict( Word16 past_qua_en[],/* (i) Q10 :Past quantized energies */ Word16 code[], /* (i) Q13 : Innovative vector. */ Word16 L_subfr, /* (i) : Subframe length. */ Word16 *gcode0, /* (o) Qxx : Predicted codebook gain */ Word16 *exp_gcode0, /* (o) : Q-Format(gcode0) */ Flag overflow_carry[] ); void Gain_update( Word16 past_qua_en[],/* (i) Q10 :Past quantized energies */ Word32 L_gbk12, /* (i) Q13 : gbk1[indice1][1]+gbk2[indice2][1] */ Flag overflow_carry[] ); void Gain_update_erasure( Word16 past_qua_en[],/* (i) Q10 :Past quantized energies */ Flag overflow_carry[] ); void Corr_xy2( Word16 xn[], /* (i) Q0 :Target vector. */ Word16 y1[], /* (i) Q0 :Adaptive codebook. */ Word16 y2[], /* (i) Q12 :Filtered innovative vector. */ Word16 g_coeff[], /* (o) Q[exp]:Correlations between xn,y1,y2 */ Word16 exp_g_coeff[], /* (o) :Q-format of g_coeff[] */ Flag overflow_carry[] ); /*-----------------------* * Bitstream function * *-----------------------*/ void prm2bits_ld8k(Word16 prm[], Word16 bits[]); void bits2prm_ld8k(Word16 bits[], Word16 prm[]); /*-----------------------------------* * Post-filter functions. * *-----------------------------------*/ void pit_pst_filt( Word16 *signal, /* (i) : input signal */ Word16 *scal_sig, /* (i) : input signal (scaled, divided by 4) */ Word16 t0_min, /* (i) : minimum value in the searched range */ Word16 t0_max, /* (i) : maximum value in the searched range */ Word16 L_subfr, /* (i) : size of filtering */ Word16 *signal_pst, /* (o) : harmonically postfiltered signal */ Flag overflow_carry[] ); /*--------------------------------------------------------------------------* * Constants and prototypes for taming procedure. * *--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------* * Prototypes for auxiliary functions. * *--------------------------------------------------------------------------*/ //Word16 Random(Flag overflow_carry[]); /* ITU-T G.729A Speech Coder ANSI-C Source Code Version 1.1 Last modified: September 1996 Copyright (c) 1996, AT&T, France Telecom, NTT, Universite de Sherbrooke All rights reserved. */ /* Double precision operations */ void L_Extract(Word32 L_32, Word16 *hi, Word16 *lo, Flag overflow_carry[]); Word32 L_Comp(Word16 hi, Word16 lo, Flag overflow_carry[]); Word32 Mpy_32(Word16 hi1, Word16 lo1, Word16 hi2, Word16 lo2, Flag overflow_carry[]); Word32 Mpy_32_16(Word16 hi, Word16 lo, Word16 n, Flag overflow_carry[]); Word32 Div_32(Word32 L_num, Word16 denom_hi, Word16 denom_lo, Flag overflow_carry[]); typedef struct { Word16 *exc; Word16 old_exc[80+143+(10+1)]; // Excitation vector Word16 lsp_old[10]; // Lsp (Line spectral pairs) Word16 mem_syn[10]; // Filter's memory Word16 sharp; // pitch sharpening of previous frame Word16 old_T0; // integer delay of previous frame Word16 gain_code; // Code gain Word16 gain_pitch; // Pitch gain } Dec_ld8a_s; typedef struct { Word16 freq_prev[4][10]; // Q13 Word16 freq_prev_reset[10]; // Q13 Word16 prev_ma; // previous MA prediction coef. Word16 prev_lsp[10]; // previous LSP vector } LspDec_s; typedef struct { // inverse filtered synthesis (with A(z/GAMMA2_PST)) Word16 * res2; Word16 * scal_res2; Word16 res2_buf[143+40]; Word16 scal_res2_buf[143+40]; Word16 mem_syn_pst[10]; // memory of filter 1/A(z/GAMMA1_PST) Word16 mem_pre; Word16 past_gain; } Postfilt_s; // 2nd order high pass filter state variable for Pre_Process typedef struct { Word16 y2_hi, y2_lo, y1_hi, y1_lo, x0, x1; } Post_Process_s; typedef struct { unsigned short L23h : 8; unsigned short L01 : 1+7; unsigned short C1h : 5; unsigned short P0 : 1; unsigned short P1 : 8; unsigned short L23l : 2; unsigned short GAB1h: 4; unsigned short S1 : 4; unsigned short C1l : 8; unsigned short C2h : 8; unsigned short P2 : 5; unsigned short GAB1l: 3; unsigned short GAB2 : 3+4; unsigned short S2 : 4; unsigned short C2l : 5; } Bits_s; typedef struct { Flag Overflow_Carry[2]; // Flag array: Overflow_Carry[0] = Overflow, Overflow_Carry[1] = Carry Word16 *synth; // Synthesis Dec_ld8a_s Dec_ld8a; Postfilt_s Postfilt; LspDec_s LspDec; Post_Process_s Post_Process; Bits_s Bitstream; Word16 synth_buf[80+10]; // Synthesis Word16 parm[11+1]; // Synthesis parameters Word16 Az_dec[(10+1)*2]; // Decoded Az for post-filter Word16 T2[2]; // Pitch lag for 2 subframes Word16 Past_qua_en[4]; // Gain predictor, Past quantized energies = -14.0 in Q10 Word16 bad_lsf; // bad LSF indicator Word16 seed; } G729ADecoder_s; void Init_Decod_ld8a(G729ADecoder_s* pG729ADecoder); void Lsp_decw_reset(G729ADecoder_s* pG729ADecoder); void Init_Post_Filter(G729ADecoder_s* pG729ADecoder); void Post_Process(G729ADecoder_s* pG729ADecoder); int G729ADecoderInit(void* ptrG729ADecoder); Word16 Random(G729ADecoder_s* pG729ADecoder); void G729A_Decoder(void* ptrG729ADecoder, short* pSerialInput, short* pSynthOut); void Bits2prm(G729ADecoder_s* pG729ADecoder); void Decod_ld8a( Word16 parm[], /* (i) : vector of synthesis parameters parm[0] = bad frame indicator (bfi) */ Word16 synth[], /* (o) : synthesis speech */ Word16 A_t[], /* (o) : decoded LP filter in 2 subframes */ Word16 *T2, /* (o) : decoded pitch lag in 2 subframes */ G729ADecoder_s* pG729ADecoder ); void Lsp_iqua_cs( Word16 prm[], /* input : codes of the selected LSP*/ Word16 lsp_q[], /* output: Quantized LSP parameters*/ Word16 erase, /* input : frame erase information */ G729ADecoder_s* pG729ADecoder ); void D_lsp( Word16 prm[], /* (i) : indexes of the selected LSP */ Word16 lsp_q[], /* (o) Q15 : Quantized LSP parameters */ Word16 erase, /* (i) : frame erase information */ G729ADecoder_s* pG729ADecoder ); void Dec_gain( Word16 index, /* (i) : Index of quantization. */ Word16 code[], /* (i) Q13 : Innovative vector. */ Word16 L_subfr, /* (i) : Subframe length. */ Word16 bfi, /* (i) : Bad frame indicator */ Word16 *gain_pit, /* (o) Q14 : Pitch gain. */ Word16 *gain_cod, /* (o) Q1 : Code gain. */ G729ADecoder_s* pG729ADecoder ); void Post_Filter( Word16 *syn, /* in/out: synthesis speech (postfiltered is output) */ Word16 *Az_4, /* input : interpolated LPC parameters in all subframes */ Word16 *T, /* input : decoded pitch lags in all subframes */ G729ADecoder_s* pG729ADecoder ); void preemphasis( Word16 *signal, /* (i/o) : input signal overwritten by the output */ Word16 g, /* (i) Q15 : preemphasis coefficient */ Word16 L, /* (i) : size of filtering */ G729ADecoder_s* pG729ADecoder ); void agc( Word16 *sig_in, /* (i) : postfilter input signal */ Word16 *sig_out, /* (i/o) : postfilter output signal */ Word16 l_trm, /* (i) : subframe size */ G729ADecoder_s* pG729ADecoder ); /*---------------------------------------------------------------* * Postfilter constant parameters (defined in "ld8a.h") * *---------------------------------------------------------------* * L_FRAME : Frame size. * * L_SUBFR : Sub-frame size. * * M : LPC order. * * MP1 : LPC order+1 * * PIT_MAX : Maximum pitch lag. * * GAMMA2_PST : Formant postfiltering factor (numerator) * * GAMMA1_PST : Formant postfiltering factor (denominator) * * GAMMAP : Harmonic postfiltering factor * * MU : Factor for tilt compensation filter * * AGC_FAC : Factor for automatic gain control * *---------------------------------------------------------------*/ /*---------------------------------------------------------------* * Procedure Init_Post_Filter: * * ~~~~~~~~~~~~~~~~ * * Initializes the postfilter parameters: * *---------------------------------------------------------------*/ void Init_Post_Filter(G729ADecoder_s* pG729ADecoder) { pG729ADecoder->Postfilt.res2 = pG729ADecoder->Postfilt.res2_buf + 143; pG729ADecoder->Postfilt.scal_res2 = pG729ADecoder->Postfilt.scal_res2_buf + 143; memset(pG729ADecoder->Postfilt.mem_syn_pst, 0, 2*10); memset(pG729ADecoder->Postfilt.res2_buf, 0, 2*(143+40)); memset(pG729ADecoder->Postfilt.scal_res2_buf, 0, 2*(143+40)); return; } /*------------------------------------------------------------------------* * Procedure Post_Filter: * * ~~~~~~~~~~~ * *------------------------------------------------------------------------* * The postfiltering process is described as follows: * * * * - inverse filtering of syn[] through A(z/GAMMA2_PST) to get res2[] * * - use res2[] to compute pitch parameters * * - perform pitch postfiltering * * - tilt compensation filtering; 1 - MU*k*z^-1 * * - synthesis filtering through 1/A(z/GAMMA1_PST) * * - adaptive gain control * *------------------------------------------------------------------------*/ void Post_Filter( Word16 *syn, /* in/out: synthesis speech (postfiltered is output) */ Word16 *Az_4, /* input : interpolated LPC parameters in all subframes */ Word16 *T, /* input : decoded pitch lags in all subframes */ G729ADecoder_s* restrict pG729ADecoder ) { /*-------------------------------------------------------------------* * Declaration of parameters * *-------------------------------------------------------------------*/ Word16 res2_pst[40]; /* res2[] after pitch postfiltering */ Word16 syn_pst[80]; /* post filtered synthesis speech */ Word16 Ap3[(10+1)], Ap4[(10+1)]; /* bandwidth expanded LP parameters */ Word16 *Az; /* pointer to Az_4: */ /* LPC parameters in each subframe */ Word16 t0_max, t0_min; /* closed-loop pitch search range */ Word16 i_subfr; /* index for beginning of subframe */ Word16 h[22]; Word16 i, j; Word16 temp1, temp2; Word32 L_tmp; Word16 * restrict pres2; Word16 * restrict pscal_res2; pres2 = pG729ADecoder->Postfilt.res2; pscal_res2 = pG729ADecoder->Postfilt.scal_res2; /*-----------------------------------------------------* * Post filtering * *-----------------------------------------------------*/ Az = Az_4; for (i_subfr = 0; i_subfr < 80; i_subfr += 40) { /* Find pitch range t0_min - t0_max */ t0_min = (sature(*T++ -3,pG729ADecoder->Overflow_Carry)); t0_max = (sature(t0_min+6,pG729ADecoder->Overflow_Carry)); // if (sub(t0_max, PIT_MAX, pG729ADecoder->Overflow_Carry) > 0) { if (t0_max > 143) { t0_max = 143; t0_min = (sature(t0_max-6,pG729ADecoder->Overflow_Carry)); } /* Find weighted filter coefficients Ap3[] and ap[4] */ Weight_Az(Az, 18022, 10, Ap3, pG729ADecoder->Overflow_Carry); Weight_Az(Az, 22938, 10, Ap4, pG729ADecoder->Overflow_Carry); /* filtering of synthesis speech by A(z/GAMMA2_PST) to find res2[] */ Residu(Ap3, &syn[i_subfr], pG729ADecoder->Postfilt.res2, 40, pG729ADecoder->Overflow_Carry); /* scaling of "res2[]" to avoid energy overflow */ for (j=0; j<40; j++) { //pG729ADecoder->Postfilt.scal_res2[j] = shr(pG729ADecoder->Postfilt.res2[j], 2, pG729ADecoder->Overflow_Carry); //pG729ADecoder->Postfilt.scal_res2[j] = pG729ADecoder->Postfilt.res2[j]>>2; pscal_res2[j] = pres2[j]>>2; } /* pitch postfiltering */ pit_pst_filt(pG729ADecoder->Postfilt.res2, pG729ADecoder->Postfilt.scal_res2, t0_min, t0_max, 40, res2_pst, pG729ADecoder->Overflow_Carry); /* tilt compensation filter */ /* impulse response of A(z/GAMMA2_PST)/A(z/GAMMA1_PST) */ memcpy(h, Ap3, 2*(10+1)); memset(&h[10+1], 0, 2*(22-10-1)); Syn_filt(Ap4, h, h, 22, &h[10+1], 0, pG729ADecoder->Overflow_Carry); /* 1st correlation of h[] */ L_tmp = L_mult(h[0], h[0], pG729ADecoder->Overflow_Carry); /*for (i=1; iOverflow_Carry);*/ for (i=1; i<22; i++){ L_tmp = (_sadd((L_tmp),(_smpy((h[i]),(h[i]))))); if (L_tmp == (Word32)0x80000000L || L_tmp == (Word32)0x7fffffffL){ pG729ADecoder->Overflow_Carry[0] = 1; } } temp1 = ((L_tmp)>>16); L_tmp = L_mult(h[0], h[1], pG729ADecoder->Overflow_Carry); /*for (i=1; iOverflow_Carry);*/ for (i=1; i<22-1; i++){ L_tmp = (_sadd((L_tmp),(_smpy((h[i]),(h[i+1]))))); if (L_tmp == (Word32)0x80000000L || L_tmp == (Word32)0x7fffffffL){ pG729ADecoder->Overflow_Carry[0] = 1; } } temp2 = ((L_tmp)>>16); if(temp2 <= 0) { temp2 = 0; } else { temp2 = (_smpy((temp2),(26214))>>16); temp2 = div_s(temp2, temp1, pG729ADecoder->Overflow_Carry); } preemphasis(res2_pst, temp2, 40, pG729ADecoder); /* filtering through 1/A(z/GAMMA1_PST) */ Syn_filt(Ap4, res2_pst, &syn_pst[i_subfr], 40, pG729ADecoder->Postfilt.mem_syn_pst, 1, pG729ADecoder->Overflow_Carry); /* scale output to input */ agc(&syn[i_subfr], &syn_pst[i_subfr], 40, pG729ADecoder); /* update res2[] buffer; shift by L_SUBFR */ memcpy(&pG729ADecoder->Postfilt.res2[-143], &pG729ADecoder->Postfilt.res2[40-143], 2*143); memcpy(&pG729ADecoder->Postfilt.scal_res2[-143], &pG729ADecoder->Postfilt.scal_res2[40-143], 2*143); Az += (10+1); } /* update syn[] buffer */ memcpy(&syn[-10], &syn[80-10], 2*10); /* overwrite synthesis speech by postfiltered synthesis speech */ memcpy(syn, syn_pst, 2*80); return; }