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