/****************************************************************************** * * * Copyright (C) 2023 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ***************************************************************************** * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore */ #include #include "ixheaac_type_def.h" #include "ixheaac_constants.h" #include "ixheaace_sbr_def.h" #include "ixheaace_resampler.h" #include "iusace_cnst.h" static VOID 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) { WORD32 i; ixheaace_iir_filter *pstr_iir_filter = &(pstr_down_sampler->iir_filter); FLOAT32 *ptr_iir_ring1, *ptr_iir_ring2; FLOAT32 coeff_temp_a, coeff_temp_b; const FLOAT32 *ptr_coeff_filt = (FLOAT32 *)pstr_iir_filter->ptr_coeff_iir_num; FLOAT32 iir_out = 0; FLOAT32 temp1 = 0.f, temp2 = 0.f; *num_out_samples = 0; ptr_iir_ring1 = ptr_ring_buf1; ptr_iir_ring2 = ptr_ring_buf2; for (i = 0; i < num_in_samples; i++) { temp1 = ptr_in_samples[i * in_stride] / 2; ptr_iir_ring1[i] = temp1; coeff_temp_b = *ptr_coeff_filt; temp1 = coeff_temp_b * (temp1 + ptr_iir_ring1[i - 10]); coeff_temp_a = *(ptr_coeff_filt + 16); iir_out = (ptr_iir_ring2[i - 10] * coeff_temp_a); coeff_temp_b = *(ptr_coeff_filt + 1); temp1 = (coeff_temp_b * (ptr_iir_ring1[i - 1] + ptr_iir_ring1[i - 9])) + temp1; coeff_temp_a = *(ptr_coeff_filt + 7); temp2 = (ptr_iir_ring2[i - 1] * coeff_temp_a) + iir_out; coeff_temp_a = *(ptr_coeff_filt + 15); iir_out = (ptr_iir_ring2[i - 9] * coeff_temp_a) + temp2; coeff_temp_b = *(ptr_coeff_filt + 2); temp1 = (coeff_temp_b * (ptr_iir_ring1[i - 2] + ptr_iir_ring1[i - 8])) + temp1; coeff_temp_a = *(ptr_coeff_filt + 8); temp2 = (ptr_iir_ring2[i - 2] * coeff_temp_a) + iir_out; coeff_temp_a = *(ptr_coeff_filt + 14); iir_out = (ptr_iir_ring2[i - 8] * coeff_temp_a) + temp2; coeff_temp_b = *(ptr_coeff_filt + 3); temp1 = (coeff_temp_b * (ptr_iir_ring1[i - 3] + ptr_iir_ring1[i - 7])) + temp1; coeff_temp_a = *(ptr_coeff_filt + 9); temp2 = (ptr_iir_ring2[i - 3] * coeff_temp_a) + iir_out; coeff_temp_a = *(ptr_coeff_filt + 13); iir_out = (ptr_iir_ring2[i - 7] * coeff_temp_a) + temp2; coeff_temp_b = *(ptr_coeff_filt + 4); temp1 = (coeff_temp_b * (ptr_iir_ring1[i - 4] + ptr_iir_ring1[i - 6])) + temp1; coeff_temp_a = *(ptr_coeff_filt + 10); temp2 = (ptr_iir_ring2[i - 4] * coeff_temp_a) + iir_out; coeff_temp_a = *(ptr_coeff_filt + 12); iir_out = (ptr_iir_ring2[i - 6] * coeff_temp_a) + temp2; coeff_temp_b = *(ptr_coeff_filt + 5); temp1 = (coeff_temp_b * ptr_iir_ring1[i - 5]) + temp1; coeff_temp_a = *(ptr_coeff_filt + 11); iir_out = (ptr_iir_ring2[i - 5] * coeff_temp_a) + iir_out; iir_out = temp1 - iir_out; ptr_iir_ring2[i] = iir_out; iir_out = (iir_out * (4681.0f / 32767.0f) * pstr_iir_filter->max); pstr_down_sampler->pending++; if (pstr_down_sampler->pending == pstr_down_sampler->ratio) { ptr_out_samples[(*num_out_samples) * out_stride] = iir_out; (*num_out_samples)++; pstr_down_sampler->pending = 0; } } } static VOID ia_enhaacplus_enc_copy_ring_buffers(FLOAT32 *ptr_iir_ring1, FLOAT32 *ptr_iir_ring2, FLOAT32 *ptr_ring_buf1, FLOAT32 *ptr_ring_buf2) { WORD32 i; FLOAT32 temp1, temp2, temp3; for (i = (LEN_RING_BUF / 2) - 1; i >= 0; i--) { temp1 = *ptr_iir_ring1++; temp2 = *ptr_iir_ring2++; temp3 = *ptr_iir_ring1++; *ptr_ring_buf1++ = temp1; temp1 = *ptr_iir_ring2++; *ptr_ring_buf2++ = temp2; *ptr_ring_buf1++ = temp3; *ptr_ring_buf2++ = temp1; } } static VOID 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) { memcpy(ptr_ring_buf1, ptr_iir_ring1, len1 * sizeof(*ptr_ring_buf1)); memcpy(ptr_ring_buf2, ptr_iir_ring2, len2 * sizeof(*ptr_ring_buf2)); } static VOID ia_enhaacplus_enc_update_ring_buffer_sos(FLOAT32 *ptr_ring_buf, FLOAT32 *ptr_samples, WORD32 len, WORD32 in_stride, WORD32 coeff_idx) { ptr_ring_buf[2 * coeff_idx] = ptr_samples[len - 2 * in_stride]; ptr_ring_buf[2 * coeff_idx + 1] = ptr_samples[len - in_stride]; } VOID ixheaace_get_input_scratch_buf(VOID *ptr_scr, FLOAT32 **ptr_scratch_buf_inp) { ixheaace_resampler_scratch *pstr_resampler_scr = (ixheaace_resampler_scratch *)ptr_scr; *ptr_scratch_buf_inp = pstr_resampler_scr->downsampler_in_buffer; } WORD32 ixheaace_resampler_scr_size(VOID) { return IXHEAAC_GET_SIZE_ALIGNED(sizeof(ixheaace_resampler_scratch), BYTE_ALIGN_8); } static VOID 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) { WORD32 i; ixheaace_iir_sos_filter *pstr_iir_filter = &(pstr_down_sampler->iir_filter); const FLOAT32 *ptr_coeff_den = (pstr_iir_filter->ptr_coeff_iir_den + (coeff_idx * IIR_SOS_COEFFS)); const FLOAT32 *ptr_coeff_num = (pstr_iir_filter->ptr_coeff_iir_num + (coeff_idx * IIR_SOS_COEFFS)); FLOAT32 iir_out = 0.f; FLOAT32 temp1 = 0.f, temp2 = 0.f; for (i = 0; i < num_in_samples; i++) { ptr_ring_buf1[2] = ptr_in_samples[i * in_stride]; temp1 = ptr_coeff_num[0] * ptr_in_samples[i * in_stride] + ptr_coeff_num[1] * ptr_ring_buf1[1] + ptr_coeff_num[2] * ptr_ring_buf1[0]; temp2 = ptr_coeff_den[1] * ptr_ring_buf2[1] + ptr_coeff_den[2] * ptr_ring_buf2[0]; iir_out = temp1 - temp2; ptr_ring_buf2[2] = iir_out; ptr_out_samples[i * in_stride] = iir_out; // Shift ring buffers ptr_ring_buf1[0] = ptr_ring_buf1[1]; ptr_ring_buf1[1] = ptr_ring_buf1[2]; ptr_ring_buf2[0] = ptr_ring_buf2[1]; ptr_ring_buf2[1] = ptr_ring_buf2[2]; } } VOID 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) { ixheaace_iir_filter *pstr_iir_filter = &(pstr_down_sampler->iir_filter); WORD32 k; FLOAT32 *ptr_iir_ring1, *ptr_iir_ring2, *ptr_out_temp; ptr_iir_ring2 = pstr_iir_filter->ring_buf_2; ptr_iir_ring1 = pstr_iir_filter->ring_buf_1; ptr_out_temp = pstr_resampler_scratch->downsampler_out_buffer; ia_enhaacplus_enc_copy_ring_buffers(ptr_iir_ring1, ptr_iir_ring2, ptr_ring_buf1, ptr_ring_buf2); ia_enhaacplus_enc_downsample_iir_filter( pstr_down_sampler, ptr_in_samples, ptr_out_temp, in_stride, num_in_samples, num_out_samples, out_stride, &ptr_ring_buf1[LEN_RING_BUF - 1], &ptr_ring_buf2[LEN_RING_BUF - 1]); for (k = 0; k < *num_out_samples; k++) { ptr_out_samples[k * in_stride] = ptr_out_temp[k * out_stride]; } ia_enhaacplus_enc_copy_ring_buffers(&ptr_ring_buf1[num_in_samples], &ptr_ring_buf2[num_in_samples], ptr_iir_ring1, ptr_iir_ring2); } VOID 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) { ixheaace_iir_sos_filter *pstr_iir_filter = &(pstr_down_sampler->iir_filter); FLOAT32 *ptr_iir_ring1, *ptr_iir_ring2; FLOAT32 *ptr_out_stage1, *ptr_out_stage2, *ptr_out_stage3, *ptr_out_stage4, *ptr_out_stage5, *ptr_out_final; WORD32 p = 0, idx = 0, offset1 = 0, offset2 = 0; FLOAT32 *ptr_temp_buf1, *ptr_temp_buf2, *ptr_temp_ring_buf; WORD32 upper_lim = num_in_samples * in_stride; ptr_iir_ring1 = pstr_iir_filter->ring_buf_sos_1; ptr_iir_ring2 = pstr_iir_filter->ring_buf_sos_2; ia_enhaacplus_enc_copy_ring_buffers_sos(ptr_iir_ring1, ptr_iir_ring2, ptr_ring_buf1, ptr_ring_buf2, LEN_RING_BUF_SOS_1, LEN_RING_BUF_SOS_2); ptr_temp_buf1 = pstr_resampler_scratch->scratch_buf1_temp; ptr_temp_buf2 = pstr_resampler_scratch->scratch_buf2_temp; ptr_temp_ring_buf = pstr_resampler_scratch->ring_buf_temp; ia_enhaacplus_enc_copy_ring_buffers_sos(ptr_ring_buf1, ptr_ring_buf2, ptr_temp_buf1, ptr_temp_buf2, LEN_RING_BUF_SOS_1, LEN_RING_BUF_SOS_1); ptr_out_stage1 = pstr_resampler_scratch->downsampler_out_buffer; ia_enhaacplus_enc_update_ring_buffer_sos(ptr_temp_ring_buf, ptr_in_samples, upper_lim, in_stride, idx); // Stage 1 ia_enhaacplus_enc_iir_sos_filter(pstr_down_sampler, ptr_in_samples, in_stride, ptr_out_stage1, num_in_samples, ptr_temp_buf1, ptr_temp_buf2, idx); offset1 = LEN_RING_BUF_SOS_1 * idx; offset2 = LEN_RING_BUF_SOS_1 * (idx + 1); ia_enhaacplus_enc_copy_ring_buffers_sos(ptr_ring_buf2 + offset1, ptr_ring_buf2 + offset2, ptr_temp_buf1, ptr_temp_buf2, LEN_RING_BUF_SOS_1, LEN_RING_BUF_SOS_1); idx++; ia_enhaacplus_enc_update_ring_buffer_sos(ptr_temp_ring_buf, ptr_out_stage1, upper_lim, in_stride, idx); ptr_out_stage2 = pstr_resampler_scratch->downsampler_in_buffer; // Stage 2 ia_enhaacplus_enc_iir_sos_filter(pstr_down_sampler, ptr_out_stage1, in_stride, ptr_out_stage2, num_in_samples, ptr_temp_buf1, ptr_temp_buf2, idx); offset1 = LEN_RING_BUF_SOS_1 * idx; offset2 = LEN_RING_BUF_SOS_1 * (idx + 1); ia_enhaacplus_enc_copy_ring_buffers_sos(ptr_ring_buf2 + offset1, ptr_ring_buf2 + offset2, ptr_temp_buf1, ptr_temp_buf2, LEN_RING_BUF_SOS_1, LEN_RING_BUF_SOS_1); idx++; ia_enhaacplus_enc_update_ring_buffer_sos(ptr_temp_ring_buf, ptr_out_stage2, upper_lim, in_stride, idx); ptr_out_stage3 = pstr_resampler_scratch->downsampler_out_buffer; // Stage 3 ia_enhaacplus_enc_iir_sos_filter(pstr_down_sampler, ptr_out_stage2, in_stride, ptr_out_stage3, num_in_samples, ptr_temp_buf1, ptr_temp_buf2, idx); offset1 = LEN_RING_BUF_SOS_1 * idx; offset2 = LEN_RING_BUF_SOS_1 * (idx + 1); ia_enhaacplus_enc_copy_ring_buffers_sos(ptr_ring_buf2 + offset1, ptr_ring_buf2 + offset2, ptr_temp_buf1, ptr_temp_buf2, LEN_RING_BUF_SOS_1, LEN_RING_BUF_SOS_1); idx++; ia_enhaacplus_enc_update_ring_buffer_sos(ptr_temp_ring_buf, ptr_out_stage3, upper_lim, in_stride, idx); ptr_out_stage4 = pstr_resampler_scratch->downsampler_in_buffer; // Stage 4 ia_enhaacplus_enc_iir_sos_filter(pstr_down_sampler, ptr_out_stage3, in_stride, ptr_out_stage4, num_in_samples, ptr_temp_buf1, ptr_temp_buf2, idx); offset1 = LEN_RING_BUF_SOS_1 * idx; offset2 = LEN_RING_BUF_SOS_1 * (idx + 1); ia_enhaacplus_enc_copy_ring_buffers_sos(ptr_ring_buf2 + offset1, ptr_ring_buf2 + offset2, ptr_temp_buf1, ptr_temp_buf2, LEN_RING_BUF_SOS_1, LEN_RING_BUF_SOS_1); idx++; ia_enhaacplus_enc_update_ring_buffer_sos(ptr_temp_ring_buf, ptr_out_stage4, upper_lim, in_stride, idx); ptr_out_stage5 = pstr_resampler_scratch->downsampler_out_buffer; // Stage 5 ia_enhaacplus_enc_iir_sos_filter(pstr_down_sampler, ptr_out_stage4, in_stride, ptr_out_stage5, num_in_samples, ptr_temp_buf1, ptr_temp_buf2, idx); idx++; ia_enhaacplus_enc_update_ring_buffer_sos(ptr_temp_ring_buf, ptr_out_stage5, upper_lim, in_stride, idx); ptr_out_final = pstr_resampler_scratch->downsampler_in_buffer; // Multiply by gain and perform downsamplng *num_out_samples = 0; for (p = 0; p < num_in_samples * in_stride; p += in_stride) { ptr_out_final[p] = ptr_out_stage5[p] * pstr_down_sampler->iir_filter.gain_sos; pstr_down_sampler->pending++; if (pstr_down_sampler->pending == pstr_down_sampler->ratio) { ptr_out_samples[(*num_out_samples) * in_stride] = ptr_out_final[p]; (*num_out_samples)++; pstr_down_sampler->pending = 0; } } // Update ring buffers ia_enhaacplus_enc_copy_ring_buffers_sos(ptr_temp_ring_buf, ptr_temp_ring_buf + LEN_RING_BUF_SOS_1, ptr_ring_buf1, ptr_ring_buf2, LEN_RING_BUF_SOS_1, LEN_RING_BUF_SOS_2); ia_enhaacplus_enc_copy_ring_buffers_sos(ptr_ring_buf1, ptr_ring_buf2, ptr_iir_ring1, ptr_iir_ring2, LEN_RING_BUF_SOS_1, LEN_RING_BUF_SOS_2); } VOID 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) { ixheaace_iir_sos_filter *pstr_iir_filter = &(pstr_up_sampler->iir_filter); FLOAT32 *ptr_iir_ring1, *ptr_iir_ring2; FLOAT32 *ptr_out_stage1, *ptr_out_stage2, *ptr_out_stage3, *ptr_out_stage4, *ptr_out_stage5; FLOAT32 out_val; FLOAT32 *ptr_temp_buf1, *ptr_temp_buf2, *ptr_temp_ring_buf; WORD32 p = 0, idx = 0, offset1 = 0, offset2 = 0; WORD32 upsample_fac = pstr_up_sampler->ratio; WORD32 upper_lim = num_in_samples * in_stride * upsample_fac; ptr_iir_ring2 = pstr_iir_filter->ring_buf_sos_2; ptr_iir_ring1 = pstr_iir_filter->ring_buf_sos_1; ia_enhaacplus_enc_copy_ring_buffers_sos(ptr_iir_ring1, ptr_iir_ring2, ptr_ring_buf1, ptr_ring_buf2, LEN_RING_BUF_SOS_1, LEN_RING_BUF_SOS_2); ptr_temp_buf1 = pstr_resampler_scratch->scratch_buf1_temp; ptr_temp_buf2 = pstr_resampler_scratch->scratch_buf2_temp; ptr_temp_ring_buf = pstr_resampler_scratch->ring_buf_temp; ia_enhaacplus_enc_copy_ring_buffers_sos(ptr_ring_buf1, ptr_ring_buf2, ptr_temp_buf1, ptr_temp_buf2, LEN_RING_BUF_SOS_1, LEN_RING_BUF_SOS_1); ptr_out_stage1 = pstr_resampler_scratch->downsampler_out_buffer; ia_enhaacplus_enc_update_ring_buffer_sos(ptr_temp_ring_buf, ptr_in_samples, upper_lim, in_stride, idx); // Stage 1 ia_enhaacplus_enc_iir_sos_filter(pstr_up_sampler, ptr_in_samples, in_stride, ptr_out_stage1, num_in_samples * upsample_fac, ptr_temp_buf1, ptr_temp_buf2, idx); offset1 = LEN_RING_BUF_SOS_1 * idx; offset2 = LEN_RING_BUF_SOS_1 * (idx + 1); ia_enhaacplus_enc_copy_ring_buffers_sos(ptr_ring_buf2 + offset1, ptr_ring_buf2 + offset2, ptr_temp_buf1, ptr_temp_buf2, LEN_RING_BUF_SOS_1, LEN_RING_BUF_SOS_1); idx++; ia_enhaacplus_enc_update_ring_buffer_sos(ptr_temp_ring_buf, ptr_out_stage1, upper_lim, in_stride, idx); ptr_out_stage2 = pstr_resampler_scratch->downsampler_in_buffer; // Stage 2 ia_enhaacplus_enc_iir_sos_filter(pstr_up_sampler, ptr_out_stage1, in_stride, ptr_out_stage2, num_in_samples * upsample_fac, ptr_temp_buf1, ptr_temp_buf2, idx); offset1 = LEN_RING_BUF_SOS_1 * idx; offset2 = LEN_RING_BUF_SOS_1 * (idx + 1); ia_enhaacplus_enc_copy_ring_buffers_sos(ptr_ring_buf2 + offset1, ptr_ring_buf2 + offset2, ptr_temp_buf1, ptr_temp_buf2, LEN_RING_BUF_SOS_1, LEN_RING_BUF_SOS_1); idx++; ia_enhaacplus_enc_update_ring_buffer_sos(ptr_temp_ring_buf, ptr_out_stage2, upper_lim, in_stride, idx); ptr_out_stage3 = pstr_resampler_scratch->downsampler_out_buffer; // Stage 3 ia_enhaacplus_enc_iir_sos_filter(pstr_up_sampler, ptr_out_stage2, in_stride, ptr_out_stage3, num_in_samples * upsample_fac, ptr_temp_buf1, ptr_temp_buf2, idx); offset1 = LEN_RING_BUF_SOS_1 * idx; offset2 = LEN_RING_BUF_SOS_1 * (idx + 1); ia_enhaacplus_enc_copy_ring_buffers_sos(ptr_ring_buf2 + offset1, ptr_ring_buf2 + offset2, ptr_temp_buf1, ptr_temp_buf2, LEN_RING_BUF_SOS_1, LEN_RING_BUF_SOS_1); idx++; ia_enhaacplus_enc_update_ring_buffer_sos(ptr_temp_ring_buf, ptr_out_stage3, upper_lim, in_stride, idx); ptr_out_stage4 = pstr_resampler_scratch->downsampler_in_buffer; // Stage 4 ia_enhaacplus_enc_iir_sos_filter(pstr_up_sampler, ptr_out_stage3, in_stride, ptr_out_stage4, num_in_samples * upsample_fac, ptr_temp_buf1, ptr_temp_buf2, idx); offset1 = LEN_RING_BUF_SOS_1 * idx; offset2 = LEN_RING_BUF_SOS_1 * (idx + 1); ia_enhaacplus_enc_copy_ring_buffers_sos(ptr_ring_buf2 + offset1, ptr_ring_buf2 + offset2, ptr_temp_buf1, ptr_temp_buf2, LEN_RING_BUF_SOS_1, LEN_RING_BUF_SOS_1); idx++; ia_enhaacplus_enc_update_ring_buffer_sos(ptr_temp_ring_buf, ptr_out_stage4, upper_lim, in_stride, idx); ptr_out_stage5 = pstr_resampler_scratch->downsampler_out_buffer; // Stage 5 ia_enhaacplus_enc_iir_sos_filter(pstr_up_sampler, ptr_out_stage4, in_stride, ptr_out_stage5, num_in_samples * upsample_fac, ptr_temp_buf1, ptr_temp_buf2, idx); idx++; ia_enhaacplus_enc_update_ring_buffer_sos(ptr_temp_ring_buf, ptr_out_stage5, upper_lim, in_stride, idx); // Multiply by gain and perform downsamplng *num_out_samples = 0; for (p = 0; p < num_in_samples * in_stride * upsample_fac; p += in_stride) { out_val = ptr_out_stage5[p] * pstr_up_sampler->iir_filter.gain_sos; ptr_out_samples[p] = out_val; (*num_out_samples)++; } ia_enhaacplus_enc_copy_ring_buffers_sos(ptr_temp_ring_buf, ptr_temp_ring_buf + LEN_RING_BUF_SOS_1, ptr_ring_buf1, ptr_ring_buf2, LEN_RING_BUF_SOS_1, LEN_RING_BUF_SOS_2); ia_enhaacplus_enc_copy_ring_buffers_sos(ptr_ring_buf1, ptr_ring_buf2, ptr_iir_ring1, ptr_iir_ring2, LEN_RING_BUF_SOS_1, LEN_RING_BUF_SOS_2); } WORD32 ia_enhaacplus_enc_compute_resampling_ratio(WORD32 ccfl_idx) { WORD32 resamp_ratio; if (ccfl_idx == SBR_4_1) { resamp_ratio = 2; } else if (ccfl_idx == SBR_8_3) { resamp_ratio = 4; } else { resamp_ratio = 1; } return resamp_ratio; } VOID ixheaace_upsampling_inp_buf_generation(FLOAT32 *ptr_inp_buf, FLOAT32 *ptr_temp_buf, WORD32 num_samples, WORD32 upsamp_fac, WORD32 offset) { WORD32 idx, m = 0; FLOAT32 *ptr_in_samples; memset(ptr_temp_buf, 0, (num_samples * IXHEAACE_MAX_CH_IN_BS_ELE * upsamp_fac * sizeof(*ptr_temp_buf))); ptr_in_samples = ptr_inp_buf + offset; // Perform actual upsampling (repeat samples) for (idx = 0; idx < num_samples; idx++) { ptr_temp_buf[m++] = ptr_in_samples[idx * IXHEAACE_MAX_CH_IN_BS_ELE]; ptr_temp_buf[m++] = ptr_in_samples[idx * IXHEAACE_MAX_CH_IN_BS_ELE + 1]; ptr_temp_buf[m++] = ptr_in_samples[idx * IXHEAACE_MAX_CH_IN_BS_ELE]; // 1st channel sample repeated for upsampling ptr_temp_buf[m++] = ptr_in_samples[idx * IXHEAACE_MAX_CH_IN_BS_ELE + 1]; // 2nd channel sample repeated for upsampling ptr_temp_buf[m++] = ptr_in_samples[idx * IXHEAACE_MAX_CH_IN_BS_ELE]; // 1st channel sample repeated for upsampling ptr_temp_buf[m++] = ptr_in_samples[idx * IXHEAACE_MAX_CH_IN_BS_ELE + 1]; // 2nd channel sample repeated for upsampling } }