dspstate.java

来自「java ogg player library. for play back o」· Java 代码 · 共 460 行

JAVA
460
字号
/* JOrbis * Copyright (C) 2000 ymnk, JCraft,Inc. *   * Written by: 2000 ymnk<ymnk@jcraft.com> *    * Many thanks to  *   Monty <monty@xiph.org> and  *   The XIPHOPHORUS Company http://www.xiph.org/ . * JOrbis has been based on their awesome works, Vorbis codec. *    * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public License * as published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version.    * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU Library General Public License for more details. *  * You should have received a copy of the GNU Library General Public * License along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */package com.jcraft.jorbis;public class DspState{  static final float M_PI=3.1415926539f;  static final int VI_TRANSFORMB=1;  static final int VI_WINDOWB=1;  int analysisp;  Info vi;  int modebits;  float[][] pcm;  //float[][] pcmret;  int      pcm_storage;  int      pcm_current;  int      pcm_returned;  float[]  multipliers;  int      envelope_storage;  int      envelope_current;  int  eofflag;  int lW;  int W;  int nW;  int centerW;  long granulepos;  long sequence;  long glue_bits;  long time_bits;  long floor_bits;  long res_bits;  // local lookup storage//!!  Envelope ve=new Envelope(); // envelope//float                **window[2][2][2]; // block, leadin, leadout, type  float[][][][][] window;                 // block, leadin, leadout, type  //vorbis_look_transform **transform[2];    // block, type   Object[][] transform;  CodeBook[] fullbooks;  // backend lookups are tied to the mode, not the backend or naked mapping  Object[] mode;  // local storage, only used on the encoding side.  This way the  // application does not need to worry about freeing some packets'  // memory and not others'; packet storage is always tracked.  // Cleared next call to a _dsp_ function  byte[] header;  byte[] header1;  byte[] header2;  public DspState(){    transform=new Object[2][];    window=new float[2][][][][];    window[0]=new float[2][][][];    window[0][0]=new float[2][][];    window[0][1]=new float[2][][];    window[0][0][0]=new float[2][];    window[0][0][1]=new float[2][];    window[0][1][0]=new float[2][];    window[0][1][1]=new float[2][];    window[1]=new float[2][][][];    window[1][0]=new float[2][][];    window[1][1]=new float[2][][];    window[1][0][0]=new float[2][];    window[1][0][1]=new float[2][];    window[1][1][0]=new float[2][];    window[1][1][1]=new float[2][];  }  private static int ilog2(int v){    int ret=0;    while(v>1){      ret++;      v>>>=1;    }    return(ret);  }  static float[] window(int type, int window, int left, int right){    float[] ret=new float[window];    switch(type){    case 0:      // The 'vorbis window' (window 0) is sin(sin(x)*sin(x)*2pi)      {	int leftbegin=window/4-left/2;	int rightbegin=window-window/4-right/2;    	for(int i=0;i<left;i++){	  float x=(float)((i+.5)/left*M_PI/2.);	  x=(float)Math.sin(x);	  x*=x;	  x*=M_PI/2.;	  x=(float)Math.sin(x);	  ret[i+leftbegin]=x;	}      	for(int i=leftbegin+left;i<rightbegin;i++){	  ret[i]=1.f;	}      	for(int i=0;i<right;i++){	  float x=(float)((right-i-.5)/right*M_PI/2.);	  x=(float)Math.sin(x);	  x*=x;	  x*=M_PI/2.;	  x=(float)Math.sin(x);	  ret[i+rightbegin]=x;	}      }      break;    default:      //free(ret);      return(null);    }    return(ret);  }  // Analysis side code, but directly related to blocking.  Thus it's  // here and not in analysis.c (which is for analysis transforms only).  // The init is here because some of it is shared  int init(Info vi, boolean encp){//System.err.println("DspState.init: vi="+vi+", encp="+encp);    //memset(v,0,sizeof(vorbis_dsp_state));    this.vi=vi;    modebits=ilog2(vi.modes);    transform[0]=new Object[VI_TRANSFORMB];    transform[1]=new Object[VI_TRANSFORMB];    // MDCT is tranform 0    transform[0][0]=new Mdct();    transform[1][0]=new Mdct();    ((Mdct)transform[0][0]).init(vi.blocksizes[0]);    ((Mdct)transform[1][0]).init(vi.blocksizes[1]);    window[0][0][0]=new float[VI_WINDOWB][];    window[0][0][1]=window[0][0][0];    window[0][1][0]=window[0][0][0];    window[0][1][1]=window[0][0][0];    window[1][0][0]=new float[VI_WINDOWB][];    window[1][0][1]=new float[VI_WINDOWB][];    window[1][1][0]=new float[VI_WINDOWB][];    window[1][1][1]=new float[VI_WINDOWB][];    for(int i=0;i<VI_WINDOWB;i++){      window[0][0][0][i]=	window(i,vi.blocksizes[0],vi.blocksizes[0]/2,vi.blocksizes[0]/2);      window[1][0][0][i]=	window(i,vi.blocksizes[1],vi.blocksizes[0]/2,vi.blocksizes[0]/2);      window[1][0][1][i]=	window(i,vi.blocksizes[1],vi.blocksizes[0]/2,vi.blocksizes[1]/2);      window[1][1][0][i]=	window(i,vi.blocksizes[1],vi.blocksizes[1]/2,vi.blocksizes[0]/2);      window[1][1][1][i]=	window(i,vi.blocksizes[1],vi.blocksizes[1]/2,vi.blocksizes[1]/2);    }//    if(encp){ // encode/decode differ here//      // finish the codebooks//      fullbooks=new CodeBook[vi.books];//      for(int i=0;i<vi.books;i++){//	fullbooks[i]=new CodeBook();//	fullbooks[i].init_encode(vi.book_param[i]);//      }//      analysisp=1;//    }//    else{      // finish the codebooks      fullbooks=new CodeBook[vi.books];      for(int i=0;i<vi.books;i++){	fullbooks[i]=new CodeBook();	fullbooks[i].init_decode(vi.book_param[i]);      }//    }    // initialize the storage vectors to a decent size greater than the    // minimum      pcm_storage=8192; // we'll assume later that we have                        // a minimum of twice the blocksize of			// accumulated samples in analysis    pcm=new float[vi.channels][];    //pcmret=new float[vi.channels][];    {      for(int i=0;i<vi.channels;i++){	pcm[i]=new float[pcm_storage];      }    }    // all 1 (large block) or 0 (small block)    // explicitly set for the sake of clarity    lW=0; // previous window size    W=0;  // current window size    // all vector indexes; multiples of samples_per_envelope_step    centerW=vi.blocksizes[1]/2;    pcm_current=centerW;    // initialize all the mapping/backend lookups    mode=new Object[vi.modes];    for(int i=0;i<vi.modes;i++){      int mapnum=vi.mode_param[i].mapping;      int maptype=vi.map_type[mapnum];      mode[i]=FuncMapping.mapping_P[maptype].look(this,vi.mode_param[i], 						  vi.map_param[mapnum]);    }    return(0);  }  public int synthesis_init(Info vi){    init(vi, false);    // Adjust centerW to allow an easier mechanism for determining output    pcm_returned=centerW;    centerW-= vi.blocksizes[W]/4+vi.blocksizes[lW]/4;    granulepos=-1;    sequence=-1;    return(0);  }  DspState(Info vi){    this();    init(vi, false);    // Adjust centerW to allow an easier mechanism for determining output    pcm_returned=centerW;    centerW-= vi.blocksizes[W]/4+vi.blocksizes[lW]/4;    granulepos=-1;    sequence=-1;  }  // Unike in analysis, the window is only partially applied for each  // block.  The time domain envelope is not yet handled at the point of  // calling (as it relies on the previous block).  public int synthesis_blockin(Block vb){    // Shift out any PCM/multipliers that we returned previously    // centerW is currently the center of the last block added    if(centerW>vi.blocksizes[1]/2 && pcm_returned>8192){      // don't shift too much; we need to have a minimum PCM buffer of      // 1/2 long block      int shiftPCM=centerW-vi.blocksizes[1]/2;      shiftPCM=(pcm_returned<shiftPCM?pcm_returned:shiftPCM);      pcm_current-=shiftPCM;      centerW-=shiftPCM;      pcm_returned-=shiftPCM;      if(shiftPCM!=0){	for(int i=0;i<vi.channels;i++){	  System.arraycopy(pcm[i], shiftPCM, pcm[i], 0, pcm_current);	}      }    }    lW=W;    W=vb.W;    nW=-1;    glue_bits+=vb.glue_bits;    time_bits+=vb.time_bits;    floor_bits+=vb.floor_bits;    res_bits+=vb.res_bits;    if(sequence+1 != vb.sequence)granulepos=-1; // out of sequence; lose count    sequence=vb.sequence;    {      int sizeW=vi.blocksizes[W];      int _centerW=centerW+vi.blocksizes[lW]/4+sizeW/4;      int beginW=_centerW-sizeW/2;      int endW=beginW+sizeW;      int beginSl=0;      int endSl=0;      // Do we have enough PCM/mult storage for the block?      if(endW>pcm_storage){	// expand the storage	pcm_storage=endW+vi.blocksizes[1];	for(int i=0;i<vi.channels;i++){          float[] foo=new float[pcm_storage];	  System.arraycopy(pcm[i], 0, foo, 0, pcm[i].length);	  pcm[i]=foo;	}      }      // overlap/add PCM      switch(W){      case 0:	beginSl=0;	endSl=vi.blocksizes[0]/2;	break;      case 1:	beginSl=vi.blocksizes[1]/4-vi.blocksizes[lW]/4;	endSl=beginSl+vi.blocksizes[lW]/2;	break;      }      for(int j=0;j<vi.channels;j++){	int _pcm=beginW;	// the overlap/add section	int i=0;	for(i=beginSl;i<endSl;i++){	  pcm[j][_pcm+i]+=vb.pcm[j][i];	}	// the remaining section	for(;i<sizeW;i++){	  pcm[j][_pcm+i]=vb.pcm[j][i];	}      }      // track the frame number... This is for convenience, but also      // making sure our last packet doesn't end with added padding.  If      // the last packet is partial, the number of samples we'll have to      // return will be past the vb->granulepos.      //             // This is not foolproof!  It will be confused if we begin      // decoding at the last page after a seek or hole.  In that case,      // we don't have a starting point to judge where the last frame      // is.  For this reason, vorbisfile will always try to make sure      // it reads the last two marked pages in proper sequence      if(granulepos==-1){	granulepos=vb.granulepos;      }      else{	granulepos+=(_centerW-centerW);	if(vb.granulepos!=-1 && granulepos!=vb.granulepos){	  if(granulepos>vb.granulepos && vb.eofflag!=0){	    // partial last frame.  Strip the padding off	    _centerW-=(granulepos-vb.granulepos);	  }// else{ Shouldn't happen *unless* the bitstream is out of           // spec.  Either way, believe the bitstream }	  granulepos=vb.granulepos;	}      }      // Update, cleanup      centerW=_centerW;      pcm_current=endW;      if(vb.eofflag!=0)eofflag=1;    }    return(0);  }  // pcm==NULL indicates we just want the pending samples, no more  public int synthesis_pcmout(float[][][] _pcm, int[] index){    if(pcm_returned<centerW){      if(_pcm!=null){	for(int i=0;i<vi.channels;i++){//	  pcmret[i]=pcm[i]+v.pcm_returned;//!!!!!!!!          index[i]=pcm_returned;	}	_pcm[0]=pcm;      }      return(centerW-pcm_returned);    }    return(0);  }  public int synthesis_read(int bytes){    if(bytes!=0 && pcm_returned+bytes>centerW)return(-1);    pcm_returned+=bytes;    return(0);  }  public void clear(){/*    if(window[0][0][0]!=0){      for(i=0;i<VI_WINDOWB;i++)	if(v->window[0][0][0][i])free(v->window[0][0][0][i]);      free(v->window[0][0][0]);      for(j=0;j<2;j++)	for(k=0;k<2;k++){	  for(i=0;i<VI_WINDOWB;i++)	    if(v->window[1][j][k][i])free(v->window[1][j][k][i]);	  free(v->window[1][j][k]);	}    }        if(v->pcm){      for(i=0;i<vi->channels;i++)	if(v->pcm[i])free(v->pcm[i]);      free(v->pcm);      if(v->pcmret)free(v->pcmret);    }    if(v->multipliers)free(v->multipliers);    _ve_envelope_clear(&v->ve);    if(v->transform[0]){      mdct_clear(v->transform[0][0]);      free(v->transform[0][0]);      free(v->transform[0]);    }    if(v->transform[1]){      mdct_clear(v->transform[1][0]);      free(v->transform[1][0]);      free(v->transform[1]);    }    // free mode lookups; these are actually vorbis_look_mapping structs    if(vi){      for(i=0;i<vi->modes;i++){	int mapnum=vi->mode_param[i]->mapping;	int maptype=vi->map_type[mapnum];	_mapping_P[maptype]->free_look(v->mode[i]);      }      // free codebooks      for(i=0;i<vi->books;i++)	vorbis_book_clear(v->fullbooks+i);    }    if(v->mode)free(v->mode);        if(v->fullbooks)free(v->fullbooks);    // free header, header1, header2    if(v->header)free(v->header);    if(v->header1)free(v->header1);    if(v->header2)free(v->header2);    memset(v,0,sizeof(vorbis_dsp_state));  }*/}}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?