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