public override int inverse(Block vb, Object l)
{
lock(this)
{
//System.err.println("Mapping0.inverse");
DspState vd=vb.vd;
Info vi=vd.vi;
LookMapping0 look=(LookMapping0)l;
InfoMapping0 info=look.map;
InfoMode mode=look.mode;
int n=vb.pcmend=vi.blocksizes[vb.W];
float[] window=vd.wnd[vb.W][vb.lW][vb.nW][mode.windowtype];
// float[][] pcmbundle=new float[vi.channels][];
// int[] nonzero=new int[vi.channels];
if(pcmbundle==null || pcmbundle.Length<vi.channels)
{
pcmbundle=new float[vi.channels][];
nonzero=new int[vi.channels];
zerobundle=new int[vi.channels];
floormemo=new Object[vi.channels];
}
// time domain information decode (note that applying the
// information would have to happen later; we'll probably add a
// function entry to the harness for that later
// NOT IMPLEMENTED
// recover the spectral envelope; store it in the PCM vector for now
for(int i=0;i<vi.channels;i++)
{
float[] pcm=vb.pcm[i];
int submap=info.chmuxlist[i];
floormemo[i]=look.floor_func[submap].inverse1(vb,look.
floor_look[submap],
floormemo[i]
);
if(floormemo[i]!=null){ nonzero[i]=1; }
else{ nonzero[i]=0; }
for(int j=0; j<n/2; j++)
{
pcm[j]=0;
}
//_analysis_output("ifloor",seq+i,pcm,n/2,0,1);
}
for(int i=0; i<info.coupling_steps; i++)
{
if(nonzero[info.coupling_mag[i]]!=0 ||
nonzero[info.coupling_ang[i]]!=0)
{
nonzero[info.coupling_mag[i]]=1;
nonzero[info.coupling_ang[i]]=1;
}
}
// recover the residue, apply directly to the spectral envelope
for(int i=0;i<info.submaps;i++)
{
int ch_in_bundle=0;
for(int j=0;j<vi.channels;j++)
{
if(info.chmuxlist[j]==i)
{
if(nonzero[j]!=0)
{
zerobundle[ch_in_bundle]=1;
}
else
{
zerobundle[ch_in_bundle]=0;
}
pcmbundle[ch_in_bundle++]=vb.pcm[j];
}
}
look.residue_func[i].inverse(vb,look.residue_look[i],
pcmbundle,zerobundle,ch_in_bundle);
}
for(int i=info.coupling_steps-1;i>=0;i--)
{
float[] pcmM=vb.pcm[info.coupling_mag[i]];
float[] pcmA=vb.pcm[info.coupling_ang[i]];
for(int j=0;j<n/2;j++)
{
float mag=pcmM[j];
float ang=pcmA[j];
if(mag>0)
{
if(ang>0)
{
pcmM[j]=mag;
pcmA[j]=mag-ang;
}
else
{
pcmA[j]=mag;
pcmM[j]=mag+ang;
}
}
else
{
if(ang>0)
{
pcmM[j]=mag;
pcmA[j]=mag+ang;
}
else
{
pcmA[j]=mag;
pcmM[j]=mag-ang;
}
}
}
}
// /* compute and apply spectral envelope */
for(int i=0;i<vi.channels;i++)
{
float[] pcm=vb.pcm[i];
int submap=info.chmuxlist[i];
look.floor_func[submap].inverse2(vb,look.floor_look[submap],floormemo[i],pcm);
}
// transform the PCM data; takes PCM vector, vb; modifies PCM vector
// only MDCT right now....
for(int i=0;i<vi.channels;i++)
{
float[] pcm=vb.pcm[i];
//_analysis_output("out",seq+i,pcm,n/2,0,0);
((Mdct)vd.transform[vb.W][0]).backward(pcm,pcm);
}
// now apply the decoded pre-window time information
// NOT IMPLEMENTED
// window the data
for(int i=0;i<vi.channels;i++)
{
float[] pcm=vb.pcm[i];
if(nonzero[i]!=0)
{
for(int j=0;j<n;j++)
{
pcm[j]*=window[j];
}
}
else
{
for(int j=0;j<n;j++)
{
pcm[j]=0.0f;
}
}
//_analysis_output("final",seq++,pcm,n,0,0);
}
// now apply the decoded post-window time information
// NOT IMPLEMENTED
// all done!
return(0);
}
}