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 header file contains some internal resampling functions.
     14  *
     15  */
     16 
     17 #include "resample_by_2_internal.h"
     18 
     19 // allpass filter coefficients.
     20 static const WebRtc_Word16 kResampleAllpass[2][3] = {
     21         {821, 6110, 12382},
     22         {3050, 9368, 15063}
     23 };
     24 
     25 //
     26 //   decimator
     27 // input:  WebRtc_Word32 (shifted 15 positions to the left, + offset 16384) OVERWRITTEN!
     28 // output: WebRtc_Word16 (saturated) (of length len/2)
     29 // state:  filter state array; length = 8
     30 
     31 void WebRtcSpl_DownBy2IntToShort(WebRtc_Word32 *in, WebRtc_Word32 len, WebRtc_Word16 *out,
     32                                  WebRtc_Word32 *state)
     33 {
     34     WebRtc_Word32 tmp0, tmp1, diff;
     35     WebRtc_Word32 i;
     36 
     37     len >>= 1;
     38 
     39     // lower allpass filter (operates on even input samples)
     40     for (i = 0; i < len; i++)
     41     {
     42         tmp0 = in[i << 1];
     43         diff = tmp0 - state[1];
     44         // scale down and round
     45         diff = (diff + (1 << 13)) >> 14;
     46         tmp1 = state[0] + diff * kResampleAllpass[1][0];
     47         state[0] = tmp0;
     48         diff = tmp1 - state[2];
     49         // scale down and truncate
     50         diff = diff >> 14;
     51         if (diff < 0)
     52             diff += 1;
     53         tmp0 = state[1] + diff * kResampleAllpass[1][1];
     54         state[1] = tmp1;
     55         diff = tmp0 - state[3];
     56         // scale down and truncate
     57         diff = diff >> 14;
     58         if (diff < 0)
     59             diff += 1;
     60         state[3] = state[2] + diff * kResampleAllpass[1][2];
     61         state[2] = tmp0;
     62 
     63         // divide by two and store temporarily
     64         in[i << 1] = (state[3] >> 1);
     65     }
     66 
     67     in++;
     68 
     69     // upper allpass filter (operates on odd input samples)
     70     for (i = 0; i < len; i++)
     71     {
     72         tmp0 = in[i << 1];
     73         diff = tmp0 - state[5];
     74         // scale down and round
     75         diff = (diff + (1 << 13)) >> 14;
     76         tmp1 = state[4] + diff * kResampleAllpass[0][0];
     77         state[4] = tmp0;
     78         diff = tmp1 - state[6];
     79         // scale down and round
     80         diff = diff >> 14;
     81         if (diff < 0)
     82             diff += 1;
     83         tmp0 = state[5] + diff * kResampleAllpass[0][1];
     84         state[5] = tmp1;
     85         diff = tmp0 - state[7];
     86         // scale down and truncate
     87         diff = diff >> 14;
     88         if (diff < 0)
     89             diff += 1;
     90         state[7] = state[6] + diff * kResampleAllpass[0][2];
     91         state[6] = tmp0;
     92 
     93         // divide by two and store temporarily
     94         in[i << 1] = (state[7] >> 1);
     95     }
     96 
     97     in--;
     98 
     99     // combine allpass outputs
    100     for (i = 0; i < len; i += 2)
    101     {
    102         // divide by two, add both allpass outputs and round
    103         tmp0 = (in[i << 1] + in[(i << 1) + 1]) >> 15;
    104         tmp1 = (in[(i << 1) + 2] + in[(i << 1) + 3]) >> 15;
    105         if (tmp0 > (WebRtc_Word32)0x00007FFF)
    106             tmp0 = 0x00007FFF;
    107         if (tmp0 < (WebRtc_Word32)0xFFFF8000)
    108             tmp0 = 0xFFFF8000;
    109         out[i] = (WebRtc_Word16)tmp0;
    110         if (tmp1 > (WebRtc_Word32)0x00007FFF)
    111             tmp1 = 0x00007FFF;
    112         if (tmp1 < (WebRtc_Word32)0xFFFF8000)
    113             tmp1 = 0xFFFF8000;
    114         out[i + 1] = (WebRtc_Word16)tmp1;
    115     }
    116 }
    117 
    118 //
    119 //   decimator
    120 // input:  WebRtc_Word16
    121 // output: WebRtc_Word32 (shifted 15 positions to the left, + offset 16384) (of length len/2)
    122 // state:  filter state array; length = 8
    123 
    124 void WebRtcSpl_DownBy2ShortToInt(const WebRtc_Word16 *in,
    125                                   WebRtc_Word32 len,
    126                                   WebRtc_Word32 *out,
    127                                   WebRtc_Word32 *state)
    128 {
    129     WebRtc_Word32 tmp0, tmp1, diff;
    130     WebRtc_Word32 i;
    131 
    132     len >>= 1;
    133 
    134     // lower allpass filter (operates on even input samples)
    135     for (i = 0; i < len; i++)
    136     {
    137         tmp0 = ((WebRtc_Word32)in[i << 1] << 15) + (1 << 14);
    138         diff = tmp0 - state[1];
    139         // scale down and round
    140         diff = (diff + (1 << 13)) >> 14;
    141         tmp1 = state[0] + diff * kResampleAllpass[1][0];
    142         state[0] = tmp0;
    143         diff = tmp1 - state[2];
    144         // scale down and truncate
    145         diff = diff >> 14;
    146         if (diff < 0)
    147             diff += 1;
    148         tmp0 = state[1] + diff * kResampleAllpass[1][1];
    149         state[1] = tmp1;
    150         diff = tmp0 - state[3];
    151         // scale down and truncate
    152         diff = diff >> 14;
    153         if (diff < 0)
    154             diff += 1;
    155         state[3] = state[2] + diff * kResampleAllpass[1][2];
    156         state[2] = tmp0;
    157 
    158         // divide by two and store temporarily
    159         out[i] = (state[3] >> 1);
    160     }
    161 
    162     in++;
    163 
    164     // upper allpass filter (operates on odd input samples)
    165     for (i = 0; i < len; i++)
    166     {
    167         tmp0 = ((WebRtc_Word32)in[i << 1] << 15) + (1 << 14);
    168         diff = tmp0 - state[5];
    169         // scale down and round
    170         diff = (diff + (1 << 13)) >> 14;
    171         tmp1 = state[4] + diff * kResampleAllpass[0][0];
    172         state[4] = tmp0;
    173         diff = tmp1 - state[6];
    174         // scale down and round
    175         diff = diff >> 14;
    176         if (diff < 0)
    177             diff += 1;
    178         tmp0 = state[5] + diff * kResampleAllpass[0][1];
    179         state[5] = tmp1;
    180         diff = tmp0 - state[7];
    181         // scale down and truncate
    182         diff = diff >> 14;
    183         if (diff < 0)
    184             diff += 1;
    185         state[7] = state[6] + diff * kResampleAllpass[0][2];
    186         state[6] = tmp0;
    187 
    188         // divide by two and store temporarily
    189         out[i] += (state[7] >> 1);
    190     }
    191 
    192     in--;
    193 }
    194 
    195 //
    196 //   interpolator
    197 // input:  WebRtc_Word16
    198 // output: WebRtc_Word32 (normalized, not saturated) (of length len*2)
    199 // state:  filter state array; length = 8
    200 void WebRtcSpl_UpBy2ShortToInt(const WebRtc_Word16 *in, WebRtc_Word32 len, WebRtc_Word32 *out,
    201                                WebRtc_Word32 *state)
    202 {
    203     WebRtc_Word32 tmp0, tmp1, diff;
    204     WebRtc_Word32 i;
    205 
    206     // upper allpass filter (generates odd output samples)
    207     for (i = 0; i < len; i++)
    208     {
    209         tmp0 = ((WebRtc_Word32)in[i] << 15) + (1 << 14);
    210         diff = tmp0 - state[5];
    211         // scale down and round
    212         diff = (diff + (1 << 13)) >> 14;
    213         tmp1 = state[4] + diff * kResampleAllpass[0][0];
    214         state[4] = tmp0;
    215         diff = tmp1 - state[6];
    216         // scale down and truncate
    217         diff = diff >> 14;
    218         if (diff < 0)
    219             diff += 1;
    220         tmp0 = state[5] + diff * kResampleAllpass[0][1];
    221         state[5] = tmp1;
    222         diff = tmp0 - state[7];
    223         // scale down and truncate
    224         diff = diff >> 14;
    225         if (diff < 0)
    226             diff += 1;
    227         state[7] = state[6] + diff * kResampleAllpass[0][2];
    228         state[6] = tmp0;
    229 
    230         // scale down, round and store
    231         out[i << 1] = state[7] >> 15;
    232     }
    233 
    234     out++;
    235 
    236     // lower allpass filter (generates even output samples)
    237     for (i = 0; i < len; i++)
    238     {
    239         tmp0 = ((WebRtc_Word32)in[i] << 15) + (1 << 14);
    240         diff = tmp0 - state[1];
    241         // scale down and round
    242         diff = (diff + (1 << 13)) >> 14;
    243         tmp1 = state[0] + diff * kResampleAllpass[1][0];
    244         state[0] = tmp0;
    245         diff = tmp1 - state[2];
    246         // scale down and truncate
    247         diff = diff >> 14;
    248         if (diff < 0)
    249             diff += 1;
    250         tmp0 = state[1] + diff * kResampleAllpass[1][1];
    251         state[1] = tmp1;
    252         diff = tmp0 - state[3];
    253         // scale down and truncate
    254         diff = diff >> 14;
    255         if (diff < 0)
    256             diff += 1;
    257         state[3] = state[2] + diff * kResampleAllpass[1][2];
    258         state[2] = tmp0;
    259 
    260         // scale down, round and store
    261         out[i << 1] = state[3] >> 15;
    262     }
    263 }
    264 
    265 //
    266 //   interpolator
    267 // input:  WebRtc_Word32 (shifted 15 positions to the left, + offset 16384)
    268 // output: WebRtc_Word32 (shifted 15 positions to the left, + offset 16384) (of length len*2)
    269 // state:  filter state array; length = 8
    270 void WebRtcSpl_UpBy2IntToInt(const WebRtc_Word32 *in, WebRtc_Word32 len, WebRtc_Word32 *out,
    271                              WebRtc_Word32 *state)
    272 {
    273     WebRtc_Word32 tmp0, tmp1, diff;
    274     WebRtc_Word32 i;
    275 
    276     // upper allpass filter (generates odd output samples)
    277     for (i = 0; i < len; i++)
    278     {
    279         tmp0 = in[i];
    280         diff = tmp0 - state[5];
    281         // scale down and round
    282         diff = (diff + (1 << 13)) >> 14;
    283         tmp1 = state[4] + diff * kResampleAllpass[0][0];
    284         state[4] = tmp0;
    285         diff = tmp1 - state[6];
    286         // scale down and truncate
    287         diff = diff >> 14;
    288         if (diff < 0)
    289             diff += 1;
    290         tmp0 = state[5] + diff * kResampleAllpass[0][1];
    291         state[5] = tmp1;
    292         diff = tmp0 - state[7];
    293         // scale down and truncate
    294         diff = diff >> 14;
    295         if (diff < 0)
    296             diff += 1;
    297         state[7] = state[6] + diff * kResampleAllpass[0][2];
    298         state[6] = tmp0;
    299 
    300         // scale down, round and store
    301         out[i << 1] = state[7];
    302     }
    303 
    304     out++;
    305 
    306     // lower allpass filter (generates even output samples)
    307     for (i = 0; i < len; i++)
    308     {
    309         tmp0 = in[i];
    310         diff = tmp0 - state[1];
    311         // scale down and round
    312         diff = (diff + (1 << 13)) >> 14;
    313         tmp1 = state[0] + diff * kResampleAllpass[1][0];
    314         state[0] = tmp0;
    315         diff = tmp1 - state[2];
    316         // scale down and truncate
    317         diff = diff >> 14;
    318         if (diff < 0)
    319             diff += 1;
    320         tmp0 = state[1] + diff * kResampleAllpass[1][1];
    321         state[1] = tmp1;
    322         diff = tmp0 - state[3];
    323         // scale down and truncate
    324         diff = diff >> 14;
    325         if (diff < 0)
    326             diff += 1;
    327         state[3] = state[2] + diff * kResampleAllpass[1][2];
    328         state[2] = tmp0;
    329 
    330         // scale down, round and store
    331         out[i << 1] = state[3];
    332     }
    333 }
    334 
    335 //
    336 //   interpolator
    337 // input:  WebRtc_Word32 (shifted 15 positions to the left, + offset 16384)
    338 // output: WebRtc_Word16 (saturated) (of length len*2)
    339 // state:  filter state array; length = 8
    340 void WebRtcSpl_UpBy2IntToShort(const WebRtc_Word32 *in, WebRtc_Word32 len, WebRtc_Word16 *out,
    341                                WebRtc_Word32 *state)
    342 {
    343     WebRtc_Word32 tmp0, tmp1, diff;
    344     WebRtc_Word32 i;
    345 
    346     // upper allpass filter (generates odd output samples)
    347     for (i = 0; i < len; i++)
    348     {
    349         tmp0 = in[i];
    350         diff = tmp0 - state[5];
    351         // scale down and round
    352         diff = (diff + (1 << 13)) >> 14;
    353         tmp1 = state[4] + diff * kResampleAllpass[0][0];
    354         state[4] = tmp0;
    355         diff = tmp1 - state[6];
    356         // scale down and round
    357         diff = diff >> 14;
    358         if (diff < 0)
    359             diff += 1;
    360         tmp0 = state[5] + diff * kResampleAllpass[0][1];
    361         state[5] = tmp1;
    362         diff = tmp0 - state[7];
    363         // scale down and truncate
    364         diff = diff >> 14;
    365         if (diff < 0)
    366             diff += 1;
    367         state[7] = state[6] + diff * kResampleAllpass[0][2];
    368         state[6] = tmp0;
    369 
    370         // scale down, saturate and store
    371         tmp1 = state[7] >> 15;
    372         if (tmp1 > (WebRtc_Word32)0x00007FFF)
    373             tmp1 = 0x00007FFF;
    374         if (tmp1 < (WebRtc_Word32)0xFFFF8000)
    375             tmp1 = 0xFFFF8000;
    376         out[i << 1] = (WebRtc_Word16)tmp1;
    377     }
    378 
    379     out++;
    380 
    381     // lower allpass filter (generates even output samples)
    382     for (i = 0; i < len; i++)
    383     {
    384         tmp0 = in[i];
    385         diff = tmp0 - state[1];
    386         // scale down and round
    387         diff = (diff + (1 << 13)) >> 14;
    388         tmp1 = state[0] + diff * kResampleAllpass[1][0];
    389         state[0] = tmp0;
    390         diff = tmp1 - state[2];
    391         // scale down and truncate
    392         diff = diff >> 14;
    393         if (diff < 0)
    394             diff += 1;
    395         tmp0 = state[1] + diff * kResampleAllpass[1][1];
    396         state[1] = tmp1;
    397         diff = tmp0 - state[3];
    398         // scale down and truncate
    399         diff = diff >> 14;
    400         if (diff < 0)
    401             diff += 1;
    402         state[3] = state[2] + diff * kResampleAllpass[1][2];
    403         state[2] = tmp0;
    404 
    405         // scale down, saturate and store
    406         tmp1 = state[3] >> 15;
    407         if (tmp1 > (WebRtc_Word32)0x00007FFF)
    408             tmp1 = 0x00007FFF;
    409         if (tmp1 < (WebRtc_Word32)0xFFFF8000)
    410             tmp1 = 0xFFFF8000;
    411         out[i << 1] = (WebRtc_Word16)tmp1;
    412     }
    413 }
    414 
    415 //   lowpass filter
    416 // input:  WebRtc_Word16
    417 // output: WebRtc_Word32 (normalized, not saturated)
    418 // state:  filter state array; length = 8
    419 void WebRtcSpl_LPBy2ShortToInt(const WebRtc_Word16* in, WebRtc_Word32 len, WebRtc_Word32* out,
    420                                WebRtc_Word32* state)
    421 {
    422     WebRtc_Word32 tmp0, tmp1, diff;
    423     WebRtc_Word32 i;
    424 
    425     len >>= 1;
    426 
    427     // lower allpass filter: odd input -> even output samples
    428     in++;
    429     // initial state of polyphase delay element
    430     tmp0 = state[12];
    431     for (i = 0; i < len; i++)
    432     {
    433         diff = tmp0 - state[1];
    434         // scale down and round
    435         diff = (diff + (1 << 13)) >> 14;
    436         tmp1 = state[0] + diff * kResampleAllpass[1][0];
    437         state[0] = tmp0;
    438         diff = tmp1 - state[2];
    439         // scale down and truncate
    440         diff = diff >> 14;
    441         if (diff < 0)
    442             diff += 1;
    443         tmp0 = state[1] + diff * kResampleAllpass[1][1];
    444         state[1] = tmp1;
    445         diff = tmp0 - state[3];
    446         // scale down and truncate
    447         diff = diff >> 14;
    448         if (diff < 0)
    449             diff += 1;
    450         state[3] = state[2] + diff * kResampleAllpass[1][2];
    451         state[2] = tmp0;
    452 
    453         // scale down, round and store
    454         out[i << 1] = state[3] >> 1;
    455         tmp0 = ((WebRtc_Word32)in[i << 1] << 15) + (1 << 14);
    456     }
    457     in--;
    458 
    459     // upper allpass filter: even input -> even output samples
    460     for (i = 0; i < len; i++)
    461     {
    462         tmp0 = ((WebRtc_Word32)in[i << 1] << 15) + (1 << 14);
    463         diff = tmp0 - state[5];
    464         // scale down and round
    465         diff = (diff + (1 << 13)) >> 14;
    466         tmp1 = state[4] + diff * kResampleAllpass[0][0];
    467         state[4] = tmp0;
    468         diff = tmp1 - state[6];
    469         // scale down and round
    470         diff = diff >> 14;
    471         if (diff < 0)
    472             diff += 1;
    473         tmp0 = state[5] + diff * kResampleAllpass[0][1];
    474         state[5] = tmp1;
    475         diff = tmp0 - state[7];
    476         // scale down and truncate
    477         diff = diff >> 14;
    478         if (diff < 0)
    479             diff += 1;
    480         state[7] = state[6] + diff * kResampleAllpass[0][2];
    481         state[6] = tmp0;
    482 
    483         // average the two allpass outputs, scale down and store
    484         out[i << 1] = (out[i << 1] + (state[7] >> 1)) >> 15;
    485     }
    486 
    487     // switch to odd output samples
    488     out++;
    489 
    490     // lower allpass filter: even input -> odd output samples
    491     for (i = 0; i < len; i++)
    492     {
    493         tmp0 = ((WebRtc_Word32)in[i << 1] << 15) + (1 << 14);
    494         diff = tmp0 - state[9];
    495         // scale down and round
    496         diff = (diff + (1 << 13)) >> 14;
    497         tmp1 = state[8] + diff * kResampleAllpass[1][0];
    498         state[8] = tmp0;
    499         diff = tmp1 - state[10];
    500         // scale down and truncate
    501         diff = diff >> 14;
    502         if (diff < 0)
    503             diff += 1;
    504         tmp0 = state[9] + diff * kResampleAllpass[1][1];
    505         state[9] = tmp1;
    506         diff = tmp0 - state[11];
    507         // scale down and truncate
    508         diff = diff >> 14;
    509         if (diff < 0)
    510             diff += 1;
    511         state[11] = state[10] + diff * kResampleAllpass[1][2];
    512         state[10] = tmp0;
    513 
    514         // scale down, round and store
    515         out[i << 1] = state[11] >> 1;
    516     }
    517 
    518     // upper allpass filter: odd input -> odd output samples
    519     in++;
    520     for (i = 0; i < len; i++)
    521     {
    522         tmp0 = ((WebRtc_Word32)in[i << 1] << 15) + (1 << 14);
    523         diff = tmp0 - state[13];
    524         // scale down and round
    525         diff = (diff + (1 << 13)) >> 14;
    526         tmp1 = state[12] + diff * kResampleAllpass[0][0];
    527         state[12] = tmp0;
    528         diff = tmp1 - state[14];
    529         // scale down and round
    530         diff = diff >> 14;
    531         if (diff < 0)
    532             diff += 1;
    533         tmp0 = state[13] + diff * kResampleAllpass[0][1];
    534         state[13] = tmp1;
    535         diff = tmp0 - state[15];
    536         // scale down and truncate
    537         diff = diff >> 14;
    538         if (diff < 0)
    539             diff += 1;
    540         state[15] = state[14] + diff * kResampleAllpass[0][2];
    541         state[14] = tmp0;
    542 
    543         // average the two allpass outputs, scale down and store
    544         out[i << 1] = (out[i << 1] + (state[15] >> 1)) >> 15;
    545     }
    546 }
    547 
    548 //   lowpass filter
    549 // input:  WebRtc_Word32 (shifted 15 positions to the left, + offset 16384)
    550 // output: WebRtc_Word32 (normalized, not saturated)
    551 // state:  filter state array; length = 8
    552 void WebRtcSpl_LPBy2IntToInt(const WebRtc_Word32* in, WebRtc_Word32 len, WebRtc_Word32* out,
    553                              WebRtc_Word32* state)
    554 {
    555     WebRtc_Word32 tmp0, tmp1, diff;
    556     WebRtc_Word32 i;
    557 
    558     len >>= 1;
    559 
    560     // lower allpass filter: odd input -> even output samples
    561     in++;
    562     // initial state of polyphase delay element
    563     tmp0 = state[12];
    564     for (i = 0; i < len; i++)
    565     {
    566         diff = tmp0 - state[1];
    567         // scale down and round
    568         diff = (diff + (1 << 13)) >> 14;
    569         tmp1 = state[0] + diff * kResampleAllpass[1][0];
    570         state[0] = tmp0;
    571         diff = tmp1 - state[2];
    572         // scale down and truncate
    573         diff = diff >> 14;
    574         if (diff < 0)
    575             diff += 1;
    576         tmp0 = state[1] + diff * kResampleAllpass[1][1];
    577         state[1] = tmp1;
    578         diff = tmp0 - state[3];
    579         // scale down and truncate
    580         diff = diff >> 14;
    581         if (diff < 0)
    582             diff += 1;
    583         state[3] = state[2] + diff * kResampleAllpass[1][2];
    584         state[2] = tmp0;
    585 
    586         // scale down, round and store
    587         out[i << 1] = state[3] >> 1;
    588         tmp0 = in[i << 1];
    589     }
    590     in--;
    591 
    592     // upper allpass filter: even input -> even output samples
    593     for (i = 0; i < len; i++)
    594     {
    595         tmp0 = in[i << 1];
    596         diff = tmp0 - state[5];
    597         // scale down and round
    598         diff = (diff + (1 << 13)) >> 14;
    599         tmp1 = state[4] + diff * kResampleAllpass[0][0];
    600         state[4] = tmp0;
    601         diff = tmp1 - state[6];
    602         // scale down and round
    603         diff = diff >> 14;
    604         if (diff < 0)
    605             diff += 1;
    606         tmp0 = state[5] + diff * kResampleAllpass[0][1];
    607         state[5] = tmp1;
    608         diff = tmp0 - state[7];
    609         // scale down and truncate
    610         diff = diff >> 14;
    611         if (diff < 0)
    612             diff += 1;
    613         state[7] = state[6] + diff * kResampleAllpass[0][2];
    614         state[6] = tmp0;
    615 
    616         // average the two allpass outputs, scale down and store
    617         out[i << 1] = (out[i << 1] + (state[7] >> 1)) >> 15;
    618     }
    619 
    620     // switch to odd output samples
    621     out++;
    622 
    623     // lower allpass filter: even input -> odd output samples
    624     for (i = 0; i < len; i++)
    625     {
    626         tmp0 = in[i << 1];
    627         diff = tmp0 - state[9];
    628         // scale down and round
    629         diff = (diff + (1 << 13)) >> 14;
    630         tmp1 = state[8] + diff * kResampleAllpass[1][0];
    631         state[8] = tmp0;
    632         diff = tmp1 - state[10];
    633         // scale down and truncate
    634         diff = diff >> 14;
    635         if (diff < 0)
    636             diff += 1;
    637         tmp0 = state[9] + diff * kResampleAllpass[1][1];
    638         state[9] = tmp1;
    639         diff = tmp0 - state[11];
    640         // scale down and truncate
    641         diff = diff >> 14;
    642         if (diff < 0)
    643             diff += 1;
    644         state[11] = state[10] + diff * kResampleAllpass[1][2];
    645         state[10] = tmp0;
    646 
    647         // scale down, round and store
    648         out[i << 1] = state[11] >> 1;
    649     }
    650 
    651     // upper allpass filter: odd input -> odd output samples
    652     in++;
    653     for (i = 0; i < len; i++)
    654     {
    655         tmp0 = in[i << 1];
    656         diff = tmp0 - state[13];
    657         // scale down and round
    658         diff = (diff + (1 << 13)) >> 14;
    659         tmp1 = state[12] + diff * kResampleAllpass[0][0];
    660         state[12] = tmp0;
    661         diff = tmp1 - state[14];
    662         // scale down and round
    663         diff = diff >> 14;
    664         if (diff < 0)
    665             diff += 1;
    666         tmp0 = state[13] + diff * kResampleAllpass[0][1];
    667         state[13] = tmp1;
    668         diff = tmp0 - state[15];
    669         // scale down and truncate
    670         diff = diff >> 14;
    671         if (diff < 0)
    672             diff += 1;
    673         state[15] = state[14] + diff * kResampleAllpass[0][2];
    674         state[14] = tmp0;
    675 
    676         // average the two allpass outputs, scale down and store
    677         out[i << 1] = (out[i << 1] + (state[15] >> 1)) >> 15;
    678     }
    679 }
    680