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 "filterbank_internal.h"
     22 
     23 #include <assert.h>
     24 
     25 #include "codec.h"
     26 #include "filterbank_tables.h"
     27 #include "settings.h"
     28 
     29 // Declare a function pointer.
     30 AllpassFilter2FixDec16 WebRtcIsacfix_AllpassFilter2FixDec16;
     31 
     32 void WebRtcIsacfix_AllpassFilter2FixDec16C(
     33     int16_t *data_ch1,  // Input and output in channel 1, in Q0
     34     int16_t *data_ch2,  // Input and output in channel 2, in Q0
     35     const int16_t *factor_ch1,  // Scaling factor for channel 1, in Q15
     36     const int16_t *factor_ch2,  // Scaling factor for channel 2, in Q15
     37     const int length,  // Length of the data buffers
     38     int32_t *filter_state_ch1,  // Filter state for channel 1, in Q16
     39     int32_t *filter_state_ch2) {  // Filter state for channel 2, in Q16
     40   int n = 0;
     41   int32_t state0_ch1 = filter_state_ch1[0], state1_ch1 = filter_state_ch1[1];
     42   int32_t state0_ch2 = filter_state_ch2[0], state1_ch2 = filter_state_ch2[1];
     43   int16_t in_out = 0;
     44   int32_t a = 0, b = 0;
     45 
     46   // Assembly file assumption.
     47   assert(length % 2 == 0);
     48 
     49   for (n = 0; n < length; n++) {
     50     // Process channel 1:
     51     in_out = data_ch1[n];
     52     a = WEBRTC_SPL_MUL_16_16(factor_ch1[0], in_out);  // Q15 * Q0 = Q15
     53     a <<= 1;  // Q15 -> Q16
     54     b = WebRtcSpl_AddSatW32(a, state0_ch1);
     55     a = WEBRTC_SPL_MUL_16_16(-factor_ch1[0], (int16_t) (b >> 16));  // Q15
     56     state0_ch1 = WebRtcSpl_AddSatW32(a << 1, (uint32_t)in_out << 16);  // Q16
     57     in_out = (int16_t) (b >> 16);  // Save as Q0
     58 
     59     a = WEBRTC_SPL_MUL_16_16(factor_ch1[1], in_out);  // Q15 * Q0 = Q15
     60     a <<= 1; // Q15 -> Q16
     61     b = WebRtcSpl_AddSatW32(a, state1_ch1);  // Q16
     62     a = WEBRTC_SPL_MUL_16_16(-factor_ch1[1], (int16_t) (b >> 16));  // Q15
     63     state1_ch1 = WebRtcSpl_AddSatW32(a << 1, (uint32_t)in_out << 16);  // Q16
     64     data_ch1[n] = (int16_t) (b >> 16);  // Save as Q0
     65 
     66     // Process channel 2:
     67     in_out = data_ch2[n];
     68     a = WEBRTC_SPL_MUL_16_16(factor_ch2[0], in_out);  // Q15 * Q0 = Q15
     69     a <<= 1;  // Q15 -> Q16
     70     b = WebRtcSpl_AddSatW32(a, state0_ch2);  // Q16
     71     a = WEBRTC_SPL_MUL_16_16(-factor_ch2[0], (int16_t) (b >> 16));  // Q15
     72     state0_ch2 = WebRtcSpl_AddSatW32(a << 1, (uint32_t)in_out << 16);  // Q16
     73     in_out = (int16_t) (b >> 16);  // Save as Q0
     74 
     75     a = WEBRTC_SPL_MUL_16_16(factor_ch2[1], in_out);  // Q15 * Q0 = Q15
     76     a <<= 1;  // Q15 -> Q16
     77     b = WebRtcSpl_AddSatW32(a, state1_ch2);  // Q16
     78     a = WEBRTC_SPL_MUL_16_16(-factor_ch2[1], (int16_t) (b >> 16));  // Q15
     79     state1_ch2 = WebRtcSpl_AddSatW32(a << 1, (uint32_t)in_out << 16);  // Q16
     80     data_ch2[n] = (int16_t) (b >> 16);  // Save as Q0
     81   }
     82 
     83   filter_state_ch1[0] = state0_ch1;
     84   filter_state_ch1[1] = state1_ch1;
     85   filter_state_ch2[0] = state0_ch2;
     86   filter_state_ch2[1] = state1_ch2;
     87 }
     88 
     89 // Declare a function pointer.
     90 HighpassFilterFixDec32 WebRtcIsacfix_HighpassFilterFixDec32;
     91 
     92 void WebRtcIsacfix_HighpassFilterFixDec32C(int16_t *io,
     93                                            int16_t len,
     94                                            const int16_t *coefficient,
     95                                            int32_t *state)
     96 {
     97   int k;
     98   int32_t a1 = 0, b1 = 0, c = 0, in = 0;
     99   int32_t a2 = 0, b2 = 0;
    100   int32_t state0 = state[0];
    101   int32_t state1 = state[1];
    102 
    103   for (k=0; k<len; k++) {
    104     in = (int32_t)io[k];
    105 
    106 #ifdef WEBRTC_ARCH_ARM_V7
    107     {
    108       register int tmp_coeff0;
    109       register int tmp_coeff1;
    110       __asm __volatile(
    111         "ldr %[tmp_coeff0], [%[coeff]]\n\t"
    112         "ldr %[tmp_coeff1], [%[coeff], #4]\n\t"
    113         "smmulr %[a2], %[tmp_coeff0], %[state0]\n\t"
    114         "smmulr %[b2], %[tmp_coeff1], %[state1]\n\t"
    115         "ldr %[tmp_coeff0], [%[coeff], #8]\n\t"
    116         "ldr %[tmp_coeff1], [%[coeff], #12]\n\t"
    117         "smmulr %[a1], %[tmp_coeff0], %[state0]\n\t"
    118         "smmulr %[b1], %[tmp_coeff1], %[state1]\n\t"
    119         :[a2]"=&r"(a2),
    120          [b2]"=&r"(b2),
    121          [a1]"=&r"(a1),
    122          [b1]"=r"(b1),
    123          [tmp_coeff0]"=&r"(tmp_coeff0),
    124          [tmp_coeff1]"=&r"(tmp_coeff1)
    125         :[coeff]"r"(coefficient),
    126          [state0]"r"(state0),
    127          [state1]"r"(state1)
    128       );
    129     }
    130 #else
    131     /* Q35 * Q4 = Q39 ; shift 32 bit => Q7 */
    132     a1 = WEBRTC_SPL_MUL_16_32_RSFT16(coefficient[5], state0) +
    133         (WEBRTC_SPL_MUL_16_32_RSFT16(coefficient[4], state0) >> 16);
    134     b1 = WEBRTC_SPL_MUL_16_32_RSFT16(coefficient[7], state1) +
    135         (WEBRTC_SPL_MUL_16_32_RSFT16(coefficient[6], state1) >> 16);
    136 
    137     /* Q30 * Q4 = Q34 ; shift 32 bit => Q2 */
    138     a2 = WEBRTC_SPL_MUL_16_32_RSFT16(coefficient[1], state0) +
    139         (WEBRTC_SPL_MUL_16_32_RSFT16(coefficient[0], state0) >> 16);
    140     b2 = WEBRTC_SPL_MUL_16_32_RSFT16(coefficient[3], state1) +
    141         (WEBRTC_SPL_MUL_16_32_RSFT16(coefficient[2], state1) >> 16);
    142 #endif
    143 
    144     c = ((int32_t)in) + WEBRTC_SPL_RSHIFT_W32(a1+b1, 7);  // Q0
    145     io[k] = (int16_t)WebRtcSpl_SatW32ToW16(c);  // Write output as Q0.
    146 
    147     c = WEBRTC_SPL_LSHIFT_W32((int32_t)in, 2) - a2 - b2;  // In Q2.
    148     c = (int32_t)WEBRTC_SPL_SAT(536870911, c, -536870912);
    149 
    150     state1 = state0;
    151     state0 = WEBRTC_SPL_LSHIFT_W32(c, 2);  // Write state as Q4
    152   }
    153   state[0] = state0;
    154   state[1] = state1;
    155 }
    156 
    157 
    158 void WebRtcIsacfix_SplitAndFilter1(int16_t *pin,
    159                                    int16_t *LP16,
    160                                    int16_t *HP16,
    161                                    PreFiltBankstr *prefiltdata)
    162 {
    163   /* Function WebRtcIsacfix_SplitAndFilter */
    164   /* This function creates low-pass and high-pass decimated versions of part of
    165      the input signal, and part of the signal in the input 'lookahead buffer'. */
    166 
    167   int k;
    168 
    169   int16_t tempin_ch1[FRAMESAMPLES/2 + QLOOKAHEAD];
    170   int16_t tempin_ch2[FRAMESAMPLES/2 + QLOOKAHEAD];
    171   int32_t tmpState_ch1[2 * (QORDER-1)]; /* 4 */
    172   int32_t tmpState_ch2[2 * (QORDER-1)]; /* 4 */
    173 
    174   /* High pass filter */
    175   WebRtcIsacfix_HighpassFilterFixDec32(pin, FRAMESAMPLES, WebRtcIsacfix_kHpStCoeffInQ30, prefiltdata->HPstates_fix);
    176 
    177 
    178   /* First Channel */
    179   for (k=0;k<FRAMESAMPLES/2;k++) {
    180     tempin_ch1[QLOOKAHEAD + k] = pin[1+WEBRTC_SPL_MUL_16_16(2, k)];
    181   }
    182   for (k=0;k<QLOOKAHEAD;k++) {
    183     tempin_ch1[k]=prefiltdata->INLABUF1_fix[k];
    184     prefiltdata->INLABUF1_fix[k]=pin[FRAMESAMPLES+1-WEBRTC_SPL_MUL_16_16(2, QLOOKAHEAD)+WEBRTC_SPL_MUL_16_16(2, k)];
    185   }
    186 
    187   /* Second Channel.  This is exactly like the first channel, except that the
    188      even samples are now filtered instead (lower channel). */
    189   for (k=0;k<FRAMESAMPLES/2;k++) {
    190     tempin_ch2[QLOOKAHEAD+k] = pin[WEBRTC_SPL_MUL_16_16(2, k)];
    191   }
    192   for (k=0;k<QLOOKAHEAD;k++) {
    193     tempin_ch2[k]=prefiltdata->INLABUF2_fix[k];
    194     prefiltdata->INLABUF2_fix[k]=pin[FRAMESAMPLES-WEBRTC_SPL_MUL_16_16(2, QLOOKAHEAD)+WEBRTC_SPL_MUL_16_16(2, k)];
    195   }
    196 
    197 
    198   /*obtain polyphase components by forward all-pass filtering through each channel */
    199   /* The all pass filtering automatically updates the filter states which are exported in the
    200      prefiltdata structure */
    201   WebRtcIsacfix_AllpassFilter2FixDec16(tempin_ch1,
    202                                        tempin_ch2,
    203                                        WebRtcIsacfix_kUpperApFactorsQ15,
    204                                        WebRtcIsacfix_kLowerApFactorsQ15,
    205                                        FRAMESAMPLES/2,
    206                                        prefiltdata->INSTAT1_fix,
    207                                        prefiltdata->INSTAT2_fix);
    208 
    209   for (k=0;k<WEBRTC_SPL_MUL_16_16(2, (QORDER-1));k++) {
    210     tmpState_ch1[k] = prefiltdata->INSTAT1_fix[k];
    211     tmpState_ch2[k] = prefiltdata->INSTAT2_fix[k];
    212   }
    213   WebRtcIsacfix_AllpassFilter2FixDec16(tempin_ch1 + FRAMESAMPLES/2,
    214                                        tempin_ch2 + FRAMESAMPLES/2,
    215                                        WebRtcIsacfix_kUpperApFactorsQ15,
    216                                        WebRtcIsacfix_kLowerApFactorsQ15,
    217                                        QLOOKAHEAD,
    218                                        tmpState_ch1,
    219                                        tmpState_ch2);
    220 
    221   /* Now Construct low-pass and high-pass signals as combinations of polyphase components */
    222   for (k=0; k<FRAMESAMPLES/2 + QLOOKAHEAD; k++) {
    223     int32_t tmp1, tmp2, tmp3;
    224     tmp1 = (int32_t)tempin_ch1[k]; // Q0 -> Q0
    225     tmp2 = (int32_t)tempin_ch2[k]; // Q0 -> Q0
    226     tmp3 = (int32_t)WEBRTC_SPL_RSHIFT_W32((tmp1 + tmp2), 1);/* low pass signal*/
    227     LP16[k] = (int16_t)WebRtcSpl_SatW32ToW16(tmp3); /*low pass */
    228     tmp3 = (int32_t)WEBRTC_SPL_RSHIFT_W32((tmp1 - tmp2), 1);/* high pass signal*/
    229     HP16[k] = (int16_t)WebRtcSpl_SatW32ToW16(tmp3); /*high pass */
    230   }
    231 
    232 }/*end of WebRtcIsacfix_SplitAndFilter */
    233 
    234 
    235 #ifdef WEBRTC_ISAC_FIX_NB_CALLS_ENABLED
    236 
    237 /* Without lookahead */
    238 void WebRtcIsacfix_SplitAndFilter2(int16_t *pin,
    239                                    int16_t *LP16,
    240                                    int16_t *HP16,
    241                                    PreFiltBankstr *prefiltdata)
    242 {
    243   /* Function WebRtcIsacfix_SplitAndFilter2 */
    244   /* This function creates low-pass and high-pass decimated versions of part of
    245      the input signal. */
    246 
    247   int k;
    248 
    249   int16_t tempin_ch1[FRAMESAMPLES/2];
    250   int16_t tempin_ch2[FRAMESAMPLES/2];
    251 
    252 
    253   /* High pass filter */
    254   WebRtcIsacfix_HighpassFilterFixDec32(pin, FRAMESAMPLES, WebRtcIsacfix_kHpStCoeffInQ30, prefiltdata->HPstates_fix);
    255 
    256 
    257   /* First Channel */
    258   for (k=0;k<FRAMESAMPLES/2;k++) {
    259     tempin_ch1[k] = pin[1+WEBRTC_SPL_MUL_16_16(2, k)];
    260   }
    261 
    262   /* Second Channel.  This is exactly like the first channel, except that the
    263      even samples are now filtered instead (lower channel). */
    264   for (k=0;k<FRAMESAMPLES/2;k++) {
    265     tempin_ch2[k] = pin[WEBRTC_SPL_MUL_16_16(2, k)];
    266   }
    267 
    268 
    269   /*obtain polyphase components by forward all-pass filtering through each channel */
    270   /* The all pass filtering automatically updates the filter states which are exported in the
    271      prefiltdata structure */
    272   WebRtcIsacfix_AllpassFilter2FixDec16(tempin_ch1,
    273                                        tempin_ch2,
    274                                        WebRtcIsacfix_kUpperApFactorsQ15,
    275                                        WebRtcIsacfix_kLowerApFactorsQ15,
    276                                        FRAMESAMPLES/2,
    277                                        prefiltdata->INSTAT1_fix,
    278                                        prefiltdata->INSTAT2_fix);
    279 
    280   /* Now Construct low-pass and high-pass signals as combinations of polyphase components */
    281   for (k=0; k<FRAMESAMPLES/2; k++) {
    282     int32_t tmp1, tmp2, tmp3;
    283     tmp1 = (int32_t)tempin_ch1[k]; // Q0 -> Q0
    284     tmp2 = (int32_t)tempin_ch2[k]; // Q0 -> Q0
    285     tmp3 = (int32_t)WEBRTC_SPL_RSHIFT_W32((tmp1 + tmp2), 1);/* low pass signal*/
    286     LP16[k] = (int16_t)WebRtcSpl_SatW32ToW16(tmp3); /*low pass */
    287     tmp3 = (int32_t)WEBRTC_SPL_RSHIFT_W32((tmp1 - tmp2), 1);/* high pass signal*/
    288     HP16[k] = (int16_t)WebRtcSpl_SatW32ToW16(tmp3); /*high pass */
    289   }
    290 
    291 }/*end of WebRtcIsacfix_SplitAndFilter */
    292 
    293 #endif
    294 
    295 
    296 
    297 //////////////////////////////////////////////////////////
    298 ////////// Combining
    299 /* Function WebRtcIsacfix_FilterAndCombine */
    300 /* This is a decoder function that takes the decimated
    301    length FRAMESAMPLES/2 input low-pass and
    302    high-pass signals and creates a reconstructed fullband
    303    output signal of length FRAMESAMPLES. WebRtcIsacfix_FilterAndCombine
    304    is the sibling function of WebRtcIsacfix_SplitAndFilter */
    305 /* INPUTS:
    306    inLP: a length FRAMESAMPLES/2 array of input low-pass
    307    samples.
    308    inHP: a length FRAMESAMPLES/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 FRAMESAMPLES 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_FilterAndCombine1(int16_t *tempin_ch1,
    319                                      int16_t *tempin_ch2,
    320                                      int16_t *out16,
    321                                      PostFiltBankstr *postfiltdata)
    322 {
    323   int k;
    324   int16_t in[FRAMESAMPLES];
    325 
    326   /* all-pass filter the new upper and lower channel signal.
    327      For upper channel, use the all-pass filter factors that were used as a
    328      lower channel at the encoding side. So at the decoder, the corresponding
    329      all-pass filter factors for each channel are swapped.
    330      For lower channel signal, since all-pass filter factors at the decoder are
    331      swapped from the ones at the encoder, the 'upper' channel all-pass filter
    332      factors (kUpperApFactors) are used to filter this new lower channel signal.
    333   */
    334   WebRtcIsacfix_AllpassFilter2FixDec16(tempin_ch1,
    335                                        tempin_ch2,
    336                                        WebRtcIsacfix_kLowerApFactorsQ15,
    337                                        WebRtcIsacfix_kUpperApFactorsQ15,
    338                                        FRAMESAMPLES/2,
    339                                        postfiltdata->STATE_0_UPPER_fix,
    340                                        postfiltdata->STATE_0_LOWER_fix);
    341 
    342   /* Merge outputs to form the full length output signal.*/
    343   for (k=0;k<FRAMESAMPLES/2;k++) {
    344     in[WEBRTC_SPL_MUL_16_16(2, k)]=tempin_ch2[k];
    345     in[WEBRTC_SPL_MUL_16_16(2, k)+1]=tempin_ch1[k];
    346   }
    347 
    348   /* High pass filter */
    349   WebRtcIsacfix_HighpassFilterFixDec32(in, FRAMESAMPLES, WebRtcIsacfix_kHPStCoeffOut1Q30, postfiltdata->HPstates1_fix);
    350   WebRtcIsacfix_HighpassFilterFixDec32(in, FRAMESAMPLES, WebRtcIsacfix_kHPStCoeffOut2Q30, postfiltdata->HPstates2_fix);
    351 
    352   for (k=0;k<FRAMESAMPLES;k++) {
    353     out16[k] = in[k];
    354   }
    355 }
    356 
    357 
    358 #ifdef WEBRTC_ISAC_FIX_NB_CALLS_ENABLED
    359 /* Function WebRtcIsacfix_FilterAndCombine */
    360 /* This is a decoder function that takes the decimated
    361    length len/2 input low-pass and
    362    high-pass signals and creates a reconstructed fullband
    363    output signal of length len. WebRtcIsacfix_FilterAndCombine
    364    is the sibling function of WebRtcIsacfix_SplitAndFilter */
    365 /* INPUTS:
    366    inLP: a length len/2 array of input low-pass
    367    samples.
    368    inHP: a length len/2 array of input high-pass
    369    samples.
    370    postfiltdata: input data structure containing the filterbank
    371    states from the previous decoding iteration.
    372    OUTPUTS:
    373    Out: a length len array of output reconstructed
    374    samples (fullband) based on the input low-pass and
    375    high-pass signals.
    376    postfiltdata: the input data structure containing the filterbank
    377    states is updated for the next decoding iteration */
    378 void WebRtcIsacfix_FilterAndCombine2(int16_t *tempin_ch1,
    379                                      int16_t *tempin_ch2,
    380                                      int16_t *out16,
    381                                      PostFiltBankstr *postfiltdata,
    382                                      int16_t len)
    383 {
    384   int k;
    385   int16_t in[FRAMESAMPLES];
    386 
    387   /* all-pass filter the new upper and lower channel signal.
    388      For upper channel, use the all-pass filter factors that were used as a
    389      lower channel at the encoding side. So at the decoder, the corresponding
    390      all-pass filter factors for each channel are swapped.
    391      For lower channel signal, since all-pass filter factors at the decoder are
    392      swapped from the ones at the encoder, the 'upper' channel all-pass filter
    393      factors (kUpperApFactors) are used to filter this new lower channel signal.
    394   */
    395   WebRtcIsacfix_AllpassFilter2FixDec16(tempin_ch1,
    396                                        tempin_ch2,
    397                                        WebRtcIsacfix_kLowerApFactorsQ15,
    398                                        WebRtcIsacfix_kUpperApFactorsQ15,
    399                                        len / 2,
    400                                        postfiltdata->STATE_0_UPPER_fix,
    401                                        postfiltdata->STATE_0_LOWER_fix);
    402 
    403   /* Merge outputs to form the full length output signal.*/
    404   for (k=0;k<len/2;k++) {
    405     in[WEBRTC_SPL_MUL_16_16(2, k)]=tempin_ch2[k];
    406     in[WEBRTC_SPL_MUL_16_16(2, k)+1]=tempin_ch1[k];
    407   }
    408 
    409   /* High pass filter */
    410   WebRtcIsacfix_HighpassFilterFixDec32(in, len, WebRtcIsacfix_kHPStCoeffOut1Q30, postfiltdata->HPstates1_fix);
    411   WebRtcIsacfix_HighpassFilterFixDec32(in, len, WebRtcIsacfix_kHPStCoeffOut2Q30, postfiltdata->HPstates2_fix);
    412 
    413   for (k=0;k<len;k++) {
    414     out16[k] = in[k];
    415   }
    416 }
    417 
    418 #endif
    419