1 /* 2 * Copyright (C) 2003 - 2016 Sony Corporation 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include "ldac.h" 18 19 /*************************************************************************************************** 20 Subfunction: Process MDCT Core 21 ***************************************************************************************************/ 22 static void proc_mdct_core_ldac( 23 INT32 *p_x, 24 INT32 *p_y, 25 int nlnn) 26 { 27 INT32 i, j, k; 28 INT32 loop1, loop2; 29 INT32 coef, index0, index1, offset; 30 int nsmpl = npow2_ldac(nlnn); 31 int shift; 32 const int *p_p; 33 const INT32 *p_w, *p_c, *p_s; 34 INT32 a_work[LDAC_MAXLSU]; 35 INT32 g0, g1, g2, g3; 36 37 i = nlnn - LDAC_1FSLNN; 38 p_w = gaa_fwin_ldac[i]; 39 p_c = gaa_wcos_ldac[i]; 40 p_s = gaa_wsin_ldac[i]; 41 p_p = gaa_perm_ldac[i]; 42 43 /* Block Floating */ 44 shift = LDAC_C_BLKFLT - get_bit_length_ldac(get_absmax_ldac(p_x, nsmpl<<1)) - 1; 45 if (shift < 0) { 46 shift = 0; 47 } 48 49 /* Windowing */ 50 if (LDAC_Q_MDCT_WIN-shift > 0){ 51 for (i = 0; i < nsmpl>>1; i++) { 52 g0 = mul_rsftrnd_ldac(-p_x[3*nsmpl/2-1-i], p_w[nsmpl/2+i], LDAC_Q_MDCT_WIN-shift); 53 g1 = mul_rsftrnd_ldac(-p_x[3*nsmpl/2+i], p_w[nsmpl/2-1-i], LDAC_Q_MDCT_WIN-shift); 54 a_work[p_p[i]] = g0 + g1; 55 56 g0 = mul_rsftrnd_ldac(p_x[i], p_w[i], LDAC_Q_MDCT_WIN-shift); 57 g1 = mul_rsftrnd_ldac(-p_x[nsmpl-1-i], p_w[nsmpl-1-i], LDAC_Q_MDCT_WIN-shift); 58 a_work[p_p[nsmpl/2+i]] = g0 + g1; 59 } 60 } 61 else{ 62 for (i = 0; i < nsmpl>>1; i++) { 63 g0 = mul_lsftrnd_ldac(-p_x[3*nsmpl/2-1-i], p_w[nsmpl/2+i], LDAC_Q_MDCT_WIN-shift); 64 g1 = mul_lsftrnd_ldac(-p_x[3*nsmpl/2+i], p_w[nsmpl/2-1-i], LDAC_Q_MDCT_WIN-shift); 65 a_work[p_p[i]] = g0 + g1; 66 67 g0 = mul_lsftrnd_ldac(p_x[i], p_w[i], LDAC_Q_MDCT_WIN-shift); 68 g1 = mul_lsftrnd_ldac(-p_x[nsmpl-1-i], p_w[nsmpl-1-i], LDAC_Q_MDCT_WIN-shift); 69 a_work[p_p[nsmpl/2+i]] = g0 + g1; 70 } 71 } 72 73 /* Butterfly */ 74 coef = 0; 75 for (i = 0; i < nlnn-1; i++) { 76 loop1 = 1 << (nlnn-2-i); 77 loop2 = 1 << i; 78 index0 = 0; 79 index1 = 1 << (i+1); 80 offset = 1 << (i+1); 81 82 for (j = 0; j < loop1; j++) { 83 for (k = 0; k < loop2; k++) { 84 g0 = mul_rsftrnd_ldac(a_work[index1], p_c[coef], LDAC_Q_MDCT_COS+1); 85 g1 = mul_rsftrnd_ldac(a_work[index1+1], p_s[coef], LDAC_Q_MDCT_SIN+1); 86 g2 = g0 + g1; 87 88 g0 = mul_rsftrnd_ldac(a_work[index1], p_s[coef], LDAC_Q_MDCT_SIN+1); 89 g1 = mul_rsftrnd_ldac(a_work[index1+1], p_c[coef], LDAC_Q_MDCT_COS+1); 90 g3 = g0 - g1; 91 92 g0 = a_work[index0] >> 1; 93 g1 = a_work[index0+1] >> 1; 94 95 a_work[index0] = g0 + g2; 96 a_work[index0+1] = g1 + g3; 97 a_work[index1] = g0 - g2; 98 a_work[index1+1] = g1 - g3; 99 100 index0 += 2; 101 index1 += 2; 102 coef++; 103 } 104 index0 += offset; 105 index1 += offset; 106 coef -= loop2; 107 } 108 coef += loop2; 109 } 110 111 for (i = 0; i < nsmpl>>1; i++) { 112 index0 = i << 1; 113 114 g0 = mul_rsftrnd_ldac(a_work[index0], p_c[coef], LDAC_Q_MDCT_COS+shift); 115 g1 = mul_rsftrnd_ldac(a_work[index0+1], p_s[coef], LDAC_Q_MDCT_SIN+shift); 116 p_y[index0] = g0 + g1; 117 118 g0 = mul_rsftrnd_ldac(a_work[index0], p_s[coef], LDAC_Q_MDCT_SIN+shift); 119 g1 = mul_rsftrnd_ldac(a_work[index0+1], p_c[coef], LDAC_Q_MDCT_COS+shift); 120 p_y[nsmpl-index0-1] = g0 - g1; 121 122 coef++; 123 } 124 125 126 return; 127 } 128 129 /*************************************************************************************************** 130 Process MDCT 131 ***************************************************************************************************/ 132 DECLFUNC void proc_mdct_ldac( 133 SFINFO *p_sfinfo, 134 int nlnn) 135 { 136 AC *p_ac; 137 int ich; 138 int nchs = p_sfinfo->cfg.ch; 139 140 for (ich = 0; ich < nchs; ich++) { 141 p_ac = p_sfinfo->ap_ac[ich]; 142 proc_mdct_core_ldac(p_ac->p_acsub->a_time, p_ac->p_acsub->a_spec, nlnn); 143 } 144 145 return; 146 } 147 148