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 "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" 14 15 extern int32_t WebRtcIsacfix_Log2Q8(uint32_t x); 16 17 void WebRtcIsacfix_PCorr2Q32(const int16_t* in, int32_t* logcorQ8) { 18 int16_t scaling,n,k; 19 int32_t ysum32,csum32, lys, lcs; 20 int32_t oneQ8; 21 const int16_t* x; 22 const int16_t* inptr; 23 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, 27 PITCH_CORR_LEN2, 28 PITCH_CORR_LEN2); 29 ysum32 = 1; 30 csum32 = 0; 31 x = in + PITCH_MAX_LAG / 2 + 2; 32 { 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; 36 n = PITCH_CORR_LEN2; 37 COMPILE_ASSERT(PITCH_CORR_LEN2 % 4 == 0); 38 __asm __volatile ( 39 ".set push \n\t" 40 ".set noreorder \n\t" 41 "1: \n\t" 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" 76 "bgtz %[n], 1b \n\t" 77 " addiu %[tmp_x], %[tmp_x], 8 \n\t" 78 ".set pop \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), 83 [n] "+r" (n) 84 : [scaling] "r" (scaling) 85 : "memory", "hi", "lo" 86 ); 87 } 88 logcorQ8 += PITCH_LAG_SPAN2 - 1; 89 lys = WebRtcIsacfix_Log2Q8((uint32_t)ysum32); // Q8 90 lys = WEBRTC_SPL_RSHIFT_W32(lys, 1); //sqrt(ysum); 91 if (csum32 > 0) { 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)) 95 } else { 96 *logcorQ8 = oneQ8; // 1.00 97 } 98 } else { 99 *logcorQ8 = 0; 100 } 101 102 for (k = 1; k < PITCH_LAG_SPAN2; k++) { 103 inptr = &in[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; 108 n = PITCH_CORR_LEN2; 109 csum32 = 0; 110 __asm __volatile ( 111 ".set push \n\t" 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" 122 "1: \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" 141 "bgtz %[n], 1b \n\t" 142 " addu %[csum32], %[csum32], %[tmp4] \n\t" 143 "b 3f \n\t" 144 " nop \n\t" 145 "2: \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" 168 "bgtz %[n], 2b \n\t" 169 " addu %[csum32], %[csum32], %[tmp4] \n\t" 170 "3: \n\t" 171 ".set pop \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), 176 [n] "+r" (n) 177 : [tmp_in1] "r" (tmp_in1), [tmp_in2] "r" (tmp_in2), 178 [scaling] "r" (scaling) 179 : "memory", "hi", "lo" 180 ); 181 182 logcorQ8--; 183 lys = WebRtcIsacfix_Log2Q8((uint32_t)ysum32); // Q8 184 lys = WEBRTC_SPL_RSHIFT_W32(lys, 1); //sqrt(ysum); 185 if (csum32 > 0) { 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)) 189 } else { 190 *logcorQ8 = oneQ8; // 1.00 191 } 192 } else { 193 *logcorQ8 = 0; 194 } 195 } 196 } 197