LCOV - code coverage report
Current view: top level - media/webrtc/trunk/webrtc/common_audio/signal_processing - resample_by_2_internal.c (source / functions) Hit Total Coverage
Test: output.info Lines: 0 400 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 7 0.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13