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 028import com.jcraft.jogg.*; 029 030class Residue0 extends FuncResidue{ 031 void pack(Object vr, Buffer opb){ 032 InfoResidue0 info=(InfoResidue0)vr; 033 int acc=0; 034 opb.write(info.begin,24); 035 opb.write(info.end,24); 036 037 opb.write(info.grouping-1,24); /* residue vectors to group and 038 code with a partitioned book */ 039 opb.write(info.partitions-1,6); /* possible partition choices */ 040 opb.write(info.groupbook,8); /* group huffman book */ 041 042 /* secondstages is a bitmask; as encoding progresses pass by pass, a 043 bitmask of one indicates this partition class has bits to write 044 this pass */ 045 for(int j=0;j<info.partitions;j++){ 046 if(ilog(info.secondstages[j])>3){ 047 /* yes, this is a minor hack due to not thinking ahead */ 048 opb.write(info.secondstages[j],3); 049 opb.write(1,1); 050 opb.write(info.secondstages[j]>>>3,5); 051 } 052 else{ 053 opb.write(info.secondstages[j],4); /* trailing zero */ 054 } 055 acc+=icount(info.secondstages[j]); 056 } 057 for(int j=0;j<acc;j++){ 058 opb.write(info.booklist[j],8); 059 } 060 } 061 062 Object unpack(Info vi, Buffer opb){ 063 int acc=0; 064 InfoResidue0 info=new InfoResidue0(); 065 066 info.begin=opb.read(24); 067 info.end=opb.read(24); 068 info.grouping=opb.read(24)+1; 069 info.partitions=opb.read(6)+1; 070 info.groupbook=opb.read(8); 071 072 for(int j=0;j<info.partitions;j++){ 073 int cascade=opb.read(3); 074 if(opb.read(1)!=0){ 075 cascade|=(opb.read(5)<<3); 076 } 077 info.secondstages[j]=cascade; 078 acc+=icount(cascade); 079 } 080 081 for(int j=0;j<acc;j++){ 082 info.booklist[j]=opb.read(8); 083// if(info.booklist[j]==255)info.booklist[j]=-1; 084 } 085 086 if(info.groupbook>=vi.books){ 087 free_info(info); 088 return(null); 089 } 090 091 for(int j=0;j<acc;j++){ 092 if(info.booklist[j]>=vi.books){ 093 free_info(info); 094 return(null); 095 } 096 } 097 return(info); 098// errout: 099// free_info(info); 100// return(NULL); 101 } 102 103 Object look(DspState vd, InfoMode vm, Object vr){ 104 InfoResidue0 info=(InfoResidue0)vr; 105 LookResidue0 look=new LookResidue0(); 106 int acc=0; 107 int dim; 108 int maxstage=0; 109 look.info=info; 110 look.map=vm.mapping; 111 112 look.parts=info.partitions; 113 look.fullbooks=vd.fullbooks; 114 look.phrasebook=vd.fullbooks[info.groupbook]; 115 116 dim=look.phrasebook.dim; 117 118 look.partbooks=new int[look.parts][]; 119 120 for(int j=0;j<look.parts;j++){ 121 int stages=ilog(info.secondstages[j]); 122 if(stages!=0){ 123 if(stages>maxstage)maxstage=stages; 124 look.partbooks[j]=new int[stages]; 125 for(int k=0; k<stages; k++){ 126 if((info.secondstages[j]&(1<<k))!=0){ 127 look.partbooks[j][k]=info.booklist[acc++]; 128 } 129 } 130 } 131 } 132 133 look.partvals=(int)Math.rint(Math.pow(look.parts,dim)); 134 look.stages=maxstage; 135 look.decodemap=new int[look.partvals][]; 136 for(int j=0;j<look.partvals;j++){ 137 int val=j; 138 int mult=look.partvals/look.parts; 139 look.decodemap[j]=new int[dim]; 140 141 for(int k=0;k<dim;k++){ 142 int deco=val/mult; 143 val-=deco*mult; 144 mult/=look.parts; 145 look.decodemap[j][k]=deco; 146 } 147 } 148 return(look); 149 } 150 void free_info(Object i){} 151 void free_look(Object i){} 152 int forward(Block vb,Object vl, float[][] in, int ch){ 153 System.err.println("Residue0.forward: not implemented"); 154 return 0; 155 } 156 157 static int[][][] partword=new int[2][][]; // _01inverse is synchronized for 158 // re-using partword 159 synchronized static int _01inverse(Block vb, Object vl, 160 float[][] in,int ch,int decodepart){ 161 int i,j,k,l,s; 162 LookResidue0 look=(LookResidue0 )vl; 163 InfoResidue0 info=look.info; 164 165 // move all this setup out later 166 int samples_per_partition=info.grouping; 167 int partitions_per_word=look.phrasebook.dim; 168 int n=info.end-info.begin; 169 170 int partvals=n/samples_per_partition; 171 int partwords=(partvals+partitions_per_word-1)/partitions_per_word; 172 173 if(partword.length<ch){ 174 partword=new int[ch][][]; 175 for(j=0;j<ch;j++){ 176 partword[j]=new int[partwords][]; 177 } 178 } 179 else{ 180 for(j=0;j<ch;j++){ 181 if(partword[j]==null || partword[j].length<partwords) 182 partword[j]=new int[partwords][]; 183 } 184 } 185 186 for(s=0;s<look.stages;s++){ 187 // each loop decodes on partition codeword containing 188 // partitions_pre_word partitions 189 for(i=0,l=0;i<partvals;l++){ 190 if(s==0){ 191 // fetch the partition word for each channel 192 for(j=0;j<ch;j++){ 193 int temp=look.phrasebook.decode(vb.opb); 194 if(temp==-1){ 195 //goto eopbreak; 196 return(0); 197 } 198 partword[j][l]=look.decodemap[temp]; 199 if(partword[j][l]==null){ 200// goto errout; 201 return(0); 202 } 203 } 204 } 205 206 // now we decode residual values for the partitions 207 for(k=0;k<partitions_per_word && i<partvals;k++,i++) 208 for(j=0;j<ch;j++){ 209 int offset=info.begin+i*samples_per_partition; 210 if((info.secondstages[partword[j][l][k]]&(1<<s))!=0){ 211 CodeBook stagebook=look.fullbooks[look.partbooks[partword[j][l][k]][s]]; 212// CodeBook stagebook=look.partbooks[partword[j][l][k]][s]; 213 if(stagebook!=null){ 214 if(decodepart==0){ 215 if(stagebook.decodevs_add(in[j],offset,vb.opb,samples_per_partition)==-1){ 216 // goto errout; 217 return(0); 218 } 219 } 220 else if(decodepart==1){ 221 if(stagebook.decodev_add(in[j], offset, vb.opb,samples_per_partition)==-1){ 222 // goto errout; 223 return(0); 224 } 225 } 226 } 227 } 228 } 229 } 230 } 231// errout: 232// eopbreak: 233 return(0); 234 } 235 236 static int _2inverse(Block vb, Object vl, float[][] in, int ch){ 237 int i,j,k,l,s; 238 LookResidue0 look=(LookResidue0 )vl; 239 InfoResidue0 info=look.info; 240 241 // move all this setup out later 242 int samples_per_partition=info.grouping; 243 int partitions_per_word=look.phrasebook.dim; 244 int n=info.end-info.begin; 245 246 int partvals=n/samples_per_partition; 247 int partwords=(partvals+partitions_per_word-1)/partitions_per_word; 248 249 int[][] partword=new int[partwords][]; 250 for(s=0;s<look.stages;s++){ 251 for(i=0,l=0;i<partvals;l++){ 252 if(s==0){ 253 // fetch the partition word for each channel 254 int temp=look.phrasebook.decode(vb.opb); 255 if(temp==-1){ 256 // goto eopbreak; 257 return(0); 258 } 259 partword[l]=look.decodemap[temp]; 260 if(partword[l]==null){ 261 // goto errout; 262 return(0); 263 } 264 } 265 266 // now we decode residual values for the partitions 267 for(k=0;k<partitions_per_word && i<partvals;k++,i++){ 268 int offset=info.begin+i*samples_per_partition; 269 if((info.secondstages[partword[l][k]]&(1<<s))!=0){ 270 CodeBook stagebook=look.fullbooks[look.partbooks[partword[l][k]][s]]; 271 if(stagebook!=null){ 272 if(stagebook.decodevv_add(in, offset, ch, vb.opb,samples_per_partition)==-1){ 273 // goto errout; 274 return(0); 275 } 276 } 277 } 278 } 279 } 280 } 281// errout: 282// eopbreak: 283 return(0); 284 } 285 286 int inverse(Block vb, Object vl, float[][] in, int[] nonzero, int ch){ 287 //System.err.println("Residue0.inverse"); 288 int used=0; 289 for(int i=0;i<ch;i++){ 290 if(nonzero[i]!=0){ 291 in[used++]=in[i]; 292 } 293 } 294 if(used!=0) 295 return(_01inverse(vb,vl,in,used,0)); 296 else 297 return(0); 298 } 299 300/* 301 int inverse(Block vb, Object vl, float[][] in, int ch){ 302//System.err.println("Residue0.inverse"); 303 int i,j,k,l,transend=vb.pcmend/2; 304 LookResidue0 look=(LookResidue0 )vl; 305 InfoResidue0 info=look.info; 306 307 // move all this setup out later 308 int samples_per_partition=info.grouping; 309 int partitions_per_word=look.phrasebook.dim; 310 int n=info.end-info.begin; 311 312 int partvals=n/samples_per_partition; 313 int partwords=(partvals+partitions_per_word-1)/partitions_per_word; 314 int[][] partword=new int[ch][]; 315 float[] work=new float[samples_per_partition]; 316 partvals=partwords*partitions_per_word; 317 318 // make sure we're zeroed up to the start 319 for(j=0;j<ch;j++){ 320 for(k=0; k<info.begin; k++)in[j][k]=0.0f; 321 } 322 323 for(i=info.begin,l=0;i<info.end;){ 324 // fetch the partition word for each channel 325 for(j=0;j<ch;j++){ 326 int temp=look.phrasebook.decode(vb.opb); 327 if(temp==-1){ 328 //goto eopbreak; 329 if(i<transend){ 330 for(j=0;j<ch;j++){ 331 for(k=0;k<transend-i;k++)in[j][i+k]=0.0f; 332 } 333 } 334 return(0); 335 } 336 partword[j]=look.decodemap[temp]; 337 if(partword[j]==null){ 338 //goto errout; 339 for(j=0;j<ch;j++){ 340 for(k=0;k<transend;k++)in[j][k]=0.0f; 341 } 342 return(0); 343 } 344 } 345 346 // now we decode interleaved residual values for the partitions 347 for(k=0;k<partitions_per_word;k++,l++,i+=samples_per_partition){ 348 for(j=0;j<ch;j++){ 349 int part=partword[j][k]; 350 if(decodepart(vb.opb,work, in[j], i,samples_per_partition, 351 info.secondstages[part], 352 look.partbooks[part])==-1){ 353 //goto eopbreak; 354 if(i<transend){ 355 for(j=0;j<ch;j++){ 356 for(k=0;k<transend-i;k++)in[j][i+k]=0.0f; 357 } 358 } 359 return(0); 360 } 361 } 362 } 363 } 364 365// eopbreak: 366 if(i<transend){ 367 for(j=0;j<ch;j++){ 368 for(k=0;k<transend-i;k++)in[j][i+k]=0.0f; 369 } 370 } 371 return(0); 372 373// errout: 374// for(j=0;j<ch;j++) 375// for(k=0;k<transend;k++)in[j][k]=0.0f; 376// return(0); 377 } 378 int decodepart(Buffer opb, float[] work, float[] vec, int veci, 379 int n, int stages, CodeBook[] books){ 380 int i,j; 381 for(i=0;i<n;i++)work[i]=0.0f; 382 383 for(j=0;j<stages;j++){ 384 int dim=books[j].dim; 385 int step=n/dim; 386 for(i=0;i<step;i++){ 387 if(books[j].decodevs(work, i, opb, step, 0)==-1){ 388 return(-1); 389 } 390 } 391 } 392 for(i=0;i<n;i++){ 393 vec[veci+i]*=work[i]; 394 } 395 return(0); 396 } 397*/ 398 399 private static int ilog(int v){ 400 int ret=0; 401 while(v!=0){ 402 ret++; 403 v>>>=1; 404 } 405 return(ret); 406 } 407 private static int icount(int v){ 408 int ret=0; 409 while(v!=0){ 410 ret+=(v&1); 411 v>>>=1; 412 } 413 return(ret); 414 } 415} 416 417class LookResidue0 { 418 InfoResidue0 info; 419 int map; 420 421 int parts; 422 int stages; 423 CodeBook[] fullbooks; 424 CodeBook phrasebook; 425 int[][] partbooks; 426// CodeBook[][] partbooks; 427 428 int partvals; 429 int[][] decodemap; 430 431 int postbits; 432 int phrasebits; 433// int[][] frames; 434 int frames; 435} 436 437class InfoResidue0{ 438 // block-partitioned VQ coded straight residue 439 int begin; 440 int end; 441 442 // first stage (lossless partitioning) 443 int grouping; // group n vectors per partition 444 int partitions; // possible codebooks for a partition 445 int groupbook; // huffbook for partitioning 446 int[] secondstages=new int[64]; // expanded out to pointers in lookup 447 int[] booklist=new int[256]; // list of second stage books 448 449 // encode-only heuristic settings 450 float[] entmax=new float[64]; // book entropy threshholds 451 float[] ampmax=new float[64]; // book amp threshholds 452 int[] subgrp=new int[64]; // book heuristic subgroup size 453 int[] blimit=new int[64]; // subgroup position limits 454}