Home | History | Annotate | Download | only in source
      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 #include <assert.h>
     12 
     13 #include "webrtc/modules/audio_coding/codecs/isac/fix/source/codec.h"
     14 
     15 // Autocorrelation function in fixed point.
     16 // NOTE! Different from SPLIB-version in how it scales the signal.
     17 int WebRtcIsacfix_AutocorrC(int32_t* __restrict r,
     18                             const int16_t* __restrict x,
     19                             int16_t N,
     20                             int16_t order,
     21                             int16_t* __restrict scale) {
     22   int i = 0;
     23   int j = 0;
     24   int16_t scaling = 0;
     25   int32_t sum = 0;
     26   uint32_t temp = 0;
     27   int64_t prod = 0;
     28 
     29   // The ARM assembly code assumptoins.
     30   assert(N % 4 == 0);
     31   assert(N >= 8);
     32 
     33   // Calculate r[0].
     34   for (i = 0; i < N; i++) {
     35     prod += x[i] * x[i];
     36   }
     37 
     38   // Calculate scaling (the value of shifting).
     39   temp = (uint32_t)(prod >> 31);
     40   if(temp == 0) {
     41     scaling = 0;
     42   } else {
     43     scaling = 32 - WebRtcSpl_NormU32(temp);
     44   }
     45   r[0] = (int32_t)(prod >> scaling);
     46 
     47   // Perform the actual correlation calculation.
     48   for (i = 1; i < order + 1; i++) {
     49     prod = 0;
     50     for (j = 0; j < N - i; j++) {
     51       prod += x[j] * x[i + j];
     52     }
     53     sum = (int32_t)(prod >> scaling);
     54     r[i] = sum;
     55   }
     56 
     57   *scale = scaling;
     58 
     59   return(order + 1);
     60 }
     61 
     62 static const int32_t kApUpperQ15[ALLPASSSECTIONS] = { 1137, 12537 };
     63 static const int32_t kApLowerQ15[ALLPASSSECTIONS] = { 5059, 24379 };
     64 
     65 
     66 static void AllpassFilterForDec32(int16_t         *InOut16, //Q0
     67                                   const int32_t   *APSectionFactors, //Q15
     68                                   int16_t         lengthInOut,
     69                                   int32_t          *FilterState) //Q16
     70 {
     71   int n, j;
     72   int32_t a, b;
     73 
     74   for (j=0; j<ALLPASSSECTIONS; j++) {
     75     for (n=0;n<lengthInOut;n+=2){
     76       a = WEBRTC_SPL_MUL_16_32_RSFT16(InOut16[n], APSectionFactors[j]); //Q0*Q31=Q31 shifted 16 gives Q15
     77       a <<= 1;  // Q15 -> Q16
     78       b = WebRtcSpl_AddSatW32(a, FilterState[j]);  //Q16+Q16=Q16
     79       // |a| in Q15 (Q0*Q31=Q31 shifted 16 gives Q15).
     80       a = WEBRTC_SPL_MUL_16_32_RSFT16(b >> 16, -APSectionFactors[j]);
     81       // FilterState[j]: Q15<<1 + Q0<<16 = Q16 + Q16 = Q16
     82       FilterState[j] = WebRtcSpl_AddSatW32(a << 1, (uint32_t)InOut16[n] << 16);
     83       InOut16[n] = (int16_t)(b >> 16);  // Save as Q0.
     84     }
     85   }
     86 }
     87 
     88 
     89 
     90 
     91 void WebRtcIsacfix_DecimateAllpass32(const int16_t *in,
     92                                      int32_t *state_in,        /* array of size: 2*ALLPASSSECTIONS+1 */
     93                                      int16_t N,                /* number of input samples */
     94                                      int16_t *out)             /* array of size N/2 */
     95 {
     96   int n;
     97   int16_t data_vec[PITCH_FRAME_LEN];
     98 
     99   /* copy input */
    100   memcpy(data_vec + 1, in, sizeof(int16_t) * (N - 1));
    101 
    102   data_vec[0] = (int16_t)(state_in[2 * ALLPASSSECTIONS] >> 16);  // z^-1 state.
    103   state_in[2 * ALLPASSSECTIONS] = (uint32_t)in[N - 1] << 16;
    104 
    105 
    106 
    107   AllpassFilterForDec32(data_vec+1, kApUpperQ15, N, state_in);
    108   AllpassFilterForDec32(data_vec, kApLowerQ15, N, state_in+ALLPASSSECTIONS);
    109 
    110   for (n=0;n<N/2;n++) {
    111     out[n] = WebRtcSpl_AddSatW16(data_vec[2 * n], data_vec[2 * n + 1]);
    112   }
    113 }
    114