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