1 /******************************************************************************
2 * *
3 * Copyright (C) 2023 The Android Open Source Project
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 *****************************************************************************
18 * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19 */
20
21 #include <string.h>
22 #include "ixheaac_type_def.h"
23 #include "ixheaac_constants.h"
24 #include "ixheaace_sbr_def.h"
25 #include "ixheaace_resampler.h"
26 #include "iusace_cnst.h"
27
ia_enhaacplus_enc_downsample_iir_filter(ixheaace_iir21_resampler * pstr_down_sampler,FLOAT32 * ptr_in_samples,FLOAT32 * ptr_out_samples,WORD32 in_stride,WORD32 num_in_samples,WORD32 * num_out_samples,WORD32 out_stride,FLOAT32 * ptr_ring_buf1,FLOAT32 * ptr_ring_buf2)28 static VOID ia_enhaacplus_enc_downsample_iir_filter(
29 ixheaace_iir21_resampler *pstr_down_sampler, FLOAT32 *ptr_in_samples,
30 FLOAT32 *ptr_out_samples, WORD32 in_stride, WORD32 num_in_samples, WORD32 *num_out_samples,
31 WORD32 out_stride, FLOAT32 *ptr_ring_buf1, FLOAT32 *ptr_ring_buf2) {
32 WORD32 i;
33 ixheaace_iir_filter *pstr_iir_filter = &(pstr_down_sampler->iir_filter);
34 FLOAT32 *ptr_iir_ring1, *ptr_iir_ring2;
35 FLOAT32 coeff_temp_a, coeff_temp_b;
36 const FLOAT32 *ptr_coeff_filt = (FLOAT32 *)pstr_iir_filter->ptr_coeff_iir_num;
37 FLOAT32 iir_out = 0;
38 FLOAT32 temp1 = 0.f, temp2 = 0.f;
39
40 *num_out_samples = 0;
41 ptr_iir_ring1 = ptr_ring_buf1;
42 ptr_iir_ring2 = ptr_ring_buf2;
43
44 for (i = 0; i < num_in_samples; i++) {
45 temp1 = ptr_in_samples[i * in_stride] / 2;
46 ptr_iir_ring1[i] = temp1;
47 coeff_temp_b = *ptr_coeff_filt;
48 temp1 = coeff_temp_b * (temp1 + ptr_iir_ring1[i - 10]);
49 coeff_temp_a = *(ptr_coeff_filt + 16);
50 iir_out = (ptr_iir_ring2[i - 10] * coeff_temp_a);
51
52 coeff_temp_b = *(ptr_coeff_filt + 1);
53 temp1 = (coeff_temp_b * (ptr_iir_ring1[i - 1] + ptr_iir_ring1[i - 9])) + temp1;
54 coeff_temp_a = *(ptr_coeff_filt + 7);
55 temp2 = (ptr_iir_ring2[i - 1] * coeff_temp_a) + iir_out;
56 coeff_temp_a = *(ptr_coeff_filt + 15);
57 iir_out = (ptr_iir_ring2[i - 9] * coeff_temp_a) + temp2;
58
59 coeff_temp_b = *(ptr_coeff_filt + 2);
60 temp1 = (coeff_temp_b * (ptr_iir_ring1[i - 2] + ptr_iir_ring1[i - 8])) + temp1;
61 coeff_temp_a = *(ptr_coeff_filt + 8);
62 temp2 = (ptr_iir_ring2[i - 2] * coeff_temp_a) + iir_out;
63 coeff_temp_a = *(ptr_coeff_filt + 14);
64 iir_out = (ptr_iir_ring2[i - 8] * coeff_temp_a) + temp2;
65
66 coeff_temp_b = *(ptr_coeff_filt + 3);
67 temp1 = (coeff_temp_b * (ptr_iir_ring1[i - 3] + ptr_iir_ring1[i - 7])) + temp1;
68 coeff_temp_a = *(ptr_coeff_filt + 9);
69 temp2 = (ptr_iir_ring2[i - 3] * coeff_temp_a) + iir_out;
70 coeff_temp_a = *(ptr_coeff_filt + 13);
71 iir_out = (ptr_iir_ring2[i - 7] * coeff_temp_a) + temp2;
72
73 coeff_temp_b = *(ptr_coeff_filt + 4);
74 temp1 = (coeff_temp_b * (ptr_iir_ring1[i - 4] + ptr_iir_ring1[i - 6])) + temp1;
75 coeff_temp_a = *(ptr_coeff_filt + 10);
76 temp2 = (ptr_iir_ring2[i - 4] * coeff_temp_a) + iir_out;
77 coeff_temp_a = *(ptr_coeff_filt + 12);
78 iir_out = (ptr_iir_ring2[i - 6] * coeff_temp_a) + temp2;
79
80 coeff_temp_b = *(ptr_coeff_filt + 5);
81 temp1 = (coeff_temp_b * ptr_iir_ring1[i - 5]) + temp1;
82 coeff_temp_a = *(ptr_coeff_filt + 11);
83 iir_out = (ptr_iir_ring2[i - 5] * coeff_temp_a) + iir_out;
84 iir_out = temp1 - iir_out;
85
86 ptr_iir_ring2[i] = iir_out;
87 iir_out = (iir_out * (4681.0f / 32767.0f) * pstr_iir_filter->max);
88
89 pstr_down_sampler->pending++;
90
91 if (pstr_down_sampler->pending == pstr_down_sampler->ratio) {
92 ptr_out_samples[(*num_out_samples) * out_stride] = iir_out;
93 (*num_out_samples)++;
94
95 pstr_down_sampler->pending = 0;
96 }
97 }
98 }
99
ia_enhaacplus_enc_copy_ring_buffers(FLOAT32 * ptr_iir_ring1,FLOAT32 * ptr_iir_ring2,FLOAT32 * ptr_ring_buf1,FLOAT32 * ptr_ring_buf2)100 static VOID ia_enhaacplus_enc_copy_ring_buffers(FLOAT32 *ptr_iir_ring1, FLOAT32 *ptr_iir_ring2,
101 FLOAT32 *ptr_ring_buf1, FLOAT32 *ptr_ring_buf2) {
102 WORD32 i;
103 FLOAT32 temp1, temp2, temp3;
104 for (i = (LEN_RING_BUF / 2) - 1; i >= 0; i--) {
105 temp1 = *ptr_iir_ring1++;
106 temp2 = *ptr_iir_ring2++;
107 temp3 = *ptr_iir_ring1++;
108
109 *ptr_ring_buf1++ = temp1;
110 temp1 = *ptr_iir_ring2++;
111 *ptr_ring_buf2++ = temp2;
112 *ptr_ring_buf1++ = temp3;
113 *ptr_ring_buf2++ = temp1;
114 }
115 }
116
ia_enhaacplus_enc_copy_ring_buffers_sos(FLOAT32 * ptr_iir_ring1,FLOAT32 * ptr_iir_ring2,FLOAT32 * ptr_ring_buf1,FLOAT32 * ptr_ring_buf2,WORD32 len1,WORD32 len2)117 static VOID ia_enhaacplus_enc_copy_ring_buffers_sos(FLOAT32 *ptr_iir_ring1,
118 FLOAT32 *ptr_iir_ring2,
119 FLOAT32 *ptr_ring_buf1,
120 FLOAT32 *ptr_ring_buf2, WORD32 len1,
121 WORD32 len2) {
122 memcpy(ptr_ring_buf1, ptr_iir_ring1, len1 * sizeof(*ptr_ring_buf1));
123 memcpy(ptr_ring_buf2, ptr_iir_ring2, len2 * sizeof(*ptr_ring_buf2));
124 }
125
ia_enhaacplus_enc_update_ring_buffer_sos(FLOAT32 * ptr_ring_buf,FLOAT32 * ptr_samples,WORD32 len,WORD32 in_stride,WORD32 coeff_idx)126 static VOID ia_enhaacplus_enc_update_ring_buffer_sos(FLOAT32 *ptr_ring_buf, FLOAT32 *ptr_samples,
127 WORD32 len, WORD32 in_stride,
128 WORD32 coeff_idx) {
129 ptr_ring_buf[2 * coeff_idx] = ptr_samples[len - 2 * in_stride];
130 ptr_ring_buf[2 * coeff_idx + 1] = ptr_samples[len - in_stride];
131 }
132
ixheaace_get_input_scratch_buf(VOID * ptr_scr,FLOAT32 ** ptr_scratch_buf_inp)133 VOID ixheaace_get_input_scratch_buf(VOID *ptr_scr, FLOAT32 **ptr_scratch_buf_inp) {
134 ixheaace_resampler_scratch *pstr_resampler_scr = (ixheaace_resampler_scratch *)ptr_scr;
135
136 *ptr_scratch_buf_inp = pstr_resampler_scr->downsampler_in_buffer;
137 }
138
ixheaace_resampler_scr_size(VOID)139 WORD32 ixheaace_resampler_scr_size(VOID) {
140 return IXHEAAC_GET_SIZE_ALIGNED(sizeof(ixheaace_resampler_scratch), BYTE_ALIGN_8);
141 }
142
ia_enhaacplus_enc_iir_sos_filter(ixheaace_iir_sos_resampler * pstr_down_sampler,FLOAT32 * ptr_in_samples,WORD32 in_stride,FLOAT32 * ptr_out_samples,WORD32 num_in_samples,FLOAT32 * ptr_ring_buf1,FLOAT32 * ptr_ring_buf2,WORD32 coeff_idx)143 static VOID ia_enhaacplus_enc_iir_sos_filter(ixheaace_iir_sos_resampler *pstr_down_sampler,
144 FLOAT32 *ptr_in_samples, WORD32 in_stride,
145 FLOAT32 *ptr_out_samples, WORD32 num_in_samples,
146 FLOAT32 *ptr_ring_buf1, FLOAT32 *ptr_ring_buf2,
147 WORD32 coeff_idx) {
148 WORD32 i;
149 ixheaace_iir_sos_filter *pstr_iir_filter = &(pstr_down_sampler->iir_filter);
150 const FLOAT32 *ptr_coeff_den =
151 (pstr_iir_filter->ptr_coeff_iir_den + (coeff_idx * IIR_SOS_COEFFS));
152 const FLOAT32 *ptr_coeff_num =
153 (pstr_iir_filter->ptr_coeff_iir_num + (coeff_idx * IIR_SOS_COEFFS));
154 FLOAT32 iir_out = 0.f;
155 FLOAT32 temp1 = 0.f, temp2 = 0.f;
156
157 for (i = 0; i < num_in_samples; i++) {
158 ptr_ring_buf1[2] = ptr_in_samples[i * in_stride];
159
160 temp1 = ptr_coeff_num[0] * ptr_in_samples[i * in_stride] +
161 ptr_coeff_num[1] * ptr_ring_buf1[1] + ptr_coeff_num[2] * ptr_ring_buf1[0];
162 temp2 = ptr_coeff_den[1] * ptr_ring_buf2[1] + ptr_coeff_den[2] * ptr_ring_buf2[0];
163
164 iir_out = temp1 - temp2;
165 ptr_ring_buf2[2] = iir_out;
166
167 ptr_out_samples[i * in_stride] = iir_out;
168
169 // Shift ring buffers
170 ptr_ring_buf1[0] = ptr_ring_buf1[1];
171 ptr_ring_buf1[1] = ptr_ring_buf1[2];
172
173 ptr_ring_buf2[0] = ptr_ring_buf2[1];
174 ptr_ring_buf2[1] = ptr_ring_buf2[2];
175 }
176 }
177
ia_enhaacplus_enc_iir_downsampler(ixheaace_iir21_resampler * pstr_down_sampler,FLOAT32 * ptr_in_samples,WORD32 num_in_samples,WORD32 in_stride,FLOAT32 * ptr_out_samples,WORD32 * num_out_samples,WORD32 out_stride,FLOAT32 * ptr_ring_buf1,FLOAT32 * ptr_ring_buf2,ixheaace_resampler_scratch * pstr_resampler_scratch)178 VOID ia_enhaacplus_enc_iir_downsampler(ixheaace_iir21_resampler *pstr_down_sampler,
179 FLOAT32 *ptr_in_samples, WORD32 num_in_samples,
180 WORD32 in_stride, FLOAT32 *ptr_out_samples,
181 WORD32 *num_out_samples, WORD32 out_stride,
182 FLOAT32 *ptr_ring_buf1, FLOAT32 *ptr_ring_buf2,
183 ixheaace_resampler_scratch *pstr_resampler_scratch) {
184 ixheaace_iir_filter *pstr_iir_filter = &(pstr_down_sampler->iir_filter);
185 WORD32 k;
186 FLOAT32 *ptr_iir_ring1, *ptr_iir_ring2, *ptr_out_temp;
187
188 ptr_iir_ring2 = pstr_iir_filter->ring_buf_2;
189 ptr_iir_ring1 = pstr_iir_filter->ring_buf_1;
190 ptr_out_temp = pstr_resampler_scratch->downsampler_out_buffer;
191
192 ia_enhaacplus_enc_copy_ring_buffers(ptr_iir_ring1, ptr_iir_ring2, ptr_ring_buf1, ptr_ring_buf2);
193
194 ia_enhaacplus_enc_downsample_iir_filter(
195 pstr_down_sampler, ptr_in_samples, ptr_out_temp, in_stride, num_in_samples, num_out_samples,
196 out_stride, &ptr_ring_buf1[LEN_RING_BUF - 1], &ptr_ring_buf2[LEN_RING_BUF - 1]);
197
198 for (k = 0; k < *num_out_samples; k++) {
199 ptr_out_samples[k * in_stride] = ptr_out_temp[k * out_stride];
200 }
201
202 ia_enhaacplus_enc_copy_ring_buffers(&ptr_ring_buf1[num_in_samples],
203 &ptr_ring_buf2[num_in_samples], ptr_iir_ring1,
204 ptr_iir_ring2);
205 }
206
ia_enhaacplus_enc_iir_sos_downsampler(ixheaace_iir_sos_resampler * pstr_down_sampler,FLOAT32 * ptr_in_samples,WORD32 num_in_samples,WORD32 in_stride,FLOAT32 * ptr_out_samples,WORD32 * num_out_samples,FLOAT32 * ptr_ring_buf1,FLOAT32 * ptr_ring_buf2,ixheaace_resampler_scratch * pstr_resampler_scratch)207 VOID ia_enhaacplus_enc_iir_sos_downsampler(ixheaace_iir_sos_resampler *pstr_down_sampler,
208 FLOAT32 *ptr_in_samples, WORD32 num_in_samples,
209 WORD32 in_stride, FLOAT32 *ptr_out_samples,
210 WORD32 *num_out_samples, FLOAT32 *ptr_ring_buf1,
211 FLOAT32 *ptr_ring_buf2,
212 ixheaace_resampler_scratch *pstr_resampler_scratch) {
213 ixheaace_iir_sos_filter *pstr_iir_filter = &(pstr_down_sampler->iir_filter);
214 FLOAT32 *ptr_iir_ring1, *ptr_iir_ring2;
215 FLOAT32 *ptr_out_stage1, *ptr_out_stage2, *ptr_out_stage3, *ptr_out_stage4, *ptr_out_stage5,
216 *ptr_out_final;
217 WORD32 p = 0, idx = 0, offset1 = 0, offset2 = 0;
218 FLOAT32 *ptr_temp_buf1, *ptr_temp_buf2, *ptr_temp_ring_buf;
219 WORD32 upper_lim = num_in_samples * in_stride;
220
221 ptr_iir_ring1 = pstr_iir_filter->ring_buf_sos_1;
222 ptr_iir_ring2 = pstr_iir_filter->ring_buf_sos_2;
223
224 ia_enhaacplus_enc_copy_ring_buffers_sos(ptr_iir_ring1, ptr_iir_ring2, ptr_ring_buf1,
225 ptr_ring_buf2, LEN_RING_BUF_SOS_1, LEN_RING_BUF_SOS_2);
226
227 ptr_temp_buf1 = pstr_resampler_scratch->scratch_buf1_temp;
228 ptr_temp_buf2 = pstr_resampler_scratch->scratch_buf2_temp;
229 ptr_temp_ring_buf = pstr_resampler_scratch->ring_buf_temp;
230
231 ia_enhaacplus_enc_copy_ring_buffers_sos(ptr_ring_buf1, ptr_ring_buf2, ptr_temp_buf1,
232 ptr_temp_buf2, LEN_RING_BUF_SOS_1, LEN_RING_BUF_SOS_1);
233
234 ptr_out_stage1 = pstr_resampler_scratch->downsampler_out_buffer;
235
236 ia_enhaacplus_enc_update_ring_buffer_sos(ptr_temp_ring_buf, ptr_in_samples, upper_lim,
237 in_stride, idx);
238
239 // Stage 1
240 ia_enhaacplus_enc_iir_sos_filter(pstr_down_sampler, ptr_in_samples, in_stride, ptr_out_stage1,
241 num_in_samples, ptr_temp_buf1, ptr_temp_buf2, idx);
242
243 offset1 = LEN_RING_BUF_SOS_1 * idx;
244 offset2 = LEN_RING_BUF_SOS_1 * (idx + 1);
245
246 ia_enhaacplus_enc_copy_ring_buffers_sos(ptr_ring_buf2 + offset1, ptr_ring_buf2 + offset2,
247 ptr_temp_buf1, ptr_temp_buf2, LEN_RING_BUF_SOS_1,
248 LEN_RING_BUF_SOS_1);
249
250 idx++;
251
252 ia_enhaacplus_enc_update_ring_buffer_sos(ptr_temp_ring_buf, ptr_out_stage1, upper_lim,
253 in_stride, idx);
254
255 ptr_out_stage2 = pstr_resampler_scratch->downsampler_in_buffer;
256
257 // Stage 2
258 ia_enhaacplus_enc_iir_sos_filter(pstr_down_sampler, ptr_out_stage1, in_stride, ptr_out_stage2,
259 num_in_samples, ptr_temp_buf1, ptr_temp_buf2, idx);
260
261 offset1 = LEN_RING_BUF_SOS_1 * idx;
262 offset2 = LEN_RING_BUF_SOS_1 * (idx + 1);
263
264 ia_enhaacplus_enc_copy_ring_buffers_sos(ptr_ring_buf2 + offset1, ptr_ring_buf2 + offset2,
265 ptr_temp_buf1, ptr_temp_buf2, LEN_RING_BUF_SOS_1,
266 LEN_RING_BUF_SOS_1);
267
268 idx++;
269
270 ia_enhaacplus_enc_update_ring_buffer_sos(ptr_temp_ring_buf, ptr_out_stage2, upper_lim,
271 in_stride, idx);
272
273 ptr_out_stage3 = pstr_resampler_scratch->downsampler_out_buffer;
274
275 // Stage 3
276 ia_enhaacplus_enc_iir_sos_filter(pstr_down_sampler, ptr_out_stage2, in_stride, ptr_out_stage3,
277 num_in_samples, ptr_temp_buf1, ptr_temp_buf2, idx);
278
279 offset1 = LEN_RING_BUF_SOS_1 * idx;
280 offset2 = LEN_RING_BUF_SOS_1 * (idx + 1);
281
282 ia_enhaacplus_enc_copy_ring_buffers_sos(ptr_ring_buf2 + offset1, ptr_ring_buf2 + offset2,
283 ptr_temp_buf1, ptr_temp_buf2, LEN_RING_BUF_SOS_1,
284 LEN_RING_BUF_SOS_1);
285
286 idx++;
287
288 ia_enhaacplus_enc_update_ring_buffer_sos(ptr_temp_ring_buf, ptr_out_stage3, upper_lim,
289 in_stride, idx);
290
291 ptr_out_stage4 = pstr_resampler_scratch->downsampler_in_buffer;
292
293 // Stage 4
294 ia_enhaacplus_enc_iir_sos_filter(pstr_down_sampler, ptr_out_stage3, in_stride, ptr_out_stage4,
295 num_in_samples, ptr_temp_buf1, ptr_temp_buf2, idx);
296
297 offset1 = LEN_RING_BUF_SOS_1 * idx;
298 offset2 = LEN_RING_BUF_SOS_1 * (idx + 1);
299
300 ia_enhaacplus_enc_copy_ring_buffers_sos(ptr_ring_buf2 + offset1, ptr_ring_buf2 + offset2,
301 ptr_temp_buf1, ptr_temp_buf2, LEN_RING_BUF_SOS_1,
302 LEN_RING_BUF_SOS_1);
303
304 idx++;
305
306 ia_enhaacplus_enc_update_ring_buffer_sos(ptr_temp_ring_buf, ptr_out_stage4, upper_lim,
307 in_stride, idx);
308
309 ptr_out_stage5 = pstr_resampler_scratch->downsampler_out_buffer;
310
311 // Stage 5
312
313 ia_enhaacplus_enc_iir_sos_filter(pstr_down_sampler, ptr_out_stage4, in_stride, ptr_out_stage5,
314 num_in_samples, ptr_temp_buf1, ptr_temp_buf2, idx);
315
316 idx++;
317
318 ia_enhaacplus_enc_update_ring_buffer_sos(ptr_temp_ring_buf, ptr_out_stage5, upper_lim,
319 in_stride, idx);
320
321 ptr_out_final = pstr_resampler_scratch->downsampler_in_buffer;
322
323 // Multiply by gain and perform downsamplng
324 *num_out_samples = 0;
325 for (p = 0; p < num_in_samples * in_stride; p += in_stride) {
326 ptr_out_final[p] = ptr_out_stage5[p] * pstr_down_sampler->iir_filter.gain_sos;
327
328 pstr_down_sampler->pending++;
329
330 if (pstr_down_sampler->pending == pstr_down_sampler->ratio) {
331 ptr_out_samples[(*num_out_samples) * in_stride] = ptr_out_final[p];
332
333 (*num_out_samples)++;
334
335 pstr_down_sampler->pending = 0;
336 }
337 }
338
339 // Update ring buffers
340 ia_enhaacplus_enc_copy_ring_buffers_sos(ptr_temp_ring_buf,
341 ptr_temp_ring_buf + LEN_RING_BUF_SOS_1, ptr_ring_buf1,
342 ptr_ring_buf2, LEN_RING_BUF_SOS_1, LEN_RING_BUF_SOS_2);
343
344 ia_enhaacplus_enc_copy_ring_buffers_sos(ptr_ring_buf1, ptr_ring_buf2, ptr_iir_ring1,
345 ptr_iir_ring2, LEN_RING_BUF_SOS_1, LEN_RING_BUF_SOS_2);
346 }
347
ia_enhaacplus_enc_iir_sos_upsampler(ixheaace_iir_sos_resampler * pstr_up_sampler,FLOAT32 * ptr_in_samples,WORD32 num_in_samples,WORD32 in_stride,FLOAT32 * ptr_out_samples,WORD32 * num_out_samples,FLOAT32 * ptr_ring_buf1,FLOAT32 * ptr_ring_buf2,ixheaace_resampler_scratch * pstr_resampler_scratch)348 VOID ia_enhaacplus_enc_iir_sos_upsampler(ixheaace_iir_sos_resampler *pstr_up_sampler,
349 FLOAT32 *ptr_in_samples, WORD32 num_in_samples,
350 WORD32 in_stride, FLOAT32 *ptr_out_samples,
351 WORD32 *num_out_samples, FLOAT32 *ptr_ring_buf1,
352 FLOAT32 *ptr_ring_buf2,
353 ixheaace_resampler_scratch *pstr_resampler_scratch) {
354 ixheaace_iir_sos_filter *pstr_iir_filter = &(pstr_up_sampler->iir_filter);
355 FLOAT32 *ptr_iir_ring1, *ptr_iir_ring2;
356 FLOAT32 *ptr_out_stage1, *ptr_out_stage2, *ptr_out_stage3, *ptr_out_stage4, *ptr_out_stage5;
357 FLOAT32 out_val;
358 FLOAT32 *ptr_temp_buf1, *ptr_temp_buf2, *ptr_temp_ring_buf;
359 WORD32 p = 0, idx = 0, offset1 = 0, offset2 = 0;
360 WORD32 upsample_fac = pstr_up_sampler->ratio;
361 WORD32 upper_lim = num_in_samples * in_stride * upsample_fac;
362
363 ptr_iir_ring2 = pstr_iir_filter->ring_buf_sos_2;
364 ptr_iir_ring1 = pstr_iir_filter->ring_buf_sos_1;
365
366 ia_enhaacplus_enc_copy_ring_buffers_sos(ptr_iir_ring1, ptr_iir_ring2, ptr_ring_buf1,
367 ptr_ring_buf2, LEN_RING_BUF_SOS_1, LEN_RING_BUF_SOS_2);
368
369 ptr_temp_buf1 = pstr_resampler_scratch->scratch_buf1_temp;
370 ptr_temp_buf2 = pstr_resampler_scratch->scratch_buf2_temp;
371 ptr_temp_ring_buf = pstr_resampler_scratch->ring_buf_temp;
372
373 ia_enhaacplus_enc_copy_ring_buffers_sos(ptr_ring_buf1, ptr_ring_buf2, ptr_temp_buf1,
374 ptr_temp_buf2, LEN_RING_BUF_SOS_1, LEN_RING_BUF_SOS_1);
375
376 ptr_out_stage1 = pstr_resampler_scratch->downsampler_out_buffer;
377
378 ia_enhaacplus_enc_update_ring_buffer_sos(ptr_temp_ring_buf, ptr_in_samples, upper_lim,
379 in_stride, idx);
380
381 // Stage 1
382 ia_enhaacplus_enc_iir_sos_filter(pstr_up_sampler, ptr_in_samples, in_stride, ptr_out_stage1,
383 num_in_samples * upsample_fac, ptr_temp_buf1, ptr_temp_buf2,
384 idx);
385
386 offset1 = LEN_RING_BUF_SOS_1 * idx;
387 offset2 = LEN_RING_BUF_SOS_1 * (idx + 1);
388
389 ia_enhaacplus_enc_copy_ring_buffers_sos(ptr_ring_buf2 + offset1, ptr_ring_buf2 + offset2,
390 ptr_temp_buf1, ptr_temp_buf2, LEN_RING_BUF_SOS_1,
391 LEN_RING_BUF_SOS_1);
392
393 idx++;
394
395 ia_enhaacplus_enc_update_ring_buffer_sos(ptr_temp_ring_buf, ptr_out_stage1, upper_lim,
396 in_stride, idx);
397
398 ptr_out_stage2 = pstr_resampler_scratch->downsampler_in_buffer;
399
400 // Stage 2
401 ia_enhaacplus_enc_iir_sos_filter(pstr_up_sampler, ptr_out_stage1, in_stride, ptr_out_stage2,
402 num_in_samples * upsample_fac, ptr_temp_buf1, ptr_temp_buf2,
403 idx);
404
405 offset1 = LEN_RING_BUF_SOS_1 * idx;
406 offset2 = LEN_RING_BUF_SOS_1 * (idx + 1);
407
408 ia_enhaacplus_enc_copy_ring_buffers_sos(ptr_ring_buf2 + offset1, ptr_ring_buf2 + offset2,
409 ptr_temp_buf1, ptr_temp_buf2, LEN_RING_BUF_SOS_1,
410 LEN_RING_BUF_SOS_1);
411
412 idx++;
413
414 ia_enhaacplus_enc_update_ring_buffer_sos(ptr_temp_ring_buf, ptr_out_stage2, upper_lim,
415 in_stride, idx);
416
417 ptr_out_stage3 = pstr_resampler_scratch->downsampler_out_buffer;
418
419 // Stage 3
420 ia_enhaacplus_enc_iir_sos_filter(pstr_up_sampler, ptr_out_stage2, in_stride, ptr_out_stage3,
421 num_in_samples * upsample_fac, ptr_temp_buf1, ptr_temp_buf2,
422 idx);
423
424 offset1 = LEN_RING_BUF_SOS_1 * idx;
425 offset2 = LEN_RING_BUF_SOS_1 * (idx + 1);
426
427 ia_enhaacplus_enc_copy_ring_buffers_sos(ptr_ring_buf2 + offset1, ptr_ring_buf2 + offset2,
428 ptr_temp_buf1, ptr_temp_buf2, LEN_RING_BUF_SOS_1,
429 LEN_RING_BUF_SOS_1);
430
431 idx++;
432
433 ia_enhaacplus_enc_update_ring_buffer_sos(ptr_temp_ring_buf, ptr_out_stage3, upper_lim,
434 in_stride, idx);
435
436 ptr_out_stage4 = pstr_resampler_scratch->downsampler_in_buffer;
437
438 // Stage 4
439 ia_enhaacplus_enc_iir_sos_filter(pstr_up_sampler, ptr_out_stage3, in_stride, ptr_out_stage4,
440 num_in_samples * upsample_fac, ptr_temp_buf1, ptr_temp_buf2,
441 idx);
442
443 offset1 = LEN_RING_BUF_SOS_1 * idx;
444 offset2 = LEN_RING_BUF_SOS_1 * (idx + 1);
445
446 ia_enhaacplus_enc_copy_ring_buffers_sos(ptr_ring_buf2 + offset1, ptr_ring_buf2 + offset2,
447 ptr_temp_buf1, ptr_temp_buf2, LEN_RING_BUF_SOS_1,
448 LEN_RING_BUF_SOS_1);
449
450 idx++;
451
452 ia_enhaacplus_enc_update_ring_buffer_sos(ptr_temp_ring_buf, ptr_out_stage4, upper_lim,
453 in_stride, idx);
454
455 ptr_out_stage5 = pstr_resampler_scratch->downsampler_out_buffer;
456
457 // Stage 5
458 ia_enhaacplus_enc_iir_sos_filter(pstr_up_sampler, ptr_out_stage4, in_stride, ptr_out_stage5,
459 num_in_samples * upsample_fac, ptr_temp_buf1, ptr_temp_buf2,
460 idx);
461
462 idx++;
463
464 ia_enhaacplus_enc_update_ring_buffer_sos(ptr_temp_ring_buf, ptr_out_stage5, upper_lim,
465 in_stride, idx);
466
467 // Multiply by gain and perform downsamplng
468 *num_out_samples = 0;
469 for (p = 0; p < num_in_samples * in_stride * upsample_fac; p += in_stride) {
470 out_val = ptr_out_stage5[p] * pstr_up_sampler->iir_filter.gain_sos;
471 ptr_out_samples[p] = out_val;
472 (*num_out_samples)++;
473 }
474
475 ia_enhaacplus_enc_copy_ring_buffers_sos(ptr_temp_ring_buf,
476 ptr_temp_ring_buf + LEN_RING_BUF_SOS_1, ptr_ring_buf1,
477 ptr_ring_buf2, LEN_RING_BUF_SOS_1, LEN_RING_BUF_SOS_2);
478
479 ia_enhaacplus_enc_copy_ring_buffers_sos(ptr_ring_buf1, ptr_ring_buf2, ptr_iir_ring1,
480 ptr_iir_ring2, LEN_RING_BUF_SOS_1, LEN_RING_BUF_SOS_2);
481 }
482
ia_enhaacplus_enc_compute_resampling_ratio(WORD32 ccfl_idx)483 WORD32 ia_enhaacplus_enc_compute_resampling_ratio(WORD32 ccfl_idx) {
484 WORD32 resamp_ratio;
485
486 if (ccfl_idx == SBR_4_1) {
487 resamp_ratio = 2;
488 } else if (ccfl_idx == SBR_8_3) {
489 resamp_ratio = 4;
490 } else {
491 resamp_ratio = 1;
492 }
493
494 return resamp_ratio;
495 }
496
ixheaace_upsampling_inp_buf_generation(FLOAT32 * ptr_inp_buf,FLOAT32 * ptr_temp_buf,WORD32 num_samples,WORD32 upsamp_fac,WORD32 offset)497 VOID ixheaace_upsampling_inp_buf_generation(FLOAT32 *ptr_inp_buf, FLOAT32 *ptr_temp_buf,
498 WORD32 num_samples, WORD32 upsamp_fac,
499 WORD32 offset) {
500 WORD32 idx, m = 0;
501 FLOAT32 *ptr_in_samples;
502
503 memset(ptr_temp_buf, 0,
504 (num_samples * IXHEAACE_MAX_CH_IN_BS_ELE * upsamp_fac * sizeof(*ptr_temp_buf)));
505
506 ptr_in_samples = ptr_inp_buf + offset;
507
508 // Perform actual upsampling (repeat samples)
509 for (idx = 0; idx < num_samples; idx++) {
510 ptr_temp_buf[m++] = ptr_in_samples[idx * IXHEAACE_MAX_CH_IN_BS_ELE];
511 ptr_temp_buf[m++] = ptr_in_samples[idx * IXHEAACE_MAX_CH_IN_BS_ELE + 1];
512 ptr_temp_buf[m++] =
513 ptr_in_samples[idx *
514 IXHEAACE_MAX_CH_IN_BS_ELE]; // 1st channel sample repeated for upsampling
515 ptr_temp_buf[m++] = ptr_in_samples[idx * IXHEAACE_MAX_CH_IN_BS_ELE +
516 1]; // 2nd channel sample repeated for upsampling
517 ptr_temp_buf[m++] =
518 ptr_in_samples[idx *
519 IXHEAACE_MAX_CH_IN_BS_ELE]; // 1st channel sample repeated for upsampling
520 ptr_temp_buf[m++] = ptr_in_samples[idx * IXHEAACE_MAX_CH_IN_BS_ELE +
521 1]; // 2nd channel sample repeated for upsampling
522 }
523 }