1/******************************************************************** 2 * * 3 * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * 4 * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * 5 * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * 6 * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * 7 * * 8 * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009 * 9 * by the Xiph.Org Foundation http://www.xiph.org/ * 10 * * 11 ******************************************************************** 12 13 function: stdio-based convenience library for opening/seeking/decoding 14 last mod: $Id: vorbisfile.c 16246 2009-07-10 03:19:29Z xiphmont $ 15 16 ********************************************************************/ 17 18#include <stdlib.h> 19#include <stdio.h> 20#include <errno.h> 21#include <string.h> 22#include <math.h> 23 24#include "vorbis/codec.h" 25 26/* we don't need or want the static callback symbols here */ 27#define OV_EXCLUDE_STATIC_CALLBACKS 28#include "vorbis/vorbisfile.h" 29 30#include "os.h" 31#include "misc.h" 32 33/* A 'chained bitstream' is a Vorbis bitstream that contains more than 34 one logical bitstream arranged end to end (the only form of Ogg 35 multiplexing allowed in a Vorbis bitstream; grouping [parallel 36 multiplexing] is not allowed in Vorbis) */ 37 38/* A Vorbis file can be played beginning to end (streamed) without 39 worrying ahead of time about chaining (see decoder_example.c). If 40 we have the whole file, however, and want random access 41 (seeking/scrubbing) or desire to know the total length/time of a 42 file, we need to account for the possibility of chaining. */ 43 44/* We can handle things a number of ways; we can determine the entire 45 bitstream structure right off the bat, or find pieces on demand. 46 This example determines and caches structure for the entire 47 bitstream, but builds a virtual decoder on the fly when moving 48 between links in the chain. */ 49 50/* There are also different ways to implement seeking. Enough 51 information exists in an Ogg bitstream to seek to 52 sample-granularity positions in the output. Or, one can seek by 53 picking some portion of the stream roughly in the desired area if 54 we only want coarse navigation through the stream. */ 55 56/************************************************************************* 57 * Many, many internal helpers. The intention is not to be confusing; 58 * rampant duplication and monolithic function implementation would be 59 * harder to understand anyway. The high level functions are last. Begin 60 * grokking near the end of the file */ 61 62/* read a little more data from the file/pipe into the ogg_sync framer 63*/ 64#define CHUNKSIZE 65536 65 66static long _get_data(OggVorbis_File *vf){ 67 errno=0; 68 if(!(vf->callbacks.read_func))return(-1); 69 if(vf->datasource){ 70 char *buffer=ogg_sync_buffer(&vf->oy,CHUNKSIZE); 71 long bytes=(vf->callbacks.read_func)(buffer,1,CHUNKSIZE,vf->datasource); 72 if(bytes>0)ogg_sync_wrote(&vf->oy,bytes); 73 if(bytes==0 && errno)return(-1); 74 return(bytes); 75 }else 76 return(0); 77} 78 79/* save a tiny smidge of verbosity to make the code more readable */ 80static int _seek_helper(OggVorbis_File *vf,ogg_int64_t offset){ 81 if(vf->datasource){ 82 if(!(vf->callbacks.seek_func)|| 83 (vf->callbacks.seek_func)(vf->datasource, offset, SEEK_SET) == -1) 84 return OV_EREAD; 85 vf->offset=offset; 86 ogg_sync_reset(&vf->oy); 87 }else{ 88 /* shouldn't happen unless someone writes a broken callback */ 89 return OV_EFAULT; 90 } 91 return 0; 92} 93 94/* The read/seek functions track absolute position within the stream */ 95 96/* from the head of the stream, get the next page. boundary specifies 97 if the function is allowed to fetch more data from the stream (and 98 how much) or only use internally buffered data. 99 100 boundary: -1) unbounded search 101 0) read no additional data; use cached only 102 n) search for a new page beginning for n bytes 103 104 return: <0) did not find a page (OV_FALSE, OV_EOF, OV_EREAD) 105 n) found a page at absolute offset n */ 106 107static ogg_int64_t _get_next_page(OggVorbis_File *vf,ogg_page *og, 108 ogg_int64_t boundary){ 109 if(boundary>0)boundary+=vf->offset; 110 while(1){ 111 long more; 112 113 if(boundary>0 && vf->offset>=boundary)return(OV_FALSE); 114 more=ogg_sync_pageseek(&vf->oy,og); 115 116 if(more<0){ 117 /* skipped n bytes */ 118 vf->offset-=more; 119 }else{ 120 if(more==0){ 121 /* send more paramedics */ 122 if(!boundary)return(OV_FALSE); 123 { 124 long ret=_get_data(vf); 125 if(ret==0)return(OV_EOF); 126 if(ret<0)return(OV_EREAD); 127 } 128 }else{ 129 /* got a page. Return the offset at the page beginning, 130 advance the internal offset past the page end */ 131 ogg_int64_t ret=vf->offset; 132 vf->offset+=more; 133 return(ret); 134 135 } 136 } 137 } 138} 139 140/* find the latest page beginning before the current stream cursor 141 position. Much dirtier than the above as Ogg doesn't have any 142 backward search linkage. no 'readp' as it will certainly have to 143 read. */ 144/* returns offset or OV_EREAD, OV_FAULT */ 145static ogg_int64_t _get_prev_page(OggVorbis_File *vf,ogg_page *og){ 146 ogg_int64_t begin=vf->offset; 147 ogg_int64_t end=begin; 148 ogg_int64_t ret; 149 ogg_int64_t offset=-1; 150 151 while(offset==-1){ 152 begin-=CHUNKSIZE; 153 if(begin<0) 154 begin=0; 155 156 ret=_seek_helper(vf,begin); 157 if(ret)return(ret); 158 159 while(vf->offset<end){ 160 memset(og,0,sizeof(*og)); 161 ret=_get_next_page(vf,og,end-vf->offset); 162 if(ret==OV_EREAD)return(OV_EREAD); 163 if(ret<0){ 164 break; 165 }else{ 166 offset=ret; 167 } 168 } 169 } 170 171 /* In a fully compliant, non-multiplexed stream, we'll still be 172 holding the last page. In multiplexed (or noncompliant streams), 173 we will probably have to re-read the last page we saw */ 174 if(og->header_len==0){ 175 ret=_seek_helper(vf,offset); 176 if(ret)return(ret); 177 178 ret=_get_next_page(vf,og,CHUNKSIZE); 179 if(ret<0) 180 /* this shouldn't be possible */ 181 return(OV_EFAULT); 182 } 183 184 return(offset); 185} 186 187static void _add_serialno(ogg_page *og,long **serialno_list, int *n){ 188 long s = ogg_page_serialno(og); 189 (*n)++; 190 191 if(*serialno_list){ 192 *serialno_list = _ogg_realloc(*serialno_list, sizeof(**serialno_list)*(*n)); 193 }else{ 194 *serialno_list = _ogg_malloc(sizeof(**serialno_list)); 195 } 196 197 (*serialno_list)[(*n)-1] = s; 198} 199 200/* returns nonzero if found */ 201static int _lookup_serialno(long s, long *serialno_list, int n){ 202 if(serialno_list){ 203 while(n--){ 204 if(*serialno_list == s) return 1; 205 serialno_list++; 206 } 207 } 208 return 0; 209} 210 211static int _lookup_page_serialno(ogg_page *og, long *serialno_list, int n){ 212 long s = ogg_page_serialno(og); 213 return _lookup_serialno(s,serialno_list,n); 214} 215 216/* performs the same search as _get_prev_page, but prefers pages of 217 the specified serial number. If a page of the specified serialno is 218 spotted during the seek-back-and-read-forward, it will return the 219 info of last page of the matching serial number instead of the very 220 last page. If no page of the specified serialno is seen, it will 221 return the info of last page and alter *serialno. */ 222static ogg_int64_t _get_prev_page_serial(OggVorbis_File *vf, 223 long *serial_list, int serial_n, 224 int *serialno, ogg_int64_t *granpos){ 225 ogg_page og; 226 ogg_int64_t begin=vf->offset; 227 ogg_int64_t end=begin; 228 ogg_int64_t ret; 229 230 ogg_int64_t prefoffset=-1; 231 ogg_int64_t offset=-1; 232 ogg_int64_t ret_serialno=-1; 233 ogg_int64_t ret_gran=-1; 234 235 while(offset==-1){ 236 begin-=CHUNKSIZE; 237 if(begin<0) 238 begin=0; 239 240 ret=_seek_helper(vf,begin); 241 if(ret)return(ret); 242 243 while(vf->offset<end){ 244 ret=_get_next_page(vf,&og,end-vf->offset); 245 if(ret==OV_EREAD)return(OV_EREAD); 246 if(ret<0){ 247 break; 248 }else{ 249 ret_serialno=ogg_page_serialno(&og); 250 ret_gran=ogg_page_granulepos(&og); 251 offset=ret; 252 253 if(ret_serialno == *serialno){ 254 prefoffset=ret; 255 *granpos=ret_gran; 256 } 257 258 if(!_lookup_serialno(ret_serialno,serial_list,serial_n)){ 259 /* we fell off the end of the link, which means we seeked 260 back too far and shouldn't have been looking in that link 261 to begin with. If we found the preferred serial number, 262 forget that we saw it. */ 263 prefoffset=-1; 264 } 265 } 266 } 267 } 268 269 /* we're not interested in the page... just the serialno and granpos. */ 270 if(prefoffset>=0)return(prefoffset); 271 272 *serialno = ret_serialno; 273 *granpos = ret_gran; 274 return(offset); 275 276} 277 278/* uses the local ogg_stream storage in vf; this is important for 279 non-streaming input sources */ 280static int _fetch_headers(OggVorbis_File *vf,vorbis_info *vi,vorbis_comment *vc, 281 long **serialno_list, int *serialno_n, 282 ogg_page *og_ptr){ 283 ogg_page og; 284 ogg_packet op; 285 int i,ret; 286 int allbos=0; 287 288 if(!og_ptr){ 289 ogg_int64_t llret=_get_next_page(vf,&og,CHUNKSIZE); 290 if(llret==OV_EREAD)return(OV_EREAD); 291 if(llret<0)return(OV_ENOTVORBIS); 292 og_ptr=&og; 293 } 294 295 vorbis_info_init(vi); 296 vorbis_comment_init(vc); 297 vf->ready_state=OPENED; 298 299 /* extract the serialnos of all BOS pages + the first set of vorbis 300 headers we see in the link */ 301 302 while(ogg_page_bos(og_ptr)){ 303 if(serialno_list){ 304 if(_lookup_page_serialno(og_ptr,*serialno_list,*serialno_n)){ 305 /* a dupe serialnumber in an initial header packet set == invalid stream */ 306 if(*serialno_list)_ogg_free(*serialno_list); 307 *serialno_list=0; 308 *serialno_n=0; 309 ret=OV_EBADHEADER; 310 goto bail_header; 311 } 312 313 _add_serialno(og_ptr,serialno_list,serialno_n); 314 } 315 316 if(vf->ready_state<STREAMSET){ 317 /* we don't have a vorbis stream in this link yet, so begin 318 prospective stream setup. We need a stream to get packets */ 319 ogg_stream_reset_serialno(&vf->os,ogg_page_serialno(og_ptr)); 320 ogg_stream_pagein(&vf->os,og_ptr); 321 322 if(ogg_stream_packetout(&vf->os,&op) > 0 && 323 vorbis_synthesis_idheader(&op)){ 324 /* vorbis header; continue setup */ 325 vf->ready_state=STREAMSET; 326 if((ret=vorbis_synthesis_headerin(vi,vc,&op))){ 327 ret=OV_EBADHEADER; 328 goto bail_header; 329 } 330 } 331 } 332 333 /* get next page */ 334 { 335 ogg_int64_t llret=_get_next_page(vf,og_ptr,CHUNKSIZE); 336 if(llret==OV_EREAD){ 337 ret=OV_EREAD; 338 goto bail_header; 339 } 340 if(llret<0){ 341 ret=OV_ENOTVORBIS; 342 goto bail_header; 343 } 344 345 /* if this page also belongs to our vorbis stream, submit it and break */ 346 if(vf->ready_state==STREAMSET && 347 vf->os.serialno == ogg_page_serialno(og_ptr)){ 348 ogg_stream_pagein(&vf->os,og_ptr); 349 break; 350 } 351 } 352 } 353 354 if(vf->ready_state!=STREAMSET){ 355 ret = OV_ENOTVORBIS; 356 goto bail_header; 357 } 358 359 while(1){ 360 361 i=0; 362 while(i<2){ /* get a page loop */ 363 364 while(i<2){ /* get a packet loop */ 365 366 int result=ogg_stream_packetout(&vf->os,&op); 367 if(result==0)break; 368 if(result==-1){ 369 ret=OV_EBADHEADER; 370 goto bail_header; 371 } 372 373 if((ret=vorbis_synthesis_headerin(vi,vc,&op))) 374 goto bail_header; 375 376 i++; 377 } 378 379 while(i<2){ 380 if(_get_next_page(vf,og_ptr,CHUNKSIZE)<0){ 381 ret=OV_EBADHEADER; 382 goto bail_header; 383 } 384 385 /* if this page belongs to the correct stream, go parse it */ 386 if(vf->os.serialno == ogg_page_serialno(og_ptr)){ 387 ogg_stream_pagein(&vf->os,og_ptr); 388 break; 389 } 390 391 /* if we never see the final vorbis headers before the link 392 ends, abort */ 393 if(ogg_page_bos(og_ptr)){ 394 if(allbos){ 395 ret = OV_EBADHEADER; 396 goto bail_header; 397 }else 398 allbos=1; 399 } 400 401 /* otherwise, keep looking */ 402 } 403 } 404 405 return 0; 406 } 407 408 bail_header: 409 vorbis_info_clear(vi); 410 vorbis_comment_clear(vc); 411 vf->ready_state=OPENED; 412 413 return ret; 414} 415 416/* Starting from current cursor position, get initial PCM offset of 417 next page. Consumes the page in the process without decoding 418 audio, however this is only called during stream parsing upon 419 seekable open. */ 420static ogg_int64_t _initial_pcmoffset(OggVorbis_File *vf, vorbis_info *vi){ 421 ogg_page og; 422 ogg_int64_t accumulated=0; 423 long lastblock=-1; 424 int result; 425 int serialno = vf->os.serialno; 426 427 while(1){ 428 ogg_packet op; 429 if(_get_next_page(vf,&og,-1)<0) 430 break; /* should not be possible unless the file is truncated/mangled */ 431 432 if(ogg_page_bos(&og)) break; 433 if(ogg_page_serialno(&og)!=serialno) continue; 434 435 /* count blocksizes of all frames in the page */ 436 ogg_stream_pagein(&vf->os,&og); 437 while((result=ogg_stream_packetout(&vf->os,&op))){ 438 if(result>0){ /* ignore holes */ 439 long thisblock=vorbis_packet_blocksize(vi,&op); 440 if(lastblock!=-1) 441 accumulated+=(lastblock+thisblock)>>2; 442 lastblock=thisblock; 443 } 444 } 445 446 if(ogg_page_granulepos(&og)!=-1){ 447 /* pcm offset of last packet on the first audio page */ 448 accumulated= ogg_page_granulepos(&og)-accumulated; 449 break; 450 } 451 } 452 453 /* less than zero? This is a stream with samples trimmed off 454 the beginning, a normal occurrence; set the offset to zero */ 455 if(accumulated<0)accumulated=0; 456 457 return accumulated; 458} 459 460/* finds each bitstream link one at a time using a bisection search 461 (has to begin by knowing the offset of the lb's initial page). 462 Recurses for each link so it can alloc the link storage after 463 finding them all, then unroll and fill the cache at the same time */ 464static int _bisect_forward_serialno(OggVorbis_File *vf, 465 ogg_int64_t begin, 466 ogg_int64_t searched, 467 ogg_int64_t end, 468 ogg_int64_t endgran, 469 int endserial, 470 long *currentno_list, 471 int currentnos, 472 long m){ 473 ogg_int64_t pcmoffset; 474 ogg_int64_t dataoffset=searched; 475 ogg_int64_t endsearched=end; 476 ogg_int64_t next=end; 477 ogg_int64_t searchgran=-1; 478 ogg_page og; 479 ogg_int64_t ret,last; 480 int serialno = vf->os.serialno; 481 482 /* invariants: 483 we have the headers and serialnos for the link beginning at 'begin' 484 we have the offset and granpos of the last page in the file (potentially 485 not a page we care about) 486 */ 487 488 /* Is the last page in our list of current serialnumbers? */ 489 if(_lookup_serialno(endserial,currentno_list,currentnos)){ 490 491 /* last page is in the starting serialno list, so we've bisected 492 down to (or just started with) a single link. Now we need to 493 find the last vorbis page belonging to the first vorbis stream 494 for this link. */ 495 496 while(endserial != serialno){ 497 endserial = serialno; 498 vf->offset=_get_prev_page_serial(vf,currentno_list,currentnos,&endserial,&endgran); 499 } 500 501 vf->links=m+1; 502 if(vf->offsets)_ogg_free(vf->offsets); 503 if(vf->serialnos)_ogg_free(vf->serialnos); 504 if(vf->dataoffsets)_ogg_free(vf->dataoffsets); 505 506 vf->offsets=_ogg_malloc((vf->links+1)*sizeof(*vf->offsets)); 507 vf->vi=_ogg_realloc(vf->vi,vf->links*sizeof(*vf->vi)); 508 vf->vc=_ogg_realloc(vf->vc,vf->links*sizeof(*vf->vc)); 509 vf->serialnos=_ogg_malloc(vf->links*sizeof(*vf->serialnos)); 510 vf->dataoffsets=_ogg_malloc(vf->links*sizeof(*vf->dataoffsets)); 511 vf->pcmlengths=_ogg_malloc(vf->links*2*sizeof(*vf->pcmlengths)); 512 513 vf->offsets[m+1]=end; 514 vf->offsets[m]=begin; 515 vf->pcmlengths[m*2+1]=endgran; 516 517 }else{ 518 519 long *next_serialno_list=NULL; 520 int next_serialnos=0; 521 vorbis_info vi; 522 vorbis_comment vc; 523 524 /* the below guards against garbage seperating the last and 525 first pages of two links. */ 526 while(searched<endsearched){ 527 ogg_int64_t bisect; 528 529 if(endsearched-searched<CHUNKSIZE){ 530 bisect=searched; 531 }else{ 532 bisect=(searched+endsearched)/2; 533 } 534 535 ret=_seek_helper(vf,bisect); 536 if(ret)return(ret); 537 538 last=_get_next_page(vf,&og,-1); 539 if(last==OV_EREAD)return(OV_EREAD); 540 if(last<0 || !_lookup_page_serialno(&og,currentno_list,currentnos)){ 541 endsearched=bisect; 542 if(last>=0)next=last; 543 }else{ 544 searched=last+og.header_len+og.body_len; 545 } 546 } 547 548 /* Bisection point found */ 549 550 /* for the time being, fetch end PCM offset the simple way */ 551 { 552 int testserial = serialno+1; 553 vf->offset = next; 554 while(testserial != serialno){ 555 testserial = serialno; 556 vf->offset=_get_prev_page_serial(vf,currentno_list,currentnos,&testserial,&searchgran); 557 } 558 } 559 560 if(vf->offset!=next){ 561 ret=_seek_helper(vf,next); 562 if(ret)return(ret); 563 } 564 565 ret=_fetch_headers(vf,&vi,&vc,&next_serialno_list,&next_serialnos,NULL); 566 if(ret)return(ret); 567 serialno = vf->os.serialno; 568 dataoffset = vf->offset; 569 570 /* this will consume a page, however the next bistection always 571 starts with a raw seek */ 572 pcmoffset = _initial_pcmoffset(vf,&vi); 573 574 ret=_bisect_forward_serialno(vf,next,vf->offset,end,endgran,endserial, 575 next_serialno_list,next_serialnos,m+1); 576 if(ret)return(ret); 577 578 if(next_serialno_list)_ogg_free(next_serialno_list); 579 580 vf->offsets[m+1]=next; 581 vf->serialnos[m+1]=serialno; 582 vf->dataoffsets[m+1]=dataoffset; 583 584 vf->vi[m+1]=vi; 585 vf->vc[m+1]=vc; 586 587 vf->pcmlengths[m*2+1]=searchgran; 588 vf->pcmlengths[m*2+2]=pcmoffset; 589 vf->pcmlengths[m*2+3]-=pcmoffset; 590 591 } 592 return(0); 593} 594 595static int _make_decode_ready(OggVorbis_File *vf){ 596 if(vf->ready_state>STREAMSET)return 0; 597 if(vf->ready_state<STREAMSET)return OV_EFAULT; 598 if(vf->seekable){ 599 if(vorbis_synthesis_init(&vf->vd,vf->vi+vf->current_link)) 600 return OV_EBADLINK; 601 }else{ 602 if(vorbis_synthesis_init(&vf->vd,vf->vi)) 603 return OV_EBADLINK; 604 } 605 vorbis_block_init(&vf->vd,&vf->vb); 606 vf->ready_state=INITSET; 607 vf->bittrack=0.f; 608 vf->samptrack=0.f; 609 return 0; 610} 611 612static int _open_seekable2(OggVorbis_File *vf){ 613 ogg_int64_t dataoffset=vf->dataoffsets[0],end,endgran=-1; 614 int endserial=vf->os.serialno; 615 int serialno=vf->os.serialno; 616 617 /* we're partially open and have a first link header state in 618 storage in vf */ 619 620 /* fetch initial PCM offset */ 621 ogg_int64_t pcmoffset = _initial_pcmoffset(vf,vf->vi); 622 623 /* we can seek, so set out learning all about this file */ 624 if(vf->callbacks.seek_func && vf->callbacks.tell_func){ 625 (vf->callbacks.seek_func)(vf->datasource,0,SEEK_END); 626 vf->offset=vf->end=(vf->callbacks.tell_func)(vf->datasource); 627 }else{ 628 vf->offset=vf->end=-1; 629 } 630 631 /* If seek_func is implemented, tell_func must also be implemented */ 632 if(vf->end==-1) return(OV_EINVAL); 633 634 /* Get the offset of the last page of the physical bitstream, or, if 635 we're lucky the last vorbis page of this link as most OggVorbis 636 files will contain a single logical bitstream */ 637 end=_get_prev_page_serial(vf,vf->serialnos+2,vf->serialnos[1],&endserial,&endgran); 638 if(end<0)return(end); 639 640 /* now determine bitstream structure recursively */ 641 if(_bisect_forward_serialno(vf,0,dataoffset,vf->offset,endgran,endserial, 642 vf->serialnos+2,vf->serialnos[1],0)<0)return(OV_EREAD); 643 644 vf->offsets[0]=0; 645 vf->serialnos[0]=serialno; 646 vf->dataoffsets[0]=dataoffset; 647 vf->pcmlengths[0]=pcmoffset; 648 vf->pcmlengths[1]-=pcmoffset; 649 650 return(ov_raw_seek(vf,dataoffset)); 651} 652 653/* clear out the current logical bitstream decoder */ 654static void _decode_clear(OggVorbis_File *vf){ 655 vorbis_dsp_clear(&vf->vd); 656 vorbis_block_clear(&vf->vb); 657 vf->ready_state=OPENED; 658} 659 660/* fetch and process a packet. Handles the case where we're at a 661 bitstream boundary and dumps the decoding machine. If the decoding 662 machine is unloaded, it loads it. It also keeps pcm_offset up to 663 date (seek and read both use this. seek uses a special hack with 664 readp). 665 666 return: <0) error, OV_HOLE (lost packet) or OV_EOF 667 0) need more data (only if readp==0) 668 1) got a packet 669*/ 670 671static int _fetch_and_process_packet(OggVorbis_File *vf, 672 ogg_packet *op_in, 673 int readp, 674 int spanp){ 675 ogg_page og; 676 677 /* handle one packet. Try to fetch it from current stream state */ 678 /* extract packets from page */ 679 while(1){ 680 681 if(vf->ready_state==STREAMSET){ 682 int ret=_make_decode_ready(vf); 683 if(ret<0)return ret; 684 } 685 686 /* process a packet if we can. */ 687 688 if(vf->ready_state==INITSET){ 689 while(1) { 690 ogg_packet op; 691 ogg_packet *op_ptr=(op_in?op_in:&op); 692 int result=ogg_stream_packetout(&vf->os,op_ptr); 693 ogg_int64_t granulepos; 694 695 op_in=NULL; 696 if(result==-1)return(OV_HOLE); /* hole in the data. */ 697 if(result>0){ 698 /* got a packet. process it */ 699 granulepos=op_ptr->granulepos; 700 if(!vorbis_synthesis(&vf->vb,op_ptr)){ /* lazy check for lazy 701 header handling. The 702 header packets aren't 703 audio, so if/when we 704 submit them, 705 vorbis_synthesis will 706 reject them */ 707 708 /* suck in the synthesis data and track bitrate */ 709 { 710 int oldsamples=vorbis_synthesis_pcmout(&vf->vd,NULL); 711 /* for proper use of libvorbis within libvorbisfile, 712 oldsamples will always be zero. */ 713 if(oldsamples)return(OV_EFAULT); 714 715 vorbis_synthesis_blockin(&vf->vd,&vf->vb); 716 vf->samptrack+=vorbis_synthesis_pcmout(&vf->vd,NULL)-oldsamples; 717 vf->bittrack+=op_ptr->bytes*8; 718 } 719 720 /* update the pcm offset. */ 721 if(granulepos!=-1 && !op_ptr->e_o_s){ 722 int link=(vf->seekable?vf->current_link:0); 723 int i,samples; 724 725 /* this packet has a pcm_offset on it (the last packet 726 completed on a page carries the offset) After processing 727 (above), we know the pcm position of the *last* sample 728 ready to be returned. Find the offset of the *first* 729 730 As an aside, this trick is inaccurate if we begin 731 reading anew right at the last page; the end-of-stream 732 granulepos declares the last frame in the stream, and the 733 last packet of the last page may be a partial frame. 734 So, we need a previous granulepos from an in-sequence page 735 to have a reference point. Thus the !op_ptr->e_o_s clause 736 above */ 737 738 if(vf->seekable && link>0) 739 granulepos-=vf->pcmlengths[link*2]; 740 if(granulepos<0)granulepos=0; /* actually, this 741 shouldn't be possible 742 here unless the stream 743 is very broken */ 744 745 samples=vorbis_synthesis_pcmout(&vf->vd,NULL); 746 747 granulepos-=samples; 748 for(i=0;i<link;i++) 749 granulepos+=vf->pcmlengths[i*2+1]; 750 vf->pcm_offset=granulepos; 751 } 752 return(1); 753 } 754 } 755 else 756 break; 757 } 758 } 759 760 if(vf->ready_state>=OPENED){ 761 ogg_int64_t ret; 762 763 while(1){ 764 /* the loop is not strictly necessary, but there's no sense in 765 doing the extra checks of the larger loop for the common 766 case in a multiplexed bistream where the page is simply 767 part of a different logical bitstream; keep reading until 768 we get one with the correct serialno */ 769 770 if(!readp)return(0); 771 if((ret=_get_next_page(vf,&og,-1))<0){ 772 return(OV_EOF); /* eof. leave unitialized */ 773 } 774 775 /* bitrate tracking; add the header's bytes here, the body bytes 776 are done by packet above */ 777 vf->bittrack+=og.header_len*8; 778 779 if(vf->ready_state==INITSET){ 780 if(vf->current_serialno!=ogg_page_serialno(&og)){ 781 782 /* two possibilities: 783 1) our decoding just traversed a bitstream boundary 784 2) another stream is multiplexed into this logical section */ 785 786 if(ogg_page_bos(&og)){ 787 /* boundary case */ 788 if(!spanp) 789 return(OV_EOF); 790 791 _decode_clear(vf); 792 793 if(!vf->seekable){ 794 vorbis_info_clear(vf->vi); 795 vorbis_comment_clear(vf->vc); 796 } 797 break; 798 799 }else 800 continue; /* possibility #2 */ 801 } 802 } 803 804 break; 805 } 806 } 807 808 /* Do we need to load a new machine before submitting the page? */ 809 /* This is different in the seekable and non-seekable cases. 810 811 In the seekable case, we already have all the header 812 information loaded and cached; we just initialize the machine 813 with it and continue on our merry way. 814 815 In the non-seekable (streaming) case, we'll only be at a 816 boundary if we just left the previous logical bitstream and 817 we're now nominally at the header of the next bitstream 818 */ 819 820 if(vf->ready_state!=INITSET){ 821 int link; 822 823 if(vf->ready_state<STREAMSET){ 824 if(vf->seekable){ 825 long serialno = ogg_page_serialno(&og); 826 827 /* match the serialno to bitstream section. We use this rather than 828 offset positions to avoid problems near logical bitstream 829 boundaries */ 830 831 for(link=0;link<vf->links;link++) 832 if(vf->serialnos[link]==serialno)break; 833 834 if(link==vf->links) continue; /* not the desired Vorbis 835 bitstream section; keep 836 trying */ 837 838 vf->current_serialno=serialno; 839 vf->current_link=link; 840 841 ogg_stream_reset_serialno(&vf->os,vf->current_serialno); 842 vf->ready_state=STREAMSET; 843 844 }else{ 845 /* we're streaming */ 846 /* fetch the three header packets, build the info struct */ 847 848 int ret=_fetch_headers(vf,vf->vi,vf->vc,NULL,NULL,&og); 849 if(ret)return(ret); 850 vf->current_serialno=vf->os.serialno; 851 vf->current_link++; 852 link=0; 853 } 854 } 855 } 856 857 /* the buffered page is the data we want, and we're ready for it; 858 add it to the stream state */ 859 ogg_stream_pagein(&vf->os,&og); 860 861 } 862} 863 864/* if, eg, 64 bit stdio is configured by default, this will build with 865 fseek64 */ 866static int _fseek64_wrap(FILE *f,ogg_int64_t off,int whence){ 867 if(f==NULL)return(-1); 868 return fseek(f,off,whence); 869} 870 871static int _ov_open1(void *f,OggVorbis_File *vf,char *initial, 872 long ibytes, ov_callbacks callbacks){ 873 int offsettest=((f && callbacks.seek_func)?callbacks.seek_func(f,0,SEEK_CUR):-1); 874 long *serialno_list=NULL; 875 int serialno_list_size=0; 876 int ret; 877 878 memset(vf,0,sizeof(*vf)); 879 vf->datasource=f; 880 vf->callbacks = callbacks; 881 882 /* init the framing state */ 883 ogg_sync_init(&vf->oy); 884 885 /* perhaps some data was previously read into a buffer for testing 886 against other stream types. Allow initialization from this 887 previously read data (especially as we may be reading from a 888 non-seekable stream) */ 889 if(initial){ 890 char *buffer=ogg_sync_buffer(&vf->oy,ibytes); 891 memcpy(buffer,initial,ibytes); 892 ogg_sync_wrote(&vf->oy,ibytes); 893 } 894 895 /* can we seek? Stevens suggests the seek test was portable */ 896 if(offsettest!=-1)vf->seekable=1; 897 898 /* No seeking yet; Set up a 'single' (current) logical bitstream 899 entry for partial open */ 900 vf->links=1; 901 vf->vi=_ogg_calloc(vf->links,sizeof(*vf->vi)); 902 vf->vc=_ogg_calloc(vf->links,sizeof(*vf->vc)); 903 ogg_stream_init(&vf->os,-1); /* fill in the serialno later */ 904 905 /* Fetch all BOS pages, store the vorbis header and all seen serial 906 numbers, load subsequent vorbis setup headers */ 907 if((ret=_fetch_headers(vf,vf->vi,vf->vc,&serialno_list,&serialno_list_size,NULL))<0){ 908 vf->datasource=NULL; 909 ov_clear(vf); 910 }else{ 911 /* serial number list for first link needs to be held somewhere 912 for second stage of seekable stream open; this saves having to 913 seek/reread first link's serialnumber data then. */ 914 vf->serialnos=_ogg_calloc(serialno_list_size+2,sizeof(*vf->serialnos)); 915 vf->serialnos[0]=vf->current_serialno; 916 vf->serialnos[1]=serialno_list_size; 917 memcpy(vf->serialnos+2,serialno_list,serialno_list_size*sizeof(*vf->serialnos)); 918 919 vf->offsets=_ogg_calloc(1,sizeof(*vf->offsets)); 920 vf->dataoffsets=_ogg_calloc(1,sizeof(*vf->dataoffsets)); 921 vf->offsets[0]=0; 922 vf->dataoffsets[0]=vf->offset; 923 vf->current_serialno=vf->os.serialno; 924 925 vf->ready_state=PARTOPEN; 926 } 927 if(serialno_list)_ogg_free(serialno_list); 928 return(ret); 929} 930 931static int _ov_open2(OggVorbis_File *vf){ 932 if(vf->ready_state != PARTOPEN) return OV_EINVAL; 933 vf->ready_state=OPENED; 934 if(vf->seekable){ 935 int ret=_open_seekable2(vf); 936 if(ret){ 937 vf->datasource=NULL; 938 ov_clear(vf); 939 } 940 return(ret); 941 }else 942 vf->ready_state=STREAMSET; 943 944 return 0; 945} 946 947 948/* clear out the OggVorbis_File struct */ 949int ov_clear(OggVorbis_File *vf){ 950 if(vf){ 951 vorbis_block_clear(&vf->vb); 952 vorbis_dsp_clear(&vf->vd); 953 ogg_stream_clear(&vf->os); 954 955 if(vf->vi && vf->links){ 956 int i; 957 for(i=0;i<vf->links;i++){ 958 vorbis_info_clear(vf->vi+i); 959 vorbis_comment_clear(vf->vc+i); 960 } 961 _ogg_free(vf->vi); 962 _ogg_free(vf->vc); 963 } 964 if(vf->dataoffsets)_ogg_free(vf->dataoffsets); 965 if(vf->pcmlengths)_ogg_free(vf->pcmlengths); 966 if(vf->serialnos)_ogg_free(vf->serialnos); 967 if(vf->offsets)_ogg_free(vf->offsets); 968 ogg_sync_clear(&vf->oy); 969 if(vf->datasource && vf->callbacks.close_func) 970 (vf->callbacks.close_func)(vf->datasource); 971 memset(vf,0,sizeof(*vf)); 972 } 973#ifdef DEBUG_LEAKS 974 _VDBG_dump(); 975#endif 976 return(0); 977} 978 979/* inspects the OggVorbis file and finds/documents all the logical 980 bitstreams contained in it. Tries to be tolerant of logical 981 bitstream sections that are truncated/woogie. 982 983 return: -1) error 984 0) OK 985*/ 986 987int ov_open_callbacks(void *f,OggVorbis_File *vf,char *initial,long ibytes, 988 ov_callbacks callbacks){ 989 int ret=_ov_open1(f,vf,initial,ibytes,callbacks); 990 if(ret)return ret; 991 return _ov_open2(vf); 992} 993 994int ov_open(FILE *f,OggVorbis_File *vf,char *initial,long ibytes){ 995 ov_callbacks callbacks = { 996 (size_t (*)(void *, size_t, size_t, void *)) fread, 997 (int (*)(void *, ogg_int64_t, int)) _fseek64_wrap, 998 (int (*)(void *)) fclose, 999 (long (*)(void *)) ftell 1000 }; 1001 1002 return ov_open_callbacks((void *)f, vf, initial, ibytes, callbacks); 1003} 1004 1005int ov_fopen(char *path,OggVorbis_File *vf){ 1006 int ret; 1007 FILE *f = fopen(path,"rb"); 1008 if(!f) return -1; 1009 1010 ret = ov_open(f,vf,NULL,0); 1011 if(ret) fclose(f); 1012 return ret; 1013} 1014 1015 1016/* cheap hack for game usage where downsampling is desirable; there's 1017 no need for SRC as we can just do it cheaply in libvorbis. */ 1018 1019int ov_halfrate(OggVorbis_File *vf,int flag){ 1020 int i; 1021 if(vf->vi==NULL)return OV_EINVAL; 1022 if(!vf->seekable)return OV_EINVAL; 1023 if(vf->ready_state>=STREAMSET) 1024 _decode_clear(vf); /* clear out stream state; later on libvorbis 1025 will be able to swap this on the fly, but 1026 for now dumping the decode machine is needed 1027 to reinit the MDCT lookups. 1.1 libvorbis 1028 is planned to be able to switch on the fly */ 1029 1030 for(i=0;i<vf->links;i++){ 1031 if(vorbis_synthesis_halfrate(vf->vi+i,flag)){ 1032 ov_halfrate(vf,0); 1033 return OV_EINVAL; 1034 } 1035 } 1036 return 0; 1037} 1038 1039int ov_halfrate_p(OggVorbis_File *vf){ 1040 if(vf->vi==NULL)return OV_EINVAL; 1041 return vorbis_synthesis_halfrate_p(vf->vi); 1042} 1043 1044/* Only partially open the vorbis file; test for Vorbisness, and load 1045 the headers for the first chain. Do not seek (although test for 1046 seekability). Use ov_test_open to finish opening the file, else 1047 ov_clear to close/free it. Same return codes as open. */ 1048 1049int ov_test_callbacks(void *f,OggVorbis_File *vf,char *initial,long ibytes, 1050 ov_callbacks callbacks) 1051{ 1052 return _ov_open1(f,vf,initial,ibytes,callbacks); 1053} 1054 1055int ov_test(FILE *f,OggVorbis_File *vf,char *initial,long ibytes){ 1056 ov_callbacks callbacks = { 1057 (size_t (*)(void *, size_t, size_t, void *)) fread, 1058 (int (*)(void *, ogg_int64_t, int)) _fseek64_wrap, 1059 (int (*)(void *)) fclose, 1060 (long (*)(void *)) ftell 1061 }; 1062 1063 return ov_test_callbacks((void *)f, vf, initial, ibytes, callbacks); 1064} 1065 1066int ov_test_open(OggVorbis_File *vf){ 1067 if(vf->ready_state!=PARTOPEN)return(OV_EINVAL); 1068 return _ov_open2(vf); 1069} 1070 1071/* How many logical bitstreams in this physical bitstream? */ 1072long ov_streams(OggVorbis_File *vf){ 1073 return vf->links; 1074} 1075 1076/* Is the FILE * associated with vf seekable? */ 1077long ov_seekable(OggVorbis_File *vf){ 1078 return vf->seekable; 1079} 1080 1081/* returns the bitrate for a given logical bitstream or the entire 1082 physical bitstream. If the file is open for random access, it will 1083 find the *actual* average bitrate. If the file is streaming, it 1084 returns the nominal bitrate (if set) else the average of the 1085 upper/lower bounds (if set) else -1 (unset). 1086 1087 If you want the actual bitrate field settings, get them from the 1088 vorbis_info structs */ 1089 1090long ov_bitrate(OggVorbis_File *vf,int i){ 1091 if(vf->ready_state<OPENED)return(OV_EINVAL); 1092 if(i>=vf->links)return(OV_EINVAL); 1093 if(!vf->seekable && i!=0)return(ov_bitrate(vf,0)); 1094 if(i<0){ 1095 ogg_int64_t bits=0; 1096 int i; 1097 float br; 1098 for(i=0;i<vf->links;i++) 1099 bits+=(vf->offsets[i+1]-vf->dataoffsets[i])*8; 1100 /* This once read: return(rint(bits/ov_time_total(vf,-1))); 1101 * gcc 3.x on x86 miscompiled this at optimisation level 2 and above, 1102 * so this is slightly transformed to make it work. 1103 */ 1104 br = bits/ov_time_total(vf,-1); 1105 return(rint(br)); 1106 }else{ 1107 if(vf->seekable){ 1108 /* return the actual bitrate */ 1109 return(rint((vf->offsets[i+1]-vf->dataoffsets[i])*8/ov_time_total(vf,i))); 1110 }else{ 1111 /* return nominal if set */ 1112 if(vf->vi[i].bitrate_nominal>0){ 1113 return vf->vi[i].bitrate_nominal; 1114 }else{ 1115 if(vf->vi[i].bitrate_upper>0){ 1116 if(vf->vi[i].bitrate_lower>0){ 1117 return (vf->vi[i].bitrate_upper+vf->vi[i].bitrate_lower)/2; 1118 }else{ 1119 return vf->vi[i].bitrate_upper; 1120 } 1121 } 1122 return(OV_FALSE); 1123 } 1124 } 1125 } 1126} 1127 1128/* returns the actual bitrate since last call. returns -1 if no 1129 additional data to offer since last call (or at beginning of stream), 1130 EINVAL if stream is only partially open 1131*/ 1132long ov_bitrate_instant(OggVorbis_File *vf){ 1133 int link=(vf->seekable?vf->current_link:0); 1134 long ret; 1135 if(vf->ready_state<OPENED)return(OV_EINVAL); 1136 if(vf->samptrack==0)return(OV_FALSE); 1137 ret=vf->bittrack/vf->samptrack*vf->vi[link].rate+.5; 1138 vf->bittrack=0.f; 1139 vf->samptrack=0.f; 1140 return(ret); 1141} 1142 1143/* Guess */ 1144long ov_serialnumber(OggVorbis_File *vf,int i){ 1145 if(i>=vf->links)return(ov_serialnumber(vf,vf->links-1)); 1146 if(!vf->seekable && i>=0)return(ov_serialnumber(vf,-1)); 1147 if(i<0){ 1148 return(vf->current_serialno); 1149 }else{ 1150 return(vf->serialnos[i]); 1151 } 1152} 1153 1154/* returns: total raw (compressed) length of content if i==-1 1155 raw (compressed) length of that logical bitstream for i==0 to n 1156 OV_EINVAL if the stream is not seekable (we can't know the length) 1157 or if stream is only partially open 1158*/ 1159ogg_int64_t ov_raw_total(OggVorbis_File *vf,int i){ 1160 if(vf->ready_state<OPENED)return(OV_EINVAL); 1161 if(!vf->seekable || i>=vf->links)return(OV_EINVAL); 1162 if(i<0){ 1163 ogg_int64_t acc=0; 1164 int i; 1165 for(i=0;i<vf->links;i++) 1166 acc+=ov_raw_total(vf,i); 1167 return(acc); 1168 }else{ 1169 return(vf->offsets[i+1]-vf->offsets[i]); 1170 } 1171} 1172 1173/* returns: total PCM length (samples) of content if i==-1 PCM length 1174 (samples) of that logical bitstream for i==0 to n 1175 OV_EINVAL if the stream is not seekable (we can't know the 1176 length) or only partially open 1177*/ 1178ogg_int64_t ov_pcm_total(OggVorbis_File *vf,int i){ 1179 if(vf->ready_state<OPENED)return(OV_EINVAL); 1180 if(!vf->seekable || i>=vf->links)return(OV_EINVAL); 1181 if(i<0){ 1182 ogg_int64_t acc=0; 1183 int i; 1184 for(i=0;i<vf->links;i++) 1185 acc+=ov_pcm_total(vf,i); 1186 return(acc); 1187 }else{ 1188 return(vf->pcmlengths[i*2+1]); 1189 } 1190} 1191 1192/* returns: total seconds of content if i==-1 1193 seconds in that logical bitstream for i==0 to n 1194 OV_EINVAL if the stream is not seekable (we can't know the 1195 length) or only partially open 1196*/ 1197double ov_time_total(OggVorbis_File *vf,int i){ 1198 if(vf->ready_state<OPENED)return(OV_EINVAL); 1199 if(!vf->seekable || i>=vf->links)return(OV_EINVAL); 1200 if(i<0){ 1201 double acc=0; 1202 int i; 1203 for(i=0;i<vf->links;i++) 1204 acc+=ov_time_total(vf,i); 1205 return(acc); 1206 }else{ 1207 return((double)(vf->pcmlengths[i*2+1])/vf->vi[i].rate); 1208 } 1209} 1210 1211/* seek to an offset relative to the *compressed* data. This also 1212 scans packets to update the PCM cursor. It will cross a logical 1213 bitstream boundary, but only if it can't get any packets out of the 1214 tail of the bitstream we seek to (so no surprises). 1215 1216 returns zero on success, nonzero on failure */ 1217 1218int ov_raw_seek(OggVorbis_File *vf,ogg_int64_t pos){ 1219 ogg_stream_state work_os; 1220 int ret; 1221 1222 if(vf->ready_state<OPENED)return(OV_EINVAL); 1223 if(!vf->seekable) 1224 return(OV_ENOSEEK); /* don't dump machine if we can't seek */ 1225 1226 if(pos<0 || pos>vf->end)return(OV_EINVAL); 1227 1228 /* don't yet clear out decoding machine (if it's initialized), in 1229 the case we're in the same link. Restart the decode lapping, and 1230 let _fetch_and_process_packet deal with a potential bitstream 1231 boundary */ 1232 vf->pcm_offset=-1; 1233 ogg_stream_reset_serialno(&vf->os, 1234 vf->current_serialno); /* must set serialno */ 1235 vorbis_synthesis_restart(&vf->vd); 1236 1237 ret=_seek_helper(vf,pos); 1238 if(ret)goto seek_error; 1239 1240 /* we need to make sure the pcm_offset is set, but we don't want to 1241 advance the raw cursor past good packets just to get to the first 1242 with a granulepos. That's not equivalent behavior to beginning 1243 decoding as immediately after the seek position as possible. 1244 1245 So, a hack. We use two stream states; a local scratch state and 1246 the shared vf->os stream state. We use the local state to 1247 scan, and the shared state as a buffer for later decode. 1248 1249 Unfortuantely, on the last page we still advance to last packet 1250 because the granulepos on the last page is not necessarily on a 1251 packet boundary, and we need to make sure the granpos is 1252 correct. 1253 */ 1254 1255 { 1256 ogg_page og; 1257 ogg_packet op; 1258 int lastblock=0; 1259 int accblock=0; 1260 int thisblock=0; 1261 int lastflag=0; 1262 int firstflag=0; 1263 ogg_int64_t pagepos=-1; 1264 1265 ogg_stream_init(&work_os,vf->current_serialno); /* get the memory ready */ 1266 ogg_stream_reset(&work_os); /* eliminate the spurious OV_HOLE 1267 return from not necessarily 1268 starting from the beginning */ 1269 1270 while(1){ 1271 if(vf->ready_state>=STREAMSET){ 1272 /* snarf/scan a packet if we can */ 1273 int result=ogg_stream_packetout(&work_os,&op); 1274 1275 if(result>0){ 1276 1277 if(vf->vi[vf->current_link].codec_setup){ 1278 thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op); 1279 if(thisblock<0){ 1280 ogg_stream_packetout(&vf->os,NULL); 1281 thisblock=0; 1282 }else{ 1283 1284 /* We can't get a guaranteed correct pcm position out of the 1285 last page in a stream because it might have a 'short' 1286 granpos, which can only be detected in the presence of a 1287 preceeding page. However, if the last page is also the first 1288 page, the granpos rules of a first page take precedence. Not 1289 only that, but for first==last, the EOS page must be treated 1290 as if its a normal first page for the stream to open/play. */ 1291 if(lastflag && !firstflag) 1292 ogg_stream_packetout(&vf->os,NULL); 1293 else 1294 if(lastblock)accblock+=(lastblock+thisblock)>>2; 1295 } 1296 1297 if(op.granulepos!=-1){ 1298 int i,link=vf->current_link; 1299 ogg_int64_t granulepos=op.granulepos-vf->pcmlengths[link*2]; 1300 if(granulepos<0)granulepos=0; 1301 1302 for(i=0;i<link;i++) 1303 granulepos+=vf->pcmlengths[i*2+1]; 1304 vf->pcm_offset=granulepos-accblock; 1305 if(vf->pcm_offset<0)vf->pcm_offset=0; 1306 break; 1307 } 1308 lastblock=thisblock; 1309 continue; 1310 }else 1311 ogg_stream_packetout(&vf->os,NULL); 1312 } 1313 } 1314 1315 if(!lastblock){ 1316 pagepos=_get_next_page(vf,&og,-1); 1317 if(pagepos<0){ 1318 vf->pcm_offset=ov_pcm_total(vf,-1); 1319 break; 1320 } 1321 }else{ 1322 /* huh? Bogus stream with packets but no granulepos */ 1323 vf->pcm_offset=-1; 1324 break; 1325 } 1326 1327 /* has our decoding just traversed a bitstream boundary? */ 1328 if(vf->ready_state>=STREAMSET){ 1329 if(vf->current_serialno!=ogg_page_serialno(&og)){ 1330 1331 /* two possibilities: 1332 1) our decoding just traversed a bitstream boundary 1333 2) another stream is multiplexed into this logical section? */ 1334 1335 if(ogg_page_bos(&og)){ 1336 /* we traversed */ 1337 _decode_clear(vf); /* clear out stream state */ 1338 ogg_stream_clear(&work_os); 1339 } /* else, do nothing; next loop will scoop another page */ 1340 } 1341 } 1342 1343 if(vf->ready_state<STREAMSET){ 1344 int link; 1345 long serialno = ogg_page_serialno(&og); 1346 1347 for(link=0;link<vf->links;link++) 1348 if(vf->serialnos[link]==serialno)break; 1349 1350 if(link==vf->links) continue; /* not the desired Vorbis 1351 bitstream section; keep 1352 trying */ 1353 vf->current_link=link; 1354 vf->current_serialno=serialno; 1355 ogg_stream_reset_serialno(&vf->os,serialno); 1356 ogg_stream_reset_serialno(&work_os,serialno); 1357 vf->ready_state=STREAMSET; 1358 firstflag=(pagepos<=vf->dataoffsets[link]); 1359 } 1360 1361 ogg_stream_pagein(&vf->os,&og); 1362 ogg_stream_pagein(&work_os,&og); 1363 lastflag=ogg_page_eos(&og); 1364 1365 } 1366 } 1367 1368 ogg_stream_clear(&work_os); 1369 vf->bittrack=0.f; 1370 vf->samptrack=0.f; 1371 return(0); 1372 1373 seek_error: 1374 /* dump the machine so we're in a known state */ 1375 vf->pcm_offset=-1; 1376 ogg_stream_clear(&work_os); 1377 _decode_clear(vf); 1378 return OV_EBADLINK; 1379} 1380 1381/* Page granularity seek (faster than sample granularity because we 1382 don't do the last bit of decode to find a specific sample). 1383 1384 Seek to the last [granule marked] page preceeding the specified pos 1385 location, such that decoding past the returned point will quickly 1386 arrive at the requested position. */ 1387int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos){ 1388 int link=-1; 1389 ogg_int64_t result=0; 1390 ogg_int64_t total=ov_pcm_total(vf,-1); 1391 1392 if(vf->ready_state<OPENED)return(OV_EINVAL); 1393 if(!vf->seekable)return(OV_ENOSEEK); 1394 1395 if(pos<0 || pos>total)return(OV_EINVAL); 1396 1397 /* which bitstream section does this pcm offset occur in? */ 1398 for(link=vf->links-1;link>=0;link--){ 1399 total-=vf->pcmlengths[link*2+1]; 1400 if(pos>=total)break; 1401 } 1402 1403 /* search within the logical bitstream for the page with the highest 1404 pcm_pos preceeding (or equal to) pos. There is a danger here; 1405 missing pages or incorrect frame number information in the 1406 bitstream could make our task impossible. Account for that (it 1407 would be an error condition) */ 1408 1409 /* new search algorithm by HB (Nicholas Vinen) */ 1410 { 1411 ogg_int64_t end=vf->offsets[link+1]; 1412 ogg_int64_t begin=vf->offsets[link]; 1413 ogg_int64_t begintime = vf->pcmlengths[link*2]; 1414 ogg_int64_t endtime = vf->pcmlengths[link*2+1]+begintime; 1415 ogg_int64_t target=pos-total+begintime; 1416 ogg_int64_t best=begin; 1417 1418 ogg_page og; 1419 while(begin<end){ 1420 ogg_int64_t bisect; 1421 1422 if(end-begin<CHUNKSIZE){ 1423 bisect=begin; 1424 }else{ 1425 /* take a (pretty decent) guess. */ 1426 bisect=begin + 1427 (ogg_int64_t)((double)(target-begintime)*(end-begin)/(endtime-begintime)) 1428 - CHUNKSIZE; 1429 if(bisect<=begin) 1430 bisect=begin+1; 1431 } 1432 1433 result=_seek_helper(vf,bisect); 1434 if(result) goto seek_error; 1435 1436 while(begin<end){ 1437 result=_get_next_page(vf,&og,end-vf->offset); 1438 if(result==OV_EREAD) goto seek_error; 1439 if(result<0){ 1440 if(bisect<=begin+1) 1441 end=begin; /* found it */ 1442 else{ 1443 if(bisect==0) goto seek_error; 1444 bisect-=CHUNKSIZE; 1445 if(bisect<=begin)bisect=begin+1; 1446 result=_seek_helper(vf,bisect); 1447 if(result) goto seek_error; 1448 } 1449 }else{ 1450 ogg_int64_t granulepos; 1451 1452 if(ogg_page_serialno(&og)!=vf->serialnos[link]) 1453 continue; 1454 1455 granulepos=ogg_page_granulepos(&og); 1456 if(granulepos==-1)continue; 1457 1458 if(granulepos<target){ 1459 best=result; /* raw offset of packet with granulepos */ 1460 begin=vf->offset; /* raw offset of next page */ 1461 begintime=granulepos; 1462 1463 if(target-begintime>44100)break; 1464 bisect=begin; /* *not* begin + 1 */ 1465 }else{ 1466 if(bisect<=begin+1) 1467 end=begin; /* found it */ 1468 else{ 1469 if(end==vf->offset){ /* we're pretty close - we'd be stuck in */ 1470 end=result; 1471 bisect-=CHUNKSIZE; /* an endless loop otherwise. */ 1472 if(bisect<=begin)bisect=begin+1; 1473 result=_seek_helper(vf,bisect); 1474 if(result) goto seek_error; 1475 }else{ 1476 end=bisect; 1477 endtime=granulepos; 1478 break; 1479 } 1480 } 1481 } 1482 } 1483 } 1484 } 1485 1486 /* found our page. seek to it, update pcm offset. Easier case than 1487 raw_seek, don't keep packets preceeding granulepos. */ 1488 { 1489 ogg_page og; 1490 ogg_packet op; 1491 1492 /* seek */ 1493 result=_seek_helper(vf,best); 1494 vf->pcm_offset=-1; 1495 if(result) goto seek_error; 1496 result=_get_next_page(vf,&og,-1); 1497 if(result<0) goto seek_error; 1498 1499 if(link!=vf->current_link){ 1500 /* Different link; dump entire decode machine */ 1501 _decode_clear(vf); 1502 1503 vf->current_link=link; 1504 vf->current_serialno=vf->serialnos[link]; 1505 vf->ready_state=STREAMSET; 1506 1507 }else{ 1508 vorbis_synthesis_restart(&vf->vd); 1509 } 1510 1511 ogg_stream_reset_serialno(&vf->os,vf->current_serialno); 1512 ogg_stream_pagein(&vf->os,&og); 1513 1514 /* pull out all but last packet; the one with granulepos */ 1515 while(1){ 1516 result=ogg_stream_packetpeek(&vf->os,&op); 1517 if(result==0){ 1518 /* !!! the packet finishing this page originated on a 1519 preceeding page. Keep fetching previous pages until we 1520 get one with a granulepos or without the 'continued' flag 1521 set. Then just use raw_seek for simplicity. */ 1522 1523 result=_seek_helper(vf,best); 1524 if(result<0) goto seek_error; 1525 1526 while(1){ 1527 result=_get_prev_page(vf,&og); 1528 if(result<0) goto seek_error; 1529 if(ogg_page_serialno(&og)==vf->current_serialno && 1530 (ogg_page_granulepos(&og)>-1 || 1531 !ogg_page_continued(&og))){ 1532 return ov_raw_seek(vf,result); 1533 } 1534 vf->offset=result; 1535 } 1536 } 1537 if(result<0){ 1538 result = OV_EBADPACKET; 1539 goto seek_error; 1540 } 1541 if(op.granulepos!=-1){ 1542 vf->pcm_offset=op.granulepos-vf->pcmlengths[vf->current_link*2]; 1543 if(vf->pcm_offset<0)vf->pcm_offset=0; 1544 vf->pcm_offset+=total; 1545 break; 1546 }else 1547 result=ogg_stream_packetout(&vf->os,NULL); 1548 } 1549 } 1550 } 1551 1552 /* verify result */ 1553 if(vf->pcm_offset>pos || pos>ov_pcm_total(vf,-1)){ 1554 result=OV_EFAULT; 1555 goto seek_error; 1556 } 1557 vf->bittrack=0.f; 1558 vf->samptrack=0.f; 1559 return(0); 1560 1561 seek_error: 1562 /* dump machine so we're in a known state */ 1563 vf->pcm_offset=-1; 1564 _decode_clear(vf); 1565 return (int)result; 1566} 1567 1568/* seek to a sample offset relative to the decompressed pcm stream 1569 returns zero on success, nonzero on failure */ 1570 1571int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos){ 1572 int thisblock,lastblock=0; 1573 int ret=ov_pcm_seek_page(vf,pos); 1574 if(ret<0)return(ret); 1575 if((ret=_make_decode_ready(vf)))return ret; 1576 1577 /* discard leading packets we don't need for the lapping of the 1578 position we want; don't decode them */ 1579 1580 while(1){ 1581 ogg_packet op; 1582 ogg_page og; 1583 1584 int ret=ogg_stream_packetpeek(&vf->os,&op); 1585 if(ret>0){ 1586 thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op); 1587 if(thisblock<0){ 1588 ogg_stream_packetout(&vf->os,NULL); 1589 continue; /* non audio packet */ 1590 } 1591 if(lastblock)vf->pcm_offset+=(lastblock+thisblock)>>2; 1592 1593 if(vf->pcm_offset+((thisblock+ 1594 vorbis_info_blocksize(vf->vi,1))>>2)>=pos)break; 1595 1596 /* remove the packet from packet queue and track its granulepos */ 1597 ogg_stream_packetout(&vf->os,NULL); 1598 vorbis_synthesis_trackonly(&vf->vb,&op); /* set up a vb with 1599 only tracking, no 1600 pcm_decode */ 1601 vorbis_synthesis_blockin(&vf->vd,&vf->vb); 1602 1603 /* end of logical stream case is hard, especially with exact 1604 length positioning. */ 1605 1606 if(op.granulepos>-1){ 1607 int i; 1608 /* always believe the stream markers */ 1609 vf->pcm_offset=op.granulepos-vf->pcmlengths[vf->current_link*2]; 1610 if(vf->pcm_offset<0)vf->pcm_offset=0; 1611 for(i=0;i<vf->current_link;i++) 1612 vf->pcm_offset+=vf->pcmlengths[i*2+1]; 1613 } 1614 1615 lastblock=thisblock; 1616 1617 }else{ 1618 if(ret<0 && ret!=OV_HOLE)break; 1619 1620 /* suck in a new page */ 1621 if(_get_next_page(vf,&og,-1)<0)break; 1622 if(ogg_page_bos(&og))_decode_clear(vf); 1623 1624 if(vf->ready_state<STREAMSET){ 1625 long serialno=ogg_page_serialno(&og); 1626 int link; 1627 1628 for(link=0;link<vf->links;link++) 1629 if(vf->serialnos[link]==serialno)break; 1630 if(link==vf->links) continue; 1631 vf->current_link=link; 1632 1633 vf->ready_state=STREAMSET; 1634 vf->current_serialno=ogg_page_serialno(&og); 1635 ogg_stream_reset_serialno(&vf->os,serialno); 1636 ret=_make_decode_ready(vf); 1637 if(ret)return ret; 1638 lastblock=0; 1639 } 1640 1641 ogg_stream_pagein(&vf->os,&og); 1642 } 1643 } 1644 1645 vf->bittrack=0.f; 1646 vf->samptrack=0.f; 1647 /* discard samples until we reach the desired position. Crossing a 1648 logical bitstream boundary with abandon is OK. */ 1649 while(vf->pcm_offset<pos){ 1650 ogg_int64_t target=pos-vf->pcm_offset; 1651 long samples=vorbis_synthesis_pcmout(&vf->vd,NULL); 1652 1653 if(samples>target)samples=target; 1654 vorbis_synthesis_read(&vf->vd,samples); 1655 vf->pcm_offset+=samples; 1656 1657 if(samples<target) 1658 if(_fetch_and_process_packet(vf,NULL,1,1)<=0) 1659 vf->pcm_offset=ov_pcm_total(vf,-1); /* eof */ 1660 } 1661 return 0; 1662} 1663 1664/* seek to a playback time relative to the decompressed pcm stream 1665 returns zero on success, nonzero on failure */ 1666int ov_time_seek(OggVorbis_File *vf,double seconds){ 1667 /* translate time to PCM position and call ov_pcm_seek */ 1668 1669 int link=-1; 1670 ogg_int64_t pcm_total=0; 1671 double time_total=0.; 1672 1673 if(vf->ready_state<OPENED)return(OV_EINVAL); 1674 if(!vf->seekable)return(OV_ENOSEEK); 1675 if(seconds<0)return(OV_EINVAL); 1676 1677 /* which bitstream section does this time offset occur in? */ 1678 for(link=0;link<vf->links;link++){ 1679 double addsec = ov_time_total(vf,link); 1680 if(seconds<time_total+addsec)break; 1681 time_total+=addsec; 1682 pcm_total+=vf->pcmlengths[link*2+1]; 1683 } 1684 1685 if(link==vf->links)return(OV_EINVAL); 1686 1687 /* enough information to convert time offset to pcm offset */ 1688 { 1689 ogg_int64_t target=pcm_total+(seconds-time_total)*vf->vi[link].rate; 1690 return(ov_pcm_seek(vf,target)); 1691 } 1692} 1693 1694/* page-granularity version of ov_time_seek 1695 returns zero on success, nonzero on failure */ 1696int ov_time_seek_page(OggVorbis_File *vf,double seconds){ 1697 /* translate time to PCM position and call ov_pcm_seek */ 1698 1699 int link=-1; 1700 ogg_int64_t pcm_total=0; 1701 double time_total=0.; 1702 1703 if(vf->ready_state<OPENED)return(OV_EINVAL); 1704 if(!vf->seekable)return(OV_ENOSEEK); 1705 if(seconds<0)return(OV_EINVAL); 1706 1707 /* which bitstream section does this time offset occur in? */ 1708 for(link=0;link<vf->links;link++){ 1709 double addsec = ov_time_total(vf,link); 1710 if(seconds<time_total+addsec)break; 1711 time_total+=addsec; 1712 pcm_total+=vf->pcmlengths[link*2+1]; 1713 } 1714 1715 if(link==vf->links)return(OV_EINVAL); 1716 1717 /* enough information to convert time offset to pcm offset */ 1718 { 1719 ogg_int64_t target=pcm_total+(seconds-time_total)*vf->vi[link].rate; 1720 return(ov_pcm_seek_page(vf,target)); 1721 } 1722} 1723 1724/* tell the current stream offset cursor. Note that seek followed by 1725 tell will likely not give the set offset due to caching */ 1726ogg_int64_t ov_raw_tell(OggVorbis_File *vf){ 1727 if(vf->ready_state<OPENED)return(OV_EINVAL); 1728 return(vf->offset); 1729} 1730 1731/* return PCM offset (sample) of next PCM sample to be read */ 1732ogg_int64_t ov_pcm_tell(OggVorbis_File *vf){ 1733 if(vf->ready_state<OPENED)return(OV_EINVAL); 1734 return(vf->pcm_offset); 1735} 1736 1737/* return time offset (seconds) of next PCM sample to be read */ 1738double ov_time_tell(OggVorbis_File *vf){ 1739 int link=0; 1740 ogg_int64_t pcm_total=0; 1741 double time_total=0.f; 1742 1743 if(vf->ready_state<OPENED)return(OV_EINVAL); 1744 if(vf->seekable){ 1745 pcm_total=ov_pcm_total(vf,-1); 1746 time_total=ov_time_total(vf,-1); 1747 1748 /* which bitstream section does this time offset occur in? */ 1749 for(link=vf->links-1;link>=0;link--){ 1750 pcm_total-=vf->pcmlengths[link*2+1]; 1751 time_total-=ov_time_total(vf,link); 1752 if(vf->pcm_offset>=pcm_total)break; 1753 } 1754 } 1755 1756 return((double)time_total+(double)(vf->pcm_offset-pcm_total)/vf->vi[link].rate); 1757} 1758 1759/* link: -1) return the vorbis_info struct for the bitstream section 1760 currently being decoded 1761 0-n) to request information for a specific bitstream section 1762 1763 In the case of a non-seekable bitstream, any call returns the 1764 current bitstream. NULL in the case that the machine is not 1765 initialized */ 1766 1767vorbis_info *ov_info(OggVorbis_File *vf,int link){ 1768 if(vf->seekable){ 1769 if(link<0) 1770 if(vf->ready_state>=STREAMSET) 1771 return vf->vi+vf->current_link; 1772 else 1773 return vf->vi; 1774 else 1775 if(link>=vf->links) 1776 return NULL; 1777 else 1778 return vf->vi+link; 1779 }else{ 1780 return vf->vi; 1781 } 1782} 1783 1784/* grr, strong typing, grr, no templates/inheritence, grr */ 1785vorbis_comment *ov_comment(OggVorbis_File *vf,int link){ 1786 if(vf->seekable){ 1787 if(link<0) 1788 if(vf->ready_state>=STREAMSET) 1789 return vf->vc+vf->current_link; 1790 else 1791 return vf->vc; 1792 else 1793 if(link>=vf->links) 1794 return NULL; 1795 else 1796 return vf->vc+link; 1797 }else{ 1798 return vf->vc; 1799 } 1800} 1801 1802static int host_is_big_endian() { 1803 ogg_int32_t pattern = 0xfeedface; /* deadbeef */ 1804 unsigned char *bytewise = (unsigned char *)&pattern; 1805 if (bytewise[0] == 0xfe) return 1; 1806 return 0; 1807} 1808 1809/* up to this point, everything could more or less hide the multiple 1810 logical bitstream nature of chaining from the toplevel application 1811 if the toplevel application didn't particularly care. However, at 1812 the point that we actually read audio back, the multiple-section 1813 nature must surface: Multiple bitstream sections do not necessarily 1814 have to have the same number of channels or sampling rate. 1815 1816 ov_read returns the sequential logical bitstream number currently 1817 being decoded along with the PCM data in order that the toplevel 1818 application can take action on channel/sample rate changes. This 1819 number will be incremented even for streamed (non-seekable) streams 1820 (for seekable streams, it represents the actual logical bitstream 1821 index within the physical bitstream. Note that the accessor 1822 functions above are aware of this dichotomy). 1823 1824 ov_read_filter is exactly the same as ov_read except that it processes 1825 the decoded audio data through a filter before packing it into the 1826 requested format. This gives greater accuracy than applying a filter 1827 after the audio has been converted into integral PCM. 1828 1829 input values: buffer) a buffer to hold packed PCM data for return 1830 length) the byte length requested to be placed into buffer 1831 bigendianp) should the data be packed LSB first (0) or 1832 MSB first (1) 1833 word) word size for output. currently 1 (byte) or 1834 2 (16 bit short) 1835 1836 return values: <0) error/hole in data (OV_HOLE), partial open (OV_EINVAL) 1837 0) EOF 1838 n) number of bytes of PCM actually returned. The 1839 below works on a packet-by-packet basis, so the 1840 return length is not related to the 'length' passed 1841 in, just guaranteed to fit. 1842 1843 *section) set to the logical bitstream number */ 1844 1845long ov_read_filter(OggVorbis_File *vf,char *buffer,int length, 1846 int bigendianp,int word,int sgned,int *bitstream, 1847 void (*filter)(float **pcm,long channels,long samples,void *filter_param),void *filter_param){ 1848 int i,j; 1849 int host_endian = host_is_big_endian(); 1850 1851 float **pcm; 1852 long samples; 1853 1854 if(vf->ready_state<OPENED)return(OV_EINVAL); 1855 1856 while(1){ 1857 if(vf->ready_state==INITSET){ 1858 samples=vorbis_synthesis_pcmout(&vf->vd,&pcm); 1859 if(samples)break; 1860 } 1861 1862 /* suck in another packet */ 1863 { 1864 int ret=_fetch_and_process_packet(vf,NULL,1,1); 1865 if(ret==OV_EOF) 1866 return(0); 1867 if(ret<=0) 1868 return(ret); 1869 } 1870 1871 } 1872 1873 if(samples>0){ 1874 1875 /* yay! proceed to pack data into the byte buffer */ 1876 1877 long channels=ov_info(vf,-1)->channels; 1878 long bytespersample=word * channels; 1879 vorbis_fpu_control fpu; 1880 if(samples>length/bytespersample)samples=length/bytespersample; 1881 1882 if(samples <= 0) 1883 return OV_EINVAL; 1884 1885 /* Here. */ 1886 if(filter) 1887 filter(pcm,channels,samples,filter_param); 1888 1889 /* a tight loop to pack each size */ 1890 { 1891 int val; 1892 if(word==1){ 1893 int off=(sgned?0:128); 1894 vorbis_fpu_setround(&fpu); 1895 for(j=0;j<samples;j++) 1896 for(i=0;i<channels;i++){ 1897 val=vorbis_ftoi(pcm[i][j]*128.f); 1898 if(val>127)val=127; 1899 else if(val<-128)val=-128; 1900 *buffer++=val+off; 1901 } 1902 vorbis_fpu_restore(fpu); 1903 }else{ 1904 int off=(sgned?0:32768); 1905 1906 if(host_endian==bigendianp){ 1907 if(sgned){ 1908 1909 vorbis_fpu_setround(&fpu); 1910 for(i=0;i<channels;i++) { /* It's faster in this order */ 1911 float *src=pcm[i]; 1912 short *dest=((short *)buffer)+i; 1913 for(j=0;j<samples;j++) { 1914 val=vorbis_ftoi(src[j]*32768.f); 1915 if(val>32767)val=32767; 1916 else if(val<-32768)val=-32768; 1917 *dest=val; 1918 dest+=channels; 1919 } 1920 } 1921 vorbis_fpu_restore(fpu); 1922 1923 }else{ 1924 1925 vorbis_fpu_setround(&fpu); 1926 for(i=0;i<channels;i++) { 1927 float *src=pcm[i]; 1928 short *dest=((short *)buffer)+i; 1929 for(j=0;j<samples;j++) { 1930 val=vorbis_ftoi(src[j]*32768.f); 1931 if(val>32767)val=32767; 1932 else if(val<-32768)val=-32768; 1933 *dest=val+off; 1934 dest+=channels; 1935 } 1936 } 1937 vorbis_fpu_restore(fpu); 1938 1939 } 1940 }else if(bigendianp){ 1941 1942 vorbis_fpu_setround(&fpu); 1943 for(j=0;j<samples;j++) 1944 for(i=0;i<channels;i++){ 1945 val=vorbis_ftoi(pcm[i][j]*32768.f); 1946 if(val>32767)val=32767; 1947 else if(val<-32768)val=-32768; 1948 val+=off; 1949 *buffer++=(val>>8); 1950 *buffer++=(val&0xff); 1951 } 1952 vorbis_fpu_restore(fpu); 1953 1954 }else{ 1955 int val; 1956 vorbis_fpu_setround(&fpu); 1957 for(j=0;j<samples;j++) 1958 for(i=0;i<channels;i++){ 1959 val=vorbis_ftoi(pcm[i][j]*32768.f); 1960 if(val>32767)val=32767; 1961 else if(val<-32768)val=-32768; 1962 val+=off; 1963 *buffer++=(val&0xff); 1964 *buffer++=(val>>8); 1965 } 1966 vorbis_fpu_restore(fpu); 1967 1968 } 1969 } 1970 } 1971 1972 vorbis_synthesis_read(&vf->vd,samples); 1973 vf->pcm_offset+=samples; 1974 if(bitstream)*bitstream=vf->current_link; 1975 return(samples*bytespersample); 1976 }else{ 1977 return(samples); 1978 } 1979} 1980 1981long ov_read(OggVorbis_File *vf,char *buffer,int length, 1982 int bigendianp,int word,int sgned,int *bitstream){ 1983 return ov_read_filter(vf, buffer, length, bigendianp, word, sgned, bitstream, NULL, NULL); 1984} 1985 1986/* input values: pcm_channels) a float vector per channel of output 1987 length) the sample length being read by the app 1988 1989 return values: <0) error/hole in data (OV_HOLE), partial open (OV_EINVAL) 1990 0) EOF 1991 n) number of samples of PCM actually returned. The 1992 below works on a packet-by-packet basis, so the 1993 return length is not related to the 'length' passed 1994 in, just guaranteed to fit. 1995 1996 *section) set to the logical bitstream number */ 1997 1998 1999 2000long ov_read_float(OggVorbis_File *vf,float ***pcm_channels,int length, 2001 int *bitstream){ 2002 2003 if(vf->ready_state<OPENED)return(OV_EINVAL); 2004 2005 while(1){ 2006 if(vf->ready_state==INITSET){ 2007 float **pcm; 2008 long samples=vorbis_synthesis_pcmout(&vf->vd,&pcm); 2009 if(samples){ 2010 if(pcm_channels)*pcm_channels=pcm; 2011 if(samples>length)samples=length; 2012 vorbis_synthesis_read(&vf->vd,samples); 2013 vf->pcm_offset+=samples; 2014 if(bitstream)*bitstream=vf->current_link; 2015 return samples; 2016 2017 } 2018 } 2019 2020 /* suck in another packet */ 2021 { 2022 int ret=_fetch_and_process_packet(vf,NULL,1,1); 2023 if(ret==OV_EOF)return(0); 2024 if(ret<=0)return(ret); 2025 } 2026 2027 } 2028} 2029 2030extern float *vorbis_window(vorbis_dsp_state *v,int W); 2031 2032static void _ov_splice(float **pcm,float **lappcm, 2033 int n1, int n2, 2034 int ch1, int ch2, 2035 float *w1, float *w2){ 2036 int i,j; 2037 float *w=w1; 2038 int n=n1; 2039 2040 if(n1>n2){ 2041 n=n2; 2042 w=w2; 2043 } 2044 2045 /* splice */ 2046 for(j=0;j<ch1 && j<ch2;j++){ 2047 float *s=lappcm[j]; 2048 float *d=pcm[j]; 2049 2050 for(i=0;i<n;i++){ 2051 float wd=w[i]*w[i]; 2052 float ws=1.-wd; 2053 d[i]=d[i]*wd + s[i]*ws; 2054 } 2055 } 2056 /* window from zero */ 2057 for(;j<ch2;j++){ 2058 float *d=pcm[j]; 2059 for(i=0;i<n;i++){ 2060 float wd=w[i]*w[i]; 2061 d[i]=d[i]*wd; 2062 } 2063 } 2064 2065} 2066 2067/* make sure vf is INITSET */ 2068static int _ov_initset(OggVorbis_File *vf){ 2069 while(1){ 2070 if(vf->ready_state==INITSET)break; 2071 /* suck in another packet */ 2072 { 2073 int ret=_fetch_and_process_packet(vf,NULL,1,0); 2074 if(ret<0 && ret!=OV_HOLE)return(ret); 2075 } 2076 } 2077 return 0; 2078} 2079 2080/* make sure vf is INITSET and that we have a primed buffer; if 2081 we're crosslapping at a stream section boundary, this also makes 2082 sure we're sanity checking against the right stream information */ 2083static int _ov_initprime(OggVorbis_File *vf){ 2084 vorbis_dsp_state *vd=&vf->vd; 2085 while(1){ 2086 if(vf->ready_state==INITSET) 2087 if(vorbis_synthesis_pcmout(vd,NULL))break; 2088 2089 /* suck in another packet */ 2090 { 2091 int ret=_fetch_and_process_packet(vf,NULL,1,0); 2092 if(ret<0 && ret!=OV_HOLE)return(ret); 2093 } 2094 } 2095 return 0; 2096} 2097 2098/* grab enough data for lapping from vf; this may be in the form of 2099 unreturned, already-decoded pcm, remaining PCM we will need to 2100 decode, or synthetic postextrapolation from last packets. */ 2101static void _ov_getlap(OggVorbis_File *vf,vorbis_info *vi,vorbis_dsp_state *vd, 2102 float **lappcm,int lapsize){ 2103 int lapcount=0,i; 2104 float **pcm; 2105 2106 /* try first to decode the lapping data */ 2107 while(lapcount<lapsize){ 2108 int samples=vorbis_synthesis_pcmout(vd,&pcm); 2109 if(samples){ 2110 if(samples>lapsize-lapcount)samples=lapsize-lapcount; 2111 for(i=0;i<vi->channels;i++) 2112 memcpy(lappcm[i]+lapcount,pcm[i],sizeof(**pcm)*samples); 2113 lapcount+=samples; 2114 vorbis_synthesis_read(vd,samples); 2115 }else{ 2116 /* suck in another packet */ 2117 int ret=_fetch_and_process_packet(vf,NULL,1,0); /* do *not* span */ 2118 if(ret==OV_EOF)break; 2119 } 2120 } 2121 if(lapcount<lapsize){ 2122 /* failed to get lapping data from normal decode; pry it from the 2123 postextrapolation buffering, or the second half of the MDCT 2124 from the last packet */ 2125 int samples=vorbis_synthesis_lapout(&vf->vd,&pcm); 2126 if(samples==0){ 2127 for(i=0;i<vi->channels;i++) 2128 memset(lappcm[i]+lapcount,0,sizeof(**pcm)*lapsize-lapcount); 2129 lapcount=lapsize; 2130 }else{ 2131 if(samples>lapsize-lapcount)samples=lapsize-lapcount; 2132 for(i=0;i<vi->channels;i++) 2133 memcpy(lappcm[i]+lapcount,pcm[i],sizeof(**pcm)*samples); 2134 lapcount+=samples; 2135 } 2136 } 2137} 2138 2139/* this sets up crosslapping of a sample by using trailing data from 2140 sample 1 and lapping it into the windowing buffer of sample 2 */ 2141int ov_crosslap(OggVorbis_File *vf1, OggVorbis_File *vf2){ 2142 vorbis_info *vi1,*vi2; 2143 float **lappcm; 2144 float **pcm; 2145 float *w1,*w2; 2146 int n1,n2,i,ret,hs1,hs2; 2147 2148 if(vf1==vf2)return(0); /* degenerate case */ 2149 if(vf1->ready_state<OPENED)return(OV_EINVAL); 2150 if(vf2->ready_state<OPENED)return(OV_EINVAL); 2151 2152 /* the relevant overlap buffers must be pre-checked and pre-primed 2153 before looking at settings in the event that priming would cross 2154 a bitstream boundary. So, do it now */ 2155 2156 ret=_ov_initset(vf1); 2157 if(ret)return(ret); 2158 ret=_ov_initprime(vf2); 2159 if(ret)return(ret); 2160 2161 vi1=ov_info(vf1,-1); 2162 vi2=ov_info(vf2,-1); 2163 hs1=ov_halfrate_p(vf1); 2164 hs2=ov_halfrate_p(vf2); 2165 2166 lappcm=alloca(sizeof(*lappcm)*vi1->channels); 2167 n1=vorbis_info_blocksize(vi1,0)>>(1+hs1); 2168 n2=vorbis_info_blocksize(vi2,0)>>(1+hs2); 2169 w1=vorbis_window(&vf1->vd,0); 2170 w2=vorbis_window(&vf2->vd,0); 2171 2172 for(i=0;i<vi1->channels;i++) 2173 lappcm[i]=alloca(sizeof(**lappcm)*n1); 2174 2175 _ov_getlap(vf1,vi1,&vf1->vd,lappcm,n1); 2176 2177 /* have a lapping buffer from vf1; now to splice it into the lapping 2178 buffer of vf2 */ 2179 /* consolidate and expose the buffer. */ 2180 vorbis_synthesis_lapout(&vf2->vd,&pcm); 2181 2182#if 0 2183 _analysis_output_always("pcmL",0,pcm[0],n1*2,0,0,0); 2184 _analysis_output_always("pcmR",0,pcm[1],n1*2,0,0,0); 2185#endif 2186 2187 /* splice */ 2188 _ov_splice(pcm,lappcm,n1,n2,vi1->channels,vi2->channels,w1,w2); 2189 2190 /* done */ 2191 return(0); 2192} 2193 2194static int _ov_64_seek_lap(OggVorbis_File *vf,ogg_int64_t pos, 2195 int (*localseek)(OggVorbis_File *,ogg_int64_t)){ 2196 vorbis_info *vi; 2197 float **lappcm; 2198 float **pcm; 2199 float *w1,*w2; 2200 int n1,n2,ch1,ch2,hs; 2201 int i,ret; 2202 2203 if(vf->ready_state<OPENED)return(OV_EINVAL); 2204 ret=_ov_initset(vf); 2205 if(ret)return(ret); 2206 vi=ov_info(vf,-1); 2207 hs=ov_halfrate_p(vf); 2208 2209 ch1=vi->channels; 2210 n1=vorbis_info_blocksize(vi,0)>>(1+hs); 2211 w1=vorbis_window(&vf->vd,0); /* window arrays from libvorbis are 2212 persistent; even if the decode state 2213 from this link gets dumped, this 2214 window array continues to exist */ 2215 2216 lappcm=alloca(sizeof(*lappcm)*ch1); 2217 for(i=0;i<ch1;i++) 2218 lappcm[i]=alloca(sizeof(**lappcm)*n1); 2219 _ov_getlap(vf,vi,&vf->vd,lappcm,n1); 2220 2221 /* have lapping data; seek and prime the buffer */ 2222 ret=localseek(vf,pos); 2223 if(ret)return ret; 2224 ret=_ov_initprime(vf); 2225 if(ret)return(ret); 2226 2227 /* Guard against cross-link changes; they're perfectly legal */ 2228 vi=ov_info(vf,-1); 2229 ch2=vi->channels; 2230 n2=vorbis_info_blocksize(vi,0)>>(1+hs); 2231 w2=vorbis_window(&vf->vd,0); 2232 2233 /* consolidate and expose the buffer. */ 2234 vorbis_synthesis_lapout(&vf->vd,&pcm); 2235 2236 /* splice */ 2237 _ov_splice(pcm,lappcm,n1,n2,ch1,ch2,w1,w2); 2238 2239 /* done */ 2240 return(0); 2241} 2242 2243int ov_raw_seek_lap(OggVorbis_File *vf,ogg_int64_t pos){ 2244 return _ov_64_seek_lap(vf,pos,ov_raw_seek); 2245} 2246 2247int ov_pcm_seek_lap(OggVorbis_File *vf,ogg_int64_t pos){ 2248 return _ov_64_seek_lap(vf,pos,ov_pcm_seek); 2249} 2250 2251int ov_pcm_seek_page_lap(OggVorbis_File *vf,ogg_int64_t pos){ 2252 return _ov_64_seek_lap(vf,pos,ov_pcm_seek_page); 2253} 2254 2255static int _ov_d_seek_lap(OggVorbis_File *vf,double pos, 2256 int (*localseek)(OggVorbis_File *,double)){ 2257 vorbis_info *vi; 2258 float **lappcm; 2259 float **pcm; 2260 float *w1,*w2; 2261 int n1,n2,ch1,ch2,hs; 2262 int i,ret; 2263 2264 if(vf->ready_state<OPENED)return(OV_EINVAL); 2265 ret=_ov_initset(vf); 2266 if(ret)return(ret); 2267 vi=ov_info(vf,-1); 2268 hs=ov_halfrate_p(vf); 2269 2270 ch1=vi->channels; 2271 n1=vorbis_info_blocksize(vi,0)>>(1+hs); 2272 w1=vorbis_window(&vf->vd,0); /* window arrays from libvorbis are 2273 persistent; even if the decode state 2274 from this link gets dumped, this 2275 window array continues to exist */ 2276 2277 lappcm=alloca(sizeof(*lappcm)*ch1); 2278 for(i=0;i<ch1;i++) 2279 lappcm[i]=alloca(sizeof(**lappcm)*n1); 2280 _ov_getlap(vf,vi,&vf->vd,lappcm,n1); 2281 2282 /* have lapping data; seek and prime the buffer */ 2283 ret=localseek(vf,pos); 2284 if(ret)return ret; 2285 ret=_ov_initprime(vf); 2286 if(ret)return(ret); 2287 2288 /* Guard against cross-link changes; they're perfectly legal */ 2289 vi=ov_info(vf,-1); 2290 ch2=vi->channels; 2291 n2=vorbis_info_blocksize(vi,0)>>(1+hs); 2292 w2=vorbis_window(&vf->vd,0); 2293 2294 /* consolidate and expose the buffer. */ 2295 vorbis_synthesis_lapout(&vf->vd,&pcm); 2296 2297 /* splice */ 2298 _ov_splice(pcm,lappcm,n1,n2,ch1,ch2,w1,w2); 2299 2300 /* done */ 2301 return(0); 2302} 2303 2304int ov_time_seek_lap(OggVorbis_File *vf,double pos){ 2305 return _ov_d_seek_lap(vf,pos,ov_time_seek); 2306} 2307 2308int ov_time_seek_page_lap(OggVorbis_File *vf,double pos){ 2309 return _ov_d_seek_lap(vf,pos,ov_time_seek_page); 2310} 2311