package net.sourceforge.jaad.aac.sbr;
import java.util.Arrays;
/**
* This class is part of JAAD ( jaadec.sourceforge.net ) that is distributed
* under the Public Domain license. Code changes provided by the JCodec project
* are distributed under FreeBSD license.
*
* @author in-somnia
*/
class AnalysisFilterbank implements FilterbankTable {
private float[] x; //x is implemented as double ringbuffer
private int x_index; //ringbuffer index
private int channels;
AnalysisFilterbank(int channels) {
this.channels = channels;
x = new float[2*channels*10];
x_index = 0;
}
public void reset() {
Arrays.fill(x, 0);
}
void sbr_qmf_analysis_32(SBR sbr, float[] input,
float[][][] X, int offset, int kx) {
float[] u = new float[64];
float[] in_real = new float[32], in_imag = new float[32];
float[] out_real = new float[32], out_imag = new float[32];
int _in = 0;
int l;
/* qmf subsample l */
for(l = 0; l<sbr.numTimeSlotsRate; l++) {
int n;
/* shift input buffer x */
/* input buffer is not shifted anymore, x is implemented as double ringbuffer */
//memmove(qmfa.x + 32, qmfa.x, (320-32)*sizeof(real_t));
/* add new samples to input buffer x */
for(n = 32-1; n>=0; n--) {
this.x[this.x_index+n] = this.x[this.x_index+n+320] = input[_in++];
}
/* window and summation to create array u */
for(n = 0; n<64; n++) {
u[n] = (this.x[this.x_index+n]*qmf_c[2*n])
+(this.x[this.x_index+n+64]*qmf_c[2*(n+64)])
+(this.x[this.x_index+n+128]*qmf_c[2*(n+128)])
+(this.x[this.x_index+n+192]*qmf_c[2*(n+192)])
+(this.x[this.x_index+n+256]*qmf_c[2*(n+256)]);
}
/* update ringbuffer index */
this.x_index -= 32;
if(this.x_index<0)
this.x_index = (320-32);
/* calculate 32 subband samples by introducing X */
// Reordering of data moved from DCT_IV to here
in_imag[31] = u[1];
in_real[0] = u[0];
for(n = 1; n<31; n++) {
in_imag[31-n] = u[n+1];
in_real[n] = -u[64-n];
}
in_imag[0] = u[32];
in_real[31] = -u[33];
// dct4_kernel is DCT_IV without reordering which is done before and after FFT
DCT.dct4_kernel(in_real, in_imag, out_real, out_imag);
// Reordering of data moved from DCT_IV to here
for(n = 0; n<16; n++) {
if(2*n+1<kx) {
X[l+offset][2*n][0] = 2.0f*out_real[n];
X[l+offset][2*n][1] = 2.0f*out_imag[n];
X[l+offset][2*n+1][0] = -2.0f*out_imag[31-n];
X[l+offset][2*n+1][1] = -2.0f*out_real[31-n];
}
else {
if(2*n<kx) {
X[l+offset][2*n][0] = 2.0f*out_real[n];
X[l+offset][2*n][1] = 2.0f*out_imag[n];
}
else {
X[l+offset][2*n][0] = 0;
X[l+offset][2*n][1] = 0;
}
X[l+offset][2*n+1][0] = 0;
X[l+offset][2*n+1][1] = 0;
}
}
}
}
}