Home | History | Annotate | Download | only in source
      1 /*
      2  *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
      3  *
      4  *  Use of this source code is governed by a BSD-style license
      5  *  that can be found in the LICENSE file in the root of the source
      6  *  tree. An additional intellectual property rights grant can be found
      7  *  in the file PATENTS.  All contributing project authors may
      8  *  be found in the AUTHORS file in the root of the source tree.
      9  */
     10 
     11 /*
     12  * filterbanks.c
     13  *
     14  * This file contains function
     15  * WebRtcIsacfix_SplitAndFilter, and WebRtcIsacfix_FilterAndCombine
     16  * which implement filterbanks that produce decimated lowpass and
     17  * highpass versions of a signal, and performs reconstruction.
     18  *
     19  */
     20 
     21 #include "codec.h"
     22 #include "filterbank_internal.h"
     23 #include "filterbank_tables.h"
     24 #include "settings.h"
     25 
     26 
     27 static void AllpassFilter2FixDec16(WebRtc_Word16 *InOut16, //Q0
     28                                    const WebRtc_Word16 *APSectionFactors, //Q15
     29                                    WebRtc_Word16 lengthInOut,
     30                                    WebRtc_Word16 NumberOfSections,
     31                                    WebRtc_Word32 *FilterState) //Q16
     32 {
     33   int n, j;
     34   WebRtc_Word32 a, b;
     35 
     36   for (j=0; j<NumberOfSections; j++) {
     37     for (n=0;n<lengthInOut;n++) {
     38 
     39 
     40       a = WEBRTC_SPL_MUL_16_16(APSectionFactors[j], InOut16[n]); //Q15*Q0=Q15
     41       a = WEBRTC_SPL_LSHIFT_W32(a, 1); // Q15 -> Q16
     42       b = WEBRTC_SPL_ADD_SAT_W32(a, FilterState[j]); //Q16+Q16=Q16
     43       a = WEBRTC_SPL_MUL_16_16_RSFT(-APSectionFactors[j], (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(b, 16), 0); //Q15*Q0=Q15
     44       FilterState[j] = WEBRTC_SPL_ADD_SAT_W32(WEBRTC_SPL_LSHIFT_W32(a,1), WEBRTC_SPL_LSHIFT_W32((WebRtc_UWord32)InOut16[n],16)); // Q15<<1 + Q0<<16 = Q16 + Q16 = Q16
     45       InOut16[n] = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(b, 16); //Save as Q0
     46 
     47     }
     48   }
     49 
     50 }
     51 
     52 
     53 void WebRtcIsacfix_HighpassFilterFixDec32(int16_t *io,
     54                                           int16_t len,
     55                                           const int16_t *coefficient,
     56                                           int32_t *state)
     57 {
     58   int k;
     59   WebRtc_Word32 a1 = 0, b1 = 0, c = 0, in = 0;
     60   WebRtc_Word32 a2 = 0, b2 = 0;
     61   WebRtc_Word32 state0 = state[0];
     62   WebRtc_Word32 state1 = state[1];
     63 
     64   for (k=0; k<len; k++) {
     65     in = (WebRtc_Word32)io[k];
     66 
     67 #ifdef WEBRTC_ARCH_ARM_V7
     68     {
     69       int tmp_coeff0 = 0;
     70       int tmp_coeff1 = 0;
     71       __asm __volatile(
     72         "ldr %[tmp_coeff0], [%[coeff]]\n\t"
     73         "ldr %[tmp_coeff1], [%[coeff], #4]\n\t"
     74         "smmulr %[a2], %[tmp_coeff0], %[state0]\n\t"
     75         "smmulr %[b2], %[tmp_coeff1], %[state1]\n\t"
     76         "ldr %[tmp_coeff0], [%[coeff], #8]\n\t"
     77         "ldr %[tmp_coeff1], [%[coeff], #12]\n\t"
     78         "smmulr %[a1], %[tmp_coeff0], %[state0]\n\t"
     79         "smmulr %[b1], %[tmp_coeff1], %[state1]\n\t"
     80         :[a2]"+r"(a2),
     81          [b2]"+r"(b2),
     82          [a1]"+r"(a1),
     83          [b1]"+r"(b1),
     84          [tmp_coeff0]"+r"(tmp_coeff0),
     85          [tmp_coeff1]"+r"(tmp_coeff1)
     86         :[coeff]"r"(coefficient),
     87          [state0]"r"(state0),
     88          [state1]"r"(state1)
     89       );
     90     }
     91 #else
     92     /* Q35 * Q4 = Q39 ; shift 32 bit => Q7 */
     93     a1 = WEBRTC_SPL_MUL_32_32_RSFT32(coefficient[5], coefficient[4], state0);
     94     b1 = WEBRTC_SPL_MUL_32_32_RSFT32(coefficient[7], coefficient[6], state1);
     95 
     96     /* Q30 * Q4 = Q34 ; shift 32 bit => Q2 */
     97     a2 = WEBRTC_SPL_MUL_32_32_RSFT32(coefficient[1], coefficient[0], state0);
     98     b2 = WEBRTC_SPL_MUL_32_32_RSFT32(coefficient[3], coefficient[2], state1);
     99 #endif
    100 
    101     c = ((WebRtc_Word32)in) + WEBRTC_SPL_RSHIFT_W32(a1+b1, 7);  // Q0
    102     io[k] = (WebRtc_Word16)WebRtcSpl_SatW32ToW16(c);  // Write output as Q0.
    103 
    104     c = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)in, 2) - a2 - b2;  // In Q2.
    105     c = (WebRtc_Word32)WEBRTC_SPL_SAT(536870911, c, -536870912);
    106 
    107     state1 = state0;
    108     state0 = WEBRTC_SPL_LSHIFT_W32(c, 2); // Write state as Q4
    109   }
    110   state[0] = state0;
    111   state[1] = state1;
    112 }
    113 
    114 
    115 void WebRtcIsacfix_SplitAndFilter1(WebRtc_Word16 *pin,
    116                                    WebRtc_Word16 *LP16,
    117                                    WebRtc_Word16 *HP16,
    118                                    PreFiltBankstr *prefiltdata)
    119 {
    120   /* Function WebRtcIsacfix_SplitAndFilter */
    121   /* This function creates low-pass and high-pass decimated versions of part of
    122      the input signal, and part of the signal in the input 'lookahead buffer'. */
    123 
    124   int k;
    125 
    126   WebRtc_Word16 tempin_ch1[FRAMESAMPLES/2 + QLOOKAHEAD];
    127   WebRtc_Word16 tempin_ch2[FRAMESAMPLES/2 + QLOOKAHEAD];
    128   WebRtc_Word32 tmpState[WEBRTC_SPL_MUL_16_16(2,(QORDER-1))]; /* 4 */
    129 
    130 
    131   /* High pass filter */
    132   WebRtcIsacfix_HighpassFilterFixDec32(pin, FRAMESAMPLES, WebRtcIsacfix_kHpStCoeffInQ30, prefiltdata->HPstates_fix);
    133 
    134 
    135   /* First Channel */
    136   for (k=0;k<FRAMESAMPLES/2;k++) {
    137     tempin_ch1[QLOOKAHEAD + k] = pin[1+WEBRTC_SPL_MUL_16_16(2, k)];
    138   }
    139   for (k=0;k<QLOOKAHEAD;k++) {
    140     tempin_ch1[k]=prefiltdata->INLABUF1_fix[k];
    141     prefiltdata->INLABUF1_fix[k]=pin[FRAMESAMPLES+1-WEBRTC_SPL_MUL_16_16(2, QLOOKAHEAD)+WEBRTC_SPL_MUL_16_16(2, k)];
    142   }
    143 
    144   /* Second Channel.  This is exactly like the first channel, except that the
    145      even samples are now filtered instead (lower channel). */
    146   for (k=0;k<FRAMESAMPLES/2;k++) {
    147     tempin_ch2[QLOOKAHEAD+k] = pin[WEBRTC_SPL_MUL_16_16(2, k)];
    148   }
    149   for (k=0;k<QLOOKAHEAD;k++) {
    150     tempin_ch2[k]=prefiltdata->INLABUF2_fix[k];
    151     prefiltdata->INLABUF2_fix[k]=pin[FRAMESAMPLES-WEBRTC_SPL_MUL_16_16(2, QLOOKAHEAD)+WEBRTC_SPL_MUL_16_16(2, k)];
    152   }
    153 
    154 
    155   /*obtain polyphase components by forward all-pass filtering through each channel */
    156   /* The all pass filtering automatically updates the filter states which are exported in the
    157      prefiltdata structure */
    158   AllpassFilter2FixDec16(tempin_ch1,WebRtcIsacfix_kUpperApFactorsQ15, FRAMESAMPLES/2 , NUMBEROFCHANNELAPSECTIONS, prefiltdata->INSTAT1_fix);
    159   AllpassFilter2FixDec16(tempin_ch2,WebRtcIsacfix_kLowerApFactorsQ15, FRAMESAMPLES/2 , NUMBEROFCHANNELAPSECTIONS, prefiltdata->INSTAT2_fix);
    160 
    161   for (k=0;k<WEBRTC_SPL_MUL_16_16(2, (QORDER-1));k++)
    162     tmpState[k] = prefiltdata->INSTAT1_fix[k];
    163   AllpassFilter2FixDec16(tempin_ch1 + FRAMESAMPLES/2,WebRtcIsacfix_kUpperApFactorsQ15, QLOOKAHEAD , NUMBEROFCHANNELAPSECTIONS, tmpState);
    164   for (k=0;k<WEBRTC_SPL_MUL_16_16(2, (QORDER-1));k++)
    165     tmpState[k] = prefiltdata->INSTAT2_fix[k];
    166   AllpassFilter2FixDec16(tempin_ch2 + FRAMESAMPLES/2,WebRtcIsacfix_kLowerApFactorsQ15, QLOOKAHEAD , NUMBEROFCHANNELAPSECTIONS, tmpState);
    167 
    168 
    169   /* Now Construct low-pass and high-pass signals as combinations of polyphase components */
    170   for (k=0; k<FRAMESAMPLES/2 + QLOOKAHEAD; k++) {
    171     WebRtc_Word32 tmp1, tmp2, tmp3;
    172     tmp1 = (WebRtc_Word32)tempin_ch1[k]; // Q0 -> Q0
    173     tmp2 = (WebRtc_Word32)tempin_ch2[k]; // Q0 -> Q0
    174     tmp3 = (WebRtc_Word32)WEBRTC_SPL_RSHIFT_W32((tmp1 + tmp2), 1);/* low pass signal*/
    175     LP16[k] = (WebRtc_Word16)WebRtcSpl_SatW32ToW16(tmp3); /*low pass */
    176     tmp3 = (WebRtc_Word32)WEBRTC_SPL_RSHIFT_W32((tmp1 - tmp2), 1);/* high pass signal*/
    177     HP16[k] = (WebRtc_Word16)WebRtcSpl_SatW32ToW16(tmp3); /*high pass */
    178   }
    179 
    180 }/*end of WebRtcIsacfix_SplitAndFilter */
    181 
    182 
    183 #ifdef WEBRTC_ISAC_FIX_NB_CALLS_ENABLED
    184 
    185 /* Without lookahead */
    186 void WebRtcIsacfix_SplitAndFilter2(WebRtc_Word16 *pin,
    187                                    WebRtc_Word16 *LP16,
    188                                    WebRtc_Word16 *HP16,
    189                                    PreFiltBankstr *prefiltdata)
    190 {
    191   /* Function WebRtcIsacfix_SplitAndFilter2 */
    192   /* This function creates low-pass and high-pass decimated versions of part of
    193      the input signal. */
    194 
    195   int k;
    196 
    197   WebRtc_Word16 tempin_ch1[FRAMESAMPLES/2];
    198   WebRtc_Word16 tempin_ch2[FRAMESAMPLES/2];
    199 
    200 
    201   /* High pass filter */
    202   WebRtcIsacfix_HighpassFilterFixDec32(pin, FRAMESAMPLES, WebRtcIsacfix_kHpStCoeffInQ30, prefiltdata->HPstates_fix);
    203 
    204 
    205   /* First Channel */
    206   for (k=0;k<FRAMESAMPLES/2;k++) {
    207     tempin_ch1[k] = pin[1+WEBRTC_SPL_MUL_16_16(2, k)];
    208   }
    209 
    210   /* Second Channel.  This is exactly like the first channel, except that the
    211      even samples are now filtered instead (lower channel). */
    212   for (k=0;k<FRAMESAMPLES/2;k++) {
    213     tempin_ch2[k] = pin[WEBRTC_SPL_MUL_16_16(2, k)];
    214   }
    215 
    216 
    217   /*obtain polyphase components by forward all-pass filtering through each channel */
    218   /* The all pass filtering automatically updates the filter states which are exported in the
    219      prefiltdata structure */
    220   AllpassFilter2FixDec16(tempin_ch1,WebRtcIsacfix_kUpperApFactorsQ15, FRAMESAMPLES/2 , NUMBEROFCHANNELAPSECTIONS, prefiltdata->INSTAT1_fix);
    221   AllpassFilter2FixDec16(tempin_ch2,WebRtcIsacfix_kLowerApFactorsQ15, FRAMESAMPLES/2 , NUMBEROFCHANNELAPSECTIONS, prefiltdata->INSTAT2_fix);
    222 
    223 
    224   /* Now Construct low-pass and high-pass signals as combinations of polyphase components */
    225   for (k=0; k<FRAMESAMPLES/2; k++) {
    226     WebRtc_Word32 tmp1, tmp2, tmp3;
    227     tmp1 = (WebRtc_Word32)tempin_ch1[k]; // Q0 -> Q0
    228     tmp2 = (WebRtc_Word32)tempin_ch2[k]; // Q0 -> Q0
    229     tmp3 = (WebRtc_Word32)WEBRTC_SPL_RSHIFT_W32((tmp1 + tmp2), 1);/* low pass signal*/
    230     LP16[k] = (WebRtc_Word16)WebRtcSpl_SatW32ToW16(tmp3); /*low pass */
    231     tmp3 = (WebRtc_Word32)WEBRTC_SPL_RSHIFT_W32((tmp1 - tmp2), 1);/* high pass signal*/
    232     HP16[k] = (WebRtc_Word16)WebRtcSpl_SatW32ToW16(tmp3); /*high pass */
    233   }
    234 
    235 }/*end of WebRtcIsacfix_SplitAndFilter */
    236 
    237 #endif
    238 
    239 
    240 
    241 //////////////////////////////////////////////////////////
    242 ////////// Combining
    243 /* Function WebRtcIsacfix_FilterAndCombine */
    244 /* This is a decoder function that takes the decimated
    245    length FRAMESAMPLES/2 input low-pass and
    246    high-pass signals and creates a reconstructed fullband
    247    output signal of length FRAMESAMPLES. WebRtcIsacfix_FilterAndCombine
    248    is the sibling function of WebRtcIsacfix_SplitAndFilter */
    249 /* INPUTS:
    250    inLP: a length FRAMESAMPLES/2 array of input low-pass
    251    samples.
    252    inHP: a length FRAMESAMPLES/2 array of input high-pass
    253    samples.
    254    postfiltdata: input data structure containing the filterbank
    255    states from the previous decoding iteration.
    256    OUTPUTS:
    257    Out: a length FRAMESAMPLES array of output reconstructed
    258    samples (fullband) based on the input low-pass and
    259    high-pass signals.
    260    postfiltdata: the input data structure containing the filterbank
    261    states is updated for the next decoding iteration */
    262 void WebRtcIsacfix_FilterAndCombine1(WebRtc_Word16 *tempin_ch1,
    263                                      WebRtc_Word16 *tempin_ch2,
    264                                      WebRtc_Word16 *out16,
    265                                      PostFiltBankstr *postfiltdata)
    266 {
    267   int k;
    268   WebRtc_Word16 in[FRAMESAMPLES];
    269 
    270   /* all-pass filter the new upper channel signal. HOWEVER, use the all-pass filter factors
    271      that were used as a lower channel at the encoding side.  So at the decoder, the
    272      corresponding all-pass filter factors for each channel are swapped.*/
    273 
    274   AllpassFilter2FixDec16(tempin_ch1, WebRtcIsacfix_kLowerApFactorsQ15, FRAMESAMPLES/2, NUMBEROFCHANNELAPSECTIONS,postfiltdata->STATE_0_UPPER_fix);
    275 
    276   /* Now, all-pass filter the new lower channel signal. But since all-pass filter factors
    277      at the decoder are swapped from the ones at the encoder, the 'upper' channel
    278      all-pass filter factors (kUpperApFactors) are used to filter this new lower channel signal */
    279 
    280   AllpassFilter2FixDec16(tempin_ch2, WebRtcIsacfix_kUpperApFactorsQ15, FRAMESAMPLES/2, NUMBEROFCHANNELAPSECTIONS,postfiltdata->STATE_0_LOWER_fix);
    281 
    282   /* Merge outputs to form the full length output signal.*/
    283   for (k=0;k<FRAMESAMPLES/2;k++) {
    284     in[WEBRTC_SPL_MUL_16_16(2, k)]=tempin_ch2[k];
    285     in[WEBRTC_SPL_MUL_16_16(2, k)+1]=tempin_ch1[k];
    286   }
    287 
    288   /* High pass filter */
    289   WebRtcIsacfix_HighpassFilterFixDec32(in, FRAMESAMPLES, WebRtcIsacfix_kHPStCoeffOut1Q30, postfiltdata->HPstates1_fix);
    290   WebRtcIsacfix_HighpassFilterFixDec32(in, FRAMESAMPLES, WebRtcIsacfix_kHPStCoeffOut2Q30, postfiltdata->HPstates2_fix);
    291 
    292   for (k=0;k<FRAMESAMPLES;k++) {
    293     out16[k] = in[k];
    294   }
    295 }
    296 
    297 
    298 #ifdef WEBRTC_ISAC_FIX_NB_CALLS_ENABLED
    299 /* Function WebRtcIsacfix_FilterAndCombine */
    300 /* This is a decoder function that takes the decimated
    301    length len/2 input low-pass and
    302    high-pass signals and creates a reconstructed fullband
    303    output signal of length len. WebRtcIsacfix_FilterAndCombine
    304    is the sibling function of WebRtcIsacfix_SplitAndFilter */
    305 /* INPUTS:
    306    inLP: a length len/2 array of input low-pass
    307    samples.
    308    inHP: a length len/2 array of input high-pass
    309    samples.
    310    postfiltdata: input data structure containing the filterbank
    311    states from the previous decoding iteration.
    312    OUTPUTS:
    313    Out: a length len array of output reconstructed
    314    samples (fullband) based on the input low-pass and
    315    high-pass signals.
    316    postfiltdata: the input data structure containing the filterbank
    317    states is updated for the next decoding iteration */
    318 void WebRtcIsacfix_FilterAndCombine2(WebRtc_Word16 *tempin_ch1,
    319                                      WebRtc_Word16 *tempin_ch2,
    320                                      WebRtc_Word16 *out16,
    321                                      PostFiltBankstr *postfiltdata,
    322                                      WebRtc_Word16 len)
    323 {
    324   int k;
    325   WebRtc_Word16 in[FRAMESAMPLES];
    326 
    327   /* all-pass filter the new upper channel signal. HOWEVER, use the all-pass filter factors
    328      that were used as a lower channel at the encoding side.  So at the decoder, the
    329      corresponding all-pass filter factors for each channel are swapped.*/
    330 
    331   AllpassFilter2FixDec16(tempin_ch1, WebRtcIsacfix_kLowerApFactorsQ15,(WebRtc_Word16) (len/2), NUMBEROFCHANNELAPSECTIONS,postfiltdata->STATE_0_UPPER_fix);
    332 
    333   /* Now, all-pass filter the new lower channel signal. But since all-pass filter factors
    334      at the decoder are swapped from the ones at the encoder, the 'upper' channel
    335      all-pass filter factors (kUpperApFactors) are used to filter this new lower channel signal */
    336 
    337   AllpassFilter2FixDec16(tempin_ch2, WebRtcIsacfix_kUpperApFactorsQ15, (WebRtc_Word16) (len/2), NUMBEROFCHANNELAPSECTIONS,postfiltdata->STATE_0_LOWER_fix);
    338 
    339   /* Merge outputs to form the full length output signal.*/
    340   for (k=0;k<len/2;k++) {
    341     in[WEBRTC_SPL_MUL_16_16(2, k)]=tempin_ch2[k];
    342     in[WEBRTC_SPL_MUL_16_16(2, k)+1]=tempin_ch1[k];
    343   }
    344 
    345   /* High pass filter */
    346   WebRtcIsacfix_HighpassFilterFixDec32(in, len, WebRtcIsacfix_kHPStCoeffOut1Q30, postfiltdata->HPstates1_fix);
    347   WebRtcIsacfix_HighpassFilterFixDec32(in, len, WebRtcIsacfix_kHPStCoeffOut2Q30, postfiltdata->HPstates2_fix);
    348 
    349   for (k=0;k<len;k++) {
    350     out16[k] = in[k];
    351   }
    352 }
    353 
    354 #endif
    355