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 /*
     13  * This file contains the resampling functions between 48, 44, 32 and 24 kHz.
     14  * The description headers can be found in signal_processing_library.h
     15  *
     16  */
     17 
     18 #include "signal_processing_library.h"
     19 
     20 // interpolation coefficients
     21 static const WebRtc_Word16 kCoefficients48To32[2][8] = {
     22         {778, -2050, 1087, 23285, 12903, -3783, 441, 222},
     23         {222, 441, -3783, 12903, 23285, 1087, -2050, 778}
     24 };
     25 
     26 static const WebRtc_Word16 kCoefficients32To24[3][8] = {
     27         {767, -2362, 2434, 24406, 10620, -3838, 721, 90},
     28         {386, -381, -2646, 19062, 19062, -2646, -381, 386},
     29         {90, 721, -3838, 10620, 24406, 2434, -2362, 767}
     30 };
     31 
     32 static const WebRtc_Word16 kCoefficients44To32[4][9] = {
     33         {117, -669, 2245, -6183, 26267, 13529, -3245, 845, -138},
     34         {-101, 612, -2283, 8532, 29790, -5138, 1789, -524, 91},
     35         {50, -292, 1016, -3064, 32010, 3933, -1147, 315, -53},
     36         {-156, 974, -3863, 18603, 21691, -6246, 2353, -712, 126}
     37 };
     38 
     39 //   Resampling ratio: 2/3
     40 // input:  WebRtc_Word32 (normalized, not saturated) :: size 3 * K
     41 // output: WebRtc_Word32 (shifted 15 positions to the left, + offset 16384) :: size 2 * K
     42 //      K: number of blocks
     43 
     44 void WebRtcSpl_Resample48khzTo32khz(const WebRtc_Word32 *In, WebRtc_Word32 *Out,
     45                                     const WebRtc_Word32 K)
     46 {
     47     /////////////////////////////////////////////////////////////
     48     // Filter operation:
     49     //
     50     // Perform resampling (3 input samples -> 2 output samples);
     51     // process in sub blocks of size 3 samples.
     52     WebRtc_Word32 tmp;
     53     WebRtc_Word32 m;
     54 
     55     for (m = 0; m < K; m++)
     56     {
     57         tmp = 1 << 14;
     58         tmp += kCoefficients48To32[0][0] * In[0];
     59         tmp += kCoefficients48To32[0][1] * In[1];
     60         tmp += kCoefficients48To32[0][2] * In[2];
     61         tmp += kCoefficients48To32[0][3] * In[3];
     62         tmp += kCoefficients48To32[0][4] * In[4];
     63         tmp += kCoefficients48To32[0][5] * In[5];
     64         tmp += kCoefficients48To32[0][6] * In[6];
     65         tmp += kCoefficients48To32[0][7] * In[7];
     66         Out[0] = tmp;
     67 
     68         tmp = 1 << 14;
     69         tmp += kCoefficients48To32[1][0] * In[1];
     70         tmp += kCoefficients48To32[1][1] * In[2];
     71         tmp += kCoefficients48To32[1][2] * In[3];
     72         tmp += kCoefficients48To32[1][3] * In[4];
     73         tmp += kCoefficients48To32[1][4] * In[5];
     74         tmp += kCoefficients48To32[1][5] * In[6];
     75         tmp += kCoefficients48To32[1][6] * In[7];
     76         tmp += kCoefficients48To32[1][7] * In[8];
     77         Out[1] = tmp;
     78 
     79         // update pointers
     80         In += 3;
     81         Out += 2;
     82     }
     83 }
     84 
     85 //   Resampling ratio: 3/4
     86 // input:  WebRtc_Word32 (normalized, not saturated) :: size 4 * K
     87 // output: WebRtc_Word32 (shifted 15 positions to the left, + offset 16384) :: size 3 * K
     88 //      K: number of blocks
     89 
     90 void WebRtcSpl_Resample32khzTo24khz(const WebRtc_Word32 *In, WebRtc_Word32 *Out,
     91                                     const WebRtc_Word32 K)
     92 {
     93     /////////////////////////////////////////////////////////////
     94     // Filter operation:
     95     //
     96     // Perform resampling (4 input samples -> 3 output samples);
     97     // process in sub blocks of size 4 samples.
     98     WebRtc_Word32 m;
     99     WebRtc_Word32 tmp;
    100 
    101     for (m = 0; m < K; m++)
    102     {
    103         tmp = 1 << 14;
    104         tmp += kCoefficients32To24[0][0] * In[0];
    105         tmp += kCoefficients32To24[0][1] * In[1];
    106         tmp += kCoefficients32To24[0][2] * In[2];
    107         tmp += kCoefficients32To24[0][3] * In[3];
    108         tmp += kCoefficients32To24[0][4] * In[4];
    109         tmp += kCoefficients32To24[0][5] * In[5];
    110         tmp += kCoefficients32To24[0][6] * In[6];
    111         tmp += kCoefficients32To24[0][7] * In[7];
    112         Out[0] = tmp;
    113 
    114         tmp = 1 << 14;
    115         tmp += kCoefficients32To24[1][0] * In[1];
    116         tmp += kCoefficients32To24[1][1] * In[2];
    117         tmp += kCoefficients32To24[1][2] * In[3];
    118         tmp += kCoefficients32To24[1][3] * In[4];
    119         tmp += kCoefficients32To24[1][4] * In[5];
    120         tmp += kCoefficients32To24[1][5] * In[6];
    121         tmp += kCoefficients32To24[1][6] * In[7];
    122         tmp += kCoefficients32To24[1][7] * In[8];
    123         Out[1] = tmp;
    124 
    125         tmp = 1 << 14;
    126         tmp += kCoefficients32To24[2][0] * In[2];
    127         tmp += kCoefficients32To24[2][1] * In[3];
    128         tmp += kCoefficients32To24[2][2] * In[4];
    129         tmp += kCoefficients32To24[2][3] * In[5];
    130         tmp += kCoefficients32To24[2][4] * In[6];
    131         tmp += kCoefficients32To24[2][5] * In[7];
    132         tmp += kCoefficients32To24[2][6] * In[8];
    133         tmp += kCoefficients32To24[2][7] * In[9];
    134         Out[2] = tmp;
    135 
    136         // update pointers
    137         In += 4;
    138         Out += 3;
    139     }
    140 }
    141 
    142 //
    143 // fractional resampling filters
    144 //   Fout = 11/16 * Fin
    145 //   Fout =  8/11 * Fin
    146 //
    147 
    148 // compute two inner-products and store them to output array
    149 static void WebRtcSpl_ResampDotProduct(const WebRtc_Word32 *in1, const WebRtc_Word32 *in2,
    150                                const WebRtc_Word16 *coef_ptr, WebRtc_Word32 *out1,
    151                                WebRtc_Word32 *out2)
    152 {
    153     WebRtc_Word32 tmp1 = 16384;
    154     WebRtc_Word32 tmp2 = 16384;
    155     WebRtc_Word16 coef;
    156 
    157     coef = coef_ptr[0];
    158     tmp1 += coef * in1[0];
    159     tmp2 += coef * in2[-0];
    160 
    161     coef = coef_ptr[1];
    162     tmp1 += coef * in1[1];
    163     tmp2 += coef * in2[-1];
    164 
    165     coef = coef_ptr[2];
    166     tmp1 += coef * in1[2];
    167     tmp2 += coef * in2[-2];
    168 
    169     coef = coef_ptr[3];
    170     tmp1 += coef * in1[3];
    171     tmp2 += coef * in2[-3];
    172 
    173     coef = coef_ptr[4];
    174     tmp1 += coef * in1[4];
    175     tmp2 += coef * in2[-4];
    176 
    177     coef = coef_ptr[5];
    178     tmp1 += coef * in1[5];
    179     tmp2 += coef * in2[-5];
    180 
    181     coef = coef_ptr[6];
    182     tmp1 += coef * in1[6];
    183     tmp2 += coef * in2[-6];
    184 
    185     coef = coef_ptr[7];
    186     tmp1 += coef * in1[7];
    187     tmp2 += coef * in2[-7];
    188 
    189     coef = coef_ptr[8];
    190     *out1 = tmp1 + coef * in1[8];
    191     *out2 = tmp2 + coef * in2[-8];
    192 }
    193 
    194 //   Resampling ratio: 8/11
    195 // input:  WebRtc_Word32 (normalized, not saturated) :: size 11 * K
    196 // output: WebRtc_Word32 (shifted 15 positions to the left, + offset 16384) :: size  8 * K
    197 //      K: number of blocks
    198 
    199 void WebRtcSpl_Resample44khzTo32khz(const WebRtc_Word32 *In, WebRtc_Word32 *Out,
    200                                     const WebRtc_Word32 K)
    201 {
    202     /////////////////////////////////////////////////////////////
    203     // Filter operation:
    204     //
    205     // Perform resampling (11 input samples -> 8 output samples);
    206     // process in sub blocks of size 11 samples.
    207     WebRtc_Word32 tmp;
    208     WebRtc_Word32 m;
    209 
    210     for (m = 0; m < K; m++)
    211     {
    212         tmp = 1 << 14;
    213 
    214         // first output sample
    215         Out[0] = ((WebRtc_Word32)In[3] << 15) + tmp;
    216 
    217         // sum and accumulate filter coefficients and input samples
    218         tmp += kCoefficients44To32[3][0] * In[5];
    219         tmp += kCoefficients44To32[3][1] * In[6];
    220         tmp += kCoefficients44To32[3][2] * In[7];
    221         tmp += kCoefficients44To32[3][3] * In[8];
    222         tmp += kCoefficients44To32[3][4] * In[9];
    223         tmp += kCoefficients44To32[3][5] * In[10];
    224         tmp += kCoefficients44To32[3][6] * In[11];
    225         tmp += kCoefficients44To32[3][7] * In[12];
    226         tmp += kCoefficients44To32[3][8] * In[13];
    227         Out[4] = tmp;
    228 
    229         // sum and accumulate filter coefficients and input samples
    230         WebRtcSpl_ResampDotProduct(&In[0], &In[17], kCoefficients44To32[0], &Out[1], &Out[7]);
    231 
    232         // sum and accumulate filter coefficients and input samples
    233         WebRtcSpl_ResampDotProduct(&In[2], &In[15], kCoefficients44To32[1], &Out[2], &Out[6]);
    234 
    235         // sum and accumulate filter coefficients and input samples
    236         WebRtcSpl_ResampDotProduct(&In[3], &In[14], kCoefficients44To32[2], &Out[3], &Out[5]);
    237 
    238         // update pointers
    239         In += 11;
    240         Out += 8;
    241     }
    242 }
    243