001/* JOrbis
002 * Copyright (C) 2000 ymnk, JCraft,Inc.
003 *  
004 * Written by: 2000 ymnk<ymnk@jcaft.com>
005 *   
006 * Many thanks to 
007 *   Monty <monty@xiph.org> and 
008 *   The XIPHOPHORUS Company http://www.xiph.org/ .
009 * JOrbis has been based on their awesome works, Vorbis codec.
010 *   
011 * This program is free software; you can redistribute it and/or
012 * modify it under the terms of the GNU Library General Public License
013 * as published by the Free Software Foundation; either version 2 of
014 * the License, or (at your option) any later version.
015   
016 * This program is distributed in the hope that it will be useful,
017 * but WITHOUT ANY WARRANTY; without even the implied warranty of
018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
019 * GNU Library General Public License for more details.
020 * 
021 * You should have received a copy of the GNU Library General Public
022 * License along with this program; if not, write to the Free Software
023 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
024 */
025
026package com.jcraft.jorbis;
027
028public class DspState{
029  static final float M_PI=3.1415926539f;
030  static final int VI_TRANSFORMB=1;
031  static final int VI_WINDOWB=1;
032
033  int analysisp;
034  Info vi;
035  int modebits;
036
037  float[][] pcm;
038  //float[][] pcmret;
039  int      pcm_storage;
040  int      pcm_current;
041  int      pcm_returned;
042
043  float[]  multipliers;
044  int      envelope_storage;
045  int      envelope_current;
046
047  int  eofflag;
048
049  int lW;
050  int W;
051  int nW;
052  int centerW;
053
054  long granulepos;
055  long sequence;
056
057  long glue_bits;
058  long time_bits;
059  long floor_bits;
060  long res_bits;
061
062  // local lookup storage
063//!!  Envelope ve=new Envelope(); // envelope
064//float                **window[2][2][2]; // block, leadin, leadout, type
065  float[][][][][] window;                 // block, leadin, leadout, type
066  //vorbis_look_transform **transform[2];    // block, type 
067  Object[][] transform;
068  CodeBook[] fullbooks;
069  // backend lookups are tied to the mode, not the backend or naked mapping
070  Object[] mode;
071
072  // local storage, only used on the encoding side.  This way the
073  // application does not need to worry about freeing some packets'
074  // memory and not others'; packet storage is always tracked.
075  // Cleared next call to a _dsp_ function
076  byte[] header;
077  byte[] header1;
078  byte[] header2;
079
080  public DspState(){
081    transform=new Object[2][];
082    window=new float[2][][][][];
083    window[0]=new float[2][][][];
084    window[0][0]=new float[2][][];
085    window[0][1]=new float[2][][];
086    window[0][0][0]=new float[2][];
087    window[0][0][1]=new float[2][];
088    window[0][1][0]=new float[2][];
089    window[0][1][1]=new float[2][];
090    window[1]=new float[2][][][];
091    window[1][0]=new float[2][][];
092    window[1][1]=new float[2][][];
093    window[1][0][0]=new float[2][];
094    window[1][0][1]=new float[2][];
095    window[1][1][0]=new float[2][];
096    window[1][1][1]=new float[2][];
097  }
098
099  private static int ilog2(int v){
100    int ret=0;
101    while(v>1){
102      ret++;
103      v>>>=1;
104    }
105    return(ret);
106  }
107
108  static float[] window(int type, int window, int left, int right){
109    float[] ret=new float[window];
110    switch(type){
111    case 0:
112      // The 'vorbis window' (window 0) is sin(sin(x)*sin(x)*2pi)
113      {
114        int leftbegin=window/4-left/2;
115        int rightbegin=window-window/4-right/2;
116    
117        for(int i=0;i<left;i++){
118          float x=(float)((i+.5)/left*M_PI/2.);
119          x=(float)Math.sin(x);
120          x*=x;
121          x*=M_PI/2.;
122          x=(float)Math.sin(x);
123          ret[i+leftbegin]=x;
124        }
125      
126        for(int i=leftbegin+left;i<rightbegin;i++){
127          ret[i]=1.f;
128        }
129      
130        for(int i=0;i<right;i++){
131          float x=(float)((right-i-.5)/right*M_PI/2.);
132          x=(float)Math.sin(x);
133          x*=x;
134          x*=M_PI/2.;
135          x=(float)Math.sin(x);
136          ret[i+rightbegin]=x;
137        }
138      }
139      break;
140    default:
141      //free(ret);
142      return(null);
143    }
144    return(ret);
145  }
146
147  // Analysis side code, but directly related to blocking.  Thus it's
148  // here and not in analysis.c (which is for analysis transforms only).
149  // The init is here because some of it is shared
150
151  int init(Info vi, boolean encp){
152//System.err.println("DspState.init: vi="+vi+", encp="+encp);
153    //memset(v,0,sizeof(vorbis_dsp_state));
154    this.vi=vi;
155    modebits=ilog2(vi.modes);
156
157    transform[0]=new Object[VI_TRANSFORMB];
158    transform[1]=new Object[VI_TRANSFORMB];
159
160    // MDCT is tranform 0
161
162    transform[0][0]=new Mdct();
163    transform[1][0]=new Mdct();
164    ((Mdct)transform[0][0]).init(vi.blocksizes[0]);
165    ((Mdct)transform[1][0]).init(vi.blocksizes[1]);
166
167    window[0][0][0]=new float[VI_WINDOWB][];
168    window[0][0][1]=window[0][0][0];
169    window[0][1][0]=window[0][0][0];
170    window[0][1][1]=window[0][0][0];
171    window[1][0][0]=new float[VI_WINDOWB][];
172    window[1][0][1]=new float[VI_WINDOWB][];
173    window[1][1][0]=new float[VI_WINDOWB][];
174    window[1][1][1]=new float[VI_WINDOWB][];
175
176    for(int i=0;i<VI_WINDOWB;i++){
177      window[0][0][0][i]=
178        window(i,vi.blocksizes[0],vi.blocksizes[0]/2,vi.blocksizes[0]/2);
179      window[1][0][0][i]=
180        window(i,vi.blocksizes[1],vi.blocksizes[0]/2,vi.blocksizes[0]/2);
181      window[1][0][1][i]=
182        window(i,vi.blocksizes[1],vi.blocksizes[0]/2,vi.blocksizes[1]/2);
183      window[1][1][0][i]=
184        window(i,vi.blocksizes[1],vi.blocksizes[1]/2,vi.blocksizes[0]/2);
185      window[1][1][1][i]=
186        window(i,vi.blocksizes[1],vi.blocksizes[1]/2,vi.blocksizes[1]/2);
187    }
188
189//    if(encp){ // encode/decode differ here
190//      // finish the codebooks
191//      fullbooks=new CodeBook[vi.books];
192//      for(int i=0;i<vi.books;i++){
193//      fullbooks[i]=new CodeBook();
194//      fullbooks[i].init_encode(vi.book_param[i]);
195//      }
196//      analysisp=1;
197//    }
198//    else{
199      // finish the codebooks
200      fullbooks=new CodeBook[vi.books];
201      for(int i=0;i<vi.books;i++){
202        fullbooks[i]=new CodeBook();
203        fullbooks[i].init_decode(vi.book_param[i]);
204      }
205//    }
206
207    // initialize the storage vectors to a decent size greater than the
208    // minimum
209  
210    pcm_storage=8192; // we'll assume later that we have
211                        // a minimum of twice the blocksize of
212                        // accumulated samples in analysis
213    pcm=new float[vi.channels][];
214    //pcmret=new float[vi.channels][];
215    {
216      for(int i=0;i<vi.channels;i++){
217        pcm[i]=new float[pcm_storage];
218      }
219    }
220
221    // all 1 (large block) or 0 (small block)
222    // explicitly set for the sake of clarity
223    lW=0; // previous window size
224    W=0;  // current window size
225
226    // all vector indexes; multiples of samples_per_envelope_step
227    centerW=vi.blocksizes[1]/2;
228
229    pcm_current=centerW;
230
231    // initialize all the mapping/backend lookups
232    mode=new Object[vi.modes];
233    for(int i=0;i<vi.modes;i++){
234      int mapnum=vi.mode_param[i].mapping;
235      int maptype=vi.map_type[mapnum];
236      mode[i]=FuncMapping.mapping_P[maptype].look(this,vi.mode_param[i], 
237                                                  vi.map_param[mapnum]);
238    }
239    return(0);
240  }
241
242  public int synthesis_init(Info vi){
243    init(vi, false);
244    // Adjust centerW to allow an easier mechanism for determining output
245    pcm_returned=centerW;
246    centerW-= vi.blocksizes[W]/4+vi.blocksizes[lW]/4;
247    granulepos=-1;
248    sequence=-1;
249    return(0);
250  }
251
252  DspState(Info vi){
253    this();
254    init(vi, false);
255    // Adjust centerW to allow an easier mechanism for determining output
256    pcm_returned=centerW;
257    centerW-= vi.blocksizes[W]/4+vi.blocksizes[lW]/4;
258    granulepos=-1;
259    sequence=-1;
260  }
261
262  // Unike in analysis, the window is only partially applied for each
263  // block.  The time domain envelope is not yet handled at the point of
264  // calling (as it relies on the previous block).
265
266  public int synthesis_blockin(Block vb){
267    // Shift out any PCM/multipliers that we returned previously
268    // centerW is currently the center of the last block added
269    if(centerW>vi.blocksizes[1]/2 && pcm_returned>8192){
270      // don't shift too much; we need to have a minimum PCM buffer of
271      // 1/2 long block
272
273      int shiftPCM=centerW-vi.blocksizes[1]/2;
274      shiftPCM=(pcm_returned<shiftPCM?pcm_returned:shiftPCM);
275
276      pcm_current-=shiftPCM;
277      centerW-=shiftPCM;
278      pcm_returned-=shiftPCM;
279      if(shiftPCM!=0){
280        for(int i=0;i<vi.channels;i++){
281          System.arraycopy(pcm[i], shiftPCM, pcm[i], 0, pcm_current);
282        }
283      }
284    }
285
286    lW=W;
287    W=vb.W;
288    nW=-1;
289
290    glue_bits+=vb.glue_bits;
291    time_bits+=vb.time_bits;
292    floor_bits+=vb.floor_bits;
293    res_bits+=vb.res_bits;
294
295    if(sequence+1 != vb.sequence)granulepos=-1; // out of sequence; lose count
296
297    sequence=vb.sequence;
298
299    {
300      int sizeW=vi.blocksizes[W];
301      int _centerW=centerW+vi.blocksizes[lW]/4+sizeW/4;
302      int beginW=_centerW-sizeW/2;
303      int endW=beginW+sizeW;
304      int beginSl=0;
305      int endSl=0;
306
307      // Do we have enough PCM/mult storage for the block?
308      if(endW>pcm_storage){
309        // expand the storage
310        pcm_storage=endW+vi.blocksizes[1];
311        for(int i=0;i<vi.channels;i++){
312          float[] foo=new float[pcm_storage];
313          System.arraycopy(pcm[i], 0, foo, 0, pcm[i].length);
314          pcm[i]=foo;
315        }
316      }
317
318      // overlap/add PCM
319      switch(W){
320      case 0:
321        beginSl=0;
322        endSl=vi.blocksizes[0]/2;
323        break;
324      case 1:
325        beginSl=vi.blocksizes[1]/4-vi.blocksizes[lW]/4;
326        endSl=beginSl+vi.blocksizes[lW]/2;
327        break;
328      }
329
330      for(int j=0;j<vi.channels;j++){
331        int _pcm=beginW;
332        // the overlap/add section
333        int i=0;
334        for(i=beginSl;i<endSl;i++){
335          pcm[j][_pcm+i]+=vb.pcm[j][i];
336        }
337        // the remaining section
338        for(;i<sizeW;i++){
339          pcm[j][_pcm+i]=vb.pcm[j][i];
340        }
341      }
342
343      // track the frame number... This is for convenience, but also
344      // making sure our last packet doesn't end with added padding.  If
345      // the last packet is partial, the number of samples we'll have to
346      // return will be past the vb->granulepos.
347      //       
348      // This is not foolproof!  It will be confused if we begin
349      // decoding at the last page after a seek or hole.  In that case,
350      // we don't have a starting point to judge where the last frame
351      // is.  For this reason, vorbisfile will always try to make sure
352      // it reads the last two marked pages in proper sequence
353
354      if(granulepos==-1){
355        granulepos=vb.granulepos;
356      }
357      else{
358        granulepos+=(_centerW-centerW);
359        if(vb.granulepos!=-1 && granulepos!=vb.granulepos){
360          if(granulepos>vb.granulepos && vb.eofflag!=0){
361            // partial last frame.  Strip the padding off
362            _centerW-=(granulepos-vb.granulepos);
363          }// else{ Shouldn't happen *unless* the bitstream is out of
364           // spec.  Either way, believe the bitstream }
365          granulepos=vb.granulepos;
366        }
367      }
368
369      // Update, cleanup
370
371      centerW=_centerW;
372      pcm_current=endW;
373      if(vb.eofflag!=0)eofflag=1;
374    }
375    return(0);
376  }
377
378  // pcm==NULL indicates we just want the pending samples, no more
379  public int synthesis_pcmout(float[][][] _pcm, int[] index){
380    if(pcm_returned<centerW){
381      if(_pcm!=null){
382        for(int i=0;i<vi.channels;i++){
383//        pcmret[i]=pcm[i]+v.pcm_returned;
384//!!!!!!!!
385          index[i]=pcm_returned;
386        }
387        _pcm[0]=pcm;
388      }
389      return(centerW-pcm_returned);
390    }
391    return(0);
392  }
393
394  public int synthesis_read(int bytes){
395    if(bytes!=0 && pcm_returned+bytes>centerW)return(-1);
396    pcm_returned+=bytes;
397    return(0);
398  }
399
400  public void clear(){
401/*
402    if(window[0][0][0]!=0){
403      for(i=0;i<VI_WINDOWB;i++)
404        if(v->window[0][0][0][i])free(v->window[0][0][0][i]);
405      free(v->window[0][0][0]);
406
407      for(j=0;j<2;j++)
408        for(k=0;k<2;k++){
409          for(i=0;i<VI_WINDOWB;i++)
410            if(v->window[1][j][k][i])free(v->window[1][j][k][i]);
411          free(v->window[1][j][k]);
412        }
413    }
414    
415    if(v->pcm){
416      for(i=0;i<vi->channels;i++)
417        if(v->pcm[i])free(v->pcm[i]);
418      free(v->pcm);
419      if(v->pcmret)free(v->pcmret);
420    }
421    if(v->multipliers)free(v->multipliers);
422
423    _ve_envelope_clear(&v->ve);
424    if(v->transform[0]){
425      mdct_clear(v->transform[0][0]);
426      free(v->transform[0][0]);
427      free(v->transform[0]);
428    }
429    if(v->transform[1]){
430      mdct_clear(v->transform[1][0]);
431      free(v->transform[1][0]);
432      free(v->transform[1]);
433    }
434
435    // free mode lookups; these are actually vorbis_look_mapping structs
436    if(vi){
437      for(i=0;i<vi->modes;i++){
438        int mapnum=vi->mode_param[i]->mapping;
439        int maptype=vi->map_type[mapnum];
440        _mapping_P[maptype]->free_look(v->mode[i]);
441      }
442      // free codebooks
443      for(i=0;i<vi->books;i++)
444        vorbis_book_clear(v->fullbooks+i);
445    }
446
447    if(v->mode)free(v->mode);    
448    if(v->fullbooks)free(v->fullbooks);
449
450    // free header, header1, header2
451    if(v->header)free(v->header);
452    if(v->header1)free(v->header1);
453    if(v->header2)free(v->header2);
454
455    memset(v,0,sizeof(vorbis_dsp_state));
456  }
457*/
458}
459}