/* * Copyright (C) 2003 - 2016 Sony Corporation * * 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. */ #include "ldac.h" /*************************************************************************************************** Subfunction: Process MDCT Core ***************************************************************************************************/ static void proc_mdct_core_ldac( INT32 *p_x, INT32 *p_y, int nlnn) { INT32 i, j, k; INT32 loop1, loop2; INT32 coef, index0, index1, offset; int nsmpl = npow2_ldac(nlnn); int shift; const int *p_p; const INT32 *p_w, *p_c, *p_s; INT32 a_work[LDAC_MAXLSU]; INT32 g0, g1, g2, g3; i = nlnn - LDAC_1FSLNN; p_w = gaa_fwin_ldac[i]; p_c = gaa_wcos_ldac[i]; p_s = gaa_wsin_ldac[i]; p_p = gaa_perm_ldac[i]; /* Block Floating */ shift = LDAC_C_BLKFLT - get_bit_length_ldac(get_absmax_ldac(p_x, nsmpl<<1)) - 1; if (shift < 0) { shift = 0; } /* Windowing */ if (LDAC_Q_MDCT_WIN-shift > 0){ for (i = 0; i < nsmpl>>1; i++) { g0 = mul_rsftrnd_ldac(-p_x[3*nsmpl/2-1-i], p_w[nsmpl/2+i], LDAC_Q_MDCT_WIN-shift); g1 = mul_rsftrnd_ldac(-p_x[3*nsmpl/2+i], p_w[nsmpl/2-1-i], LDAC_Q_MDCT_WIN-shift); a_work[p_p[i]] = g0 + g1; g0 = mul_rsftrnd_ldac(p_x[i], p_w[i], LDAC_Q_MDCT_WIN-shift); g1 = mul_rsftrnd_ldac(-p_x[nsmpl-1-i], p_w[nsmpl-1-i], LDAC_Q_MDCT_WIN-shift); a_work[p_p[nsmpl/2+i]] = g0 + g1; } } else{ for (i = 0; i < nsmpl>>1; i++) { g0 = mul_lsftrnd_ldac(-p_x[3*nsmpl/2-1-i], p_w[nsmpl/2+i], LDAC_Q_MDCT_WIN-shift); g1 = mul_lsftrnd_ldac(-p_x[3*nsmpl/2+i], p_w[nsmpl/2-1-i], LDAC_Q_MDCT_WIN-shift); a_work[p_p[i]] = g0 + g1; g0 = mul_lsftrnd_ldac(p_x[i], p_w[i], LDAC_Q_MDCT_WIN-shift); g1 = mul_lsftrnd_ldac(-p_x[nsmpl-1-i], p_w[nsmpl-1-i], LDAC_Q_MDCT_WIN-shift); a_work[p_p[nsmpl/2+i]] = g0 + g1; } } /* Butterfly */ coef = 0; for (i = 0; i < nlnn-1; i++) { loop1 = 1 << (nlnn-2-i); loop2 = 1 << i; index0 = 0; index1 = 1 << (i+1); offset = 1 << (i+1); for (j = 0; j < loop1; j++) { for (k = 0; k < loop2; k++) { g0 = mul_rsftrnd_ldac(a_work[index1], p_c[coef], LDAC_Q_MDCT_COS+1); g1 = mul_rsftrnd_ldac(a_work[index1+1], p_s[coef], LDAC_Q_MDCT_SIN+1); g2 = g0 + g1; g0 = mul_rsftrnd_ldac(a_work[index1], p_s[coef], LDAC_Q_MDCT_SIN+1); g1 = mul_rsftrnd_ldac(a_work[index1+1], p_c[coef], LDAC_Q_MDCT_COS+1); g3 = g0 - g1; g0 = a_work[index0] >> 1; g1 = a_work[index0+1] >> 1; a_work[index0] = g0 + g2; a_work[index0+1] = g1 + g3; a_work[index1] = g0 - g2; a_work[index1+1] = g1 - g3; index0 += 2; index1 += 2; coef++; } index0 += offset; index1 += offset; coef -= loop2; } coef += loop2; } for (i = 0; i < nsmpl>>1; i++) { index0 = i << 1; g0 = mul_rsftrnd_ldac(a_work[index0], p_c[coef], LDAC_Q_MDCT_COS+shift); g1 = mul_rsftrnd_ldac(a_work[index0+1], p_s[coef], LDAC_Q_MDCT_SIN+shift); p_y[index0] = g0 + g1; g0 = mul_rsftrnd_ldac(a_work[index0], p_s[coef], LDAC_Q_MDCT_SIN+shift); g1 = mul_rsftrnd_ldac(a_work[index0+1], p_c[coef], LDAC_Q_MDCT_COS+shift); p_y[nsmpl-index0-1] = g0 - g1; coef++; } return; } /*************************************************************************************************** Process MDCT ***************************************************************************************************/ DECLFUNC void proc_mdct_ldac( SFINFO *p_sfinfo, int nlnn) { AC *p_ac; int ich; int nchs = p_sfinfo->cfg.ch; for (ich = 0; ich < nchs; ich++) { p_ac = p_sfinfo->ap_ac[ich]; proc_mdct_core_ldac(p_ac->p_acsub->a_time, p_ac->p_acsub->a_spec, nlnn); } return; }