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}