1 /********************************************************************
3 * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
4 * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
5 * THE GNU LESSER/LIBRARY PUBLIC LICENSE, WHICH IS INCLUDED WITH *
6 * THIS SOURCE. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
8 * THE OggVorbis 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.33 2000/11/29 21:13:34 xiphmont Exp $
17 ********************************************************************/
24 #include "vorbis/codec.h"
25 #include "vorbis/vorbisfile.h"
30 /* A 'chained bitstream' is a Vorbis bitstream that contains more than
31 one logical bitstream arranged end to end (the only form of Ogg
32 multiplexing allowed in a Vorbis bitstream; grouping [parallel
33 multiplexing] is not allowed in Vorbis) */
35 /* A Vorbis file can be played beginning to end (streamed) without
36 worrying ahead of time about chaining (see decoder_example.c). If
37 we have the whole file, however, and want random access
38 (seeking/scrubbing) or desire to know the total length/time of a
39 file, we need to account for the possibility of chaining. */
41 /* We can handle things a number of ways; we can determine the entire
42 bitstream structure right off the bat, or find pieces on demand.
43 This example determines and caches structure for the entire
44 bitstream, but builds a virtual decoder on the fly when moving
45 between links in the chain. */
47 /* There are also different ways to implement seeking. Enough
48 information exists in an Ogg bitstream to seek to
49 sample-granularity positions in the output. Or, one can seek by
50 picking some portion of the stream roughly in the desired area if
51 we only want course navigation through the stream. */
53 /*************************************************************************
54 * Many, many internal helpers. The intention is not to be confusing;
55 * rampant duplication and monolithic function implementation would be
56 * harder to understand anyway. The high level functions are last. Begin
57 * grokking near the end of the file */
59 /* read a little more data from the file/pipe into the ogg_sync framer */
60 #define CHUNKSIZE 4096
61 static long _get_data(OggVorbis_File *vf){
62 char *buffer=ogg_sync_buffer(&vf->oy,CHUNKSIZE);
63 long bytes=(vf->callbacks.read_func)(buffer,1,CHUNKSIZE,vf->datasource);
64 if(bytes>0)ogg_sync_wrote(&vf->oy,bytes);
68 /* save a tiny smidge of verbosity to make the code more readable */
69 static void _seek_helper(OggVorbis_File *vf,long offset){
70 (vf->callbacks.seek_func)(vf->datasource, offset, SEEK_SET);
72 ogg_sync_reset(&vf->oy);
75 /* The read/seek functions track absolute position within the stream */
77 /* from the head of the stream, get the next page. boundary specifies
78 if the function is allowed to fetch more data from the stream (and
79 how much) or only use internally buffered data.
81 boundary: -1) unbounded search
82 0) read no additional data; use cached only
83 n) search for a new page beginning for n bytes
85 return: <0) did not find a page (OV_FALSE, OV_EOF, OV_EREAD)
86 n) found a page at absolute offset n */
88 static long _get_next_page(OggVorbis_File *vf,ogg_page *og,int boundary){
89 if(boundary>0)boundary+=vf->offset;
93 if(boundary>0 && vf->offset>=boundary)return(OV_FALSE);
94 more=ogg_sync_pageseek(&vf->oy,og);
101 /* send more paramedics */
102 if(!boundary)return(OV_FALSE);
104 long ret=_get_data(vf);
105 if(ret==0)return(OV_EOF);
106 if(ret<0)return(OV_EREAD);
109 /* got a page. Return the offset at the page beginning,
110 advance the internal offset past the page end */
120 /* find the latest page beginning before the current stream cursor
121 position. Much dirtier than the above as Ogg doesn't have any
122 backward search linkage. no 'readp' as it will certainly have to
124 /* returns offset or OV_EREAD, OV_FAULT */
125 static long _get_prev_page(OggVorbis_File *vf,ogg_page *og){
126 long begin=vf->offset;
132 _seek_helper(vf,begin);
133 while(vf->offset<begin+CHUNKSIZE){
134 ret=_get_next_page(vf,og,begin+CHUNKSIZE-vf->offset);
135 if(ret==OV_EREAD)return(OV_EREAD);
144 /* we have the offset. Actually snork and hold the page now */
145 _seek_helper(vf,offset);
146 ret=_get_next_page(vf,og,CHUNKSIZE);
148 /* this shouldn't be possible */
154 /* finds each bitstream link one at a time using a bisection search
155 (has to begin by knowing the offset of the lb's initial page).
156 Recurses for each link so it can alloc the link storage after
157 finding them all, then unroll and fill the cache at the same time */
158 static int _bisect_forward_serialno(OggVorbis_File *vf,
164 long endsearched=end;
169 /* the below guards against garbage seperating the last and
170 first pages of two links. */
171 while(searched<endsearched){
174 if(endsearched-searched<CHUNKSIZE){
177 bisect=(searched+endsearched)/2;
180 _seek_helper(vf,bisect);
181 ret=_get_next_page(vf,&og,-1);
182 if(ret==OV_EREAD)return(OV_EREAD);
183 if(ret<0 || ogg_page_serialno(&og)!=currentno){
187 searched=ret+og.header_len+og.body_len;
191 _seek_helper(vf,next);
192 ret=_get_next_page(vf,&og,-1);
193 if(ret==OV_EREAD)return(OV_EREAD);
195 if(searched>=end || ret<0){
197 vf->offsets=_ogg_malloc((m+2)*sizeof(ogg_int64_t));
198 vf->offsets[m+1]=searched;
200 ret=_bisect_forward_serialno(vf,next,vf->offset,
201 end,ogg_page_serialno(&og),m+1);
202 if(ret==OV_EREAD)return(OV_EREAD);
205 vf->offsets[m]=begin;
209 /* uses the local ogg_stream storage in vf; this is important for
210 non-streaming input sources */
211 static int _fetch_headers(OggVorbis_File *vf,vorbis_info *vi,vorbis_comment *vc,
212 long *serialno,ogg_page *og_ptr){
218 ret=_get_next_page(vf,&og,CHUNKSIZE);
219 if(ret==OV_EREAD)return(OV_EREAD);
220 if(ret<0)return OV_ENOTVORBIS;
224 if(serialno)*serialno=ogg_page_serialno(og_ptr);
225 ogg_stream_init(&vf->os,ogg_page_serialno(og_ptr));
227 /* extract the initial header from the first page and verify that the
228 Ogg bitstream is in fact Vorbis data */
230 vorbis_info_init(vi);
231 vorbis_comment_init(vc);
235 ogg_stream_pagein(&vf->os,og_ptr);
237 int result=ogg_stream_packetout(&vf->os,&op);
243 if((ret=vorbis_synthesis_headerin(vi,vc,&op))){
249 if(_get_next_page(vf,og_ptr,1)<0){
257 vorbis_info_clear(vi);
258 vorbis_comment_clear(vc);
259 ogg_stream_clear(&vf->os);
263 /* last step of the OggVorbis_File initialization; get all the
264 vorbis_info structs and PCM positions. Only called by the seekable
265 initialization (local stream storage is hacked slightly; pay
266 attention to how that's done) */
268 /* this is void and does not propogate errors up because we want to be
269 able to open and use damaged bitstreams as well as we can. Just
270 watch out for missing information for links in the OggVorbis_File
272 static void _prefetch_all_headers(OggVorbis_File *vf,vorbis_info *first_i,
273 vorbis_comment *first_c,
278 vf->vi=_ogg_calloc(vf->links,sizeof(vorbis_info));
279 vf->vc=_ogg_calloc(vf->links,sizeof(vorbis_info));
280 vf->dataoffsets=_ogg_malloc(vf->links*sizeof(ogg_int64_t));
281 vf->pcmlengths=_ogg_malloc(vf->links*sizeof(ogg_int64_t));
282 vf->serialnos=_ogg_malloc(vf->links*sizeof(long));
284 for(i=0;i<vf->links;i++){
285 if(first_i && first_c && i==0){
286 /* we already grabbed the initial header earlier. This just
287 saves the waste of grabbing it again */
288 memcpy(vf->vi+i,first_i,sizeof(vorbis_info));
289 memcpy(vf->vc+i,first_c,sizeof(vorbis_comment));
290 vf->dataoffsets[i]=dataoffset;
293 /* seek to the location of the initial header */
295 _seek_helper(vf,vf->offsets[i]);
296 if(_fetch_headers(vf,vf->vi+i,vf->vc+i,NULL,NULL)<0){
297 vf->dataoffsets[i]=-1;
299 vf->dataoffsets[i]=vf->offset;
300 ogg_stream_clear(&vf->os);
304 /* get the serial number and PCM length of this link. To do this,
305 get the last page of the stream */
307 long end=vf->offsets[i+1];
308 _seek_helper(vf,end);
311 ret=_get_prev_page(vf,&og);
313 /* this should not be possible, actually */
314 vorbis_info_clear(vf->vi+i);
315 vorbis_comment_clear(vf->vc+i);
318 if(ogg_page_granulepos(&og)!=-1){
319 vf->serialnos[i]=ogg_page_serialno(&og);
320 vf->pcmlengths[i]=ogg_page_granulepos(&og);
328 static void _make_decode_ready(OggVorbis_File *vf){
329 if(vf->decode_ready)return;
331 vorbis_synthesis_init(&vf->vd,vf->vi+vf->current_link);
333 vorbis_synthesis_init(&vf->vd,vf->vi);
335 vorbis_block_init(&vf->vd,&vf->vb);
340 static int _open_seekable(OggVorbis_File *vf){
341 vorbis_info initial_i;
342 vorbis_comment initial_c;
348 /* is this even vorbis...? */
349 ret=_fetch_headers(vf,&initial_i,&initial_c,&serialno,NULL);
350 dataoffset=vf->offset;
351 ogg_stream_clear(&vf->os);
352 if(ret<0)return(ret);
354 /* we can seek, so set out learning all about this file */
356 (vf->callbacks.seek_func)(vf->datasource,0,SEEK_END);
357 vf->offset=vf->end=(vf->callbacks.tell_func)(vf->datasource);
359 /* We get the offset for the last page of the physical bitstream.
360 Most OggVorbis files will contain a single logical bitstream */
361 end=_get_prev_page(vf,&og);
363 ogg_stream_clear(&vf->os);
367 /* more than one logical bitstream? */
368 if(ogg_page_serialno(&og)!=serialno){
370 /* Chained bitstream. Bisect-search each logical bitstream
371 section. Do so based on serial number only */
372 if(_bisect_forward_serialno(vf,0,0,end+1,serialno,0)<0){
373 ogg_stream_clear(&vf->os);
379 /* Only one logical bitstream */
380 if(_bisect_forward_serialno(vf,0,end,end+1,serialno,0)){
381 ogg_stream_clear(&vf->os);
387 _prefetch_all_headers(vf,&initial_i,&initial_c,dataoffset);
388 return(ov_raw_seek(vf,0));
392 static int _open_nonseekable(OggVorbis_File *vf){
394 /* we cannot seek. Set up a 'single' (current) logical bitstream entry */
396 vf->vi=_ogg_calloc(vf->links,sizeof(vorbis_info));
397 vf->vc=_ogg_calloc(vf->links,sizeof(vorbis_info));
399 /* Try to fetch the headers, maintaining all the storage */
400 if((ret=_fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno,NULL))<0)
402 _make_decode_ready(vf);
407 /* clear out the current logical bitstream decoder */
408 static void _decode_clear(OggVorbis_File *vf){
409 ogg_stream_clear(&vf->os);
410 vorbis_dsp_clear(&vf->vd);
411 vorbis_block_clear(&vf->vb);
418 /* fetch and process a packet. Handles the case where we're at a
419 bitstream boundary and dumps the decoding machine. If the decoding
420 machine is unloaded, it loads it. It also keeps pcm_offset up to
421 date (seek and read both use this. seek uses a special hack with
424 return: <0) error, OV_HOLE (lost packet) or OV_EOF
425 0) need more data (only if readp==0)
429 static int _process_packet(OggVorbis_File *vf,int readp){
432 /* handle one packet. Try to fetch it from current stream state */
433 /* extract packets from page */
436 /* process a packet if we can. If the machine isn't loaded,
438 if(vf->decode_ready){
440 int result=ogg_stream_packetout(&vf->os,&op);
441 ogg_int64_t granulepos;
443 if(result==-1)return(OV_HOLE); /* hole in the data. */
445 /* got a packet. process it */
446 granulepos=op.granulepos;
447 if(!vorbis_synthesis(&vf->vb,&op)){ /* lazy check for lazy
449 header packets aren't
452 vorbis_synthesis will
455 /* suck in the synthesis data and track bitrate */
457 int oldsamples=vorbis_synthesis_pcmout(&vf->vd,NULL);
458 vorbis_synthesis_blockin(&vf->vd,&vf->vb);
459 vf->samptrack+=vorbis_synthesis_pcmout(&vf->vd,NULL)-oldsamples;
460 vf->bittrack+=op.bytes*8;
463 /* update the pcm offset. */
464 if(granulepos!=-1 && !op.e_o_s){
465 int link=(vf->seekable?vf->current_link:0);
468 /* this packet has a pcm_offset on it (the last packet
469 completed on a page carries the offset) After processing
470 (above), we know the pcm position of the *last* sample
471 ready to be returned. Find the offset of the *first*
473 As an aside, this trick is inaccurate if we begin
474 reading anew right at the last page; the end-of-stream
475 granulepos declares the last frame in the stream, and the
476 last packet of the last page may be a partial frame.
477 So, we need a previous granulepos from an in-sequence page
478 to have a reference point. Thus the !op.e_o_s clause
481 samples=vorbis_synthesis_pcmout(&vf->vd,NULL);
485 granulepos+=vf->pcmlengths[i];
486 vf->pcm_offset=granulepos;
494 if(_get_next_page(vf,&og,-1)<0)return(OV_EOF); /* eof. leave unitialized */
496 /* bitrate tracking; add the header's bytes here, the body bytes
497 are done by packet above */
498 vf->bittrack+=og.header_len*8;
500 /* has our decoding just traversed a bitstream boundary? */
501 if(vf->decode_ready){
502 if(vf->current_serialno!=ogg_page_serialno(&og)){
507 /* Do we need to load a new machine before submitting the page? */
508 /* This is different in the seekable and non-seekable cases.
510 In the seekable case, we already have all the header
511 information loaded and cached; we just initialize the machine
512 with it and continue on our merry way.
514 In the non-seekable (streaming) case, we'll only be at a
515 boundary if we just left the previous logical bitstream and
516 we're now nominally at the header of the next bitstream
519 if(!vf->decode_ready){
522 vf->current_serialno=ogg_page_serialno(&og);
524 /* match the serialno to bitstream section. We use this rather than
525 offset positions to avoid problems near logical bitstream
527 for(link=0;link<vf->links;link++)
528 if(vf->serialnos[link]==vf->current_serialno)break;
529 if(link==vf->links)return(OV_EBADLINK); /* sign of a bogus
534 vf->current_link=link;
536 ogg_stream_init(&vf->os,vf->current_serialno);
537 ogg_stream_reset(&vf->os);
540 /* we're streaming */
541 /* fetch the three header packets, build the info struct */
543 _fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno,&og);
548 _make_decode_ready(vf);
550 ogg_stream_pagein(&vf->os,&og);
554 /**********************************************************************
555 * The helpers are over; it's all toplevel interface from here on out */
557 /* clear out the OggVorbis_File struct */
558 int ov_clear(OggVorbis_File *vf){
560 vorbis_block_clear(&vf->vb);
561 vorbis_dsp_clear(&vf->vd);
562 ogg_stream_clear(&vf->os);
564 if(vf->vi && vf->links){
566 for(i=0;i<vf->links;i++){
567 vorbis_info_clear(vf->vi+i);
568 vorbis_comment_clear(vf->vc+i);
573 if(vf->dataoffsets)_ogg_free(vf->dataoffsets);
574 if(vf->pcmlengths)_ogg_free(vf->pcmlengths);
575 if(vf->serialnos)_ogg_free(vf->serialnos);
576 if(vf->offsets)_ogg_free(vf->offsets);
577 ogg_sync_clear(&vf->oy);
578 if(vf->datasource)(vf->callbacks.close_func)(vf->datasource);
579 memset(vf,0,sizeof(OggVorbis_File));
587 static int _fseek64_wrap(FILE *f,ogg_int64_t off,int whence){
588 return fseek(f,(int)off,whence);
591 /* inspects the OggVorbis file and finds/documents all the logical
592 bitstreams contained in it. Tries to be tolerant of logical
593 bitstream sections that are truncated/woogie.
599 int ov_open(FILE *f,OggVorbis_File *vf,char *initial,long ibytes){
600 ov_callbacks callbacks = {
601 (size_t (*)(void *, size_t, size_t, void *)) fread,
602 (int (*)(void *, ogg_int64_t, int)) _fseek64_wrap,
603 (int (*)(void *)) fclose,
604 (long (*)(void *)) ftell
607 return ov_open_callbacks((void *)f, vf, initial, ibytes, callbacks);
611 int ov_open_callbacks(void *f,OggVorbis_File *vf,char *initial,long ibytes,
612 ov_callbacks callbacks)
614 long offset=callbacks.seek_func(f,0,SEEK_CUR);
617 memset(vf,0,sizeof(OggVorbis_File));
619 vf->callbacks = callbacks;
621 /* init the framing state */
622 ogg_sync_init(&vf->oy);
624 /* perhaps some data was previously read into a buffer for testing
625 against other stream types. Allow initialization from this
626 previously read data (as we may be reading from a non-seekable
629 char *buffer=ogg_sync_buffer(&vf->oy,ibytes);
630 memcpy(buffer,initial,ibytes);
631 ogg_sync_wrote(&vf->oy,ibytes);
634 /* can we seek? Stevens suggests the seek test was portable */
636 ret=_open_seekable(vf);
638 ret=_open_nonseekable(vf);
647 /* How many logical bitstreams in this physical bitstream? */
648 long ov_streams(OggVorbis_File *vf){
652 /* Is the FILE * associated with vf seekable? */
653 long ov_seekable(OggVorbis_File *vf){
657 /* returns the bitrate for a given logical bitstream or the entire
658 physical bitstream. If the file is open for random access, it will
659 find the *actual* average bitrate. If the file is streaming, it
660 returns the nominal bitrate (if set) else the average of the
661 upper/lower bounds (if set) else -1 (unset).
663 If you want the actual bitrate field settings, get them from the
664 vorbis_info structs */
666 long ov_bitrate(OggVorbis_File *vf,int i){
667 if(i>=vf->links)return(OV_EINVAL);
668 if(!vf->seekable && i!=0)return(ov_bitrate(vf,0));
672 for(i=0;i<vf->links;i++)
673 bits+=(vf->offsets[i+1]-vf->dataoffsets[i])*8;
674 return(rint(bits/ov_time_total(vf,-1)));
677 /* return the actual bitrate */
678 return(rint((vf->offsets[i+1]-vf->dataoffsets[i])*8/ov_time_total(vf,i)));
680 /* return nominal if set */
681 if(vf->vi[i].bitrate_nominal>0){
682 return vf->vi[i].bitrate_nominal;
684 if(vf->vi[i].bitrate_upper>0){
685 if(vf->vi[i].bitrate_lower>0){
686 return (vf->vi[i].bitrate_upper+vf->vi[i].bitrate_lower)/2;
688 return vf->vi[i].bitrate_upper;
697 /* returns the actual bitrate since last call. returns -1 if no
698 additional data to offer since last call (or at beginning of stream) */
699 long ov_bitrate_instant(OggVorbis_File *vf){
700 int link=(vf->seekable?vf->current_link:0);
702 if(vf->samptrack==0)return(OV_FALSE);
703 ret=vf->bittrack/vf->samptrack*vf->vi[link].rate+.5;
710 long ov_serialnumber(OggVorbis_File *vf,int i){
711 if(i>=vf->links)return(ov_serialnumber(vf,vf->links-1));
712 if(!vf->seekable && i>=0)return(ov_serialnumber(vf,-1));
714 return(vf->current_serialno);
716 return(vf->serialnos[i]);
720 /* returns: total raw (compressed) length of content if i==-1
721 raw (compressed) length of that logical bitstream for i==0 to n
722 -1 if the stream is not seekable (we can't know the length)
724 ogg_int64_t ov_raw_total(OggVorbis_File *vf,int i){
725 if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
729 for(i=0;i<vf->links;i++)
730 acc+=ov_raw_total(vf,i);
733 return(vf->offsets[i+1]-vf->offsets[i]);
737 /* returns: total PCM length (samples) of content if i==-1
738 PCM length (samples) of that logical bitstream for i==0 to n
739 -1 if the stream is not seekable (we can't know the length)
741 ogg_int64_t ov_pcm_total(OggVorbis_File *vf,int i){
742 if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
746 for(i=0;i<vf->links;i++)
747 acc+=ov_pcm_total(vf,i);
750 return(vf->pcmlengths[i]);
754 /* returns: total seconds of content if i==-1
755 seconds in that logical bitstream for i==0 to n
756 -1 if the stream is not seekable (we can't know the length)
758 double ov_time_total(OggVorbis_File *vf,int i){
759 if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
763 for(i=0;i<vf->links;i++)
764 acc+=ov_time_total(vf,i);
767 return((float)(vf->pcmlengths[i])/vf->vi[i].rate);
771 /* seek to an offset relative to the *compressed* data. This also
772 immediately sucks in and decodes pages to update the PCM cursor. It
773 will cross a logical bitstream boundary, but only if it can't get
774 any packets out of the tail of the bitstream we seek to (so no
777 returns zero on success, nonzero on failure */
779 int ov_raw_seek(OggVorbis_File *vf,long pos){
781 if(!vf->seekable)return(OV_ENOSEEK); /* don't dump machine if we can't seek */
782 if(pos<0 || pos>vf->offsets[vf->links])return(OV_EINVAL);
784 /* clear out decoding machine state */
789 _seek_helper(vf,pos);
791 /* we need to make sure the pcm_offset is set. We use the
792 _fetch_packet helper to process one packet with readp set, then
793 call it until it returns '0' with readp not set (the last packet
794 from a page has the 'granulepos' field set, and that's how the
795 helper updates the offset */
798 switch(_process_packet(vf,1)){
800 /* oh, eof. There are no packets remaining. Set the pcm offset to
802 vf->pcm_offset=ov_pcm_total(vf,-1);
816 /* don't have to check each time through for the updated granule;
817 it's always the last complete packet on a page */
818 switch(_process_packet(vf,0)){
820 /* the offset is set unless it's a bogus bitstream with no
821 offset information but that's not our fault. We still run
822 gracefully, we're just missing the offset */
827 /* continue processing packets */
833 /* dump the machine so we're in a known state */
839 /* Page granularity seek (faster than sample granularity because we
840 don't do the last bit of decode to find a specific sample).
842 Seek to the last [granule marked] page preceeding the specified pos
843 location, such that decoding past the returned point will quickly
844 arrive at the requested position. */
845 int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos){
848 ogg_int64_t total=ov_pcm_total(vf,-1);
850 if(!vf->seekable)return(OV_ENOSEEK);
851 if(pos<0 || pos>total)return(OV_EINVAL);
853 /* which bitstream section does this pcm offset occur in? */
854 for(link=vf->links-1;link>=0;link--){
855 total-=vf->pcmlengths[link];
859 /* search within the logical bitstream for the page with the highest
860 pcm_pos preceeding (or equal to) pos. There is a danger here;
861 missing pages or incorrect frame number information in the
862 bitstream could make our task impossible. Account for that (it
863 would be an error condition) */
865 ogg_int64_t target=pos-total;
866 long end=vf->offsets[link+1];
867 long begin=vf->offsets[link];
874 if(end-begin<CHUNKSIZE){
877 bisect=(end+begin)/2;
880 _seek_helper(vf,bisect);
881 ret=_get_next_page(vf,&og,end-bisect);
883 case OV_FALSE: case OV_EOF:
890 ogg_int64_t granulepos=ogg_page_granulepos(&og);
891 if(granulepos<target){
892 best=ret; /* raw offset of packet with granulepos */
893 begin=vf->offset; /* raw offset of next packet */
901 /* found our page. seek to it (call raw_seek). */
903 if((ret=ov_raw_seek(vf,best)))goto seek_error;
907 if(vf->pcm_offset>=pos || pos>ov_pcm_total(vf,-1)){
914 /* dump machine so we're in a known state */
920 /* seek to a sample offset relative to the decompressed pcm stream
921 returns zero on success, nonzero on failure */
923 int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos){
924 int ret=ov_pcm_seek_page(vf,pos);
925 if(ret<0)return(ret);
927 /* discard samples until we reach the desired position. Crossing a
928 logical bitstream boundary with abandon is OK. */
929 while(vf->pcm_offset<pos){
931 long target=pos-vf->pcm_offset;
932 long samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
934 if(samples>target)samples=target;
935 vorbis_synthesis_read(&vf->vd,samples);
936 vf->pcm_offset+=samples;
939 if(_process_packet(vf,1)==0)
940 vf->pcm_offset=ov_pcm_total(vf,-1); /* eof */
945 /* seek to a playback time relative to the decompressed pcm stream
946 returns zero on success, nonzero on failure */
947 int ov_time_seek(OggVorbis_File *vf,double seconds){
948 /* translate time to PCM position and call ov_pcm_seek */
951 ogg_int64_t pcm_total=ov_pcm_total(vf,-1);
952 double time_total=ov_time_total(vf,-1);
954 if(!vf->seekable)return(OV_ENOSEEK);
955 if(seconds<0 || seconds>time_total)return(OV_EINVAL);
957 /* which bitstream section does this time offset occur in? */
958 for(link=vf->links-1;link>=0;link--){
959 pcm_total-=vf->pcmlengths[link];
960 time_total-=ov_time_total(vf,link);
961 if(seconds>=time_total)break;
964 /* enough information to convert time offset to pcm offset */
966 ogg_int64_t target=pcm_total+(seconds-time_total)*vf->vi[link].rate;
967 return(ov_pcm_seek(vf,target));
971 /* page-granularity version of ov_time_seek
972 returns zero on success, nonzero on failure */
973 int ov_time_seek_page(OggVorbis_File *vf,double seconds){
974 /* translate time to PCM position and call ov_pcm_seek */
977 ogg_int64_t pcm_total=ov_pcm_total(vf,-1);
978 double time_total=ov_time_total(vf,-1);
980 if(!vf->seekable)return(OV_ENOSEEK);
981 if(seconds<0 || seconds>time_total)return(OV_EINVAL);
983 /* which bitstream section does this time offset occur in? */
984 for(link=vf->links-1;link>=0;link--){
985 pcm_total-=vf->pcmlengths[link];
986 time_total-=ov_time_total(vf,link);
987 if(seconds>=time_total)break;
990 /* enough information to convert time offset to pcm offset */
992 ogg_int64_t target=pcm_total+(seconds-time_total)*vf->vi[link].rate;
993 return(ov_pcm_seek_page(vf,target));
997 /* tell the current stream offset cursor. Note that seek followed by
998 tell will likely not give the set offset due to caching */
999 ogg_int64_t ov_raw_tell(OggVorbis_File *vf){
1003 /* return PCM offset (sample) of next PCM sample to be read */
1004 ogg_int64_t ov_pcm_tell(OggVorbis_File *vf){
1005 return(vf->pcm_offset);
1008 /* return time offset (seconds) of next PCM sample to be read */
1009 double ov_time_tell(OggVorbis_File *vf){
1010 /* translate time to PCM position and call ov_pcm_seek */
1013 ogg_int64_t pcm_total=0;
1014 double time_total=0.;
1017 pcm_total=ov_pcm_total(vf,-1);
1018 time_total=ov_time_total(vf,-1);
1020 /* which bitstream section does this time offset occur in? */
1021 for(link=vf->links-1;link>=0;link--){
1022 pcm_total-=vf->pcmlengths[link];
1023 time_total-=ov_time_total(vf,link);
1024 if(vf->pcm_offset>=pcm_total)break;
1028 return((double)time_total+(double)(vf->pcm_offset-pcm_total)/vf->vi[link].rate);
1031 /* link: -1) return the vorbis_info struct for the bitstream section
1032 currently being decoded
1033 0-n) to request information for a specific bitstream section
1035 In the case of a non-seekable bitstream, any call returns the
1036 current bitstream. NULL in the case that the machine is not
1039 vorbis_info *ov_info(OggVorbis_File *vf,int link){
1042 if(vf->decode_ready)
1043 return vf->vi+vf->current_link;
1052 if(vf->decode_ready)
1059 /* grr, strong typing, grr, no templates/inheritence, grr */
1060 vorbis_comment *ov_comment(OggVorbis_File *vf,int link){
1063 if(vf->decode_ready)
1064 return vf->vc+vf->current_link;
1073 if(vf->decode_ready)
1080 int host_is_big_endian() {
1081 ogg_int32_t pattern = 0xfeedface; /* deadbeef */
1082 unsigned char *bytewise = (unsigned char *)&pattern;
1083 if (bytewise[0] == 0xfe) return 1;
1087 /* up to this point, everything could more or less hide the multiple
1088 logical bitstream nature of chaining from the toplevel application
1089 if the toplevel application didn't particularly care. However, at
1090 the point that we actually read audio back, the multiple-section
1091 nature must surface: Multiple bitstream sections do not necessarily
1092 have to have the same number of channels or sampling rate.
1094 ov_read returns the sequential logical bitstream number currently
1095 being decoded along with the PCM data in order that the toplevel
1096 application can take action on channel/sample rate changes. This
1097 number will be incremented even for streamed (non-seekable) streams
1098 (for seekable streams, it represents the actual logical bitstream
1099 index within the physical bitstream. Note that the accessor
1100 functions above are aware of this dichotomy).
1102 input values: buffer) a buffer to hold packed PCM data for return
1103 length) the byte length requested to be placed into buffer
1104 bigendianp) should the data be packed LSB first (0) or
1106 word) word size for output. currently 1 (byte) or
1109 return values: <0) error/hole in data (OV_HOLE)
1111 n) number of bytes of PCM actually returned. The
1112 below works on a packet-by-packet basis, so the
1113 return length is not related to the 'length' passed
1114 in, just guaranteed to fit.
1116 *section) set to the logical bitstream number */
1118 long ov_read(OggVorbis_File *vf,char *buffer,int length,
1119 int bigendianp,int word,int sgned,int *bitstream){
1121 int host_endian = host_is_big_endian();
1124 if(vf->decode_ready){
1126 long samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
1128 /* yay! proceed to pack data into the byte buffer */
1130 long channels=ov_info(vf,-1)->channels;
1131 long bytespersample=word * channels;
1132 vorbis_fpu_control fpu;
1133 if(samples>length/bytespersample)samples=length/bytespersample;
1135 /* a tight loop to pack each size */
1139 int off=(sgned?0:128);
1140 vorbis_fpu_setround(&fpu);
1141 for(j=0;j<samples;j++)
1142 for(i=0;i<channels;i++){
1143 val=vorbis_ftoi(pcm[i][j]*128.);
1145 else if(val<-128)val=-128;
1148 vorbis_fpu_restore(fpu);
1150 int off=(sgned?0:32768);
1152 if(host_endian==bigendianp){
1155 vorbis_fpu_setround(&fpu);
1156 for(i=0;i<channels;i++) { /* It's faster in this order */
1158 short *dest=((short *)buffer)+i;
1159 for(j=0;j<samples;j++) {
1160 val=vorbis_ftoi(src[j]*32768.);
1161 if(val>32767)val=32767;
1162 else if(val<-32768)val=-32768;
1167 vorbis_fpu_restore(fpu);
1171 vorbis_fpu_setround(&fpu);
1172 for(i=0;i<channels;i++) {
1174 short *dest=((short *)buffer)+i;
1175 for(j=0;j<samples;j++) {
1176 val=vorbis_ftoi(src[j]*32768.);
1177 if(val>32767)val=32767;
1178 else if(val<-32768)val=-32768;
1183 vorbis_fpu_restore(fpu);
1186 }else if(bigendianp){
1188 vorbis_fpu_setround(&fpu);
1189 for(j=0;j<samples;j++)
1190 for(i=0;i<channels;i++){
1191 val=vorbis_ftoi(pcm[i][j]*32768.);
1192 if(val>32767)val=32767;
1193 else if(val<-32768)val=-32768;
1196 *buffer++=(val&0xff);
1198 vorbis_fpu_restore(fpu);
1202 vorbis_fpu_setround(&fpu);
1203 for(j=0;j<samples;j++)
1204 for(i=0;i<channels;i++){
1205 val=vorbis_ftoi(pcm[i][j]*32768.);
1206 if(val>32767)val=32767;
1207 else if(val<-32768)val=-32768;
1209 *buffer++=(val&0xff);
1212 vorbis_fpu_restore(fpu);
1218 vorbis_synthesis_read(&vf->vd,samples);
1219 vf->pcm_offset+=samples;
1220 if(bitstream)*bitstream=vf->current_link;
1221 return(samples*bytespersample);
1225 /* suck in another packet */
1226 switch(_process_packet(vf,1)){
1232 return(OV_EBADLINK);