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