Home | History | Annotate | Download | only in src
      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