void mdct_sub(double sb_sample[2][3][18][SBLIMIT], double (*mdct_freq)[2][samp_per_frame2], side_info_t *side_info) { double (*mdct_enc)[2][32][18] = (double (*)[2][32][18]) mdct_freq; int ch,gr,band,k,j; gr_info *cod_info; double mdct_in[36]; double bu,bd; for(gr=0; gr<2; gr++) for(ch=config.wave.channels; ch--; ) { cod_info = (gr_info*) &(side_info->gr[gr].ch[ch]) ; /* Compensate for inversion in the analysis filter */ for(band=32; band--; ) for(k=18; k--; ) if((band&1) && (k&1)) sb_sample[ch][gr+1][k][band] *= -1.0; /* Perform imdct of 18 previous subband samples + 18 current subband samples */ for(band=32; band--; ) { for(k=18; k--; ) { mdct_in[k] = sb_sample[ch][ gr ][k][band]; mdct_in[k+18] = sb_sample[ch][gr+1][k][band]; } mdct(mdct_in,&mdct_enc[gr][ch][band][0]); } /* Perform aliasing reduction butterfly*/ for(band=31; band--; ) for(k=8; k--; ) { bu = mdct_enc[gr][ch][band][17-k] * cs[k] + mdct_enc[gr][ch][band+1][k] * ca[k]; bd = mdct_enc[gr][ch][band+1][k] * cs[k] - mdct_enc[gr][ch][band][17-k] * ca[k]; mdct_enc[gr][ch][band][17-k] = bu; mdct_enc[gr][ch][band+1][k] = bd; } } /* Save latest granule's subband samples to be used in the next mdct call */ for(ch=config.wave.channels ;ch--; ) for(j=18; j--; ) for(band=32; band--; ) sb_sample[ch][0][j][band] = sb_sample[ch][2][j][band]; }
/* only works for LTP -> no overlapping, no short blocks */ void filter_bank_ltp(fb_info *fb, uint8_t window_sequence, uint8_t window_shape, uint8_t window_shape_prev, real_t *in_data, real_t *out_mdct, uint8_t object_type, uint16_t frame_len) { int16_t i; ALIGN real_t windowed_buf[2*1024] = {0}; const real_t *window_long = NULL; const real_t *window_long_prev = NULL; const real_t *window_short = NULL; const real_t *window_short_prev = NULL; uint16_t nlong = frame_len; uint16_t nshort = frame_len/8; uint16_t nflat_ls = (nlong-nshort)/2; assert(window_sequence != EIGHT_SHORT_SEQUENCE); #ifdef LD_DEC if (object_type == LD) { window_long = fb->ld_window[window_shape]; window_long_prev = fb->ld_window[window_shape_prev]; } else { #endif window_long = fb->long_window[window_shape]; window_long_prev = fb->long_window[window_shape_prev]; window_short = fb->short_window[window_shape]; window_short_prev = fb->short_window[window_shape_prev]; #ifdef LD_DEC } #endif switch(window_sequence) { case ONLY_LONG_SEQUENCE: for (i = nlong-1; i >= 0; i--) { windowed_buf[i] = MUL_F(in_data[i], window_long_prev[i]); windowed_buf[i+nlong] = MUL_F(in_data[i+nlong], window_long[nlong-1-i]); } mdct(fb, windowed_buf, out_mdct, 2*nlong); break; case LONG_START_SEQUENCE: for (i = 0; i < nlong; i++) windowed_buf[i] = MUL_F(in_data[i], window_long_prev[i]); for (i = 0; i < nflat_ls; i++) windowed_buf[i+nlong] = in_data[i+nlong]; for (i = 0; i < nshort; i++) windowed_buf[i+nlong+nflat_ls] = MUL_F(in_data[i+nlong+nflat_ls], window_short[nshort-1-i]); for (i = 0; i < nflat_ls; i++) windowed_buf[i+nlong+nflat_ls+nshort] = 0; mdct(fb, windowed_buf, out_mdct, 2*nlong); break; case LONG_STOP_SEQUENCE: for (i = 0; i < nflat_ls; i++) windowed_buf[i] = 0; for (i = 0; i < nshort; i++) windowed_buf[i+nflat_ls] = MUL_F(in_data[i+nflat_ls], window_short_prev[i]); for (i = 0; i < nflat_ls; i++) windowed_buf[i+nflat_ls+nshort] = in_data[i+nflat_ls+nshort]; for (i = 0; i < nlong; i++) windowed_buf[i+nlong] = MUL_F(in_data[i+nlong], window_long[nlong-1-i]); mdct(fb, windowed_buf, out_mdct, 2*nlong); break; } }