Chisato Kenmochi | 9470443 | 2017-01-10 11:56:48 +0900 | [diff] [blame] | 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 | |