2 * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
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.
11 #include "webrtc/modules/audio_coding/codecs/isac/fix/source/pitch_estimator.h"
12 #include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
13 #include "webrtc/system_wrappers/interface/compile_assert_c.h"
15 extern int32_t WebRtcIsacfix_Log2Q8(uint32_t x);
17 void WebRtcIsacfix_PCorr2Q32(const int16_t* in, int32_t* logcorQ8) {
19 int32_t ysum32,csum32, lys, lcs;
24 oneQ8 = WEBRTC_SPL_LSHIFT_W32((int32_t)1, 8); // 1.00 in Q8
25 x = in + PITCH_MAX_LAG / 2 + 2;
26 scaling = WebRtcSpl_GetScalingSquare((int16_t*)in,
31 x = in + PITCH_MAX_LAG / 2 + 2;
33 const int16_t* tmp_x = x;
34 const int16_t* tmp_in = in;
35 int32_t tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8;
37 COMPILE_ASSERT(PITCH_CORR_LEN2 % 4 == 0);
42 "lh %[tmp1], 0(%[tmp_in]) \n\t"
43 "lh %[tmp2], 2(%[tmp_in]) \n\t"
44 "lh %[tmp3], 4(%[tmp_in]) \n\t"
45 "lh %[tmp4], 6(%[tmp_in]) \n\t"
46 "lh %[tmp5], 0(%[tmp_x]) \n\t"
47 "lh %[tmp6], 2(%[tmp_x]) \n\t"
48 "lh %[tmp7], 4(%[tmp_x]) \n\t"
49 "lh %[tmp8], 6(%[tmp_x]) \n\t"
50 "mul %[tmp5], %[tmp1], %[tmp5] \n\t"
51 "mul %[tmp1], %[tmp1], %[tmp1] \n\t"
52 "mul %[tmp6], %[tmp2], %[tmp6] \n\t"
53 "mul %[tmp2], %[tmp2], %[tmp2] \n\t"
54 "mul %[tmp7], %[tmp3], %[tmp7] \n\t"
55 "mul %[tmp3], %[tmp3], %[tmp3] \n\t"
56 "mul %[tmp8], %[tmp4], %[tmp8] \n\t"
57 "mul %[tmp4], %[tmp4], %[tmp4] \n\t"
58 "addiu %[n], %[n], -4 \n\t"
59 "srav %[tmp5], %[tmp5], %[scaling] \n\t"
60 "srav %[tmp1], %[tmp1], %[scaling] \n\t"
61 "srav %[tmp6], %[tmp6], %[scaling] \n\t"
62 "srav %[tmp2], %[tmp2], %[scaling] \n\t"
63 "srav %[tmp7], %[tmp7], %[scaling] \n\t"
64 "srav %[tmp3], %[tmp3], %[scaling] \n\t"
65 "srav %[tmp8], %[tmp8], %[scaling] \n\t"
66 "srav %[tmp4], %[tmp4], %[scaling] \n\t"
67 "addu %[ysum32], %[ysum32], %[tmp1] \n\t"
68 "addu %[csum32], %[csum32], %[tmp5] \n\t"
69 "addu %[ysum32], %[ysum32], %[tmp2] \n\t"
70 "addu %[csum32], %[csum32], %[tmp6] \n\t"
71 "addu %[ysum32], %[ysum32], %[tmp3] \n\t"
72 "addu %[csum32], %[csum32], %[tmp7] \n\t"
73 "addu %[ysum32], %[ysum32], %[tmp4] \n\t"
74 "addu %[csum32], %[csum32], %[tmp8] \n\t"
75 "addiu %[tmp_in], %[tmp_in], 8 \n\t"
77 " addiu %[tmp_x], %[tmp_x], 8 \n\t"
79 : [tmp1] "=&r" (tmp1), [tmp2] "=&r" (tmp2), [tmp3] "=&r" (tmp3),
80 [tmp4] "=&r" (tmp4), [tmp5] "=&r" (tmp5), [tmp6] "=&r" (tmp6),
81 [tmp7] "=&r" (tmp7), [tmp8] "=&r" (tmp8), [tmp_in] "+r" (tmp_in),
82 [ysum32] "+r" (ysum32), [tmp_x] "+r" (tmp_x), [csum32] "+r" (csum32),
84 : [scaling] "r" (scaling)
85 : "memory", "hi", "lo"
88 logcorQ8 += PITCH_LAG_SPAN2 - 1;
89 lys = WebRtcIsacfix_Log2Q8((uint32_t)ysum32); // Q8
90 lys = WEBRTC_SPL_RSHIFT_W32(lys, 1); //sqrt(ysum);
92 lcs = WebRtcIsacfix_Log2Q8((uint32_t)csum32); // 2log(csum) in Q8
93 if (lcs > (lys + oneQ8)) { // csum/sqrt(ysum) > 2 in Q8
94 *logcorQ8 = lcs - lys; // log2(csum/sqrt(ysum))
96 *logcorQ8 = oneQ8; // 1.00
102 for (k = 1; k < PITCH_LAG_SPAN2; k++) {
104 const int16_t* tmp_in1 = &in[k - 1];
105 const int16_t* tmp_in2 = &in[PITCH_CORR_LEN2 + k - 1];
106 const int16_t* tmp_x = x;
107 int32_t tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8;
112 ".set noreorder \n\t"
113 "lh %[tmp1], 0(%[tmp_in1]) \n\t"
114 "lh %[tmp2], 0(%[tmp_in2]) \n\t"
115 "mul %[tmp1], %[tmp1], %[tmp1] \n\t"
116 "mul %[tmp2], %[tmp2], %[tmp2] \n\t"
117 "srav %[tmp1], %[tmp1], %[scaling] \n\t"
118 "srav %[tmp2], %[tmp2], %[scaling] \n\t"
119 "subu %[ysum32], %[ysum32], %[tmp1] \n\t"
120 "bnez %[scaling], 2f \n\t"
121 " addu %[ysum32], %[ysum32], %[tmp2] \n\t"
123 "lh %[tmp1], 0(%[inptr]) \n\t"
124 "lh %[tmp2], 0(%[tmp_x]) \n\t"
125 "lh %[tmp3], 2(%[inptr]) \n\t"
126 "lh %[tmp4], 2(%[tmp_x]) \n\t"
127 "lh %[tmp5], 4(%[inptr]) \n\t"
128 "lh %[tmp6], 4(%[tmp_x]) \n\t"
129 "lh %[tmp7], 6(%[inptr]) \n\t"
130 "lh %[tmp8], 6(%[tmp_x]) \n\t"
131 "mul %[tmp1], %[tmp1], %[tmp2] \n\t"
132 "mul %[tmp2], %[tmp3], %[tmp4] \n\t"
133 "mul %[tmp3], %[tmp5], %[tmp6] \n\t"
134 "mul %[tmp4], %[tmp7], %[tmp8] \n\t"
135 "addiu %[n], %[n], -4 \n\t"
136 "addiu %[inptr], %[inptr], 8 \n\t"
137 "addiu %[tmp_x], %[tmp_x], 8 \n\t"
138 "addu %[csum32], %[csum32], %[tmp1] \n\t"
139 "addu %[csum32], %[csum32], %[tmp2] \n\t"
140 "addu %[csum32], %[csum32], %[tmp3] \n\t"
142 " addu %[csum32], %[csum32], %[tmp4] \n\t"
146 "lh %[tmp1], 0(%[inptr]) \n\t"
147 "lh %[tmp2], 0(%[tmp_x]) \n\t"
148 "lh %[tmp3], 2(%[inptr]) \n\t"
149 "lh %[tmp4], 2(%[tmp_x]) \n\t"
150 "lh %[tmp5], 4(%[inptr]) \n\t"
151 "lh %[tmp6], 4(%[tmp_x]) \n\t"
152 "lh %[tmp7], 6(%[inptr]) \n\t"
153 "lh %[tmp8], 6(%[tmp_x]) \n\t"
154 "mul %[tmp1], %[tmp1], %[tmp2] \n\t"
155 "mul %[tmp2], %[tmp3], %[tmp4] \n\t"
156 "mul %[tmp3], %[tmp5], %[tmp6] \n\t"
157 "mul %[tmp4], %[tmp7], %[tmp8] \n\t"
158 "addiu %[n], %[n], -4 \n\t"
159 "addiu %[inptr], %[inptr], 8 \n\t"
160 "addiu %[tmp_x], %[tmp_x], 8 \n\t"
161 "srav %[tmp1], %[tmp1], %[scaling] \n\t"
162 "srav %[tmp2], %[tmp2], %[scaling] \n\t"
163 "srav %[tmp3], %[tmp3], %[scaling] \n\t"
164 "srav %[tmp4], %[tmp4], %[scaling] \n\t"
165 "addu %[csum32], %[csum32], %[tmp1] \n\t"
166 "addu %[csum32], %[csum32], %[tmp2] \n\t"
167 "addu %[csum32], %[csum32], %[tmp3] \n\t"
169 " addu %[csum32], %[csum32], %[tmp4] \n\t"
172 : [tmp1] "=&r" (tmp1), [tmp2] "=&r" (tmp2), [tmp3] "=&r" (tmp3),
173 [tmp4] "=&r" (tmp4), [tmp5] "=&r" (tmp5), [tmp6] "=&r" (tmp6),
174 [tmp7] "=&r" (tmp7), [tmp8] "=&r" (tmp8), [inptr] "+r" (inptr),
175 [csum32] "+r" (csum32), [tmp_x] "+r" (tmp_x), [ysum32] "+r" (ysum32),
177 : [tmp_in1] "r" (tmp_in1), [tmp_in2] "r" (tmp_in2),
178 [scaling] "r" (scaling)
179 : "memory", "hi", "lo"
183 lys = WebRtcIsacfix_Log2Q8((uint32_t)ysum32); // Q8
184 lys = WEBRTC_SPL_RSHIFT_W32(lys, 1); //sqrt(ysum);
186 lcs = WebRtcIsacfix_Log2Q8((uint32_t)csum32); // 2log(csum) in Q8
187 if (lcs > (lys + oneQ8)) { // csum/sqrt(ysum) > 2
188 *logcorQ8 = lcs - lys; // log2(csum/sqrt(ysum))
190 *logcorQ8 = oneQ8; // 1.00