/src/libxaac/encoder/ixheaace_resampler.c
Line | Count | Source |
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 | | |
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 | 692k | WORD32 out_stride, FLOAT32 *ptr_ring_buf1, FLOAT32 *ptr_ring_buf2) { |
32 | 692k | WORD32 i; |
33 | 692k | ixheaace_iir_filter *pstr_iir_filter = &(pstr_down_sampler->iir_filter); |
34 | 692k | FLOAT32 *ptr_iir_ring1, *ptr_iir_ring2; |
35 | 692k | FLOAT32 coeff_temp_a, coeff_temp_b; |
36 | 692k | const FLOAT32 *ptr_coeff_filt = (FLOAT32 *)pstr_iir_filter->ptr_coeff_iir_num; |
37 | 692k | FLOAT32 iir_out = 0; |
38 | 692k | FLOAT32 temp1 = 0.f, temp2 = 0.f; |
39 | | |
40 | 692k | *num_out_samples = 0; |
41 | 692k | ptr_iir_ring1 = ptr_ring_buf1; |
42 | 692k | ptr_iir_ring2 = ptr_ring_buf2; |
43 | | |
44 | 1.56G | for (i = 0; i < num_in_samples; i++) { |
45 | 1.55G | temp1 = ptr_in_samples[i * in_stride] / 2; |
46 | 1.55G | ptr_iir_ring1[i] = temp1; |
47 | 1.55G | coeff_temp_b = *ptr_coeff_filt; |
48 | 1.55G | temp1 = coeff_temp_b * (temp1 + ptr_iir_ring1[i - 10]); |
49 | 1.55G | coeff_temp_a = *(ptr_coeff_filt + 16); |
50 | 1.55G | iir_out = (ptr_iir_ring2[i - 10] * coeff_temp_a); |
51 | | |
52 | 1.55G | coeff_temp_b = *(ptr_coeff_filt + 1); |
53 | 1.55G | temp1 = (coeff_temp_b * (ptr_iir_ring1[i - 1] + ptr_iir_ring1[i - 9])) + temp1; |
54 | 1.55G | coeff_temp_a = *(ptr_coeff_filt + 7); |
55 | 1.55G | temp2 = (ptr_iir_ring2[i - 1] * coeff_temp_a) + iir_out; |
56 | 1.55G | coeff_temp_a = *(ptr_coeff_filt + 15); |
57 | 1.55G | iir_out = (ptr_iir_ring2[i - 9] * coeff_temp_a) + temp2; |
58 | | |
59 | 1.55G | coeff_temp_b = *(ptr_coeff_filt + 2); |
60 | 1.55G | temp1 = (coeff_temp_b * (ptr_iir_ring1[i - 2] + ptr_iir_ring1[i - 8])) + temp1; |
61 | 1.55G | coeff_temp_a = *(ptr_coeff_filt + 8); |
62 | 1.55G | temp2 = (ptr_iir_ring2[i - 2] * coeff_temp_a) + iir_out; |
63 | 1.55G | coeff_temp_a = *(ptr_coeff_filt + 14); |
64 | 1.55G | iir_out = (ptr_iir_ring2[i - 8] * coeff_temp_a) + temp2; |
65 | | |
66 | 1.55G | coeff_temp_b = *(ptr_coeff_filt + 3); |
67 | 1.55G | temp1 = (coeff_temp_b * (ptr_iir_ring1[i - 3] + ptr_iir_ring1[i - 7])) + temp1; |
68 | 1.55G | coeff_temp_a = *(ptr_coeff_filt + 9); |
69 | 1.55G | temp2 = (ptr_iir_ring2[i - 3] * coeff_temp_a) + iir_out; |
70 | 1.55G | coeff_temp_a = *(ptr_coeff_filt + 13); |
71 | 1.55G | iir_out = (ptr_iir_ring2[i - 7] * coeff_temp_a) + temp2; |
72 | | |
73 | 1.55G | coeff_temp_b = *(ptr_coeff_filt + 4); |
74 | 1.55G | temp1 = (coeff_temp_b * (ptr_iir_ring1[i - 4] + ptr_iir_ring1[i - 6])) + temp1; |
75 | 1.55G | coeff_temp_a = *(ptr_coeff_filt + 10); |
76 | 1.55G | temp2 = (ptr_iir_ring2[i - 4] * coeff_temp_a) + iir_out; |
77 | 1.55G | coeff_temp_a = *(ptr_coeff_filt + 12); |
78 | 1.55G | iir_out = (ptr_iir_ring2[i - 6] * coeff_temp_a) + temp2; |
79 | | |
80 | 1.55G | coeff_temp_b = *(ptr_coeff_filt + 5); |
81 | 1.55G | temp1 = (coeff_temp_b * ptr_iir_ring1[i - 5]) + temp1; |
82 | 1.55G | coeff_temp_a = *(ptr_coeff_filt + 11); |
83 | 1.55G | iir_out = (ptr_iir_ring2[i - 5] * coeff_temp_a) + iir_out; |
84 | 1.55G | iir_out = temp1 - iir_out; |
85 | | |
86 | 1.55G | ptr_iir_ring2[i] = iir_out; |
87 | 1.55G | iir_out = (iir_out * (4681.0f / 32767.0f) * pstr_iir_filter->max); |
88 | | |
89 | 1.55G | pstr_down_sampler->pending++; |
90 | | |
91 | 1.55G | if (pstr_down_sampler->pending == pstr_down_sampler->ratio) { |
92 | 633M | ptr_out_samples[(*num_out_samples) * out_stride] = iir_out; |
93 | 633M | (*num_out_samples)++; |
94 | | |
95 | 633M | pstr_down_sampler->pending = 0; |
96 | 633M | } |
97 | 1.55G | } |
98 | 692k | } |
99 | | |
100 | | static VOID ia_enhaacplus_enc_copy_ring_buffers(FLOAT32 *ptr_iir_ring1, FLOAT32 *ptr_iir_ring2, |
101 | 1.38M | FLOAT32 *ptr_ring_buf1, FLOAT32 *ptr_ring_buf2) { |
102 | 1.38M | WORD32 i; |
103 | 1.38M | FLOAT32 temp1, temp2, temp3; |
104 | 9.69M | for (i = (LEN_RING_BUF / 2) - 1; i >= 0; i--) { |
105 | 8.31M | temp1 = *ptr_iir_ring1++; |
106 | 8.31M | temp2 = *ptr_iir_ring2++; |
107 | 8.31M | temp3 = *ptr_iir_ring1++; |
108 | | |
109 | 8.31M | *ptr_ring_buf1++ = temp1; |
110 | 8.31M | temp1 = *ptr_iir_ring2++; |
111 | 8.31M | *ptr_ring_buf2++ = temp2; |
112 | 8.31M | *ptr_ring_buf1++ = temp3; |
113 | 8.31M | *ptr_ring_buf2++ = temp1; |
114 | 8.31M | } |
115 | 1.38M | } |
116 | | |
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 | 977k | WORD32 len2) { |
122 | 977k | memcpy(ptr_ring_buf1, ptr_iir_ring1, len1 * sizeof(*ptr_ring_buf1)); |
123 | 977k | memcpy(ptr_ring_buf2, ptr_iir_ring2, len2 * sizeof(*ptr_ring_buf2)); |
124 | 977k | } |
125 | | |
126 | | static VOID ia_enhaacplus_enc_update_ring_buffer_sos(FLOAT32 *ptr_ring_buf, FLOAT32 *ptr_samples, |
127 | | WORD32 len, WORD32 in_stride, |
128 | 733k | WORD32 coeff_idx) { |
129 | 733k | ptr_ring_buf[2 * coeff_idx] = ptr_samples[len - 2 * in_stride]; |
130 | 733k | ptr_ring_buf[2 * coeff_idx + 1] = ptr_samples[len - in_stride]; |
131 | 733k | } |
132 | | |
133 | 258k | VOID ixheaace_get_input_scratch_buf(VOID *ptr_scr, FLOAT32 **ptr_scratch_buf_inp) { |
134 | 258k | ixheaace_resampler_scratch *pstr_resampler_scr = (ixheaace_resampler_scratch *)ptr_scr; |
135 | | |
136 | 258k | *ptr_scratch_buf_inp = pstr_resampler_scr->downsampler_in_buffer; |
137 | 258k | } |
138 | | |
139 | 6.36k | WORD32 ixheaace_resampler_scr_size(VOID) { |
140 | 6.36k | return IXHEAAC_GET_SIZE_ALIGNED(sizeof(ixheaace_resampler_scratch), BYTE_ALIGN_8); |
141 | 6.36k | } |
142 | | |
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 | 610k | WORD32 coeff_idx) { |
148 | 610k | WORD32 i; |
149 | 610k | ixheaace_iir_sos_filter *pstr_iir_filter = &(pstr_down_sampler->iir_filter); |
150 | 610k | const FLOAT32 *ptr_coeff_den = |
151 | 610k | (pstr_iir_filter->ptr_coeff_iir_den + (coeff_idx * IIR_SOS_COEFFS)); |
152 | 610k | const FLOAT32 *ptr_coeff_num = |
153 | 610k | (pstr_iir_filter->ptr_coeff_iir_num + (coeff_idx * IIR_SOS_COEFFS)); |
154 | 610k | FLOAT32 iir_out = 0.f; |
155 | 610k | FLOAT32 temp1 = 0.f, temp2 = 0.f; |
156 | | |
157 | 3.75G | for (i = 0; i < num_in_samples; i++) { |
158 | 3.75G | ptr_ring_buf1[2] = ptr_in_samples[i * in_stride]; |
159 | | |
160 | 3.75G | temp1 = ptr_coeff_num[0] * ptr_in_samples[i * in_stride] + |
161 | 3.75G | ptr_coeff_num[1] * ptr_ring_buf1[1] + ptr_coeff_num[2] * ptr_ring_buf1[0]; |
162 | 3.75G | temp2 = ptr_coeff_den[1] * ptr_ring_buf2[1] + ptr_coeff_den[2] * ptr_ring_buf2[0]; |
163 | | |
164 | 3.75G | iir_out = temp1 - temp2; |
165 | 3.75G | ptr_ring_buf2[2] = iir_out; |
166 | | |
167 | 3.75G | ptr_out_samples[i * in_stride] = iir_out; |
168 | | |
169 | | // Shift ring buffers |
170 | 3.75G | ptr_ring_buf1[0] = ptr_ring_buf1[1]; |
171 | 3.75G | ptr_ring_buf1[1] = ptr_ring_buf1[2]; |
172 | | |
173 | 3.75G | ptr_ring_buf2[0] = ptr_ring_buf2[1]; |
174 | 3.75G | ptr_ring_buf2[1] = ptr_ring_buf2[2]; |
175 | 3.75G | } |
176 | 610k | } |
177 | | |
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 | 692k | ixheaace_resampler_scratch *pstr_resampler_scratch) { |
184 | 692k | ixheaace_iir_filter *pstr_iir_filter = &(pstr_down_sampler->iir_filter); |
185 | 692k | WORD32 k; |
186 | 692k | FLOAT32 *ptr_iir_ring1, *ptr_iir_ring2, *ptr_out_temp; |
187 | | |
188 | 692k | ptr_iir_ring2 = pstr_iir_filter->ring_buf_2; |
189 | 692k | ptr_iir_ring1 = pstr_iir_filter->ring_buf_1; |
190 | 692k | ptr_out_temp = pstr_resampler_scratch->downsampler_out_buffer; |
191 | | |
192 | 692k | ia_enhaacplus_enc_copy_ring_buffers(ptr_iir_ring1, ptr_iir_ring2, ptr_ring_buf1, ptr_ring_buf2); |
193 | | |
194 | 692k | ia_enhaacplus_enc_downsample_iir_filter( |
195 | 692k | pstr_down_sampler, ptr_in_samples, ptr_out_temp, in_stride, num_in_samples, num_out_samples, |
196 | 692k | out_stride, &ptr_ring_buf1[LEN_RING_BUF - 1], &ptr_ring_buf2[LEN_RING_BUF - 1]); |
197 | | |
198 | 634M | for (k = 0; k < *num_out_samples; k++) { |
199 | 633M | ptr_out_samples[k * in_stride] = ptr_out_temp[k * out_stride]; |
200 | 633M | } |
201 | | |
202 | 692k | ia_enhaacplus_enc_copy_ring_buffers(&ptr_ring_buf1[num_in_samples], |
203 | 692k | &ptr_ring_buf2[num_in_samples], ptr_iir_ring1, |
204 | 692k | ptr_iir_ring2); |
205 | 692k | } |
206 | | |
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 | 61.0k | ixheaace_resampler_scratch *pstr_resampler_scratch) { |
213 | 61.0k | ixheaace_iir_sos_filter *pstr_iir_filter = &(pstr_down_sampler->iir_filter); |
214 | 61.0k | FLOAT32 *ptr_iir_ring1, *ptr_iir_ring2; |
215 | 61.0k | FLOAT32 *ptr_out_stage1, *ptr_out_stage2, *ptr_out_stage3, *ptr_out_stage4, *ptr_out_stage5, |
216 | 61.0k | *ptr_out_final; |
217 | 61.0k | WORD32 p = 0, idx = 0, offset1 = 0, offset2 = 0; |
218 | 61.0k | FLOAT32 *ptr_temp_buf1, *ptr_temp_buf2, *ptr_temp_ring_buf; |
219 | 61.0k | WORD32 upper_lim = num_in_samples * in_stride; |
220 | | |
221 | 61.0k | ptr_iir_ring1 = pstr_iir_filter->ring_buf_sos_1; |
222 | 61.0k | ptr_iir_ring2 = pstr_iir_filter->ring_buf_sos_2; |
223 | | |
224 | 61.0k | ia_enhaacplus_enc_copy_ring_buffers_sos(ptr_iir_ring1, ptr_iir_ring2, ptr_ring_buf1, |
225 | 61.0k | ptr_ring_buf2, LEN_RING_BUF_SOS_1, LEN_RING_BUF_SOS_2); |
226 | | |
227 | 61.0k | ptr_temp_buf1 = pstr_resampler_scratch->scratch_buf1_temp; |
228 | 61.0k | ptr_temp_buf2 = pstr_resampler_scratch->scratch_buf2_temp; |
229 | 61.0k | ptr_temp_ring_buf = pstr_resampler_scratch->ring_buf_temp; |
230 | | |
231 | 61.0k | ia_enhaacplus_enc_copy_ring_buffers_sos(ptr_ring_buf1, ptr_ring_buf2, ptr_temp_buf1, |
232 | 61.0k | ptr_temp_buf2, LEN_RING_BUF_SOS_1, LEN_RING_BUF_SOS_1); |
233 | | |
234 | 61.0k | ptr_out_stage1 = pstr_resampler_scratch->downsampler_out_buffer; |
235 | | |
236 | 61.0k | ia_enhaacplus_enc_update_ring_buffer_sos(ptr_temp_ring_buf, ptr_in_samples, upper_lim, |
237 | 61.0k | in_stride, idx); |
238 | | |
239 | | // Stage 1 |
240 | 61.0k | ia_enhaacplus_enc_iir_sos_filter(pstr_down_sampler, ptr_in_samples, in_stride, ptr_out_stage1, |
241 | 61.0k | num_in_samples, ptr_temp_buf1, ptr_temp_buf2, idx); |
242 | | |
243 | 61.0k | offset1 = LEN_RING_BUF_SOS_1 * idx; |
244 | 61.0k | offset2 = LEN_RING_BUF_SOS_1 * (idx + 1); |
245 | | |
246 | 61.0k | ia_enhaacplus_enc_copy_ring_buffers_sos(ptr_ring_buf2 + offset1, ptr_ring_buf2 + offset2, |
247 | 61.0k | ptr_temp_buf1, ptr_temp_buf2, LEN_RING_BUF_SOS_1, |
248 | 61.0k | LEN_RING_BUF_SOS_1); |
249 | | |
250 | 61.0k | idx++; |
251 | | |
252 | 61.0k | ia_enhaacplus_enc_update_ring_buffer_sos(ptr_temp_ring_buf, ptr_out_stage1, upper_lim, |
253 | 61.0k | in_stride, idx); |
254 | | |
255 | 61.0k | ptr_out_stage2 = pstr_resampler_scratch->downsampler_in_buffer; |
256 | | |
257 | | // Stage 2 |
258 | 61.0k | ia_enhaacplus_enc_iir_sos_filter(pstr_down_sampler, ptr_out_stage1, in_stride, ptr_out_stage2, |
259 | 61.0k | num_in_samples, ptr_temp_buf1, ptr_temp_buf2, idx); |
260 | | |
261 | 61.0k | offset1 = LEN_RING_BUF_SOS_1 * idx; |
262 | 61.0k | offset2 = LEN_RING_BUF_SOS_1 * (idx + 1); |
263 | | |
264 | 61.0k | ia_enhaacplus_enc_copy_ring_buffers_sos(ptr_ring_buf2 + offset1, ptr_ring_buf2 + offset2, |
265 | 61.0k | ptr_temp_buf1, ptr_temp_buf2, LEN_RING_BUF_SOS_1, |
266 | 61.0k | LEN_RING_BUF_SOS_1); |
267 | | |
268 | 61.0k | idx++; |
269 | | |
270 | 61.0k | ia_enhaacplus_enc_update_ring_buffer_sos(ptr_temp_ring_buf, ptr_out_stage2, upper_lim, |
271 | 61.0k | in_stride, idx); |
272 | | |
273 | 61.0k | ptr_out_stage3 = pstr_resampler_scratch->downsampler_out_buffer; |
274 | | |
275 | | // Stage 3 |
276 | 61.0k | ia_enhaacplus_enc_iir_sos_filter(pstr_down_sampler, ptr_out_stage2, in_stride, ptr_out_stage3, |
277 | 61.0k | num_in_samples, ptr_temp_buf1, ptr_temp_buf2, idx); |
278 | | |
279 | 61.0k | offset1 = LEN_RING_BUF_SOS_1 * idx; |
280 | 61.0k | offset2 = LEN_RING_BUF_SOS_1 * (idx + 1); |
281 | | |
282 | 61.0k | ia_enhaacplus_enc_copy_ring_buffers_sos(ptr_ring_buf2 + offset1, ptr_ring_buf2 + offset2, |
283 | 61.0k | ptr_temp_buf1, ptr_temp_buf2, LEN_RING_BUF_SOS_1, |
284 | 61.0k | LEN_RING_BUF_SOS_1); |
285 | | |
286 | 61.0k | idx++; |
287 | | |
288 | 61.0k | ia_enhaacplus_enc_update_ring_buffer_sos(ptr_temp_ring_buf, ptr_out_stage3, upper_lim, |
289 | 61.0k | in_stride, idx); |
290 | | |
291 | 61.0k | ptr_out_stage4 = pstr_resampler_scratch->downsampler_in_buffer; |
292 | | |
293 | | // Stage 4 |
294 | 61.0k | ia_enhaacplus_enc_iir_sos_filter(pstr_down_sampler, ptr_out_stage3, in_stride, ptr_out_stage4, |
295 | 61.0k | num_in_samples, ptr_temp_buf1, ptr_temp_buf2, idx); |
296 | | |
297 | 61.0k | offset1 = LEN_RING_BUF_SOS_1 * idx; |
298 | 61.0k | offset2 = LEN_RING_BUF_SOS_1 * (idx + 1); |
299 | | |
300 | 61.0k | ia_enhaacplus_enc_copy_ring_buffers_sos(ptr_ring_buf2 + offset1, ptr_ring_buf2 + offset2, |
301 | 61.0k | ptr_temp_buf1, ptr_temp_buf2, LEN_RING_BUF_SOS_1, |
302 | 61.0k | LEN_RING_BUF_SOS_1); |
303 | | |
304 | 61.0k | idx++; |
305 | | |
306 | 61.0k | ia_enhaacplus_enc_update_ring_buffer_sos(ptr_temp_ring_buf, ptr_out_stage4, upper_lim, |
307 | 61.0k | in_stride, idx); |
308 | | |
309 | 61.0k | ptr_out_stage5 = pstr_resampler_scratch->downsampler_out_buffer; |
310 | | |
311 | | // Stage 5 |
312 | | |
313 | 61.0k | ia_enhaacplus_enc_iir_sos_filter(pstr_down_sampler, ptr_out_stage4, in_stride, ptr_out_stage5, |
314 | 61.0k | num_in_samples, ptr_temp_buf1, ptr_temp_buf2, idx); |
315 | | |
316 | 61.0k | idx++; |
317 | | |
318 | 61.0k | ia_enhaacplus_enc_update_ring_buffer_sos(ptr_temp_ring_buf, ptr_out_stage5, upper_lim, |
319 | 61.0k | in_stride, idx); |
320 | | |
321 | 61.0k | ptr_out_final = pstr_resampler_scratch->downsampler_in_buffer; |
322 | | |
323 | | // Multiply by gain and perform downsamplng |
324 | 61.0k | *num_out_samples = 0; |
325 | 375M | for (p = 0; p < num_in_samples * in_stride; p += in_stride) { |
326 | 375M | ptr_out_final[p] = ptr_out_stage5[p] * pstr_down_sampler->iir_filter.gain_sos; |
327 | | |
328 | 375M | pstr_down_sampler->pending++; |
329 | | |
330 | 375M | if (pstr_down_sampler->pending == pstr_down_sampler->ratio) { |
331 | 46.9M | ptr_out_samples[(*num_out_samples) * in_stride] = ptr_out_final[p]; |
332 | | |
333 | 46.9M | (*num_out_samples)++; |
334 | | |
335 | 46.9M | pstr_down_sampler->pending = 0; |
336 | 46.9M | } |
337 | 375M | } |
338 | | |
339 | | // Update ring buffers |
340 | 61.0k | ia_enhaacplus_enc_copy_ring_buffers_sos(ptr_temp_ring_buf, |
341 | 61.0k | ptr_temp_ring_buf + LEN_RING_BUF_SOS_1, ptr_ring_buf1, |
342 | 61.0k | ptr_ring_buf2, LEN_RING_BUF_SOS_1, LEN_RING_BUF_SOS_2); |
343 | | |
344 | 61.0k | ia_enhaacplus_enc_copy_ring_buffers_sos(ptr_ring_buf1, ptr_ring_buf2, ptr_iir_ring1, |
345 | 61.0k | ptr_iir_ring2, LEN_RING_BUF_SOS_1, LEN_RING_BUF_SOS_2); |
346 | 61.0k | } |
347 | | |
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 | 61.0k | ixheaace_resampler_scratch *pstr_resampler_scratch) { |
354 | 61.0k | ixheaace_iir_sos_filter *pstr_iir_filter = &(pstr_up_sampler->iir_filter); |
355 | 61.0k | FLOAT32 *ptr_iir_ring1, *ptr_iir_ring2; |
356 | 61.0k | FLOAT32 *ptr_out_stage1, *ptr_out_stage2, *ptr_out_stage3, *ptr_out_stage4, *ptr_out_stage5; |
357 | 61.0k | FLOAT32 out_val; |
358 | 61.0k | FLOAT32 *ptr_temp_buf1, *ptr_temp_buf2, *ptr_temp_ring_buf; |
359 | 61.0k | WORD32 p = 0, idx = 0, offset1 = 0, offset2 = 0; |
360 | 61.0k | WORD32 upsample_fac = pstr_up_sampler->ratio; |
361 | 61.0k | WORD32 upper_lim = num_in_samples * in_stride * upsample_fac; |
362 | | |
363 | 61.0k | ptr_iir_ring2 = pstr_iir_filter->ring_buf_sos_2; |
364 | 61.0k | ptr_iir_ring1 = pstr_iir_filter->ring_buf_sos_1; |
365 | | |
366 | 61.0k | ia_enhaacplus_enc_copy_ring_buffers_sos(ptr_iir_ring1, ptr_iir_ring2, ptr_ring_buf1, |
367 | 61.0k | ptr_ring_buf2, LEN_RING_BUF_SOS_1, LEN_RING_BUF_SOS_2); |
368 | | |
369 | 61.0k | ptr_temp_buf1 = pstr_resampler_scratch->scratch_buf1_temp; |
370 | 61.0k | ptr_temp_buf2 = pstr_resampler_scratch->scratch_buf2_temp; |
371 | 61.0k | ptr_temp_ring_buf = pstr_resampler_scratch->ring_buf_temp; |
372 | | |
373 | 61.0k | ia_enhaacplus_enc_copy_ring_buffers_sos(ptr_ring_buf1, ptr_ring_buf2, ptr_temp_buf1, |
374 | 61.0k | ptr_temp_buf2, LEN_RING_BUF_SOS_1, LEN_RING_BUF_SOS_1); |
375 | | |
376 | 61.0k | ptr_out_stage1 = pstr_resampler_scratch->downsampler_out_buffer; |
377 | | |
378 | 61.0k | ia_enhaacplus_enc_update_ring_buffer_sos(ptr_temp_ring_buf, ptr_in_samples, upper_lim, |
379 | 61.0k | in_stride, idx); |
380 | | |
381 | | // Stage 1 |
382 | 61.0k | ia_enhaacplus_enc_iir_sos_filter(pstr_up_sampler, ptr_in_samples, in_stride, ptr_out_stage1, |
383 | 61.0k | num_in_samples * upsample_fac, ptr_temp_buf1, ptr_temp_buf2, |
384 | 61.0k | idx); |
385 | | |
386 | 61.0k | offset1 = LEN_RING_BUF_SOS_1 * idx; |
387 | 61.0k | offset2 = LEN_RING_BUF_SOS_1 * (idx + 1); |
388 | | |
389 | 61.0k | ia_enhaacplus_enc_copy_ring_buffers_sos(ptr_ring_buf2 + offset1, ptr_ring_buf2 + offset2, |
390 | 61.0k | ptr_temp_buf1, ptr_temp_buf2, LEN_RING_BUF_SOS_1, |
391 | 61.0k | LEN_RING_BUF_SOS_1); |
392 | | |
393 | 61.0k | idx++; |
394 | | |
395 | 61.0k | ia_enhaacplus_enc_update_ring_buffer_sos(ptr_temp_ring_buf, ptr_out_stage1, upper_lim, |
396 | 61.0k | in_stride, idx); |
397 | | |
398 | 61.0k | ptr_out_stage2 = pstr_resampler_scratch->downsampler_in_buffer; |
399 | | |
400 | | // Stage 2 |
401 | 61.0k | ia_enhaacplus_enc_iir_sos_filter(pstr_up_sampler, ptr_out_stage1, in_stride, ptr_out_stage2, |
402 | 61.0k | num_in_samples * upsample_fac, ptr_temp_buf1, ptr_temp_buf2, |
403 | 61.0k | idx); |
404 | | |
405 | 61.0k | offset1 = LEN_RING_BUF_SOS_1 * idx; |
406 | 61.0k | offset2 = LEN_RING_BUF_SOS_1 * (idx + 1); |
407 | | |
408 | 61.0k | ia_enhaacplus_enc_copy_ring_buffers_sos(ptr_ring_buf2 + offset1, ptr_ring_buf2 + offset2, |
409 | 61.0k | ptr_temp_buf1, ptr_temp_buf2, LEN_RING_BUF_SOS_1, |
410 | 61.0k | LEN_RING_BUF_SOS_1); |
411 | | |
412 | 61.0k | idx++; |
413 | | |
414 | 61.0k | ia_enhaacplus_enc_update_ring_buffer_sos(ptr_temp_ring_buf, ptr_out_stage2, upper_lim, |
415 | 61.0k | in_stride, idx); |
416 | | |
417 | 61.0k | ptr_out_stage3 = pstr_resampler_scratch->downsampler_out_buffer; |
418 | | |
419 | | // Stage 3 |
420 | 61.0k | ia_enhaacplus_enc_iir_sos_filter(pstr_up_sampler, ptr_out_stage2, in_stride, ptr_out_stage3, |
421 | 61.0k | num_in_samples * upsample_fac, ptr_temp_buf1, ptr_temp_buf2, |
422 | 61.0k | idx); |
423 | | |
424 | 61.0k | offset1 = LEN_RING_BUF_SOS_1 * idx; |
425 | 61.0k | offset2 = LEN_RING_BUF_SOS_1 * (idx + 1); |
426 | | |
427 | 61.0k | ia_enhaacplus_enc_copy_ring_buffers_sos(ptr_ring_buf2 + offset1, ptr_ring_buf2 + offset2, |
428 | 61.0k | ptr_temp_buf1, ptr_temp_buf2, LEN_RING_BUF_SOS_1, |
429 | 61.0k | LEN_RING_BUF_SOS_1); |
430 | | |
431 | 61.0k | idx++; |
432 | | |
433 | 61.0k | ia_enhaacplus_enc_update_ring_buffer_sos(ptr_temp_ring_buf, ptr_out_stage3, upper_lim, |
434 | 61.0k | in_stride, idx); |
435 | | |
436 | 61.0k | ptr_out_stage4 = pstr_resampler_scratch->downsampler_in_buffer; |
437 | | |
438 | | // Stage 4 |
439 | 61.0k | ia_enhaacplus_enc_iir_sos_filter(pstr_up_sampler, ptr_out_stage3, in_stride, ptr_out_stage4, |
440 | 61.0k | num_in_samples * upsample_fac, ptr_temp_buf1, ptr_temp_buf2, |
441 | 61.0k | idx); |
442 | | |
443 | 61.0k | offset1 = LEN_RING_BUF_SOS_1 * idx; |
444 | 61.0k | offset2 = LEN_RING_BUF_SOS_1 * (idx + 1); |
445 | | |
446 | 61.0k | ia_enhaacplus_enc_copy_ring_buffers_sos(ptr_ring_buf2 + offset1, ptr_ring_buf2 + offset2, |
447 | 61.0k | ptr_temp_buf1, ptr_temp_buf2, LEN_RING_BUF_SOS_1, |
448 | 61.0k | LEN_RING_BUF_SOS_1); |
449 | | |
450 | 61.0k | idx++; |
451 | | |
452 | 61.0k | ia_enhaacplus_enc_update_ring_buffer_sos(ptr_temp_ring_buf, ptr_out_stage4, upper_lim, |
453 | 61.0k | in_stride, idx); |
454 | | |
455 | 61.0k | ptr_out_stage5 = pstr_resampler_scratch->downsampler_out_buffer; |
456 | | |
457 | | // Stage 5 |
458 | 61.0k | ia_enhaacplus_enc_iir_sos_filter(pstr_up_sampler, ptr_out_stage4, in_stride, ptr_out_stage5, |
459 | 61.0k | num_in_samples * upsample_fac, ptr_temp_buf1, ptr_temp_buf2, |
460 | 61.0k | idx); |
461 | | |
462 | 61.0k | idx++; |
463 | | |
464 | 61.0k | ia_enhaacplus_enc_update_ring_buffer_sos(ptr_temp_ring_buf, ptr_out_stage5, upper_lim, |
465 | 61.0k | in_stride, idx); |
466 | | |
467 | | // Multiply by gain and perform downsamplng |
468 | 61.0k | *num_out_samples = 0; |
469 | 375M | for (p = 0; p < num_in_samples * in_stride * upsample_fac; p += in_stride) { |
470 | 375M | out_val = ptr_out_stage5[p] * pstr_up_sampler->iir_filter.gain_sos; |
471 | 375M | ptr_out_samples[p] = out_val; |
472 | 375M | (*num_out_samples)++; |
473 | 375M | } |
474 | | |
475 | 61.0k | ia_enhaacplus_enc_copy_ring_buffers_sos(ptr_temp_ring_buf, |
476 | 61.0k | ptr_temp_ring_buf + LEN_RING_BUF_SOS_1, ptr_ring_buf1, |
477 | 61.0k | ptr_ring_buf2, LEN_RING_BUF_SOS_1, LEN_RING_BUF_SOS_2); |
478 | | |
479 | 61.0k | ia_enhaacplus_enc_copy_ring_buffers_sos(ptr_ring_buf1, ptr_ring_buf2, ptr_iir_ring1, |
480 | 61.0k | ptr_iir_ring2, LEN_RING_BUF_SOS_1, LEN_RING_BUF_SOS_2); |
481 | 61.0k | } |
482 | | |
483 | 177k | WORD32 ia_enhaacplus_enc_compute_resampling_ratio(WORD32 ccfl_idx) { |
484 | 177k | WORD32 resamp_ratio; |
485 | | |
486 | 177k | if (ccfl_idx == SBR_4_1) { |
487 | 52.0k | resamp_ratio = 2; |
488 | 125k | } else if (ccfl_idx == SBR_8_3) { |
489 | 33.3k | resamp_ratio = 4; |
490 | 92.5k | } else { |
491 | 92.5k | resamp_ratio = 1; |
492 | 92.5k | } |
493 | | |
494 | 177k | return resamp_ratio; |
495 | 177k | } |
496 | | |
497 | | VOID ixheaace_upsampling_inp_buf_generation(FLOAT32 *ptr_inp_buf, FLOAT32 *ptr_temp_buf, |
498 | | WORD32 num_samples, WORD32 upsamp_fac, |
499 | 33.3k | WORD32 offset) { |
500 | 33.3k | WORD32 idx, m = 0; |
501 | 33.3k | FLOAT32 *ptr_in_samples; |
502 | | |
503 | 33.3k | memset(ptr_temp_buf, 0, |
504 | 33.3k | (num_samples * IXHEAACE_MAX_CH_IN_BS_ELE * upsamp_fac * sizeof(*ptr_temp_buf))); |
505 | | |
506 | 33.3k | ptr_in_samples = ptr_inp_buf + offset; |
507 | | |
508 | | // Perform actual upsampling (repeat samples) |
509 | 68.2M | for (idx = 0; idx < num_samples; idx++) { |
510 | 68.2M | ptr_temp_buf[m++] = ptr_in_samples[idx * IXHEAACE_MAX_CH_IN_BS_ELE]; |
511 | 68.2M | ptr_temp_buf[m++] = ptr_in_samples[idx * IXHEAACE_MAX_CH_IN_BS_ELE + 1]; |
512 | 68.2M | ptr_temp_buf[m++] = |
513 | 68.2M | ptr_in_samples[idx * |
514 | 68.2M | IXHEAACE_MAX_CH_IN_BS_ELE]; // 1st channel sample repeated for upsampling |
515 | 68.2M | ptr_temp_buf[m++] = ptr_in_samples[idx * IXHEAACE_MAX_CH_IN_BS_ELE + |
516 | 68.2M | 1]; // 2nd channel sample repeated for upsampling |
517 | 68.2M | ptr_temp_buf[m++] = |
518 | 68.2M | ptr_in_samples[idx * |
519 | 68.2M | IXHEAACE_MAX_CH_IN_BS_ELE]; // 1st channel sample repeated for upsampling |
520 | 68.2M | ptr_temp_buf[m++] = ptr_in_samples[idx * IXHEAACE_MAX_CH_IN_BS_ELE + |
521 | 68.2M | 1]; // 2nd channel sample repeated for upsampling |
522 | 68.2M | } |
523 | 33.3k | } |