Home | History | Annotate | Download | only in signal_processing
      1 /*
      2  *  Copyright (c) 2011 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  * This file contains the splitting filter functions.
     13  *
     14  */
     15 
     16 #include "signal_processing_library.h"
     17 
     18 // Number of samples in a low/high-band frame.
     19 enum
     20 {
     21     kBandFrameLength = 160
     22 };
     23 
     24 // QMF filter coefficients in Q16.
     25 static const WebRtc_UWord16 WebRtcSpl_kAllPassFilter1[3] = {6418, 36982, 57261};
     26 static const WebRtc_UWord16 WebRtcSpl_kAllPassFilter2[3] = {21333, 49062, 63010};
     27 
     28 ///////////////////////////////////////////////////////////////////////////////////////////////
     29 // WebRtcSpl_AllPassQMF(...)
     30 //
     31 // Allpass filter used by the analysis and synthesis parts of the QMF filter.
     32 //
     33 // Input:
     34 //    - in_data             : Input data sequence (Q10)
     35 //    - data_length         : Length of data sequence (>2)
     36 //    - filter_coefficients : Filter coefficients (length 3, Q16)
     37 //
     38 // Input & Output:
     39 //    - filter_state        : Filter state (length 6, Q10).
     40 //
     41 // Output:
     42 //    - out_data            : Output data sequence (Q10), length equal to
     43 //                            |data_length|
     44 //
     45 
     46 void WebRtcSpl_AllPassQMF(WebRtc_Word32* in_data, const WebRtc_Word16 data_length,
     47                           WebRtc_Word32* out_data, const WebRtc_UWord16* filter_coefficients,
     48                           WebRtc_Word32* filter_state)
     49 {
     50     // The procedure is to filter the input with three first order all pass filters
     51     // (cascade operations).
     52     //
     53     //         a_3 + q^-1    a_2 + q^-1    a_1 + q^-1
     54     // y[n] =  -----------   -----------   -----------   x[n]
     55     //         1 + a_3q^-1   1 + a_2q^-1   1 + a_1q^-1
     56     //
     57     // The input vector |filter_coefficients| includes these three filter coefficients.
     58     // The filter state contains the in_data state, in_data[-1], followed by
     59     // the out_data state, out_data[-1]. This is repeated for each cascade.
     60     // The first cascade filter will filter the |in_data| and store the output in
     61     // |out_data|. The second will the take the |out_data| as input and make an
     62     // intermediate storage in |in_data|, to save memory. The third, and final, cascade
     63     // filter operation takes the |in_data| (which is the output from the previous cascade
     64     // filter) and store the output in |out_data|.
     65     // Note that the input vector values are changed during the process.
     66     WebRtc_Word16 k;
     67     WebRtc_Word32 diff;
     68     // First all-pass cascade; filter from in_data to out_data.
     69 
     70     // Let y_i[n] indicate the output of cascade filter i (with filter coefficient a_i) at
     71     // vector position n. Then the final output will be y[n] = y_3[n]
     72 
     73     // First loop, use the states stored in memory.
     74     // "diff" should be safe from wrap around since max values are 2^25
     75     diff = WEBRTC_SPL_SUB_SAT_W32(in_data[0], filter_state[1]); // = (x[0] - y_1[-1])
     76     // y_1[0] =  x[-1] + a_1 * (x[0] - y_1[-1])
     77     out_data[0] = WEBRTC_SPL_SCALEDIFF32(filter_coefficients[0], diff, filter_state[0]);
     78 
     79     // For the remaining loops, use previous values.
     80     for (k = 1; k < data_length; k++)
     81     {
     82         diff = WEBRTC_SPL_SUB_SAT_W32(in_data[k], out_data[k - 1]); // = (x[n] - y_1[n-1])
     83         // y_1[n] =  x[n-1] + a_1 * (x[n] - y_1[n-1])
     84         out_data[k] = WEBRTC_SPL_SCALEDIFF32(filter_coefficients[0], diff, in_data[k - 1]);
     85     }
     86 
     87     // Update states.
     88     filter_state[0] = in_data[data_length - 1]; // x[N-1], becomes x[-1] next time
     89     filter_state[1] = out_data[data_length - 1]; // y_1[N-1], becomes y_1[-1] next time
     90 
     91     // Second all-pass cascade; filter from out_data to in_data.
     92     diff = WEBRTC_SPL_SUB_SAT_W32(out_data[0], filter_state[3]); // = (y_1[0] - y_2[-1])
     93     // y_2[0] =  y_1[-1] + a_2 * (y_1[0] - y_2[-1])
     94     in_data[0] = WEBRTC_SPL_SCALEDIFF32(filter_coefficients[1], diff, filter_state[2]);
     95     for (k = 1; k < data_length; k++)
     96     {
     97         diff = WEBRTC_SPL_SUB_SAT_W32(out_data[k], in_data[k - 1]); // =(y_1[n] - y_2[n-1])
     98         // y_2[0] =  y_1[-1] + a_2 * (y_1[0] - y_2[-1])
     99         in_data[k] = WEBRTC_SPL_SCALEDIFF32(filter_coefficients[1], diff, out_data[k-1]);
    100     }
    101 
    102     filter_state[2] = out_data[data_length - 1]; // y_1[N-1], becomes y_1[-1] next time
    103     filter_state[3] = in_data[data_length - 1]; // y_2[N-1], becomes y_2[-1] next time
    104 
    105     // Third all-pass cascade; filter from in_data to out_data.
    106     diff = WEBRTC_SPL_SUB_SAT_W32(in_data[0], filter_state[5]); // = (y_2[0] - y[-1])
    107     // y[0] =  y_2[-1] + a_3 * (y_2[0] - y[-1])
    108     out_data[0] = WEBRTC_SPL_SCALEDIFF32(filter_coefficients[2], diff, filter_state[4]);
    109     for (k = 1; k < data_length; k++)
    110     {
    111         diff = WEBRTC_SPL_SUB_SAT_W32(in_data[k], out_data[k - 1]); // = (y_2[n] - y[n-1])
    112         // y[n] =  y_2[n-1] + a_3 * (y_2[n] - y[n-1])
    113         out_data[k] = WEBRTC_SPL_SCALEDIFF32(filter_coefficients[2], diff, in_data[k-1]);
    114     }
    115     filter_state[4] = in_data[data_length - 1]; // y_2[N-1], becomes y_2[-1] next time
    116     filter_state[5] = out_data[data_length - 1]; // y[N-1], becomes y[-1] next time
    117 }
    118 
    119 void WebRtcSpl_AnalysisQMF(const WebRtc_Word16* in_data, WebRtc_Word16* low_band,
    120                            WebRtc_Word16* high_band, WebRtc_Word32* filter_state1,
    121                            WebRtc_Word32* filter_state2)
    122 {
    123     WebRtc_Word16 i;
    124     WebRtc_Word16 k;
    125     WebRtc_Word32 tmp;
    126     WebRtc_Word32 half_in1[kBandFrameLength];
    127     WebRtc_Word32 half_in2[kBandFrameLength];
    128     WebRtc_Word32 filter1[kBandFrameLength];
    129     WebRtc_Word32 filter2[kBandFrameLength];
    130 
    131     // Split even and odd samples. Also shift them to Q10.
    132     for (i = 0, k = 0; i < kBandFrameLength; i++, k += 2)
    133     {
    134         half_in2[i] = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)in_data[k], 10);
    135         half_in1[i] = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)in_data[k + 1], 10);
    136     }
    137 
    138     // All pass filter even and odd samples, independently.
    139     WebRtcSpl_AllPassQMF(half_in1, kBandFrameLength, filter1, WebRtcSpl_kAllPassFilter1,
    140                          filter_state1);
    141     WebRtcSpl_AllPassQMF(half_in2, kBandFrameLength, filter2, WebRtcSpl_kAllPassFilter2,
    142                          filter_state2);
    143 
    144     // Take the sum and difference of filtered version of odd and even
    145     // branches to get upper & lower band.
    146     for (i = 0; i < kBandFrameLength; i++)
    147     {
    148         tmp = filter1[i] + filter2[i] + 1024;
    149         tmp = WEBRTC_SPL_RSHIFT_W32(tmp, 11);
    150         low_band[i] = WebRtcSpl_SatW32ToW16(tmp);
    151 
    152         tmp = filter1[i] - filter2[i] + 1024;
    153         tmp = WEBRTC_SPL_RSHIFT_W32(tmp, 11);
    154         high_band[i] = WebRtcSpl_SatW32ToW16(tmp);
    155     }
    156 }
    157 
    158 void WebRtcSpl_SynthesisQMF(const WebRtc_Word16* low_band, const WebRtc_Word16* high_band,
    159                             WebRtc_Word16* out_data, WebRtc_Word32* filter_state1,
    160                             WebRtc_Word32* filter_state2)
    161 {
    162     WebRtc_Word32 tmp;
    163     WebRtc_Word32 half_in1[kBandFrameLength];
    164     WebRtc_Word32 half_in2[kBandFrameLength];
    165     WebRtc_Word32 filter1[kBandFrameLength];
    166     WebRtc_Word32 filter2[kBandFrameLength];
    167     WebRtc_Word16 i;
    168     WebRtc_Word16 k;
    169 
    170     // Obtain the sum and difference channels out of upper and lower-band channels.
    171     // Also shift to Q10 domain.
    172     for (i = 0; i < kBandFrameLength; i++)
    173     {
    174         tmp = (WebRtc_Word32)low_band[i] + (WebRtc_Word32)high_band[i];
    175         half_in1[i] = WEBRTC_SPL_LSHIFT_W32(tmp, 10);
    176         tmp = (WebRtc_Word32)low_band[i] - (WebRtc_Word32)high_band[i];
    177         half_in2[i] = WEBRTC_SPL_LSHIFT_W32(tmp, 10);
    178     }
    179 
    180     // all-pass filter the sum and difference channels
    181     WebRtcSpl_AllPassQMF(half_in1, kBandFrameLength, filter1, WebRtcSpl_kAllPassFilter2,
    182                          filter_state1);
    183     WebRtcSpl_AllPassQMF(half_in2, kBandFrameLength, filter2, WebRtcSpl_kAllPassFilter1,
    184                          filter_state2);
    185 
    186     // The filtered signals are even and odd samples of the output. Combine
    187     // them. The signals are Q10 should shift them back to Q0 and take care of
    188     // saturation.
    189     for (i = 0, k = 0; i < kBandFrameLength; i++)
    190     {
    191         tmp = WEBRTC_SPL_RSHIFT_W32(filter2[i] + 512, 10);
    192         out_data[k++] = WebRtcSpl_SatW32ToW16(tmp);
    193 
    194         tmp = WEBRTC_SPL_RSHIFT_W32(filter1[i] + 512, 10);
    195         out_data[k++] = WebRtcSpl_SatW32ToW16(tmp);
    196     }
    197 
    198 }
    199