/* L3mdct */ #include "l3mdct.h" #include "l3subband.h" #include "types.h" /* This is table B.9: coefficients for aliasing reduction */ #define MDCT_CA(coef) (int32_t)(coef / sqrt(1.0 + (coef * coef)) * 0x7fffffff) #define MDCT_CS(coef) (int32_t)(1.0 / sqrt(1.0 + (coef * coef)) * 0x7fffffff) #define MDCT_CA0 MDCT_CA(-0.6) #define MDCT_CA1 MDCT_CA(-0.535) #define MDCT_CA2 MDCT_CA(-0.33) #define MDCT_CA3 MDCT_CA(-0.185) #define MDCT_CA4 MDCT_CA(-0.095) #define MDCT_CA5 MDCT_CA(-0.041) #define MDCT_CA6 MDCT_CA(-0.0142) #define MDCT_CA7 MDCT_CA(-0.0037) #define MDCT_CS0 MDCT_CS(-0.6) #define MDCT_CS1 MDCT_CS(-0.535) #define MDCT_CS2 MDCT_CS(-0.33) #define MDCT_CS3 MDCT_CS(-0.185) #define MDCT_CS4 MDCT_CS(-0.095) #define MDCT_CS5 MDCT_CS(-0.041) #define MDCT_CS6 MDCT_CS(-0.0142) #define MDCT_CS7 MDCT_CS(-0.0037) /* * shine_mdct_initialise: * ------------------- */ void shine_mdct_initialise(shine_global_config *config) { int m, k; /* prepare the mdct coefficients */ for (m = 18; m--;) for (k = 36; k--;) /* combine window and mdct coefficients into a single table */ /* scale and convert to fixed point before storing */ config->mdct.cos_l[m][k] = (int32_t)(sin(PI36 * (k + 0.5)) * cos((PI / 72) * (2 * k + 19) * (2 * m + 1)) * 0x7fffffff); } /* * shine_mdct_sub: * ------------ */ void shine_mdct_sub(shine_global_config *config, int stride) { /* note. we wish to access the array 'config->mdct_freq[2][2][576]' as * [2][2][32][18]. (32*18=576), */ int32_t(*mdct_enc)[18]; int ch, gr, band, j, k; int32_t mdct_in[36]; for (ch = config->wave.channels; ch--;) { for (gr = 0; gr < config->mpeg.granules_per_frame; gr++) { /* set up pointer to the part of config->mdct_freq we're using */ mdct_enc = (int32_t(*)[18])config->mdct_freq[ch][gr]; /* polyphase filtering */ for (k = 0; k < 18; k += 2) { shine_window_filter_subband(&config->buffer[ch], &config->l3_sb_sample[ch][gr + 1][k][0], ch, config, stride); shine_window_filter_subband(&config->buffer[ch], &config->l3_sb_sample[ch][gr + 1][k + 1][0], ch, config, stride); /* Compensate for inversion in the analysis filter * (every odd index of band AND k) */ for (band = 1; band < 32; band += 2) config->l3_sb_sample[ch][gr + 1][k + 1][band] *= -1; } /* Perform imdct of 18 previous subband samples + 18 current subband * samples */ for (band = 0; band < 32; band++) { for (k = 18; k--;) { mdct_in[k] = config->l3_sb_sample[ch][gr][k][band]; mdct_in[k + 18] = config->l3_sb_sample[ch][gr + 1][k][band]; } /* Calculation of the MDCT * In the case of long blocks ( block_type 0,1,3 ) there are * 36 coefficients in the time domain and 18 in the frequency * domain. */ for (k = 18; k--;) { int32_t vm; #ifdef __BORLANDC__ uint32_t vm_lo; #else uint32_t vm_lo __attribute__((unused)); #endif mul0(vm, vm_lo, mdct_in[35], config->mdct.cos_l[k][35]); for (j = 35; j; j -= 7) { muladd(vm, vm_lo, mdct_in[j - 1], config->mdct.cos_l[k][j - 1]); muladd(vm, vm_lo, mdct_in[j - 2], config->mdct.cos_l[k][j - 2]); muladd(vm, vm_lo, mdct_in[j - 3], config->mdct.cos_l[k][j - 3]); muladd(vm, vm_lo, mdct_in[j - 4], config->mdct.cos_l[k][j - 4]); muladd(vm, vm_lo, mdct_in[j - 5], config->mdct.cos_l[k][j - 5]); muladd(vm, vm_lo, mdct_in[j - 6], config->mdct.cos_l[k][j - 6]); muladd(vm, vm_lo, mdct_in[j - 7], config->mdct.cos_l[k][j - 7]); } mulz(vm, vm_lo); mdct_enc[band][k] = vm; } /* Perform aliasing reduction butterfly */ if (band != 0) { cmuls(mdct_enc[band][0], mdct_enc[band - 1][17 - 0], mdct_enc[band][0], mdct_enc[band - 1][17 - 0], MDCT_CS0, MDCT_CA0); cmuls(mdct_enc[band][1], mdct_enc[band - 1][17 - 1], mdct_enc[band][1], mdct_enc[band - 1][17 - 1], MDCT_CS1, MDCT_CA1); cmuls(mdct_enc[band][2], mdct_enc[band - 1][17 - 2], mdct_enc[band][2], mdct_enc[band - 1][17 - 2], MDCT_CS2, MDCT_CA2); cmuls(mdct_enc[band][3], mdct_enc[band - 1][17 - 3], mdct_enc[band][3], mdct_enc[band - 1][17 - 3], MDCT_CS3, MDCT_CA3); cmuls(mdct_enc[band][4], mdct_enc[band - 1][17 - 4], mdct_enc[band][4], mdct_enc[band - 1][17 - 4], MDCT_CS4, MDCT_CA4); cmuls(mdct_enc[band][5], mdct_enc[band - 1][17 - 5], mdct_enc[band][5], mdct_enc[band - 1][17 - 5], MDCT_CS5, MDCT_CA5); cmuls(mdct_enc[band][6], mdct_enc[band - 1][17 - 6], mdct_enc[band][6], mdct_enc[band - 1][17 - 6], MDCT_CS6, MDCT_CA6); cmuls(mdct_enc[band][7], mdct_enc[band - 1][17 - 7], mdct_enc[band][7], mdct_enc[band - 1][17 - 7], MDCT_CS7, MDCT_CA7); } } } /* Save latest granule's subband samples to be used in the next mdct call */ memcpy(config->l3_sb_sample[ch][0], config->l3_sb_sample[ch][config->mpeg.granules_per_frame], sizeof(config->l3_sb_sample[0][0])); } }