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.*; 029import java.io.InputStream; 030 031public class VorbisFile{ 032 static final int CHUNKSIZE=8500; 033 static final int SEEK_SET=0; 034 static final int SEEK_CUR=1; 035 static final int SEEK_END=2; 036 037 static final int OV_FALSE=-1; 038 static final int OV_EOF=-2; 039 static final int OV_HOLE=-3; 040 041 static final int OV_EREAD=-128; 042 static final int OV_EFAULT=-129; 043 static final int OV_EIMPL=-130; 044 static final int OV_EINVAL=-131; 045 static final int OV_ENOTVORBIS=-132; 046 static final int OV_EBADHEADER=-133; 047 static final int OV_EVERSION=-134; 048 static final int OV_ENOTAUDIO=-135; 049 static final int OV_EBADPACKET=-136; 050 static final int OV_EBADLINK=-137; 051 static final int OV_ENOSEEK=-138; 052 053 InputStream datasource; 054 boolean seekable=false; 055 long offset; 056 long end; 057 058 SyncState oy=new SyncState(); 059 060 int links; 061 long[] offsets; 062 long[] dataoffsets; 063 int[] serialnos; 064 long[] pcmlengths; 065 Info[] vi; 066 Comment[] vc; 067 068 // Decoding working state local storage 069 long pcm_offset; 070 boolean decode_ready=false; 071 int current_serialno; 072 int current_link; 073 074 float bittrack; 075 float samptrack; 076 077 StreamState os=new StreamState(); // take physical pages, weld into a logical 078 // stream of packets 079 DspState vd=new DspState(); // central working state for 080 // the packet->PCM decoder 081 Block vb=new Block(vd); // local working space for packet->PCM decode 082 083 //ov_callbacks callbacks; 084 085 public VorbisFile(String file) throws JOrbisException { 086 super(); 087 InputStream is=null; 088 /* 089 try{ is=new java.io.FileInputStream(file);} 090 catch(Exception e){ 091 throw new JOrbisException("VorbisFile: "+e.toString()); 092 } 093 */ 094 try{ is=new SeekableInputStream(file);} 095 catch(Exception e){ 096 throw new JOrbisException("VorbisFile: "+e.toString()); 097 } 098 int ret=open(is, null, 0); 099 if(ret==-1){ 100 throw new JOrbisException("VorbisFile: open return -1"); 101 } 102 } 103 104 public VorbisFile(InputStream is, byte[] initial, int ibytes) 105 throws JOrbisException { 106 super(); 107 int ret=open(is, initial, ibytes); 108 if(ret==-1){ 109 } 110 } 111 112 private int get_data(){ 113 int index=oy.buffer(CHUNKSIZE); 114 byte[] buffer=oy.data; 115// int bytes=callbacks.read_func(buffer, index, 1, CHUNKSIZE, datasource); 116 int bytes=0; 117 try{ 118 bytes=datasource.read(buffer, index, CHUNKSIZE); 119 } 120 catch(Exception e){ 121 System.err.println(e); 122 return OV_EREAD; 123 } 124 oy.wrote(bytes); 125 if(bytes==-1){ 126// System.out.println("bytes="+bytes); 127 bytes=0; 128 } 129 return bytes; 130 } 131 132 private void seek_helper(long offst){ 133 //callbacks.seek_func(datasource, offst, SEEK_SET); 134 fseek(datasource, offst, SEEK_SET); 135 this.offset=offst; 136 oy.reset(); 137 } 138 139 private int get_next_page(Page page, long boundary){ 140 if(boundary>0) boundary+=offset; 141 while(true){ 142 int more; 143 if(boundary>0 && offset>=boundary)return OV_FALSE; 144 more=oy.pageseek(page); 145 if(more<0){offset-=more;} 146 else{ 147 if(more==0){ 148 if(boundary==0)return OV_FALSE; 149// if(get_data()<=0)return -1; 150 int ret=get_data(); 151 if(ret==0) return OV_EOF; 152 if(ret<0) return OV_EREAD; 153 } 154 else{ 155 int ret=(int)offset; //!!! 156 offset+=more; 157 return ret; 158 } 159 } 160 } 161 } 162 163 private int get_prev_page(Page page){ 164 long begin=offset; //!!! 165 int ret; 166 int offst=-1; 167 while(offst==-1){ 168 begin-=CHUNKSIZE; 169 if(begin<0) 170 begin=0; 171 seek_helper(begin); 172 while(offset<begin+CHUNKSIZE){ 173 ret=get_next_page(page, begin+CHUNKSIZE-offset); 174 if(ret==OV_EREAD){ return OV_EREAD; } 175 if(ret<0){ break; } 176 else{ offst=ret; } 177 } 178 } 179 seek_helper(offst); //!!! 180 ret=get_next_page(page, CHUNKSIZE); 181 if(ret<0){ 182 //System.err.println("Missed page fencepost at end of logical bitstream Exiting"); 183 //System.exit(1); 184 return OV_EFAULT; 185 } 186 return offst; 187 } 188 189 int bisect_forward_serialno(long begin, long searched, long end, int currentno, int m){ 190 long endsearched=end; 191 long next=end; 192 Page page=new Page(); 193 int ret; 194 195 while(searched<endsearched){ 196 long bisect; 197 if(endsearched-searched<CHUNKSIZE){ 198 bisect=searched; 199 } 200 else{ 201 bisect=(searched+endsearched)/2; 202 } 203 204 seek_helper(bisect); 205 ret=get_next_page(page, -1); 206 if(ret==OV_EREAD) return OV_EREAD; 207 if(ret<0 || page.serialno()!=currentno){ 208 endsearched=bisect; 209 if(ret>=0)next=ret; 210 } 211 else{ 212 searched=ret+page.header_len+page.body_len; 213 } 214 } 215 seek_helper(next); 216 ret=get_next_page(page, -1); 217 if(ret==OV_EREAD) return OV_EREAD; 218 219 if(searched>=end || ret==-1){ 220 links=m+1; 221 offsets=new long[m+2]; 222 offsets[m+1]=searched; 223 } 224 else{ 225 ret=bisect_forward_serialno(next, offset, end, page.serialno(), m+1); 226 if(ret==OV_EREAD)return OV_EREAD; 227 } 228 offsets[m]=begin; 229 return 0; 230 } 231 232 // uses the local ogg_stream storage in vf; this is important for 233 // non-streaming input sources 234 int fetch_headers(Info vi, Comment vc, int[] serialno, Page og_ptr){ 235 //System.err.println("fetch_headers"); 236 Page og=new Page(); 237 Packet op=new Packet(); 238 int ret; 239 240 if(og_ptr==null){ 241 ret=get_next_page(og, CHUNKSIZE); 242 if(ret==OV_EREAD)return OV_EREAD; 243 if(ret<0) return OV_ENOTVORBIS; 244 og_ptr=og; 245 } 246 247 if(serialno!=null)serialno[0]=og_ptr.serialno(); 248 249 os.init(og_ptr.serialno()); 250 251 // extract the initial header from the first page and verify that the 252 // Ogg bitstream is in fact Vorbis data 253 254 vi.init(); 255 vc.init(); 256 257 int i=0; 258 while(i<3){ 259 os.pagein(og_ptr); 260 while(i<3){ 261 int result=os.packetout(op); 262 if(result==0)break; 263 if(result==-1){ 264 System.err.println("Corrupt header in logical bitstream."); 265 //goto bail_header; 266 vi.clear(); 267 vc.clear(); 268 os.clear(); 269 return -1; 270 } 271 if(vi.synthesis_headerin(vc, op)!=0){ 272 System.err.println("Illegal header in logical bitstream."); 273 //goto bail_header; 274 vi.clear(); 275 vc.clear(); 276 os.clear(); 277 return -1; 278 } 279 i++; 280 } 281 if(i<3) 282 if(get_next_page(og_ptr, 1)<0){ 283 System.err.println("Missing header in logical bitstream."); 284 //goto bail_header; 285 vi.clear(); 286 vc.clear(); 287 os.clear(); 288 return -1; 289 } 290 } 291 return 0; 292 293// bail_header: 294// vorbis_info_clear(vi); 295// vorbis_comment_clear(vc); 296// ogg_stream_clear(&vf->os); 297// return -1; 298 } 299 300 // last step of the OggVorbis_File initialization; get all the 301 // vorbis_info structs and PCM positions. Only called by the seekable 302 // initialization (local stream storage is hacked slightly; pay 303 // attention to how that's done) 304 void prefetch_all_headers(Info first_i,Comment first_c, int dataoffset){ 305 Page og=new Page(); 306 int ret; 307 308 vi=new Info[links]; 309 vc=new Comment[links]; 310 dataoffsets=new long[links]; 311 pcmlengths=new long[links]; 312 serialnos=new int[links]; 313 314 for(int i=0;i<links;i++){ 315 if(first_i!=null && first_c!=null && i==0){ 316 // we already grabbed the initial header earlier. This just 317 // saves the waste of grabbing it again 318 // !!!!!!!!!!!!! 319 vi[i]=first_i; 320 //memcpy(vf->vi+i,first_i,sizeof(vorbis_info)); 321 vc[i]=first_c; 322 //memcpy(vf->vc+i,first_c,sizeof(vorbis_comment)); 323 dataoffsets[i]=dataoffset; 324 } 325 else{ 326 // seek to the location of the initial header 327 seek_helper(offsets[i]); //!!! 328 if(fetch_headers(vi[i], vc[i], null, null)==-1){ 329 System.err.println("Error opening logical bitstream #"+(i+1)+"\n"); 330 dataoffsets[i]=-1; 331 } 332 else{ 333 dataoffsets[i]=offset; 334 os.clear(); 335 } 336 } 337 338 // get the serial number and PCM length of this link. To do this, 339 // get the last page of the stream 340 { 341 long end=offsets[i+1]; //!!! 342 seek_helper(end); 343 344 while(true){ 345 ret=get_prev_page(og); 346 if(ret==-1){ 347 // this should not be possible 348 System.err.println("Could not find last page of logical "+ 349 "bitstream #"+(i)+"\n"); 350 vi[i].clear(); 351 vc[i].clear(); 352 break; 353 } 354 if(og.granulepos()!=-1){ 355 serialnos[i]=og.serialno(); 356 pcmlengths[i]=og.granulepos(); 357 break; 358 } 359 } 360 } 361 } 362 } 363 364 int make_decode_ready(){ 365 if(decode_ready)System.exit(1); 366 vd.synthesis_init(vi[0]); 367 vb.init(vd); 368 decode_ready=true; 369 return(0); 370 } 371 372 int open_seekable(){ 373 Info initial_i=new Info(); 374 Comment initial_c=new Comment(); 375 int serialno; 376 long end; 377 int ret; 378 int dataoffset; 379 Page og=new Page(); 380 // is this even vorbis...? 381 int[] foo=new int[1]; 382 ret=fetch_headers(initial_i, initial_c, foo, null); 383 serialno=foo[0]; 384 dataoffset=(int)offset; //!! 385 os.clear(); 386 if(ret==-1)return(-1); 387 // we can seek, so set out learning all about this file 388 seekable=true; 389 //(callbacks.seek_func)(datasource, 0, SEEK_END); 390 fseek(datasource, 0, SEEK_END); 391 //offset=end=(callbacks.tell_func)(datasource); 392 offset=ftell(datasource); 393 end=offset; 394 // We get the offset for the last page of the physical bitstream. 395 // Most OggVorbis files will contain a single logical bitstream 396 end=get_prev_page(og); 397 // moer than one logical bitstream? 398 if(og.serialno()!=serialno){ 399 // Chained bitstream. Bisect-search each logical bitstream 400 // section. Do so based on serial number only 401 if(bisect_forward_serialno(0,0,end+1,serialno,0)<0){ 402 clear(); 403 return OV_EREAD; 404 } 405 } 406 else{ 407 // Only one logical bitstream 408 if(bisect_forward_serialno(0,end,end+1,serialno,0)<0){ 409 clear(); 410 return OV_EREAD; 411 } 412 } 413 prefetch_all_headers(initial_i, initial_c, dataoffset); 414 return(raw_seek(0)); 415 } 416 417 int open_nonseekable(){ 418 //System.err.println("open_nonseekable"); 419 // we cannot seek. Set up a 'single' (current) logical bitstream entry 420 links=1; 421 vi=new Info[links]; vi[0]=new Info(); // ?? 422 vc=new Comment[links]; vc[0]=new Comment(); // ?? bug? 423 424 // Try to fetch the headers, maintaining all the storage 425 int[]foo=new int[1]; 426 if(fetch_headers(vi[0], vc[0], foo, null)==-1)return(-1); 427 current_serialno=foo[0]; 428 make_decode_ready(); 429 return 0; 430 } 431 432 // clear out the current logical bitstream decoder 433 void decode_clear(){ 434 os.clear(); 435 vd.clear(); 436 vb.clear(); 437 decode_ready=false; 438 bittrack=0.f; 439 samptrack=0.f; 440 } 441 442 // fetch and process a packet. Handles the case where we're at a 443 // bitstream boundary and dumps the decoding machine. If the decoding 444 // machine is unloaded, it loads it. It also keeps pcm_offset up to 445 // date (seek and read both use this. seek uses a special hack with 446 // readp). 447 // 448 // return: -1) hole in the data (lost packet) 449 // 0) need more date (only if readp==0)/eof 450 // 1) got a packet 451 452 int process_packet(int readp){ 453 Page og=new Page(); 454 455 // handle one packet. Try to fetch it from current stream state 456 // extract packets from page 457 while(true){ 458 // process a packet if we can. If the machine isn't loaded, 459 // neither is a page 460 if(decode_ready){ 461 Packet op=new Packet(); 462 int result=os.packetout(op); 463 long granulepos; 464 // if(result==-1)return(-1); // hole in the data. For now, swallow 465 // and go. We'll need to add a real 466 // error code in a bit. 467 if(result>0){ 468 // got a packet. process it 469 granulepos=op.granulepos; 470 if(vb.synthesis(op)==0){ // lazy check for lazy 471 // header handling. The 472 // header packets aren't 473 // audio, so if/when we 474 // submit them, 475 // vorbis_synthesis will 476 // reject them 477 // suck in the synthesis data and track bitrate 478 { 479 int oldsamples=vd.synthesis_pcmout(null, null); 480 vd.synthesis_blockin(vb); 481 samptrack+=vd.synthesis_pcmout(null, null)-oldsamples; 482 bittrack+=op.bytes*8; 483 } 484 485 // update the pcm offset. 486 if(granulepos!=-1 && op.e_o_s==0){ 487 int link=(seekable?current_link:0); 488 int samples; 489 // this packet has a pcm_offset on it (the last packet 490 // completed on a page carries the offset) After processing 491 // (above), we know the pcm position of the *last* sample 492 // ready to be returned. Find the offset of the *first* 493 // 494 // As an aside, this trick is inaccurate if we begin 495 // reading anew right at the last page; the end-of-stream 496 // granulepos declares the last frame in the stream, and the 497 // last packet of the last page may be a partial frame. 498 // So, we need a previous granulepos from an in-sequence page 499 // to have a reference point. Thus the !op.e_o_s clause above 500 501 samples=vd.synthesis_pcmout(null, null); 502 granulepos-=samples; 503 for(int i=0;i<link;i++){ 504 granulepos+=pcmlengths[i]; 505 } 506 pcm_offset=granulepos; 507 } 508 return(1); 509 } 510 } 511 } 512 513 if(readp==0)return(0); 514 if(get_next_page(og,-1)<0)return(0); // eof. leave unitialized 515 516 // bitrate tracking; add the header's bytes here, the body bytes 517 // are done by packet above 518 bittrack+=og.header_len*8; 519 520 // has our decoding just traversed a bitstream boundary? 521 if(decode_ready){ 522 if(current_serialno!=og.serialno()){ 523 decode_clear(); 524 } 525 } 526 527 // Do we need to load a new machine before submitting the page? 528 // This is different in the seekable and non-seekable cases. 529 // 530 // In the seekable case, we already have all the header 531 // information loaded and cached; we just initialize the machine 532 // with it and continue on our merry way. 533 // 534 // In the non-seekable (streaming) case, we'll only be at a 535 // boundary if we just left the previous logical bitstream and 536 // we're now nominally at the header of the next bitstream 537 538 if(!decode_ready){ 539 int i; 540 if(seekable){ 541 current_serialno=og.serialno(); 542 543 // match the serialno to bitstream section. We use this rather than 544 // offset positions to avoid problems near logical bitstream 545 // boundaries 546 for(i=0;i<links;i++){ 547 if(serialnos[i]==current_serialno)break; 548 } 549 if(i==links)return(-1); // sign of a bogus stream. error out, 550 // leave machine uninitialized 551 current_link=i; 552 553 os.init(current_serialno); 554 os.reset(); 555 556 } 557 else{ 558 // we're streaming 559 // fetch the three header packets, build the info struct 560 int foo[]=new int[1]; 561 int ret=fetch_headers(vi[0], vc[0], foo, og); 562 current_serialno=foo[0]; 563 if(ret!=0)return ret; 564 current_link++; 565 i=0; 566 } 567 make_decode_ready(); 568 } 569 os.pagein(og); 570 } 571 } 572 573 //The helpers are over; it's all toplevel interface from here on out 574 // clear out the OggVorbis_File struct 575 int clear(){ 576 vb.clear(); 577 vd.clear(); 578 os.clear(); 579 580 if(vi!=null && links!=0){ 581 for(int i=0;i<links;i++){ 582 vi[i].clear(); 583 vc[i].clear(); 584 } 585 vi=null; 586 vc=null; 587 } 588 if(dataoffsets!=null)dataoffsets=null; 589 if(pcmlengths!=null)pcmlengths=null; 590 if(serialnos!=null)serialnos=null; 591 if(offsets!=null)offsets=null; 592 oy.clear(); 593 //if(datasource!=null)(vf->callbacks.close_func)(vf->datasource); 594 //memset(vf,0,sizeof(OggVorbis_File)); 595 return(0); 596 } 597 598 static int fseek(InputStream fis, 599 //int64_t off, 600 long off, 601 int whence){ 602 if(fis instanceof SeekableInputStream){ 603 SeekableInputStream sis=(SeekableInputStream)fis; 604 try{ 605 if(whence==SEEK_SET){ 606 sis.seek(off); 607 } 608 else if(whence==SEEK_END){ 609 sis.seek(sis.getLength()-off); 610 } 611 else{ 612 System.out.println("seek: "+whence+" is not supported"); 613 } 614 } 615 catch(Exception e){ 616 } 617 return 0; 618 } 619 try{ 620 if(whence==0){ fis.reset(); } 621 fis.skip(off); 622 } 623 catch(Exception e){return -1;} 624 return 0; 625 } 626 627 static long ftell(InputStream fis){ 628 try{ 629 if(fis instanceof SeekableInputStream){ 630 SeekableInputStream sis=(SeekableInputStream)fis; 631 return (sis.tell()); 632 } 633 } 634 catch(Exception e){ 635 } 636 return 0; 637 } 638 639 // inspects the OggVorbis file and finds/documents all the logical 640 // bitstreams contained in it. Tries to be tolerant of logical 641 // bitstream sections that are truncated/woogie. 642 // 643 // return: -1) error 644 // 0) OK 645 646 int open(InputStream is, byte[] initial, int ibytes){ 647 //callbacks callbacks = { 648 // (size_t (*)(void *, size_t, size_t, void *)) fread, 649 // (int (*)(void *, int64_t, int)) _fseek, 650 // (int (*)(void *)) fclose, 651 // (long (*)(void *)) ftell 652 // }; 653 return open_callbacks(is, initial, ibytes//, callbacks 654 ); 655 } 656 657 int open_callbacks(InputStream is, byte[] initial, 658 int ibytes//, callbacks callbacks 659 ){ 660 int ret; 661 datasource=is; 662 //callbacks = _callbacks; 663 // init the framing state 664 oy.init(); 665 666 // perhaps some data was previously read into a buffer for testing 667 // against other stream types. Allow initialization from this 668 // previously read data (as we may be reading from a non-seekable 669 // stream) 670 if(initial!=null){ 671 int index=oy.buffer(ibytes); 672 System.arraycopy(initial, 0, oy.data, index, ibytes); 673 oy.wrote(ibytes); 674 } 675 // can we seek? Stevens suggests the seek test was portable 676 if(is instanceof SeekableInputStream){ ret=open_seekable(); } 677 else{ ret=open_nonseekable(); } 678 if(ret!=0){ 679 datasource=null; 680 clear(); 681 } 682 return(ret); 683 } 684 685 // How many logical bitstreams in this physical bitstream? 686 public int streams(){ 687 return links; 688 } 689 690 // Is the FILE * associated with vf seekable? 691 public boolean seekable(){ 692 return seekable; 693 } 694 695 // returns the bitrate for a given logical bitstream or the entire 696 // physical bitstream. If the file is open for random access, it will 697 // find the *actual* average bitrate. If the file is streaming, it 698 // returns the nominal bitrate (if set) else the average of the 699 // upper/lower bounds (if set) else -1 (unset). 700 // 701 // If you want the actual bitrate field settings, get them from the 702 // vorbis_info structs 703 704 public int bitrate(int i){ 705 if(i>=links)return(-1); 706 if(!seekable && i!=0)return(bitrate(0)); 707 if(i<0){ 708 long bits=0; 709 for(int j=0;j<links;j++){ 710 bits+=(offsets[j+1]-dataoffsets[j])*8; 711 } 712 return((int)Math.rint(bits/time_total(-1))); 713 } 714 else{ 715 if(seekable){ 716 // return the actual bitrate 717 return((int)Math.rint((offsets[i+1]-dataoffsets[i])*8/time_total(i))); 718 } 719 else{ 720 // return nominal if set 721 if(vi[i].bitrate_nominal>0){ 722 return vi[i].bitrate_nominal; 723 } 724 else{ 725 if(vi[i].bitrate_upper>0){ 726 if(vi[i].bitrate_lower>0){ 727 return (vi[i].bitrate_upper+vi[i].bitrate_lower)/2; 728 }else{ 729 return vi[i].bitrate_upper; 730 } 731 } 732 return(-1); 733 } 734 } 735 } 736 } 737 738 // returns the actual bitrate since last call. returns -1 if no 739 // additional data to offer since last call (or at beginning of stream) 740 public int bitrate_instant(){ 741 int _link=(seekable?current_link:0); 742 if(samptrack==0)return(-1); 743 int ret=(int)(bittrack/samptrack*vi[_link].rate+.5); 744 bittrack=0.f; 745 samptrack=0.f; 746 return(ret); 747 } 748 749 public int serialnumber(int i){ 750 if(i>=links)return(-1); 751 if(!seekable && i>=0)return(serialnumber(-1)); 752 if(i<0){ 753 return(current_serialno); 754 } 755 else{ 756 return(serialnos[i]); 757 } 758 } 759 760 // returns: total raw (compressed) length of content if i==-1 761 // raw (compressed) length of that logical bitstream for i==0 to n 762 // -1 if the stream is not seekable (we can't know the length) 763 764 public long raw_total(int i){ 765 if(!seekable || i>=links)return(-1); 766 if(i<0){ 767 long acc=0; // bug? 768 for(int j=0;j<links;j++){ 769 acc+=raw_total(j); 770 } 771 return(acc); 772 } 773 else{ 774 return(offsets[i+1]-offsets[i]); 775 } 776 } 777 778 // returns: total PCM length (samples) of content if i==-1 779 // PCM length (samples) of that logical bitstream for i==0 to n 780 // -1 if the stream is not seekable (we can't know the length) 781 public long pcm_total(int i){ 782 if(!seekable || i>=links)return(-1); 783 if(i<0){ 784 long acc=0; 785 for(int j=0;j<links;j++){ 786 acc+=pcm_total(j); 787 } 788 return(acc); 789 } 790 else{ 791 return(pcmlengths[i]); 792 } 793 } 794 795 // returns: total seconds of content if i==-1 796 // seconds in that logical bitstream for i==0 to n 797 // -1 if the stream is not seekable (we can't know the length) 798 public float time_total(int i){ 799 if(!seekable || i>=links)return(-1); 800 if(i<0){ 801 float acc=0; 802 for(int j=0;j<links;j++){ 803 acc+=time_total(j); 804 } 805 return(acc); 806 } 807 else{ 808 return((float)(pcmlengths[i])/vi[i].rate); 809 } 810 } 811 812 // seek to an offset relative to the *compressed* data. This also 813 // immediately sucks in and decodes pages to update the PCM cursor. It 814 // will cross a logical bitstream boundary, but only if it can't get 815 // any packets out of the tail of the bitstream we seek to (so no 816 // surprises). 817 // 818 // returns zero on success, nonzero on failure 819 820 public int raw_seek(int pos){ 821 if(!seekable)return(-1); // don't dump machine if we can't seek 822 if(pos<0 || pos>offsets[links]){ 823 //goto seek_error; 824 pcm_offset=-1; 825 decode_clear(); 826 return -1; 827 } 828 829 // clear out decoding machine state 830 pcm_offset=-1; 831 decode_clear(); 832 833 // seek 834 seek_helper(pos); 835 836 // we need to make sure the pcm_offset is set. We use the 837 // _fetch_packet helper to process one packet with readp set, then 838 // call it until it returns '0' with readp not set (the last packet 839 // from a page has the 'granulepos' field set, and that's how the 840 // helper updates the offset 841 842 switch(process_packet(1)){ 843 case 0: 844 // oh, eof. There are no packets remaining. Set the pcm offset to 845 // the end of file 846 pcm_offset=pcm_total(-1); 847 return(0); 848 case -1: 849 // error! missing data or invalid bitstream structure 850 //goto seek_error; 851 pcm_offset=-1; 852 decode_clear(); 853 return -1; 854 default: 855 // all OK 856 break; 857 } 858 while(true){ 859 switch(process_packet(0)){ 860 case 0: 861 // the offset is set. If it's a bogus bitstream with no offset 862 // information, it's not but that's not our fault. We still run 863 // gracefully, we're just missing the offset 864 return(0); 865 case -1: 866 // error! missing data or invalid bitstream structure 867 //goto seek_error; 868 pcm_offset=-1; 869 decode_clear(); 870 return -1; 871 default: 872 // continue processing packets 873 break; 874 } 875 } 876 877 // seek_error: 878 // dump the machine so we're in a known state 879 //pcm_offset=-1; 880 //decode_clear(); 881 //return -1; 882 } 883 884 // seek to a sample offset relative to the decompressed pcm stream 885 // returns zero on success, nonzero on failure 886 887 public int pcm_seek(long pos){ 888 int link=-1; 889 long total=pcm_total(-1); 890 891 if(!seekable)return(-1); // don't dump machine if we can't seek 892 if(pos<0 || pos>total){ 893 //goto seek_error; 894 pcm_offset=-1; 895 decode_clear(); 896 return -1; 897 } 898 899 // which bitstream section does this pcm offset occur in? 900 for(link=links-1;link>=0;link--){ 901 total-=pcmlengths[link]; 902 if(pos>=total)break; 903 } 904 905 // search within the logical bitstream for the page with the highest 906 // pcm_pos preceeding (or equal to) pos. There is a danger here; 907 // missing pages or incorrect frame number information in the 908 // bitstream could make our task impossible. Account for that (it 909 // would be an error condition) 910 { 911 long target=pos-total; 912 long end=offsets[link+1]; 913 long begin=offsets[link]; 914 int best=(int)begin; 915 916 Page og=new Page(); 917 while(begin<end){ 918 long bisect; 919 int ret; 920 921 if(end-begin<CHUNKSIZE){ 922 bisect=begin; 923 } 924 else{ 925 bisect=(end+begin)/2; 926 } 927 928 seek_helper(bisect); 929 ret=get_next_page(og,end-bisect); 930 931 if(ret==-1){ 932 end=bisect; 933 } 934 else{ 935 long granulepos=og.granulepos(); 936 if(granulepos<target){ 937 best=ret; // raw offset of packet with granulepos 938 begin=offset; // raw offset of next packet 939 } 940 else{ 941 end=bisect; 942 } 943 } 944 } 945 // found our page. seek to it (call raw_seek). 946 if(raw_seek(best)!=0){ 947 //goto seek_error; 948 pcm_offset=-1; 949 decode_clear(); 950 return -1; 951 } 952 } 953 954 // verify result 955 if(pcm_offset>=pos){ 956 //goto seek_error; 957 pcm_offset=-1; 958 decode_clear(); 959 return -1; 960 } 961 if(pos>pcm_total(-1)){ 962 //goto seek_error; 963 pcm_offset=-1; 964 decode_clear(); 965 return -1; 966 } 967 968 // discard samples until we reach the desired position. Crossing a 969 // logical bitstream boundary with abandon is OK. 970 while(pcm_offset<pos){ 971 float[][] pcm; 972 int target=(int)(pos-pcm_offset); 973 float[][][] _pcm=new float[1][][]; 974 int[] _index=new int[getInfo(-1).channels]; 975 int samples=vd.synthesis_pcmout(_pcm, _index); 976 pcm=_pcm[0]; 977 978 if(samples>target)samples=target; 979 vd.synthesis_read(samples); 980 pcm_offset+=samples; 981 982 if(samples<target) 983 if(process_packet(1)==0){ 984 pcm_offset=pcm_total(-1); // eof 985 } 986 } 987 return 0; 988 989 // seek_error: 990 // dump machine so we're in a known state 991 //pcm_offset=-1; 992 //decode_clear(); 993 //return -1; 994 } 995 996 // seek to a playback time relative to the decompressed pcm stream 997 // returns zero on success, nonzero on failure 998 int time_seek(float seconds){ 999 // translate time to PCM position and call pcm_seek 1000 1001 int link=-1; 1002 long pcm_total=pcm_total(-1); 1003 float time_total=time_total(-1); 1004 1005 if(!seekable)return(-1); // don't dump machine if we can't seek 1006 if(seconds<0 || seconds>time_total){ 1007 //goto seek_error; 1008 pcm_offset=-1; 1009 decode_clear(); 1010 return -1; 1011 } 1012 1013 // which bitstream section does this time offset occur in? 1014 for(link=links-1;link>=0;link--){ 1015 pcm_total-=pcmlengths[link]; 1016 time_total-=time_total(link); 1017 if(seconds>=time_total)break; 1018 } 1019 1020 // enough information to convert time offset to pcm offset 1021 { 1022 long target=(long)(pcm_total+(seconds-time_total)*vi[link].rate); 1023 return(pcm_seek(target)); 1024 } 1025 1026 //seek_error: 1027 // dump machine so we're in a known state 1028 //pcm_offset=-1; 1029 //decode_clear(); 1030 //return -1; 1031 } 1032 1033 // tell the current stream offset cursor. Note that seek followed by 1034 // tell will likely not give the set offset due to caching 1035 public long raw_tell(){ 1036 return(offset); 1037 } 1038 1039 // return PCM offset (sample) of next PCM sample to be read 1040 public long pcm_tell(){ 1041 return(pcm_offset); 1042 } 1043 1044 // return time offset (seconds) of next PCM sample to be read 1045 public float time_tell(){ 1046 // translate time to PCM position and call pcm_seek 1047 1048 int link=-1; 1049 long pcm_total=0; 1050 float time_total=0.f; 1051 1052 if(seekable){ 1053 pcm_total=pcm_total(-1); 1054 time_total=time_total(-1); 1055 1056 // which bitstream section does this time offset occur in? 1057 for(link=links-1;link>=0;link--){ 1058 pcm_total-=pcmlengths[link]; 1059 time_total-=time_total(link); 1060 if(pcm_offset>=pcm_total)break; 1061 } 1062 } 1063 1064 return((float)time_total+(float)(pcm_offset-pcm_total)/vi[link].rate); 1065 } 1066 1067 // link: -1) return the vorbis_info struct for the bitstream section 1068 // currently being decoded 1069 // 0-n) to request information for a specific bitstream section 1070 // 1071 // In the case of a non-seekable bitstream, any call returns the 1072 // current bitstream. NULL in the case that the machine is not 1073 // initialized 1074 1075 public Info getInfo(int link){ 1076 if(seekable){ 1077 if(link<0){ 1078 if(decode_ready){ 1079 return vi[current_link]; 1080 } 1081 else{ 1082 return null; 1083 } 1084 } 1085 else{ 1086 if(link>=links){ 1087 return null; 1088 } 1089 else{ 1090 return vi[link]; 1091 } 1092 } 1093 } 1094 else{ 1095 if(decode_ready){ 1096 return vi[0]; 1097 } 1098 else{ 1099 return null; 1100 } 1101 } 1102 } 1103 1104 public Comment getComment(int link){ 1105 if(seekable){ 1106 if(link<0){ 1107 if(decode_ready){ return vc[current_link]; } 1108 else{ return null; } 1109 } 1110 else{ 1111 if(link>=links){ return null;} 1112 else{ return vc[link]; } 1113 } 1114 } 1115 else{ 1116 if(decode_ready){ return vc[0]; } 1117 else{ return null; } 1118 } 1119 } 1120 1121 int host_is_big_endian() { 1122 return 1; 1123// short pattern = 0xbabe; 1124// unsigned char *bytewise = (unsigned char *)&pattern; 1125// if (bytewise[0] == 0xba) return 1; 1126// assert(bytewise[0] == 0xbe); 1127// return 0; 1128 } 1129 1130 // up to this point, everything could more or less hide the multiple 1131 // logical bitstream nature of chaining from the toplevel application 1132 // if the toplevel application didn't particularly care. However, at 1133 // the point that we actually read audio back, the multiple-section 1134 // nature must surface: Multiple bitstream sections do not necessarily 1135 // have to have the same number of channels or sampling rate. 1136 // 1137 // read returns the sequential logical bitstream number currently 1138 // being decoded along with the PCM data in order that the toplevel 1139 // application can take action on channel/sample rate changes. This 1140 // number will be incremented even for streamed (non-seekable) streams 1141 // (for seekable streams, it represents the actual logical bitstream 1142 // index within the physical bitstream. Note that the accessor 1143 // functions above are aware of this dichotomy). 1144 // 1145 // input values: buffer) a buffer to hold packed PCM data for return 1146 // length) the byte length requested to be placed into buffer 1147 // bigendianp) should the data be packed LSB first (0) or 1148 // MSB first (1) 1149 // word) word size for output. currently 1 (byte) or 1150 // 2 (16 bit short) 1151 // 1152 // return values: -1) error/hole in data 1153 // 0) EOF 1154 // n) number of bytes of PCM actually returned. The 1155 // below works on a packet-by-packet basis, so the 1156 // return length is not related to the 'length' passed 1157 // in, just guaranteed to fit. 1158 // 1159 // *section) set to the logical bitstream number 1160 1161 int read(byte[] buffer,int length, 1162 int bigendianp, int word, int sgned, int[] bitstream){ 1163 int host_endian = host_is_big_endian(); 1164 int index=0; 1165 1166 while(true){ 1167 if(decode_ready){ 1168 float[][] pcm; 1169 float[][][] _pcm=new float[1][][]; 1170 int[] _index=new int[getInfo(-1).channels]; 1171 int samples=vd.synthesis_pcmout(_pcm, _index); 1172 pcm=_pcm[0]; 1173 if(samples!=0){ 1174 // yay! proceed to pack data into the byte buffer 1175 int channels=getInfo(-1).channels; 1176 int bytespersample=word * channels; 1177 if(samples>length/bytespersample)samples=length/bytespersample; 1178 1179 // a tight loop to pack each size 1180 { 1181 int val; 1182 if(word==1){ 1183 int off=(sgned!=0?0:128); 1184 for(int j=0;j<samples;j++){ 1185 for(int i=0;i<channels;i++){ 1186 val=(int)(pcm[i][_index[i]+j]*128. + 0.5); 1187 if(val>127)val=127; 1188 else if(val<-128)val=-128; 1189 buffer[index++]=(byte)(val+off); 1190 } 1191 } 1192 } 1193 else{ 1194 int off=(sgned!=0?0:32768); 1195 1196 if(host_endian==bigendianp){ 1197 if(sgned!=0){ 1198 for(int i=0;i<channels;i++) { // It's faster in this order 1199 int src=_index[i]; 1200 int dest=i; 1201 for(int j=0;j<samples;j++) { 1202 val=(int)(pcm[i][src+j]*32768. + 0.5); 1203 if(val>32767)val=32767; 1204 else if(val<-32768)val=-32768; 1205 buffer[dest]=(byte)(val>>>8); 1206 buffer[dest+1]=(byte)(val); 1207 dest+=channels*2; 1208 } 1209 } 1210 } 1211 else{ 1212 for(int i=0;i<channels;i++) { 1213 float[] src=pcm[i]; 1214 int dest=i; 1215 for(int j=0;j<samples;j++) { 1216 val=(int)(src[j]*32768. + 0.5); 1217 if(val>32767)val=32767; 1218 else if(val<-32768)val=-32768; 1219 buffer[dest]=(byte)((val+off)>>>8); 1220 buffer[dest+1]=(byte)(val+off); 1221 dest+=channels*2; 1222 } 1223 } 1224 } 1225 } 1226 else if(bigendianp!=0){ 1227 for(int j=0;j<samples;j++){ 1228 for(int i=0;i<channels;i++){ 1229 val=(int)(pcm[i][j]*32768. + 0.5); 1230 if(val>32767)val=32767; 1231 else if(val<-32768)val=-32768; 1232 val+=off; 1233 buffer[index++]=(byte)(val>>>8); 1234 buffer[index++]=(byte)val; 1235 } 1236 } 1237 } 1238 else{ 1239 //int val; 1240 for(int j=0;j<samples;j++){ 1241 for(int i=0;i<channels;i++){ 1242 val=(int)(pcm[i][j]*32768. + 0.5); 1243 if(val>32767)val=32767; 1244 else if(val<-32768)val=-32768; 1245 val+=off; 1246 buffer[index++]=(byte)val; 1247 buffer[index++]=(byte)(val>>>8); 1248 } 1249 } 1250 } 1251 } 1252 } 1253 1254 vd.synthesis_read(samples); 1255 pcm_offset+=samples; 1256 if(bitstream!=null)bitstream[0]=current_link; 1257 return(samples*bytespersample); 1258 } 1259 } 1260 1261 // suck in another packet 1262 switch(process_packet(1)){ 1263 case 0: 1264 return(0); 1265 case -1: 1266 return -1; 1267 default: 1268 break; 1269 } 1270 } 1271 } 1272 1273 public Info[] getInfo(){return vi;} 1274 public Comment[] getComment(){return vc;} 1275 1276 public static void main(String[] arg){ 1277 try{ 1278 VorbisFile foo=new VorbisFile(arg[0]); 1279 int links=foo.streams(); 1280 System.out.println("links="+links); 1281 Comment[] comment=foo.getComment(); 1282 Info[] info=foo.getInfo(); 1283 for(int i=0; i<links; i++){ 1284 System.out.println(info[i]); 1285 System.out.println(comment[i]); 1286 } 1287 System.out.println("raw_total: "+foo.raw_total(-1)); 1288 System.out.println("pcm_total: "+foo.pcm_total(-1)); 1289 System.out.println("time_total: "+foo.time_total(-1)); 1290 } 1291 catch(Exception e){ 1292 System.err.println(e); 1293 } 1294 } 1295 1296 class SeekableInputStream extends InputStream { 1297 java.io.RandomAccessFile raf=null; 1298 static final String mode="r"; 1299 private SeekableInputStream(){ 1300 } 1301 SeekableInputStream(String file) throws java.io.FileNotFoundException{ 1302 raf=new java.io.RandomAccessFile(file, mode); 1303 } 1304 public int read() throws java.io.IOException{ 1305 return raf.read(); 1306 } 1307 public int read(byte[] buf) throws java.io.IOException{ 1308 return raf.read(buf); 1309 } 1310 public int read(byte[] buf , int s, int len) throws java.io.IOException{ 1311 return raf.read(buf, s, len); 1312 } 1313 public long skip(long n) throws java.io.IOException{ 1314 return (long)(raf.skipBytes((int)n)); 1315 } 1316 public long getLength() throws java.io.IOException{ 1317 return raf.length(); 1318 } 1319 public long tell() throws java.io.IOException{ 1320 return raf.getFilePointer(); 1321 } 1322 public int available() throws java.io.IOException{ 1323 return (raf.length()==raf.getFilePointer())? 0 : 1; 1324 } 1325 public void close() throws java.io.IOException{ 1326 raf.close(); 1327 } 1328 public synchronized void mark(int m){ 1329 } 1330 public synchronized void reset() throws java.io.IOException{ 1331 } 1332 public boolean markSupported(){ 1333 return false; 1334 } 1335 public void seek(long pos) throws java.io.IOException{ 1336 raf.seek(pos); 1337 } 1338 } 1339 1340}