1 /********************************************************************
3 * THIS FILE IS PART OF THE Ogg Vorbis SOFTWARE CODEC SOURCE CODE. *
4 * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
5 * THE GNU PUBLIC LICENSE 2, WHICH IS INCLUDED WITH THIS SOURCE. *
6 * PLEASE READ THESE TERMS DISTRIBUTING. *
8 * THE OggSQUISH SOURCE CODE IS (C) COPYRIGHT 1994-2000 *
9 * by Monty <monty@xiph.org> and The XIPHOPHORUS Company *
10 * http://www.xiph.org/ *
12 ********************************************************************
14 function: stdio-based convenience library for opening/seeking/decoding
15 last mod: $Id: vorbisfile.c,v 1.30 2000/10/13 19:48:03 xiphmont Exp $
17 ********************************************************************/
25 #include "vorbis/codec.h"
26 #include "vorbis/vorbisfile.h"
31 /* A 'chained bitstream' is a Vorbis bitstream that contains more than
32 one logical bitstream arranged end to end (the only form of Ogg
33 multiplexing allowed in a Vorbis bitstream; grouping [parallel
34 multiplexing] is not allowed in Vorbis) */
36 /* A Vorbis file can be played beginning to end (streamed) without
37 worrying ahead of time about chaining (see decoder_example.c). If
38 we have the whole file, however, and want random access
39 (seeking/scrubbing) or desire to know the total length/time of a
40 file, we need to account for the possibility of chaining. */
42 /* We can handle things a number of ways; we can determine the entire
43 bitstream structure right off the bat, or find pieces on demand.
44 This example determines and caches structure for the entire
45 bitstream, but builds a virtual decoder on the fly when moving
46 between links in the chain. */
48 /* There are also different ways to implement seeking. Enough
49 information exists in an Ogg bitstream to seek to
50 sample-granularity positions in the output. Or, one can seek by
51 picking some portion of the stream roughly in the desired area if
52 we only want course navigation through the stream. */
54 /*************************************************************************
55 * Many, many internal helpers. The intention is not to be confusing;
56 * rampant duplication and monolithic function implementation would be
57 * harder to understand anyway. The high level functions are last. Begin
58 * grokking near the end of the file */
60 /* read a little more data from the file/pipe into the ogg_sync framer */
61 #define CHUNKSIZE 4096
62 static long _get_data(OggVorbis_File *vf){
63 char *buffer=ogg_sync_buffer(&vf->oy,CHUNKSIZE);
64 long bytes=(vf->callbacks.read_func)(buffer,1,CHUNKSIZE,vf->datasource);
65 ogg_sync_wrote(&vf->oy,bytes);
69 /* save a tiny smidge of verbosity to make the code more readable */
70 static void _seek_helper(OggVorbis_File *vf,long offset){
71 (vf->callbacks.seek_func)(vf->datasource, offset, SEEK_SET);
73 ogg_sync_reset(&vf->oy);
76 /* The read/seek functions track absolute position within the stream */
78 /* from the head of the stream, get the next page. boundary specifies
79 if the function is allowed to fetch more data from the stream (and
80 how much) or only use internally buffered data.
82 boundary: -1) unbounded search
83 0) read no additional data; use cached only
84 n) search for a new page beginning for n bytes
86 return: -1) did not find a page
87 n) found a page at absolute offset n */
89 static long _get_next_page(OggVorbis_File *vf,ogg_page *og,int boundary){
90 if(boundary>0)boundary+=vf->offset;
94 if(boundary>0 && vf->offset>=boundary)return(-1);
95 more=ogg_sync_pageseek(&vf->oy,og);
102 /* send more paramedics */
103 if(!boundary)return(-1);
104 if(_get_data(vf)<=0)return(-1);
106 /* got a page. Return the offset at the page beginning,
107 advance the internal offset past the page end */
117 /* find the latest page beginning before the current stream cursor
118 position. Much dirtier than the above as Ogg doesn't have any
119 backward search linkage. no 'readp' as it will certainly have to
121 static long _get_prev_page(OggVorbis_File *vf,ogg_page *og){
122 long begin=vf->offset;
128 _seek_helper(vf,begin);
129 while(vf->offset<begin+CHUNKSIZE){
130 ret=_get_next_page(vf,og,begin+CHUNKSIZE-vf->offset);
139 /* we have the offset. Actually snork and hold the page now */
140 _seek_helper(vf,offset);
141 ret=_get_next_page(vf,og,CHUNKSIZE);
143 /* this shouldn't be possible */
144 fprintf(stderr,"Missed page fencepost at end of logical bitstream. "
151 /* finds each bitstream link one at a time using a bisection search
152 (has to begin by knowing the offset of the lb's initial page).
153 Recurses for each link so it can alloc the link storage after
154 finding them all, then unroll and fill the cache at the same time */
155 static void _bisect_forward_serialno(OggVorbis_File *vf,
161 long endsearched=end;
166 /* the below guards against garbage seperating the last and
167 first pages of two links. */
168 while(searched<endsearched){
171 if(endsearched-searched<CHUNKSIZE){
174 bisect=(searched+endsearched)/2;
177 _seek_helper(vf,bisect);
178 ret=_get_next_page(vf,&og,-1);
179 if(ret<0 || ogg_page_serialno(&og)!=currentno){
183 searched=ret+og.header_len+og.body_len;
187 _seek_helper(vf,next);
188 ret=_get_next_page(vf,&og,-1);
190 if(searched>=end || ret==-1){
192 vf->offsets=malloc((m+2)*sizeof(ogg_int64_t));
193 vf->offsets[m+1]=searched;
195 _bisect_forward_serialno(vf,next,vf->offset,
196 end,ogg_page_serialno(&og),m+1);
199 vf->offsets[m]=begin;
202 /* uses the local ogg_stream storage in vf; this is important for
203 non-streaming input sources */
204 static int _fetch_headers(OggVorbis_File *vf,vorbis_info *vi,vorbis_comment *vc,
205 long *serialno,ogg_page *og_ptr){
211 ret=_get_next_page(vf,&og,CHUNKSIZE);
213 fprintf(stderr,"Did not find initial header for bitstream.\n");
219 if(serialno)*serialno=ogg_page_serialno(og_ptr);
220 ogg_stream_init(&vf->os,ogg_page_serialno(og_ptr));
222 /* extract the initial header from the first page and verify that the
223 Ogg bitstream is in fact Vorbis data */
225 vorbis_info_init(vi);
226 vorbis_comment_init(vc);
230 ogg_stream_pagein(&vf->os,og_ptr);
232 int result=ogg_stream_packetout(&vf->os,&op);
235 fprintf(stderr,"Corrupt header in logical bitstream.\n");
238 if(vorbis_synthesis_headerin(vi,vc,&op)){
239 fprintf(stderr,"Illegal header in logical bitstream.\n");
245 if(_get_next_page(vf,og_ptr,1)<0){
246 fprintf(stderr,"Missing header in logical bitstream.\n");
253 vorbis_info_clear(vi);
254 vorbis_comment_clear(vc);
255 ogg_stream_clear(&vf->os);
259 /* last step of the OggVorbis_File initialization; get all the
260 vorbis_info structs and PCM positions. Only called by the seekable
261 initialization (local stream storage is hacked slightly; pay
262 attention to how that's done) */
263 static void _prefetch_all_headers(OggVorbis_File *vf,vorbis_info *first_i,
264 vorbis_comment *first_c,
269 vf->vi=calloc(vf->links,sizeof(vorbis_info));
270 vf->vc=calloc(vf->links,sizeof(vorbis_info));
271 vf->dataoffsets=malloc(vf->links*sizeof(ogg_int64_t));
272 vf->pcmlengths=malloc(vf->links*sizeof(ogg_int64_t));
273 vf->serialnos=malloc(vf->links*sizeof(long));
275 for(i=0;i<vf->links;i++){
276 if(first_i && first_c && i==0){
277 /* we already grabbed the initial header earlier. This just
278 saves the waste of grabbing it again */
279 memcpy(vf->vi+i,first_i,sizeof(vorbis_info));
280 memcpy(vf->vc+i,first_c,sizeof(vorbis_comment));
281 vf->dataoffsets[i]=dataoffset;
284 /* seek to the location of the initial header */
286 _seek_helper(vf,vf->offsets[i]);
287 if(_fetch_headers(vf,vf->vi+i,vf->vc+i,NULL,NULL)==-1){
288 fprintf(stderr,"Error opening logical bitstream #%d.\n\n",i+1);
289 vf->dataoffsets[i]=-1;
291 vf->dataoffsets[i]=vf->offset;
292 ogg_stream_clear(&vf->os);
296 /* get the serial number and PCM length of this link. To do this,
297 get the last page of the stream */
299 long end=vf->offsets[i+1];
300 _seek_helper(vf,end);
303 ret=_get_prev_page(vf,&og);
305 /* this should not be possible */
306 fprintf(stderr,"Could not find last page of logical "
307 "bitstream #%d\n\n",i);
308 vorbis_info_clear(vf->vi+i);
309 vorbis_comment_clear(vf->vc+i);
312 if(ogg_page_granulepos(&og)!=-1){
313 vf->serialnos[i]=ogg_page_serialno(&og);
314 vf->pcmlengths[i]=ogg_page_granulepos(&og);
322 static int _make_decode_ready(OggVorbis_File *vf){
323 if(vf->decode_ready)exit(1);
325 vorbis_synthesis_init(&vf->vd,vf->vi+vf->current_link);
327 vorbis_synthesis_init(&vf->vd,vf->vi);
329 vorbis_block_init(&vf->vd,&vf->vb);
334 static int _open_seekable(OggVorbis_File *vf){
335 vorbis_info initial_i;
336 vorbis_comment initial_c;
342 /* is this even vorbis...? */
343 ret=_fetch_headers(vf,&initial_i,&initial_c,&serialno,NULL);
344 dataoffset=vf->offset;
345 ogg_stream_clear(&vf->os);
346 if(ret==-1)return(-1);
348 /* we can seek, so set out learning all about this file */
350 (vf->callbacks.seek_func)(vf->datasource,0,SEEK_END);
351 vf->offset=vf->end=(vf->callbacks.tell_func)(vf->datasource);
353 /* We get the offset for the last page of the physical bitstream.
354 Most OggVorbis files will contain a single logical bitstream */
355 end=_get_prev_page(vf,&og);
357 /* moer than one logical bitstream? */
358 if(ogg_page_serialno(&og)!=serialno){
360 /* Chained bitstream. Bisect-search each logical bitstream
361 section. Do so based on serial number only */
362 _bisect_forward_serialno(vf,0,0,end+1,serialno,0);
366 /* Only one logical bitstream */
367 _bisect_forward_serialno(vf,0,end,end+1,serialno,0);
371 _prefetch_all_headers(vf,&initial_i,&initial_c,dataoffset);
372 return(ov_raw_seek(vf,0));
376 static int _open_nonseekable(OggVorbis_File *vf){
377 /* we cannot seek. Set up a 'single' (current) logical bitstream entry */
379 vf->vi=calloc(vf->links,sizeof(vorbis_info));
380 vf->vc=calloc(vf->links,sizeof(vorbis_info));
382 /* Try to fetch the headers, maintaining all the storage */
383 if(_fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno,NULL)==-1)return(-1);
384 _make_decode_ready(vf);
389 /* clear out the current logical bitstream decoder */
390 static void _decode_clear(OggVorbis_File *vf){
391 ogg_stream_clear(&vf->os);
392 vorbis_dsp_clear(&vf->vd);
393 vorbis_block_clear(&vf->vb);
400 /* fetch and process a packet. Handles the case where we're at a
401 bitstream boundary and dumps the decoding machine. If the decoding
402 machine is unloaded, it loads it. It also keeps pcm_offset up to
403 date (seek and read both use this. seek uses a special hack with
406 return: -1) hole in the data (lost packet)
407 0) need more date (only if readp==0)/eof
411 static int _process_packet(OggVorbis_File *vf,int readp){
414 /* handle one packet. Try to fetch it from current stream state */
415 /* extract packets from page */
418 /* process a packet if we can. If the machine isn't loaded,
420 if(vf->decode_ready){
422 int result=ogg_stream_packetout(&vf->os,&op);
423 ogg_int64_t granulepos;
425 /* if(result==-1)return(-1); hole in the data. For now, swallow
426 and go. We'll need to add a real
427 error code in a bit. */
429 /* got a packet. process it */
430 granulepos=op.granulepos;
431 if(!vorbis_synthesis(&vf->vb,&op)){ /* lazy check for lazy
433 header packets aren't
436 vorbis_synthesis will
439 /* suck in the synthesis data and track bitrate */
441 int oldsamples=vorbis_synthesis_pcmout(&vf->vd,NULL);
442 vorbis_synthesis_blockin(&vf->vd,&vf->vb);
443 vf->samptrack+=vorbis_synthesis_pcmout(&vf->vd,NULL)-oldsamples;
444 vf->bittrack+=op.bytes*8;
447 /* update the pcm offset. */
448 if(granulepos!=-1 && !op.e_o_s){
449 int link=(vf->seekable?vf->current_link:0);
452 /* this packet has a pcm_offset on it (the last packet
453 completed on a page carries the offset) After processing
454 (above), we know the pcm position of the *last* sample
455 ready to be returned. Find the offset of the *first*
457 As an aside, this trick is inaccurate if we begin
458 reading anew right at the last page; the end-of-stream
459 granulepos declares the last frame in the stream, and the
460 last packet of the last page may be a partial frame.
461 So, we need a previous granulepos from an in-sequence page
462 to have a reference point. Thus the !op.e_o_s clause
465 samples=vorbis_synthesis_pcmout(&vf->vd,NULL);
469 granulepos+=vf->pcmlengths[i];
470 vf->pcm_offset=granulepos;
478 if(_get_next_page(vf,&og,-1)<0)return(0); /* eof. leave unitialized */
480 /* bitrate tracking; add the header's bytes here, the body bytes
481 are done by packet above */
482 vf->bittrack+=og.header_len*8;
484 /* has our decoding just traversed a bitstream boundary? */
485 if(vf->decode_ready){
486 if(vf->current_serialno!=ogg_page_serialno(&og)){
491 /* Do we need to load a new machine before submitting the page? */
492 /* This is different in the seekable and non-seekable cases.
494 In the seekable case, we already have all the header
495 information loaded and cached; we just initialize the machine
496 with it and continue on our merry way.
498 In the non-seekable (streaming) case, we'll only be at a
499 boundary if we just left the previous logical bitstream and
500 we're now nominally at the header of the next bitstream
503 if(!vf->decode_ready){
506 vf->current_serialno=ogg_page_serialno(&og);
508 /* match the serialno to bitstream section. We use this rather than
509 offset positions to avoid problems near logical bitstream
511 for(link=0;link<vf->links;link++)
512 if(vf->serialnos[link]==vf->current_serialno)break;
513 if(link==vf->links)return(-1); /* sign of a bogus stream. error out,
514 leave machine uninitialized */
516 vf->current_link=link;
518 ogg_stream_init(&vf->os,vf->current_serialno);
519 ogg_stream_reset(&vf->os);
522 /* we're streaming */
523 /* fetch the three header packets, build the info struct */
525 _fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno,&og);
530 _make_decode_ready(vf);
532 ogg_stream_pagein(&vf->os,&og);
536 /**********************************************************************
537 * The helpers are over; it's all toplevel interface from here on out */
539 /* clear out the OggVorbis_File struct */
540 int ov_clear(OggVorbis_File *vf){
542 vorbis_block_clear(&vf->vb);
543 vorbis_dsp_clear(&vf->vd);
544 ogg_stream_clear(&vf->os);
546 if(vf->vi && vf->links){
548 for(i=0;i<vf->links;i++){
549 vorbis_info_clear(vf->vi+i);
550 vorbis_comment_clear(vf->vc+i);
555 if(vf->dataoffsets)free(vf->dataoffsets);
556 if(vf->pcmlengths)free(vf->pcmlengths);
557 if(vf->serialnos)free(vf->serialnos);
558 if(vf->offsets)free(vf->offsets);
559 ogg_sync_clear(&vf->oy);
560 if(vf->datasource)(vf->callbacks.close_func)(vf->datasource);
561 memset(vf,0,sizeof(OggVorbis_File));
569 static int _fseek64_wrap(FILE *f,ogg_int64_t off,int whence){
570 return fseek(f,(int)off,whence);
573 /* inspects the OggVorbis file and finds/documents all the logical
574 bitstreams contained in it. Tries to be tolerant of logical
575 bitstream sections that are truncated/woogie.
581 int ov_open(FILE *f,OggVorbis_File *vf,char *initial,long ibytes){
582 ov_callbacks callbacks = {
583 (size_t (*)(void *, size_t, size_t, void *)) fread,
584 (int (*)(void *, ogg_int64_t, int)) _fseek64_wrap,
585 (int (*)(void *)) fclose,
586 (long (*)(void *)) ftell
589 return ov_open_callbacks((void *)f, vf, initial, ibytes, callbacks);
593 int ov_open_callbacks(void *f,OggVorbis_File *vf,char *initial,long ibytes,
594 ov_callbacks callbacks)
596 long offset=callbacks.seek_func(f,0,SEEK_CUR);
599 memset(vf,0,sizeof(OggVorbis_File));
601 vf->callbacks = callbacks;
603 /* init the framing state */
604 ogg_sync_init(&vf->oy);
606 /* perhaps some data was previously read into a buffer for testing
607 against other stream types. Allow initialization from this
608 previously read data (as we may be reading from a non-seekable
611 char *buffer=ogg_sync_buffer(&vf->oy,ibytes);
612 memcpy(buffer,initial,ibytes);
613 ogg_sync_wrote(&vf->oy,ibytes);
616 /* can we seek? Stevens suggests the seek test was portable */
618 ret=_open_seekable(vf);
620 ret=_open_nonseekable(vf);
629 /* How many logical bitstreams in this physical bitstream? */
630 long ov_streams(OggVorbis_File *vf){
634 /* Is the FILE * associated with vf seekable? */
635 long ov_seekable(OggVorbis_File *vf){
639 /* returns the bitrate for a given logical bitstream or the entire
640 physical bitstream. If the file is open for random access, it will
641 find the *actual* average bitrate. If the file is streaming, it
642 returns the nominal bitrate (if set) else the average of the
643 upper/lower bounds (if set) else -1 (unset).
645 If you want the actual bitrate field settings, get them from the
646 vorbis_info structs */
648 long ov_bitrate(OggVorbis_File *vf,int i){
649 if(i>=vf->links)return(-1);
650 if(!vf->seekable && i!=0)return(ov_bitrate(vf,0));
654 for(i=0;i<vf->links;i++)
655 bits+=(vf->offsets[i+1]-vf->dataoffsets[i])*8;
656 return(rint(bits/ov_time_total(vf,-1)));
659 /* return the actual bitrate */
660 return(rint((vf->offsets[i+1]-vf->dataoffsets[i])*8/ov_time_total(vf,i)));
662 /* return nominal if set */
663 if(vf->vi[i].bitrate_nominal>0){
664 return vf->vi[i].bitrate_nominal;
666 if(vf->vi[i].bitrate_upper>0){
667 if(vf->vi[i].bitrate_lower>0){
668 return (vf->vi[i].bitrate_upper+vf->vi[i].bitrate_lower)/2;
670 return vf->vi[i].bitrate_upper;
679 /* returns the actual bitrate since last call. returns -1 if no
680 additional data to offer since last call (or at beginning of stream) */
681 long ov_bitrate_instant(OggVorbis_File *vf){
682 int link=(vf->seekable?vf->current_link:0);
684 if(vf->samptrack==0)return(-1);
685 ret=vf->bittrack/vf->samptrack*vf->vi[link].rate+.5;
692 long ov_serialnumber(OggVorbis_File *vf,int i){
693 if(i>=vf->links)return(-1);
694 if(!vf->seekable && i>=0)return(ov_serialnumber(vf,-1));
696 return(vf->current_serialno);
698 return(vf->serialnos[i]);
702 /* returns: total raw (compressed) length of content if i==-1
703 raw (compressed) length of that logical bitstream for i==0 to n
704 -1 if the stream is not seekable (we can't know the length)
706 ogg_int64_t ov_raw_total(OggVorbis_File *vf,int i){
707 if(!vf->seekable || i>=vf->links)return(-1);
711 for(i=0;i<vf->links;i++)
712 acc+=ov_raw_total(vf,i);
715 return(vf->offsets[i+1]-vf->offsets[i]);
719 /* returns: total PCM length (samples) of content if i==-1
720 PCM length (samples) of that logical bitstream for i==0 to n
721 -1 if the stream is not seekable (we can't know the length)
723 ogg_int64_t ov_pcm_total(OggVorbis_File *vf,int i){
724 if(!vf->seekable || i>=vf->links)return(-1);
728 for(i=0;i<vf->links;i++)
729 acc+=ov_pcm_total(vf,i);
732 return(vf->pcmlengths[i]);
736 /* returns: total seconds of content if i==-1
737 seconds in that logical bitstream for i==0 to n
738 -1 if the stream is not seekable (we can't know the length)
740 double ov_time_total(OggVorbis_File *vf,int i){
741 if(!vf->seekable || i>=vf->links)return(-1);
745 for(i=0;i<vf->links;i++)
746 acc+=ov_time_total(vf,i);
749 return((float)(vf->pcmlengths[i])/vf->vi[i].rate);
753 /* seek to an offset relative to the *compressed* data. This also
754 immediately sucks in and decodes pages to update the PCM cursor. It
755 will cross a logical bitstream boundary, but only if it can't get
756 any packets out of the tail of the bitstream we seek to (so no
759 returns zero on success, nonzero on failure */
761 int ov_raw_seek(OggVorbis_File *vf,long pos){
763 if(!vf->seekable)return(-1); /* don't dump machine if we can't seek */
764 if(pos<0 || pos>vf->offsets[vf->links])goto seek_error;
766 /* clear out decoding machine state */
771 _seek_helper(vf,pos);
773 /* we need to make sure the pcm_offset is set. We use the
774 _fetch_packet helper to process one packet with readp set, then
775 call it until it returns '0' with readp not set (the last packet
776 from a page has the 'granulepos' field set, and that's how the
777 helper updates the offset */
779 switch(_process_packet(vf,1)){
781 /* oh, eof. There are no packets remaining. Set the pcm offset to
783 vf->pcm_offset=ov_pcm_total(vf,-1);
786 /* error! missing data or invalid bitstream structure */
794 switch(_process_packet(vf,0)){
796 /* the offset is set. If it's a bogus bitstream with no offset
797 information, it's not but that's not our fault. We still run
798 gracefully, we're just missing the offset */
801 /* error! missing data or invalid bitstream structure */
804 /* continue processing packets */
810 /* dump the machine so we're in a known state */
816 /* Page granularity seek (faster than sample granularity because we
817 don't do the last bit of decode to find a specific sample).
819 Seek to the last [granule marked] page preceeding the specified pos
820 location, such that decoding past the returned point will quickly
821 arrive at the requested position. */
822 int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos){
824 ogg_int64_t total=ov_pcm_total(vf,-1);
826 if(!vf->seekable)return(-1); /* don't dump machine if we can't seek */
827 if(pos<0 || pos>total)goto seek_error;
829 /* which bitstream section does this pcm offset occur in? */
830 for(link=vf->links-1;link>=0;link--){
831 total-=vf->pcmlengths[link];
835 /* search within the logical bitstream for the page with the highest
836 pcm_pos preceeding (or equal to) pos. There is a danger here;
837 missing pages or incorrect frame number information in the
838 bitstream could make our task impossible. Account for that (it
839 would be an error condition) */
841 ogg_int64_t target=pos-total;
842 long end=vf->offsets[link+1];
843 long begin=vf->offsets[link];
851 if(end-begin<CHUNKSIZE){
854 bisect=(end+begin)/2;
857 _seek_helper(vf,bisect);
858 ret=_get_next_page(vf,&og,end-bisect);
863 ogg_int64_t granulepos=ogg_page_granulepos(&og);
864 if(granulepos<target){
865 best=ret; /* raw offset of packet with granulepos */
866 begin=vf->offset; /* raw offset of next packet */
873 /* found our page. seek to it (call raw_seek). */
875 if(ov_raw_seek(vf,best))goto seek_error;
879 if(vf->pcm_offset>=pos)goto seek_error;
880 if(pos>ov_pcm_total(vf,-1))goto seek_error;
884 /* dump machine so we're in a known state */
890 /* seek to a sample offset relative to the decompressed pcm stream
891 returns zero on success, nonzero on failure */
893 int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos){
894 if(ov_pcm_seek_page(vf,pos))return(-1);
896 /* discard samples until we reach the desired position. Crossing a
897 logical bitstream boundary with abandon is OK. */
898 while(vf->pcm_offset<pos){
900 long target=pos-vf->pcm_offset;
901 long samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
903 if(samples>target)samples=target;
904 vorbis_synthesis_read(&vf->vd,samples);
905 vf->pcm_offset+=samples;
908 if(_process_packet(vf,1)==0)
909 vf->pcm_offset=ov_pcm_total(vf,-1); /* eof */
914 /* seek to a playback time relative to the decompressed pcm stream
915 returns zero on success, nonzero on failure */
916 int ov_time_seek(OggVorbis_File *vf,double seconds){
917 /* translate time to PCM position and call ov_pcm_seek */
920 ogg_int64_t pcm_total=ov_pcm_total(vf,-1);
921 double time_total=ov_time_total(vf,-1);
923 if(!vf->seekable)return(-1); /* don't dump machine if we can't seek */
924 if(seconds<0 || seconds>time_total)goto seek_error;
926 /* which bitstream section does this time offset occur in? */
927 for(link=vf->links-1;link>=0;link--){
928 pcm_total-=vf->pcmlengths[link];
929 time_total-=ov_time_total(vf,link);
930 if(seconds>=time_total)break;
933 /* enough information to convert time offset to pcm offset */
935 ogg_int64_t target=pcm_total+(seconds-time_total)*vf->vi[link].rate;
936 return(ov_pcm_seek(vf,target));
940 /* dump machine so we're in a known state */
946 /* page-granularity version of ov_time_seek
947 returns zero on success, nonzero on failure */
948 int ov_time_seek_page(OggVorbis_File *vf,double seconds){
949 /* translate time to PCM position and call ov_pcm_seek */
952 ogg_int64_t pcm_total=ov_pcm_total(vf,-1);
953 double time_total=ov_time_total(vf,-1);
955 if(!vf->seekable)return(-1); /* don't dump machine if we can't seek */
956 if(seconds<0 || seconds>time_total)goto seek_error;
958 /* which bitstream section does this time offset occur in? */
959 for(link=vf->links-1;link>=0;link--){
960 pcm_total-=vf->pcmlengths[link];
961 time_total-=ov_time_total(vf,link);
962 if(seconds>=time_total)break;
965 /* enough information to convert time offset to pcm offset */
967 ogg_int64_t target=pcm_total+(seconds-time_total)*vf->vi[link].rate;
968 return(ov_pcm_seek_page(vf,target));
972 /* dump machine so we're in a known state */
978 /* tell the current stream offset cursor. Note that seek followed by
979 tell will likely not give the set offset due to caching */
980 ogg_int64_t ov_raw_tell(OggVorbis_File *vf){
984 /* return PCM offset (sample) of next PCM sample to be read */
985 ogg_int64_t ov_pcm_tell(OggVorbis_File *vf){
986 return(vf->pcm_offset);
989 /* return time offset (seconds) of next PCM sample to be read */
990 double ov_time_tell(OggVorbis_File *vf){
991 /* translate time to PCM position and call ov_pcm_seek */
994 ogg_int64_t pcm_total=0;
995 double time_total=0.;
998 pcm_total=ov_pcm_total(vf,-1);
999 time_total=ov_time_total(vf,-1);
1001 /* which bitstream section does this time offset occur in? */
1002 for(link=vf->links-1;link>=0;link--){
1003 pcm_total-=vf->pcmlengths[link];
1004 time_total-=ov_time_total(vf,link);
1005 if(vf->pcm_offset>=pcm_total)break;
1009 return((double)time_total+(double)(vf->pcm_offset-pcm_total)/vf->vi[link].rate);
1012 /* link: -1) return the vorbis_info struct for the bitstream section
1013 currently being decoded
1014 0-n) to request information for a specific bitstream section
1016 In the case of a non-seekable bitstream, any call returns the
1017 current bitstream. NULL in the case that the machine is not
1020 vorbis_info *ov_info(OggVorbis_File *vf,int link){
1023 if(vf->decode_ready)
1024 return vf->vi+vf->current_link;
1033 if(vf->decode_ready)
1040 /* grr, strong typing, grr, no templates/inheritence, grr */
1041 vorbis_comment *ov_comment(OggVorbis_File *vf,int link){
1044 if(vf->decode_ready)
1045 return vf->vc+vf->current_link;
1054 if(vf->decode_ready)
1061 int host_is_big_endian() {
1062 short pattern = 0xbabe;
1063 unsigned char *bytewise = (unsigned char *)&pattern;
1064 if (bytewise[0] == 0xba) return 1;
1066 assert(bytewise[0] == 0xbe);
1070 /* up to this point, everything could more or less hide the multiple
1071 logical bitstream nature of chaining from the toplevel application
1072 if the toplevel application didn't particularly care. However, at
1073 the point that we actually read audio back, the multiple-section
1074 nature must surface: Multiple bitstream sections do not necessarily
1075 have to have the same number of channels or sampling rate.
1077 ov_read returns the sequential logical bitstream number currently
1078 being decoded along with the PCM data in order that the toplevel
1079 application can take action on channel/sample rate changes. This
1080 number will be incremented even for streamed (non-seekable) streams
1081 (for seekable streams, it represents the actual logical bitstream
1082 index within the physical bitstream. Note that the accessor
1083 functions above are aware of this dichotomy).
1085 input values: buffer) a buffer to hold packed PCM data for return
1086 length) the byte length requested to be placed into buffer
1087 bigendianp) should the data be packed LSB first (0) or
1089 word) word size for output. currently 1 (byte) or
1092 return values: -1) error/hole in data
1094 n) number of bytes of PCM actually returned. The
1095 below works on a packet-by-packet basis, so the
1096 return length is not related to the 'length' passed
1097 in, just guaranteed to fit.
1099 *section) set to the logical bitstream number */
1101 long ov_read(OggVorbis_File *vf,char *buffer,int length,
1102 int bigendianp,int word,int sgned,int *bitstream){
1104 int host_endian = host_is_big_endian();
1107 if(vf->decode_ready){
1109 long samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
1111 /* yay! proceed to pack data into the byte buffer */
1113 long channels=ov_info(vf,-1)->channels;
1114 long bytespersample=word * channels;
1115 if(samples>length/bytespersample)samples=length/bytespersample;
1117 /* a tight loop to pack each size */
1121 int off=(sgned?0:128);
1122 for(j=0;j<samples;j++)
1123 for(i=0;i<channels;i++){
1124 val=(int)(pcm[i][j]*128. + 0.5);
1126 else if(val<-128)val=-128;
1130 int off=(sgned?0:32768);
1132 if(host_endian==bigendianp){
1134 for(i=0;i<channels;i++) { /* It's faster in this order */
1136 short *dest=((short *)buffer)+i;
1137 for(j=0;j<samples;j++) {
1138 val=(int)(src[j]*32768. + 0.5);
1139 if(val>32767)val=32767;
1140 else if(val<-32768)val=-32768;
1146 for(i=0;i<channels;i++) {
1148 short *dest=((short *)buffer)+i;
1149 for(j=0;j<samples;j++) {
1150 val=(int)(src[j]*32768. + 0.5);
1151 if(val>32767)val=32767;
1152 else if(val<-32768)val=-32768;
1158 }else if(bigendianp){
1159 for(j=0;j<samples;j++)
1160 for(i=0;i<channels;i++){
1161 val=(int)(pcm[i][j]*32768. + 0.5);
1162 if(val>32767)val=32767;
1163 else if(val<-32768)val=-32768;
1166 *buffer++=(val&0xff);
1170 for(j=0;j<samples;j++)
1171 for(i=0;i<channels;i++){
1172 val=(int)(pcm[i][j]*32768. + 0.5);
1173 if(val>32767)val=32767;
1174 else if(val<-32768)val=-32768;
1176 *buffer++=(val&0xff);
1184 vorbis_synthesis_read(&vf->vd,samples);
1185 vf->pcm_offset+=samples;
1186 if(bitstream)*bitstream=vf->current_link;
1187 return(samples*bytespersample);
1191 /* suck in another packet */
1192 switch(_process_packet(vf,1)){