Line data Source code
1 : /******************************************************************************
2 : * ETSI TS 103 634 V1.6.1 *
3 : * Low Complexity Communication Codec Plus (LC3plus) *
4 : * *
5 : * Copyright licence is solely granted through ETSI Intellectual Property *
6 : * Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
7 : * estoppel or otherwise. *
8 : ******************************************************************************/
9 :
10 : #include "options.h"
11 : #include "wmc_auto.h"
12 : #include "functions.h"
13 :
14 : static void filter_olpa(LC3_FLOAT* in, LC3_FLOAT* out, const LC3_FLOAT* buf, LC3_INT32 len_input);
15 : static LC3_INT searchMaxIndice(LC3_FLOAT* in, LC3_INT32 len);
16 :
17 1189311 : void filter_olpa(LC3_FLOAT* in, LC3_FLOAT* out, const LC3_FLOAT* buf, LC3_INT32 len_input)
18 : {
19 : /* a = 1, so denominator == 1, nothing to do here */
20 : LC3_INT32 i, j;
21 :
22 :
23 1189311 : j = 0;
24 40846111 : for (i = 4; i < len_input; i += 2) {
25 39656800 : out[j++] = (buf[0] * in[i]) + (buf[1] * in[i - 1]) + (buf[2] * in[i - 2]) + (buf[3] * in[i - 3]) + (buf[4] * in[i - 4]);
26 : }
27 1189311 : }
28 :
29 2378622 : LC3_INT searchMaxIndice(LC3_FLOAT* in, LC3_INT len)
30 : {
31 2378622 : LC3_INT max_i = 0, i;
32 2378622 : LC3_FLOAT max = in[0];
33 :
34 2378622 : if (len <= 0) {
35 0 : return -128;
36 : }
37 :
38 129220411 : for (i = 0; i < len; i++) {
39 126841789 : if (in[i] > max) {
40 15391681 : max = in[i];
41 15391681 : max_i = i;
42 : }
43 : }
44 :
45 2378622 : return max_i;
46 : }
47 :
48 1189311 : void processOlpa_fl(LC3_FLOAT* s_12k8, LC3_FLOAT* mem_s12k8, LC3_FLOAT* mem_s6k4, LC3_INT* mem_old_T0,
49 : LC3_INT* pitch_flag,
50 : LC3_INT* T0_out, LC3_FLOAT* normcorr_out, LC3_INT len, LC3PLUS_FrameDuration frame_dms)
51 : {
52 1189311 : LC3_FLOAT norm_corr = 0, sum = 0, sum0 = 0, sum1 = 0, sum2 = 0, norm_corr2 = 0, *s6k4;
53 : LC3_FLOAT buf[LEN_6K4 + MAX_PITCH_6K4 + MAX_LEN], R0[RANGE_PITCH_6K4]; /* constant length */
54 1189311 : LC3_INT i = 0, len2 = 0, T0 = 0, T02 = 0, min_pitch = 0, max_pitch = 0, L = 0, mem_in_len = 0, acflen = 0, delta = 0;
55 :
56 1189311 : len2 = len / 2;
57 1189311 : switch(frame_dms)
58 : {
59 1139323 : case LC3PLUS_FRAME_DURATION_5MS:
60 1139323 : delta = len / 2;
61 1139323 : acflen = len2 * 2;
62 1139323 : break;
63 :
64 16 : case LC3PLUS_FRAME_DURATION_2p5MS:
65 16 : delta = 3*(len /2);
66 16 : acflen = len2*4;
67 16 : break;
68 : #ifdef CR9_C_ADD_1p25MS
69 0 : case LC3PLUS_FRAME_DURATION_1p25MS:
70 0 : delta = 7 * (len / 2);
71 0 : acflen = len2 * 8;
72 0 : break;
73 : #endif
74 :
75 49972 : default:
76 49972 : delta = 0;
77 49972 : acflen = len2;
78 : }
79 :
80 1189311 : mem_in_len = MAX_PITCH_6K4 + delta;
81 :
82 : /* Downsampling */
83 1189311 : move_float(buf, mem_s12k8, 3);
84 1189311 : move_float(&buf[3], s_12k8, len);
85 1189311 : move_float(mem_s12k8, &buf[len], 3);
86 1189311 : filter_olpa(buf, R0, olpa_down2, len + 3);
87 :
88 : /* Compute autocorrelation */
89 1189311 : s6k4 = &buf[mem_in_len - delta];
90 1189311 : move_float(&buf[mem_in_len], R0, len2);
91 1189311 : move_float(buf, mem_s6k4, mem_in_len);
92 1189311 : move_float(mem_s6k4, &buf[len2], mem_in_len);
93 :
94 117741789 : for (i = MIN_PITCH_6K4; i <= MAX_PITCH_6K4; i++) {
95 116552478 : sum = mac_loop(s6k4, &s6k4[-i], acflen);
96 116552478 : R0[i - MIN_PITCH_6K4] = sum;
97 : }
98 :
99 : /* Weight autocorrelation and find maximum */
100 :
101 : /* Second try in the neighborhood of the previous pitch */
102 1189311 : min_pitch = MAX(MIN_PITCH_6K4, *mem_old_T0 - 4);
103 1189311 : max_pitch = MIN(MAX_PITCH_6K4, *mem_old_T0 + 4);
104 :
105 1189311 : L = searchMaxIndice(&R0[min_pitch - MIN_PITCH_6K4], max_pitch - min_pitch + 1 );
106 1189311 : T02 = L + min_pitch;
107 :
108 117741789 : for (i = 0; i < RANGE_PITCH_6K4; i++) {
109 116552478 : R0[i] = R0[i] * olpa_acw[i];
110 : }
111 1189311 : L = searchMaxIndice(R0, RANGE_PITCH_6K4);
112 1189311 : T0 = L + MIN_PITCH_6K4;
113 :
114 : /* Compute normalized correlation */
115 1189311 : sum0 = sum1 = sum2 = 0;
116 :
117 77305215 : for (i = 0; i < acflen; i++) {
118 76115904 : sum0 += s6k4[i] * s6k4[i - T0];
119 76115904 : sum1 += s6k4[i - T0] * s6k4[i - T0];
120 76115904 : sum2 += s6k4[i] * s6k4[i];
121 : }
122 1189311 : sum1 = sum1 * sum2;
123 1189311 : sum1 = LC3_SQRT(sum1) + 1.00e-05;
124 1189311 : norm_corr = sum0 / sum1;
125 1189311 : norm_corr = MAX(0, norm_corr);
126 :
127 1189311 : if (T02 != T0) {
128 591269 : sum0 = sum1 = sum2 = 0;
129 38432485 : for (i = 0; i < acflen; i++) {
130 37841216 : sum0 += s6k4[i] * s6k4[i - T02];
131 37841216 : sum1 += s6k4[i - T02] * s6k4[i - T02];
132 37841216 : sum2 += s6k4[i] * s6k4[i];
133 : }
134 591269 : sum1 = sum1 * sum2;
135 591269 : sum1 = LC3_SQRT(sum1) + 1.00e-05;
136 591269 : norm_corr2 = sum0 / sum1;
137 591269 : norm_corr2 = MAX(0, norm_corr2);
138 :
139 591269 : if (norm_corr2 > (norm_corr * 0.85)) {
140 286375 : T0 = T02;
141 286375 : norm_corr = norm_corr2;
142 : }
143 : }
144 :
145 1189311 : switch(frame_dms)
146 : {
147 1139323 : case LC3PLUS_FRAME_DURATION_5MS:
148 1139323 : if (*pitch_flag == 1)
149 : {
150 569656 : *mem_old_T0 = T0;
151 569656 : *pitch_flag = 0;
152 : }
153 : else
154 : {
155 569667 : *pitch_flag += 1;
156 : }
157 1139323 : break;
158 :
159 16 : case LC3PLUS_FRAME_DURATION_2p5MS:
160 16 : if (*pitch_flag == 3)
161 : {
162 4 : *mem_old_T0 = T0;
163 4 : *pitch_flag = 0;
164 : }
165 : else
166 : {
167 12 : *pitch_flag += 1;
168 : }
169 16 : break;
170 : #ifdef CR9_C_ADD_1p25MS
171 0 : case LC3PLUS_FRAME_DURATION_1p25MS:
172 0 : if (*pitch_flag == 7)
173 : {
174 0 : *mem_old_T0 = T0;
175 0 : *pitch_flag = 0;
176 : }
177 : else
178 : {
179 0 : *pitch_flag += 1;
180 : }
181 0 : break;
182 : #endif
183 :
184 49972 : default:
185 49972 : *mem_old_T0 = T0;
186 : }
187 :
188 1189311 : *T0_out = T0 * 2.0;
189 1189311 : *normcorr_out = norm_corr;
190 1189311 : }
|