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