Line data Source code
1 : /******************************************************************************
2 : * ETSI TS 103 634 V1.5.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 LC3_INT searchMaxIndice(LC3_FLOAT* in, LC3_INT len);
15 :
16 1617786 : LC3_INT searchMaxIndice(LC3_FLOAT* in, LC3_INT len)
17 : {
18 1617786 : LC3_INT max_i = 0, i;
19 1617786 : LC3_FLOAT max = 0;
20 :
21 1617786 : if (len <= 0) {
22 0 : return -128;
23 : }
24 :
25 14407825 : for (i = 0; i < len; i++) {
26 12790039 : if (in[i] > max) {
27 6806040 : max = in[i];
28 6806040 : max_i = i;
29 : }
30 : }
31 :
32 1617786 : return max_i;
33 : }
34 :
35 1189311 : void process_ltpf_coder_fl(LC3_FLOAT* xin, LC3_INT xLen, LC3_INT ltpf_enable, LC3_INT pitch_ol, LC3_FLOAT pitch_ol_norm_corr, LC3_INT frame_dms,
36 : LC3_FLOAT* mem_old_x, LC3_INT memLen, LC3_FLOAT* mem_norm_corr_past, LC3_INT* mem_on, LC3_FLOAT* mem_pitch,
37 : LC3_INT* param, LC3_FLOAT* mem_norm_corr_past_past, LC3_INT* bits
38 : , LC3_INT16 hrmode
39 : )
40 : {
41 1189311 : LC3_FLOAT buffer[LTPF_MEMIN_LEN + LEN_12K8 + 1 + (LEN_12K8 >> 2)], sum = 0, cor_up[(MAX_PITCH_12K8 - MIN_PITCH_12K8) / 2] = {0}, *x;
42 : LC3_INT i, j, n, step, N, ltpf_active, pitch_search_delta,
43 1189311 : pitch_search_upsamp = 0, pitch_search_L_interpol1 = 0,
44 1189311 : t0_min = 0, t0_max = 0, t_min = 0, t_max = 0, temp2 = 0, t1 = 0, pitch_int = 0, pitch_fr = 0, midpoint = 0,
45 1189311 : delta_up = 0, delta_down = 0, pitch_index = 0, gain = 0, acflen = 0;
46 1189311 : LC3_FLOAT cor_tmp, cor_int_tmp, norm_corr = 0, cor[MAX_LEN_NR], cor_int[MAX_LEN_NR], sum1 = 0, sum2 = 0, sum3 = 0;
47 1189311 : LC3_FLOAT pitch = 0;
48 :
49 1189311 : LC3_FLOAT normCorrTh = 0.0f;
50 1189311 : if (hrmode) {
51 0 : normCorrTh = 0.4;
52 : } else {
53 1189311 : normCorrTh = 0.6;
54 : }
55 :
56 : /* Signal Buffer */
57 1189311 : N = xLen - 1;
58 1189311 : x = &buffer[memLen];
59 :
60 1189311 : move_float(buffer, mem_old_x, memLen);
61 1189311 : move_float(x, xin, xLen);
62 1189311 : move_float(mem_old_x, &buffer[N], xLen + memLen - N);
63 :
64 1189311 : ltpf_active = 0;
65 1189311 : norm_corr = 0;
66 :
67 1189311 : pitch_search_delta = 4;
68 1189311 : pitch_search_upsamp = 4;
69 1189311 : pitch_search_L_interpol1 = 4;
70 :
71 1189311 : if (pitch_ol_norm_corr > normCorrTh) {
72 : /* Search Bounds */
73 889031 : t0_min = pitch_ol - pitch_search_delta;
74 889031 : t0_max = pitch_ol + pitch_search_delta;
75 889031 : t0_min = MAX(t0_min, MIN_PITCH_12K8);
76 889031 : t0_max = MIN(t0_max, MAX_PITCH_12K8);
77 889031 : acflen = N;
78 :
79 889031 : if (frame_dms == 25)
80 : {
81 0 : acflen = 2 * N;
82 0 : x = x - N;
83 : }
84 :
85 : /* Cross-Correlation Bounds */
86 889031 : t_min = t0_min - pitch_search_L_interpol1;
87 889031 : t_max = t0_max + pitch_search_L_interpol1;
88 :
89 : /* Compute norm */
90 889031 : sum1 = sum2 = 0;
91 60324871 : for (j = 0; j < acflen; j++) {
92 59435840 : sum1 += x[j] * x[j];
93 59435840 : sum2 += x[j - t_min] * x[j - t_min];
94 : }
95 :
96 : /* Do first iteration outside of loop */
97 889031 : sum = mac_loop(x, &x[-t_min], acflen);
98 :
99 889031 : sum3 = LC3_SQRT(sum1 * sum2) + 1.00e-05;
100 889031 : norm_corr = sum / sum3;
101 :
102 889031 : norm_corr = MAX(0, norm_corr);
103 889031 : cor[0] = norm_corr;
104 :
105 : /* Compute Cross-Correlation */
106 15052435 : for (i = t_min + 1; i <= t_max; i++) {
107 14163404 : sum = mac_loop(x, &x[-i], acflen);
108 :
109 14163404 : sum2 = sum2 + x[-i]*x[-i]
110 14163404 : - x[acflen - 1 - ( i - 1 )]*x[acflen - 1 - ( i - 1 )];
111 :
112 14163404 : sum3 = LC3_SQRT(sum1 * sum2) + 1.00e-05;
113 14163404 : norm_corr = sum / sum3;
114 :
115 14163404 : norm_corr = MAX(0, norm_corr);
116 14163404 : cor[i - t_min] = norm_corr;
117 :
118 : }
119 :
120 : /* Find Integer Pitch-Lag */
121 889031 : temp2 = searchMaxIndice(&cor[pitch_search_L_interpol1], t_max - t_min - pitch_search_L_interpol1 - pitch_search_L_interpol1 + 1);
122 :
123 889031 : t1 = temp2 + t0_min;
124 889031 : assert(t1 >= t0_min && t1 <= t0_max);
125 :
126 : /* Find Fractional Pitch-Lag */
127 889031 : if (t1 >= RES2_PITCH_12K8) {
128 160276 : pitch_int = t1;
129 160276 : pitch_fr = 0;
130 : } else {
131 728755 : j = 0;
132 :
133 13081600 : for (i = 0; i < pitch_search_upsamp * (t_max - t_min) + 1; i = i + pitch_search_upsamp) {
134 12352845 : cor_up[i] = cor[j];
135 12352845 : j++;
136 : }
137 :
138 26819975 : for (i = 0; i < pitch_search_upsamp * (t0_max - t0_min + 1); i++) {
139 26091220 : sum = mac_loop(&cor_up[i], (const LC3_FLOAT *)inter4_1, 32);
140 :
141 26091220 : cor_int[i] = sum;
142 : }
143 :
144 728755 : if (t1 >= RES4_PITCH_12K8) {
145 34614 : step = 2;
146 : } else {
147 694141 : step = 1;
148 : }
149 :
150 728755 : midpoint = pitch_search_upsamp * (t1 - t0_min) + 1;
151 728755 : delta_up = pitch_search_upsamp - step;
152 :
153 728755 : if (t1 == t0_min) {
154 38899 : delta_down = 0;
155 : } else {
156 689856 : delta_down = pitch_search_upsamp - step;
157 : }
158 :
159 728755 : j = 0;
160 6272748 : for (i = midpoint - delta_down - 1; i <= midpoint + delta_up; i = i + step) {
161 5543993 : cor[j] = cor_int[i];
162 5543993 : j++;
163 : }
164 :
165 :
166 728755 : temp2 = searchMaxIndice(cor, ((midpoint + delta_up) - (midpoint - delta_down)) / step + 1);
167 728755 : pitch_fr = temp2 * step - delta_down;
168 :
169 728755 : if (pitch_fr >= 0) {
170 643832 : pitch_int = t1;
171 : } else {
172 84923 : pitch_int = t1 - 1;
173 84923 : pitch_fr = pitch_search_upsamp + pitch_fr;
174 : }
175 : }
176 :
177 889031 : assert((pitch_int <= MAX_PITCH_12K8 && pitch_int >= RES2_PITCH_12K8 && pitch_fr == 0) ||
178 : (pitch_int < RES2_PITCH_12K8 && pitch_int >= RES4_PITCH_12K8 && (pitch_fr == 0 || pitch_fr == 2)) ||
179 : (pitch_int < RES4_PITCH_12K8 && pitch_int >= MIN_PITCH_12K8 &&
180 : (pitch_fr == 0 || pitch_fr == 1 || pitch_fr == 2 || pitch_fr == 3)));
181 :
182 889031 : if (pitch_int < RES4_PITCH_12K8) {
183 694273 : pitch_index = pitch_int * 4 + pitch_fr - (MIN_PITCH_12K8 * 4);
184 194758 : } else if (pitch_int < RES2_PITCH_12K8) {
185 34482 : pitch_index = pitch_int * 2 + floor(pitch_fr / 2) - (RES4_PITCH_12K8 * 2) + ((RES4_PITCH_12K8 - MIN_PITCH_12K8) * 4);
186 : } else {
187 160276 : pitch_index = pitch_int - RES2_PITCH_12K8 + ((RES4_PITCH_12K8 - MIN_PITCH_12K8) * 4) + ((RES2_PITCH_12K8 - RES4_PITCH_12K8) * 2);
188 : }
189 :
190 889031 : assert(pitch_index >= 0 && pitch_index < 512);
191 889031 : pitch = (LC3_FLOAT) pitch_int + (LC3_FLOAT) pitch_fr / 4.0;
192 :
193 :
194 : /* Normalized Correlation */
195 889031 : sum1 = sum2 = sum3 = 0;
196 60324871 : for (n = 0; n < acflen; n++)
197 : {
198 59435840 : cor_tmp = x[n + 1] * enc_inter_filter[0][0] +
199 59435840 : x[n] * enc_inter_filter[0][1] +
200 59435840 : x[n - 1] * enc_inter_filter[0][2];
201 :
202 59435840 : cor_int_tmp = x[n - pitch_int + 1] * enc_inter_filter[pitch_fr][0] +
203 59435840 : x[n - pitch_int] * enc_inter_filter[pitch_fr][1] +
204 59435840 : x[n - pitch_int - 1] * enc_inter_filter[pitch_fr][2] +
205 59435840 : x[n - pitch_int - 2] * enc_inter_filter[pitch_fr][3];
206 :
207 59435840 : sum1 += cor_tmp * cor_int_tmp;
208 59435840 : sum2 += cor_tmp * cor_tmp;
209 59435840 : sum3 += cor_int_tmp * cor_int_tmp;
210 : }
211 :
212 889031 : sum2 = LC3_SQRT(sum2 * sum3) + 1.00e-05;
213 889031 : norm_corr = sum1 / sum2;
214 :
215 889031 : assert(norm_corr >= -1.00001 && norm_corr <= 1.00001);
216 889031 : norm_corr = MIN(1, MAX(-1, norm_corr));
217 889031 : if (norm_corr < 0) {
218 2138 : norm_corr = 0;
219 : }
220 :
221 889031 : if (ltpf_enable == 1) {
222 : /* Decision if ltpf active */
223 0 : if ((*mem_on == 0 && (frame_dms == 100 || *mem_norm_corr_past_past > 0.94) && *mem_norm_corr_past > 0.94 &&
224 0 : norm_corr > 0.94) ||
225 0 : (*mem_on == 1 && norm_corr > 0.9) ||
226 0 : (*mem_on == 1 && LC3_FABS(pitch - *mem_pitch) < 2 && (norm_corr - *mem_norm_corr_past) > -0.1 &&
227 0 : norm_corr > 0.84)) {
228 0 : ltpf_active = 1;
229 : }
230 : }
231 :
232 889031 : gain = 4;
233 :
234 : } else {
235 300280 : gain = 0;
236 300280 : norm_corr = pitch_ol_norm_corr;
237 300280 : pitch = 0;
238 : }
239 :
240 1189311 : if (gain > 0) {
241 889031 : param[0] = 1;
242 889031 : param[1] = ltpf_active;
243 889031 : param[2] = pitch_index;
244 889031 : *bits = 11;
245 : } else {
246 300280 : zero_int(param, 3);
247 :
248 300280 : *bits = 1;
249 : }
250 :
251 1189311 : if (frame_dms < 100) {
252 1139339 : *mem_norm_corr_past_past = *mem_norm_corr_past;
253 : }
254 :
255 1189311 : *mem_norm_corr_past = norm_corr;
256 1189311 : *mem_on = ltpf_active;
257 1189311 : *mem_pitch = pitch;
258 1189311 : }
|