Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / third_party / webrtc / modules / audio_coding / codecs / isac / fix / source / filters.c
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 += WEBRTC_SPL_MUL_16_16(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 += WEBRTC_SPL_MUL_16_16(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 = WEBRTC_SPL_LSHIFT_W32(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] = WebRtcSpl_AddSatW32(
82           WEBRTC_SPL_LSHIFT_W32(a,1),
83           WEBRTC_SPL_LSHIFT_W32((uint32_t)InOut16[n], 16)); // Q15<<1 + Q0<<16 = Q16 + Q16 = Q16
84       InOut16[n] = (int16_t)(b >> 16);  // Save as Q0.
85     }
86   }
87 }
88
89
90
91
92 void WebRtcIsacfix_DecimateAllpass32(const int16_t *in,
93                                      int32_t *state_in,        /* array of size: 2*ALLPASSSECTIONS+1 */
94                                      int16_t N,                /* number of input samples */
95                                      int16_t *out)             /* array of size N/2 */
96 {
97   int n;
98   int16_t data_vec[PITCH_FRAME_LEN];
99
100   /* copy input */
101   memcpy(data_vec+1, in, WEBRTC_SPL_MUL_16_16(sizeof(int16_t), (N-1)));
102
103
104   data_vec[0] = (int16_t)(state_in[2 * ALLPASSSECTIONS] >> 16);  // z^-1 state.
105   state_in[WEBRTC_SPL_MUL_16_16(2, ALLPASSSECTIONS)] = WEBRTC_SPL_LSHIFT_W32((uint32_t)in[N-1],16);
106
107
108
109   AllpassFilterForDec32(data_vec+1, kApUpperQ15, N, state_in);
110   AllpassFilterForDec32(data_vec, kApLowerQ15, N, state_in+ALLPASSSECTIONS);
111
112   for (n=0;n<N/2;n++) {
113     out[n] = WebRtcSpl_AddSatW16(data_vec[WEBRTC_SPL_MUL_16_16(2, n)],
114                                  data_vec[WEBRTC_SPL_MUL_16_16(2, n) + 1]);
115   }
116 }