OPtimized case of seeking within a single link; reset decode state
[platform/upstream/libvorbis.git] / lib / vorbisfile.c
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-2002             *
9  * by the XIPHOPHORUS Company http://www.xiph.org/                  *
10  *                                                                  *
11  ********************************************************************
12
13  function: stdio-based convenience library for opening/seeking/decoding
14  last mod: $Id: vorbisfile.c,v 1.67 2003/03/04 21:22:11 xiphmont Exp $
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 #include "vorbis/vorbisfile.h"
26
27 #include "os.h"
28 #include "misc.h"
29
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) */
34
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. */
40
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. */
46
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 coarse navigation through the stream. */
52
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 */
58
59 /* read a little more data from the file/pipe into the ogg_sync framer
60 */
61 #define CHUNKSIZE 8500 /* a shade over 8k; anyone using pages well
62                           over 8k gets what they deserve */
63 static long _get_data(OggVorbis_File *vf){
64   errno=0;
65   if(vf->datasource){
66     char *buffer=ogg_sync_buffer(&vf->oy,CHUNKSIZE);
67     long bytes=(vf->callbacks.read_func)(buffer,1,CHUNKSIZE,vf->datasource);
68     if(bytes>0)ogg_sync_wrote(&vf->oy,bytes);
69     if(bytes==0 && errno)return(-1);
70     return(bytes);
71   }else
72     return(0);
73 }
74
75 /* save a tiny smidge of verbosity to make the code more readable */
76 static void _seek_helper(OggVorbis_File *vf,ogg_int64_t offset){
77   if(vf->datasource){ 
78     (vf->callbacks.seek_func)(vf->datasource, offset, SEEK_SET);
79     vf->offset=offset;
80     ogg_sync_reset(&vf->oy);
81   }else{
82     /* shouldn't happen unless someone writes a broken callback */
83     return;
84   }
85 }
86
87 /* The read/seek functions track absolute position within the stream */
88
89 /* from the head of the stream, get the next page.  boundary specifies
90    if the function is allowed to fetch more data from the stream (and
91    how much) or only use internally buffered data.
92
93    boundary: -1) unbounded search
94               0) read no additional data; use cached only
95               n) search for a new page beginning for n bytes
96
97    return:   <0) did not find a page (OV_FALSE, OV_EOF, OV_EREAD)
98               n) found a page at absolute offset n */
99
100 static ogg_int64_t _get_next_page(OggVorbis_File *vf,ogg_page *og,
101                                   ogg_int64_t boundary){
102   if(boundary>0)boundary+=vf->offset;
103   while(1){
104     long more;
105
106     if(boundary>0 && vf->offset>=boundary)return(OV_FALSE);
107     more=ogg_sync_pageseek(&vf->oy,og);
108     
109     if(more<0){
110       /* skipped n bytes */
111       vf->offset-=more;
112     }else{
113       if(more==0){
114         /* send more paramedics */
115         if(!boundary)return(OV_FALSE);
116         {
117           long ret=_get_data(vf);
118           if(ret==0)return(OV_EOF);
119           if(ret<0)return(OV_EREAD);
120         }
121       }else{
122         /* got a page.  Return the offset at the page beginning,
123            advance the internal offset past the page end */
124         ogg_int64_t ret=vf->offset;
125         vf->offset+=more;
126         return(ret);
127         
128       }
129     }
130   }
131 }
132
133 /* find the latest page beginning before the current stream cursor
134    position. Much dirtier than the above as Ogg doesn't have any
135    backward search linkage.  no 'readp' as it will certainly have to
136    read. */
137 /* returns offset or OV_EREAD, OV_FAULT */
138 static ogg_int64_t _get_prev_page(OggVorbis_File *vf,ogg_page *og){
139   ogg_int64_t begin=vf->offset;
140   ogg_int64_t end=begin;
141   ogg_int64_t ret;
142   ogg_int64_t offset=-1;
143
144   while(offset==-1){
145     begin-=CHUNKSIZE;
146     if(begin<0)
147       begin=0;
148     _seek_helper(vf,begin);
149     while(vf->offset<end){
150       ret=_get_next_page(vf,og,end-vf->offset);
151       if(ret==OV_EREAD)return(OV_EREAD);
152       if(ret<0){
153         break;
154       }else{
155         offset=ret;
156       }
157     }
158   }
159
160   /* we have the offset.  Actually snork and hold the page now */
161   _seek_helper(vf,offset);
162   ret=_get_next_page(vf,og,CHUNKSIZE);
163   if(ret<0)
164     /* this shouldn't be possible */
165     return(OV_EFAULT);
166
167   return(offset);
168 }
169
170 /* finds each bitstream link one at a time using a bisection search
171    (has to begin by knowing the offset of the lb's initial page).
172    Recurses for each link so it can alloc the link storage after
173    finding them all, then unroll and fill the cache at the same time */
174 static int _bisect_forward_serialno(OggVorbis_File *vf,
175                                     ogg_int64_t begin,
176                                     ogg_int64_t searched,
177                                     ogg_int64_t end,
178                                     long currentno,
179                                     long m){
180   ogg_int64_t endsearched=end;
181   ogg_int64_t next=end;
182   ogg_page og;
183   ogg_int64_t ret;
184   
185   /* the below guards against garbage seperating the last and
186      first pages of two links. */
187   while(searched<endsearched){
188     ogg_int64_t bisect;
189     
190     if(endsearched-searched<CHUNKSIZE){
191       bisect=searched;
192     }else{
193       bisect=(searched+endsearched)/2;
194     }
195     
196     _seek_helper(vf,bisect);
197     ret=_get_next_page(vf,&og,-1);
198     if(ret==OV_EREAD)return(OV_EREAD);
199     if(ret<0 || ogg_page_serialno(&og)!=currentno){
200       endsearched=bisect;
201       if(ret>=0)next=ret;
202     }else{
203       searched=ret+og.header_len+og.body_len;
204     }
205   }
206
207   _seek_helper(vf,next);
208   ret=_get_next_page(vf,&og,-1);
209   if(ret==OV_EREAD)return(OV_EREAD);
210   
211   if(searched>=end || ret<0){
212     vf->links=m+1;
213     vf->offsets=_ogg_malloc((vf->links+1)*sizeof(*vf->offsets));
214     vf->serialnos=_ogg_malloc(vf->links*sizeof(*vf->serialnos));
215     vf->offsets[m+1]=searched;
216   }else{
217     ret=_bisect_forward_serialno(vf,next,vf->offset,
218                                  end,ogg_page_serialno(&og),m+1);
219     if(ret==OV_EREAD)return(OV_EREAD);
220   }
221   
222   vf->offsets[m]=begin;
223   vf->serialnos[m]=currentno;
224   return(0);
225 }
226
227 /* uses the local ogg_stream storage in vf; this is important for
228    non-streaming input sources */
229 static int _fetch_headers(OggVorbis_File *vf,vorbis_info *vi,vorbis_comment *vc,
230                           long *serialno,ogg_page *og_ptr){
231   ogg_page og;
232   ogg_packet op;
233   int i,ret;
234   
235   if(!og_ptr){
236     ogg_int64_t llret=_get_next_page(vf,&og,CHUNKSIZE);
237     if(llret==OV_EREAD)return(OV_EREAD);
238     if(llret<0)return OV_ENOTVORBIS;
239     og_ptr=&og;
240   }
241
242   ogg_stream_reset_serialno(&vf->os,ogg_page_serialno(og_ptr));
243   if(serialno)*serialno=vf->os.serialno;
244   vf->ready_state=STREAMSET;
245   
246   /* extract the initial header from the first page and verify that the
247      Ogg bitstream is in fact Vorbis data */
248   
249   vorbis_info_init(vi);
250   vorbis_comment_init(vc);
251   
252   i=0;
253   while(i<3){
254     ogg_stream_pagein(&vf->os,og_ptr);
255     while(i<3){
256       int result=ogg_stream_packetout(&vf->os,&op);
257       if(result==0)break;
258       if(result==-1){
259         ret=OV_EBADHEADER;
260         goto bail_header;
261       }
262       if((ret=vorbis_synthesis_headerin(vi,vc,&op))){
263         goto bail_header;
264       }
265       i++;
266     }
267     if(i<3)
268       if(_get_next_page(vf,og_ptr,CHUNKSIZE)<0){
269         ret=OV_EBADHEADER;
270         goto bail_header;
271       }
272   }
273   return 0; 
274
275  bail_header:
276   vorbis_info_clear(vi);
277   vorbis_comment_clear(vc);
278   vf->ready_state=OPENED;
279
280   return ret;
281 }
282
283 /* last step of the OggVorbis_File initialization; get all the
284    vorbis_info structs and PCM positions.  Only called by the seekable
285    initialization (local stream storage is hacked slightly; pay
286    attention to how that's done) */
287
288 /* this is void and does not propogate errors up because we want to be
289    able to open and use damaged bitstreams as well as we can.  Just
290    watch out for missing information for links in the OggVorbis_File
291    struct */
292 static void _prefetch_all_headers(OggVorbis_File *vf, ogg_int64_t dataoffset){
293   ogg_page og;
294   int i;
295   ogg_int64_t ret;
296   
297   vf->vi=_ogg_realloc(vf->vi,vf->links*sizeof(*vf->vi));
298   vf->vc=_ogg_realloc(vf->vc,vf->links*sizeof(*vf->vc));
299   vf->dataoffsets=_ogg_malloc(vf->links*sizeof(*vf->dataoffsets));
300   vf->pcmlengths=_ogg_malloc(vf->links*2*sizeof(*vf->pcmlengths));
301   
302   for(i=0;i<vf->links;i++){
303     if(i==0){
304       /* we already grabbed the initial header earlier.  Just set the offset */
305       vf->dataoffsets[i]=dataoffset;
306       _seek_helper(vf,dataoffset);
307
308     }else{
309
310       /* seek to the location of the initial header */
311
312       _seek_helper(vf,vf->offsets[i]);
313       if(_fetch_headers(vf,vf->vi+i,vf->vc+i,NULL,NULL)<0){
314         vf->dataoffsets[i]=-1;
315       }else{
316         vf->dataoffsets[i]=vf->offset;
317       }
318     }
319
320     /* fetch beginning PCM offset */
321
322     if(vf->dataoffsets[i]!=-1){
323       ogg_int64_t accumulated=0;
324       long        lastblock=-1;
325       int         result;
326
327       ogg_stream_reset_serialno(&vf->os,vf->serialnos[i]);
328
329       while(1){
330         ogg_packet op;
331
332         ret=_get_next_page(vf,&og,-1);
333         if(ret<0)
334           /* this should not be possible unless the file is
335              truncated/mangled */
336           break;
337        
338         if(ogg_page_serialno(&og)!=vf->serialnos[i])
339           break;
340         
341         /* count blocksizes of all frames in the page */
342         ogg_stream_pagein(&vf->os,&og);
343         while((result=ogg_stream_packetout(&vf->os,&op))){
344           if(result>0){ /* ignore holes */
345             long thisblock=vorbis_packet_blocksize(vf->vi+i,&op);
346             if(lastblock!=-1)
347               accumulated+=(lastblock+thisblock)>>2;
348             lastblock=thisblock;
349           }
350         }
351
352         if(ogg_page_granulepos(&og)!=-1){
353           /* pcm offset of last packet on the first audio page */
354           accumulated= ogg_page_granulepos(&og)-accumulated;
355           break;
356         }
357       }
358
359       /* less than zero?  This is a stream with samples trimmed off
360          the beginning, a normal occurrence; set the offset to zero */
361       if(accumulated<0)accumulated=0;
362
363       vf->pcmlengths[i*2]=accumulated;
364     }
365
366     /* get the PCM length of this link. To do this,
367        get the last page of the stream */
368     {
369       ogg_int64_t end=vf->offsets[i+1];
370       _seek_helper(vf,end);
371
372       while(1){
373         ret=_get_prev_page(vf,&og);
374         if(ret<0){
375           /* this should not be possible */
376           vorbis_info_clear(vf->vi+i);
377           vorbis_comment_clear(vf->vc+i);
378           break;
379         }
380         if(ogg_page_granulepos(&og)!=-1){
381           vf->pcmlengths[i*2+1]=ogg_page_granulepos(&og)-vf->pcmlengths[i*2];
382           break;
383         }
384         vf->offset=ret;
385       }
386     }
387   }
388 }
389
390 static void _make_decode_ready(OggVorbis_File *vf){
391   if(vf->ready_state!=STREAMSET)return;
392   if(vf->seekable){
393     vorbis_synthesis_init(&vf->vd,vf->vi+vf->current_link);
394   }else{
395     vorbis_synthesis_init(&vf->vd,vf->vi);
396   }    
397   vorbis_block_init(&vf->vd,&vf->vb);
398   vf->ready_state=INITSET;
399   return;
400 }
401
402 static int _open_seekable2(OggVorbis_File *vf){
403   long serialno=vf->current_serialno;
404   ogg_int64_t dataoffset=vf->offset, end;
405   ogg_page og;
406
407   /* we're partially open and have a first link header state in
408      storage in vf */
409   /* we can seek, so set out learning all about this file */
410   (vf->callbacks.seek_func)(vf->datasource,0,SEEK_END);
411   vf->offset=vf->end=(vf->callbacks.tell_func)(vf->datasource);
412   
413   /* We get the offset for the last page of the physical bitstream.
414      Most OggVorbis files will contain a single logical bitstream */
415   end=_get_prev_page(vf,&og);
416   if(end<0)return(end);
417
418   /* more than one logical bitstream? */
419   if(ogg_page_serialno(&og)!=serialno){
420
421     /* Chained bitstream. Bisect-search each logical bitstream
422        section.  Do so based on serial number only */
423     if(_bisect_forward_serialno(vf,0,0,end+1,serialno,0)<0)return(OV_EREAD);
424
425   }else{
426
427     /* Only one logical bitstream */
428     if(_bisect_forward_serialno(vf,0,end,end+1,serialno,0))return(OV_EREAD);
429
430   }
431
432   /* the initial header memory is referenced by vf after; don't free it */
433   _prefetch_all_headers(vf,dataoffset);
434   return(ov_raw_seek(vf,0));
435 }
436
437 /* clear out the current logical bitstream decoder */ 
438 static void _decode_clear(OggVorbis_File *vf){
439   vorbis_dsp_clear(&vf->vd);
440   vorbis_block_clear(&vf->vb);
441   vf->ready_state=OPENED;
442
443   vf->bittrack=0.f;
444   vf->samptrack=0.f;
445 }
446
447 /* restart the decoder, but don't clear out machine init */
448 static void _decode_restart(OggVorbis_File *vf){
449   vorbis_synthesis_restart(&vf->vd);
450   vf->bittrack=0.f;
451   vf->samptrack=0.f;
452 }
453
454
455 /* fetch and process a packet.  Handles the case where we're at a
456    bitstream boundary and dumps the decoding machine.  If the decoding
457    machine is unloaded, it loads it.  It also keeps pcm_offset up to
458    date (seek and read both use this.  seek uses a special hack with
459    readp). 
460
461    return: <0) error, OV_HOLE (lost packet) or OV_EOF
462             0) need more data (only if readp==0)
463             1) got a packet 
464 */
465
466 static int _fetch_and_process_packet(OggVorbis_File *vf,
467                                      ogg_packet *op_in,
468                                      int readp,
469                                      int spanp){
470   ogg_page og;
471
472   /* handle one packet.  Try to fetch it from current stream state */
473   /* extract packets from page */
474   while(1){
475     
476     /* process a packet if we can.  If the machine isn't loaded,
477        neither is a page */
478     if(vf->ready_state==INITSET){
479       while(1) {
480         ogg_packet op;
481         ogg_packet *op_ptr=(op_in?op_in:&op);
482         int result=ogg_stream_packetout(&vf->os,op_ptr);
483         ogg_int64_t granulepos;
484
485         op_in=NULL;
486         if(result==-1)return(OV_HOLE); /* hole in the data. */
487         if(result>0){
488           /* got a packet.  process it */
489           granulepos=op_ptr->granulepos;
490           if(!vorbis_synthesis(&vf->vb,op_ptr)){ /* lazy check for lazy
491                                                     header handling.  The
492                                                     header packets aren't
493                                                     audio, so if/when we
494                                                     submit them,
495                                                     vorbis_synthesis will
496                                                     reject them */
497
498             /* suck in the synthesis data and track bitrate */
499             {
500               int oldsamples=vorbis_synthesis_pcmout(&vf->vd,NULL);
501               /* for proper use of libvorbis within libvorbisfile,
502                  oldsamples will always be zero. */
503               if(oldsamples)return(OV_EFAULT);
504               
505               vorbis_synthesis_blockin(&vf->vd,&vf->vb);
506               vf->samptrack+=vorbis_synthesis_pcmout(&vf->vd,NULL)-oldsamples;
507               vf->bittrack+=op_ptr->bytes*8;
508             }
509           
510             /* update the pcm offset. */
511             if(granulepos!=-1 && !op_ptr->e_o_s){
512               int link=(vf->seekable?vf->current_link:0);
513               int i,samples;
514             
515               /* this packet has a pcm_offset on it (the last packet
516                  completed on a page carries the offset) After processing
517                  (above), we know the pcm position of the *last* sample
518                  ready to be returned. Find the offset of the *first*
519
520                  As an aside, this trick is inaccurate if we begin
521                  reading anew right at the last page; the end-of-stream
522                  granulepos declares the last frame in the stream, and the
523                  last packet of the last page may be a partial frame.
524                  So, we need a previous granulepos from an in-sequence page
525                  to have a reference point.  Thus the !op_ptr->e_o_s clause
526                  above */
527
528               if(vf->seekable && link>0)
529                 granulepos-=vf->pcmlengths[link*2];
530               if(granulepos<0)granulepos=0; /* actually, this
531                                                shouldn't be possible
532                                                here unless the stream
533                                                is very broken */
534
535               samples=vorbis_synthesis_pcmout(&vf->vd,NULL);
536             
537               granulepos-=samples;
538               for(i=0;i<link;i++)
539                 granulepos+=vf->pcmlengths[i*2+1];
540               vf->pcm_offset=granulepos;
541             }
542             return(1);
543           }
544         }
545         else 
546           break;
547       }
548     }
549
550     if(vf->ready_state>=OPENED){
551       int ret;
552       if(!readp)return(0);
553       if((ret=_get_next_page(vf,&og,-1))<0){
554         return(OV_EOF); /* eof. 
555                            leave unitialized */
556       }
557
558         /* bitrate tracking; add the header's bytes here, the body bytes
559            are done by packet above */
560       vf->bittrack+=og.header_len*8;
561       
562       /* has our decoding just traversed a bitstream boundary? */
563       if(vf->ready_state==INITSET){
564         if(vf->current_serialno!=ogg_page_serialno(&og)){
565           if(!spanp)
566             return(OV_EOF);
567
568           _decode_clear(vf);
569           
570           if(!vf->seekable){
571             vorbis_info_clear(vf->vi);
572             vorbis_comment_clear(vf->vc);
573           }
574         }
575       }
576     }
577
578     /* Do we need to load a new machine before submitting the page? */
579     /* This is different in the seekable and non-seekable cases.  
580
581        In the seekable case, we already have all the header
582        information loaded and cached; we just initialize the machine
583        with it and continue on our merry way.
584
585        In the non-seekable (streaming) case, we'll only be at a
586        boundary if we just left the previous logical bitstream and
587        we're now nominally at the header of the next bitstream
588     */
589
590     if(vf->ready_state!=INITSET){ 
591       int link;
592
593       if(vf->ready_state<STREAMSET){
594         if(vf->seekable){
595           vf->current_serialno=ogg_page_serialno(&og);
596           
597           /* match the serialno to bitstream section.  We use this rather than
598              offset positions to avoid problems near logical bitstream
599              boundaries */
600           for(link=0;link<vf->links;link++)
601             if(vf->serialnos[link]==vf->current_serialno)break;
602           if(link==vf->links)return(OV_EBADLINK); /* sign of a bogus
603                                                      stream.  error out,
604                                                      leave machine
605                                                      uninitialized */
606           
607           vf->current_link=link;
608           
609           ogg_stream_reset_serialno(&vf->os,vf->current_serialno);
610           vf->ready_state=STREAMSET;
611           
612         }else{
613           /* we're streaming */
614           /* fetch the three header packets, build the info struct */
615           
616           int ret=_fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno,&og);
617           if(ret)return(ret);
618           vf->current_link++;
619           link=0;
620         }
621       }
622       
623       _make_decode_ready(vf);
624     }
625     ogg_stream_pagein(&vf->os,&og);
626   }
627 }
628
629 /* if, eg, 64 bit stdio is configured by default, this will build with
630    fseek64 */
631 static int _fseek64_wrap(FILE *f,ogg_int64_t off,int whence){
632   if(f==NULL)return(-1);
633   return fseek(f,off,whence);
634 }
635
636 static int _ov_open1(void *f,OggVorbis_File *vf,char *initial,
637                      long ibytes, ov_callbacks callbacks){
638   int offsettest=(f?callbacks.seek_func(f,0,SEEK_CUR):-1);
639   int ret;
640
641   memset(vf,0,sizeof(*vf));
642   vf->datasource=f;
643   vf->callbacks = callbacks;
644
645   /* init the framing state */
646   ogg_sync_init(&vf->oy);
647
648   /* perhaps some data was previously read into a buffer for testing
649      against other stream types.  Allow initialization from this
650      previously read data (as we may be reading from a non-seekable
651      stream) */
652   if(initial){
653     char *buffer=ogg_sync_buffer(&vf->oy,ibytes);
654     memcpy(buffer,initial,ibytes);
655     ogg_sync_wrote(&vf->oy,ibytes);
656   }
657
658   /* can we seek? Stevens suggests the seek test was portable */
659   if(offsettest!=-1)vf->seekable=1;
660
661   /* No seeking yet; Set up a 'single' (current) logical bitstream
662      entry for partial open */
663   vf->links=1;
664   vf->vi=_ogg_calloc(vf->links,sizeof(*vf->vi));
665   vf->vc=_ogg_calloc(vf->links,sizeof(*vf->vc));
666   ogg_stream_init(&vf->os,-1); /* fill in the serialno later */
667
668   /* Try to fetch the headers, maintaining all the storage */
669   if((ret=_fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno,NULL))<0){
670     vf->datasource=NULL;
671     ov_clear(vf);
672   }else if(vf->ready_state < PARTOPEN)
673     vf->ready_state=PARTOPEN;
674   return(ret);
675 }
676
677 static int _ov_open2(OggVorbis_File *vf){
678   if(vf->ready_state < OPENED)
679     vf->ready_state=OPENED;
680   if(vf->seekable){
681     int ret=_open_seekable2(vf);
682     if(ret){
683       vf->datasource=NULL;
684       ov_clear(vf);
685     }
686     return(ret);
687   }
688   return 0;
689 }
690
691
692 /* clear out the OggVorbis_File struct */
693 int ov_clear(OggVorbis_File *vf){
694   if(vf){
695     vorbis_block_clear(&vf->vb);
696     vorbis_dsp_clear(&vf->vd);
697     ogg_stream_clear(&vf->os);
698     
699     if(vf->vi && vf->links){
700       int i;
701       for(i=0;i<vf->links;i++){
702         vorbis_info_clear(vf->vi+i);
703         vorbis_comment_clear(vf->vc+i);
704       }
705       _ogg_free(vf->vi);
706       _ogg_free(vf->vc);
707     }
708     if(vf->dataoffsets)_ogg_free(vf->dataoffsets);
709     if(vf->pcmlengths)_ogg_free(vf->pcmlengths);
710     if(vf->serialnos)_ogg_free(vf->serialnos);
711     if(vf->offsets)_ogg_free(vf->offsets);
712     ogg_sync_clear(&vf->oy);
713     if(vf->datasource)(vf->callbacks.close_func)(vf->datasource);
714     memset(vf,0,sizeof(*vf));
715   }
716 #ifdef DEBUG_LEAKS
717   _VDBG_dump();
718 #endif
719   return(0);
720 }
721
722 /* inspects the OggVorbis file and finds/documents all the logical
723    bitstreams contained in it.  Tries to be tolerant of logical
724    bitstream sections that are truncated/woogie. 
725
726    return: -1) error
727             0) OK
728 */
729
730 int ov_open_callbacks(void *f,OggVorbis_File *vf,char *initial,long ibytes,
731     ov_callbacks callbacks){
732   int ret=_ov_open1(f,vf,initial,ibytes,callbacks);
733   if(ret)return ret;
734   return _ov_open2(vf);
735 }
736
737 int ov_open(FILE *f,OggVorbis_File *vf,char *initial,long ibytes){
738   ov_callbacks callbacks = {
739     (size_t (*)(void *, size_t, size_t, void *))  fread,
740     (int (*)(void *, ogg_int64_t, int))              _fseek64_wrap,
741     (int (*)(void *))                             fclose,
742     (long (*)(void *))                            ftell
743   };
744
745   return ov_open_callbacks((void *)f, vf, initial, ibytes, callbacks);
746 }
747   
748 /* Only partially open the vorbis file; test for Vorbisness, and load
749    the headers for the first chain.  Do not seek (although test for
750    seekability).  Use ov_test_open to finish opening the file, else
751    ov_clear to close/free it. Same return codes as open. */
752
753 int ov_test_callbacks(void *f,OggVorbis_File *vf,char *initial,long ibytes,
754     ov_callbacks callbacks)
755 {
756   return _ov_open1(f,vf,initial,ibytes,callbacks);
757 }
758
759 int ov_test(FILE *f,OggVorbis_File *vf,char *initial,long ibytes){
760   ov_callbacks callbacks = {
761     (size_t (*)(void *, size_t, size_t, void *))  fread,
762     (int (*)(void *, ogg_int64_t, int))              _fseek64_wrap,
763     (int (*)(void *))                             fclose,
764     (long (*)(void *))                            ftell
765   };
766
767   return ov_test_callbacks((void *)f, vf, initial, ibytes, callbacks);
768 }
769   
770 int ov_test_open(OggVorbis_File *vf){
771   if(vf->ready_state!=PARTOPEN)return(OV_EINVAL);
772   return _ov_open2(vf);
773 }
774
775 /* How many logical bitstreams in this physical bitstream? */
776 long ov_streams(OggVorbis_File *vf){
777   return vf->links;
778 }
779
780 /* Is the FILE * associated with vf seekable? */
781 long ov_seekable(OggVorbis_File *vf){
782   return vf->seekable;
783 }
784
785 /* returns the bitrate for a given logical bitstream or the entire
786    physical bitstream.  If the file is open for random access, it will
787    find the *actual* average bitrate.  If the file is streaming, it
788    returns the nominal bitrate (if set) else the average of the
789    upper/lower bounds (if set) else -1 (unset).
790
791    If you want the actual bitrate field settings, get them from the
792    vorbis_info structs */
793
794 long ov_bitrate(OggVorbis_File *vf,int i){
795   if(vf->ready_state<OPENED)return(OV_EINVAL);
796   if(i>=vf->links)return(OV_EINVAL);
797   if(!vf->seekable && i!=0)return(ov_bitrate(vf,0));
798   if(i<0){
799     ogg_int64_t bits=0;
800     int i;
801     float br;
802     for(i=0;i<vf->links;i++)
803       bits+=(vf->offsets[i+1]-vf->dataoffsets[i])*8;
804     /* This once read: return(rint(bits/ov_time_total(vf,-1)));
805      * gcc 3.x on x86 miscompiled this at optimisation level 2 and above,
806      * so this is slightly transformed to make it work.
807      */
808     br = bits/ov_time_total(vf,-1);
809     return(rint(br));
810   }else{
811     if(vf->seekable){
812       /* return the actual bitrate */
813       return(rint((vf->offsets[i+1]-vf->dataoffsets[i])*8/ov_time_total(vf,i)));
814     }else{
815       /* return nominal if set */
816       if(vf->vi[i].bitrate_nominal>0){
817         return vf->vi[i].bitrate_nominal;
818       }else{
819         if(vf->vi[i].bitrate_upper>0){
820           if(vf->vi[i].bitrate_lower>0){
821             return (vf->vi[i].bitrate_upper+vf->vi[i].bitrate_lower)/2;
822           }else{
823             return vf->vi[i].bitrate_upper;
824           }
825         }
826         return(OV_FALSE);
827       }
828     }
829   }
830 }
831
832 /* returns the actual bitrate since last call.  returns -1 if no
833    additional data to offer since last call (or at beginning of stream),
834    EINVAL if stream is only partially open 
835 */
836 long ov_bitrate_instant(OggVorbis_File *vf){
837   int link=(vf->seekable?vf->current_link:0);
838   long ret;
839   if(vf->ready_state<OPENED)return(OV_EINVAL);
840   if(vf->samptrack==0)return(OV_FALSE);
841   ret=vf->bittrack/vf->samptrack*vf->vi[link].rate+.5;
842   vf->bittrack=0.f;
843   vf->samptrack=0.f;
844   return(ret);
845 }
846
847 /* Guess */
848 long ov_serialnumber(OggVorbis_File *vf,int i){
849   if(i>=vf->links)return(ov_serialnumber(vf,vf->links-1));
850   if(!vf->seekable && i>=0)return(ov_serialnumber(vf,-1));
851   if(i<0){
852     return(vf->current_serialno);
853   }else{
854     return(vf->serialnos[i]);
855   }
856 }
857
858 /* returns: total raw (compressed) length of content if i==-1
859             raw (compressed) length of that logical bitstream for i==0 to n
860             OV_EINVAL if the stream is not seekable (we can't know the length)
861             or if stream is only partially open
862 */
863 ogg_int64_t ov_raw_total(OggVorbis_File *vf,int i){
864   if(vf->ready_state<OPENED)return(OV_EINVAL);
865   if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
866   if(i<0){
867     ogg_int64_t acc=0;
868     int i;
869     for(i=0;i<vf->links;i++)
870       acc+=ov_raw_total(vf,i);
871     return(acc);
872   }else{
873     return(vf->offsets[i+1]-vf->offsets[i]);
874   }
875 }
876
877 /* returns: total PCM length (samples) of content if i==-1 PCM length
878             (samples) of that logical bitstream for i==0 to n
879             OV_EINVAL if the stream is not seekable (we can't know the
880             length) or only partially open 
881 */
882 ogg_int64_t ov_pcm_total(OggVorbis_File *vf,int i){
883   if(vf->ready_state<OPENED)return(OV_EINVAL);
884   if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
885   if(i<0){
886     ogg_int64_t acc=0;
887     int i;
888     for(i=0;i<vf->links;i++)
889       acc+=ov_pcm_total(vf,i);
890     return(acc);
891   }else{
892     return(vf->pcmlengths[i*2+1]);
893   }
894 }
895
896 /* returns: total seconds of content if i==-1
897             seconds in that logical bitstream for i==0 to n
898             OV_EINVAL if the stream is not seekable (we can't know the
899             length) or only partially open 
900 */
901 double ov_time_total(OggVorbis_File *vf,int i){
902   if(vf->ready_state<OPENED)return(OV_EINVAL);
903   if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
904   if(i<0){
905     double acc=0;
906     int i;
907     for(i=0;i<vf->links;i++)
908       acc+=ov_time_total(vf,i);
909     return(acc);
910   }else{
911     return((double)(vf->pcmlengths[i*2+1])/vf->vi[i].rate);
912   }
913 }
914
915 /* seek to an offset relative to the *compressed* data. This also
916    scans packets to update the PCM cursor. It will cross a logical
917    bitstream boundary, but only if it can't get any packets out of the
918    tail of the bitstream we seek to (so no surprises).
919
920    returns zero on success, nonzero on failure */
921
922 int ov_raw_seek(OggVorbis_File *vf,ogg_int64_t pos){
923   ogg_stream_state work_os;
924   int i;
925   ogg_int64_t count=0;
926
927   if(vf->ready_state<OPENED)return(OV_EINVAL);
928   if(!vf->seekable)
929     return(OV_ENOSEEK); /* don't dump machine if we can't seek */
930
931   if(pos<0 || pos>vf->end)return(OV_EINVAL);
932
933   /* don't yet clear out decoding machine (if it's initialized), in
934      the case we're in the same link.  Restart the decode lapping, and
935      let _fetch_and_process_packet deal with a potential bitstream
936      boundary */
937   vf->pcm_offset=-1;
938   ogg_stream_reset_serialno(&vf->os,
939                             vf->current_serialno); /* must set serialno */
940   _decode_restart(vf);
941   //_decode_clear(vf);
942   
943   _seek_helper(vf,pos);
944
945   /* we need to make sure the pcm_offset is set, but we don't want to
946      advance the raw cursor past good packets just to get to the first
947      with a granulepos.  That's not equivalent behavior to beginning
948      decoding as immediately after the seek position as possible.
949
950      So, a hack.  We use two stream states; a local scratch state and
951      the shared vf->os stream state.  We use the local state to
952      scan, and the shared state as a buffer for later decode. 
953
954      Unfortuantely, on the last page we still advance to last packet
955      because the granulepos on the last page is not necessarily on a
956      packet boundary, and we need to make sure the granpos is
957      correct. 
958   */
959
960   {
961     ogg_page og;
962     ogg_packet op;
963     int lastblock=0;
964     int accblock=0;
965     int thisblock;
966     int eosflag;
967
968     ogg_stream_init(&work_os,vf->current_serialno); /* get the memory ready */
969     ogg_stream_reset(&work_os); /* eliminate the spurious OV_HOLE
970                                    return from not necessarily
971                                    starting from the beginning */
972
973     while(1){
974       if(vf->ready_state>=STREAMSET){
975         /* snarf/scan a packet if we can */
976         int result=ogg_stream_packetout(&work_os,&op);
977       
978         if(result>0){
979
980           if(vf->vi[vf->current_link].codec_setup){
981             thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op);
982             if(thisblock<0){
983               ogg_stream_packetout(&vf->os,NULL);
984               continue;
985             }
986           }
987           if(eosflag)
988             ogg_stream_packetout(&vf->os,NULL);
989           else
990             if(lastblock)accblock+=(lastblock+thisblock)>>2;
991
992           if(op.granulepos!=-1){
993             int i,link=vf->current_link;
994             ogg_int64_t granulepos=op.granulepos-vf->pcmlengths[link*2];
995             if(granulepos<0)granulepos=0;
996             
997             for(i=0;i<link;i++)
998               granulepos+=vf->pcmlengths[i*2+1];
999             vf->pcm_offset=granulepos-accblock;
1000             break;
1001           }
1002           lastblock=thisblock;
1003           continue;
1004         }
1005       }
1006       
1007       if(!lastblock){
1008         if(_get_next_page(vf,&og,-1)<0){
1009           vf->pcm_offset=ov_pcm_total(vf,-1);
1010           break;
1011         }
1012       }else{
1013         /* huh?  Bogus stream with packets but no granulepos */
1014         vf->pcm_offset=-1;
1015         break;
1016       }
1017       
1018       /* has our decoding just traversed a bitstream boundary? */
1019       if(vf->ready_state>=STREAMSET)
1020         if(vf->current_serialno!=ogg_page_serialno(&og)){
1021           _decode_clear(vf); /* clear out stream state */
1022           ogg_stream_clear(&work_os);
1023         }
1024
1025       if(vf->ready_state<STREAMSET){
1026         int link;
1027         
1028         vf->current_serialno=ogg_page_serialno(&og);
1029         for(link=0;link<vf->links;link++)
1030           if(vf->serialnos[link]==vf->current_serialno)break;
1031         if(link==vf->links)goto seek_error; /* sign of a bogus stream.
1032                                                error out, leave
1033                                                machine uninitialized */
1034         vf->current_link=link;
1035         
1036         ogg_stream_reset_serialno(&vf->os,vf->current_serialno);
1037         ogg_stream_reset_serialno(&work_os,vf->current_serialno); 
1038         vf->ready_state=STREAMSET;
1039         
1040       }
1041     
1042       ogg_stream_pagein(&vf->os,&og);
1043       ogg_stream_pagein(&work_os,&og);
1044       eosflag=ogg_page_eos(&og);
1045     }
1046   }
1047
1048   ogg_stream_clear(&work_os);
1049   return(0);
1050
1051  seek_error:
1052   /* dump the machine so we're in a known state */
1053   vf->pcm_offset=-1;
1054   ogg_stream_clear(&work_os);
1055   _decode_clear(vf);
1056   return OV_EBADLINK;
1057 }
1058
1059 /* Page granularity seek (faster than sample granularity because we
1060    don't do the last bit of decode to find a specific sample).
1061
1062    Seek to the last [granule marked] page preceeding the specified pos
1063    location, such that decoding past the returned point will quickly
1064    arrive at the requested position. */
1065 int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos){
1066   int link=-1;
1067   ogg_int64_t result=0;
1068   ogg_int64_t total=ov_pcm_total(vf,-1);
1069
1070   if(vf->ready_state<OPENED)return(OV_EINVAL);
1071   if(!vf->seekable)return(OV_ENOSEEK);
1072
1073   if(pos<0 || pos>total)return(OV_EINVAL);
1074  
1075   /* which bitstream section does this pcm offset occur in? */
1076   for(link=vf->links-1;link>=0;link--){
1077     total-=vf->pcmlengths[link*2+1];
1078     if(pos>=total)break;
1079   }
1080
1081   /* search within the logical bitstream for the page with the highest
1082      pcm_pos preceeding (or equal to) pos.  There is a danger here;
1083      missing pages or incorrect frame number information in the
1084      bitstream could make our task impossible.  Account for that (it
1085      would be an error condition) */
1086
1087   /* new search algorithm by HB (Nicholas Vinen) */
1088   {
1089     ogg_int64_t end=vf->offsets[link+1];
1090     ogg_int64_t begin=vf->offsets[link];
1091     ogg_int64_t begintime = vf->pcmlengths[link*2];
1092     ogg_int64_t endtime = vf->pcmlengths[link*2+1]+begintime;
1093     ogg_int64_t target=pos-total+begintime;
1094     ogg_int64_t best=begin;
1095     
1096     ogg_page og;
1097     while(begin<end){
1098       ogg_int64_t bisect;
1099       
1100       if(end-begin<CHUNKSIZE){
1101         bisect=begin;
1102       }else{
1103         /* take a (pretty decent) guess. */
1104         bisect=begin + 
1105           (target-begintime)*(end-begin)/(endtime-begintime) - CHUNKSIZE;
1106         if(bisect<=begin)
1107           bisect=begin+1;
1108       }
1109       
1110       _seek_helper(vf,bisect);
1111     
1112       while(begin<end){
1113         result=_get_next_page(vf,&og,end-vf->offset);
1114         if(result==OV_EREAD) goto seek_error;
1115         if(result<0){
1116           if(bisect<=begin+1)
1117             end=begin; /* found it */
1118           else{
1119             if(bisect==0) goto seek_error;
1120             bisect-=CHUNKSIZE;
1121             if(bisect<=begin)bisect=begin+1;
1122             _seek_helper(vf,bisect);
1123           }
1124         }else{
1125           ogg_int64_t granulepos=ogg_page_granulepos(&og);
1126           if(granulepos==-1)continue;
1127           if(granulepos<target){
1128             best=result;  /* raw offset of packet with granulepos */ 
1129             begin=vf->offset; /* raw offset of next page */
1130             begintime=granulepos;
1131             
1132             if(target-begintime>44100)break;
1133             bisect=begin; /* *not* begin + 1 */
1134           }else{
1135             if(bisect<=begin+1)
1136               end=begin;  /* found it */
1137             else{
1138               if(end==vf->offset){ /* we're pretty close - we'd be stuck in */
1139                 end=result;
1140                 bisect-=CHUNKSIZE; /* an endless loop otherwise. */
1141                 if(bisect<=begin)bisect=begin+1;
1142                 _seek_helper(vf,bisect);
1143               }else{
1144                 end=result;
1145                 endtime=granulepos;
1146                 break;
1147               }
1148             }
1149           }
1150         }
1151       }
1152     }
1153
1154     /* found our page. seek to it, update pcm offset. Easier case than
1155        raw_seek, don't keep packets preceeding granulepos. */
1156     {
1157       ogg_page og;
1158       ogg_packet op;
1159       
1160       /* seek */
1161       _seek_helper(vf,best);
1162       vf->pcm_offset=-1;
1163       
1164       if(_get_next_page(vf,&og,-1)<0)return(OV_EOF); /* shouldn't happen */
1165       
1166       if(link!=vf->current_link){
1167         /* Different link; dump entire decode machine */
1168         _decode_clear(vf);  
1169         
1170         vf->current_link=link;
1171         vf->current_serialno=ogg_page_serialno(&og);
1172         vf->ready_state=STREAMSET;
1173         
1174       }else{
1175         _decode_restart(vf);  
1176       }
1177
1178       ogg_stream_reset_serialno(&vf->os,vf->current_serialno);
1179       ogg_stream_pagein(&vf->os,&og);
1180
1181       /* pull out all but last packet; the one with granulepos */
1182       while(1){
1183         result=ogg_stream_packetpeek(&vf->os,&op);
1184         if(result==0){
1185           /* !!! the packet finishing this page originated on a
1186              preceeding page. Keep fetching previous pages until we
1187              get one with a granulepos or without the 'continued' flag
1188              set.  Then just use raw_seek for simplicity. */
1189           
1190           //_decode_restart(vf);  
1191           _seek_helper(vf,best);
1192           
1193           while(1){
1194             result=_get_prev_page(vf,&og);
1195             if(result<0) goto seek_error;
1196             if(ogg_page_granulepos(&og)>-1 ||
1197                !ogg_page_continued(&og)){
1198               return ov_raw_seek(vf,result);
1199             }
1200             vf->offset=result;
1201           }
1202         }
1203         if(result<0){
1204           result = OV_EBADPACKET; 
1205           goto seek_error;
1206         }
1207         if(op.granulepos!=-1){
1208           vf->pcm_offset=op.granulepos-vf->pcmlengths[vf->current_link*2];
1209           if(vf->pcm_offset<0)vf->pcm_offset=0;
1210           vf->pcm_offset+=total;
1211           break;
1212         }else
1213           result=ogg_stream_packetout(&vf->os,NULL);
1214       }
1215     }
1216   }
1217   
1218   /* verify result */
1219   if(vf->pcm_offset>pos || pos>ov_pcm_total(vf,-1)){
1220     result=OV_EFAULT;
1221     goto seek_error;
1222   }
1223   return(0);
1224   
1225  seek_error:
1226   /* dump machine so we're in a known state */
1227   vf->pcm_offset=-1;
1228   _decode_clear(vf);
1229   return (int)result;
1230 }
1231
1232 /* seek to a sample offset relative to the decompressed pcm stream 
1233    returns zero on success, nonzero on failure */
1234
1235 int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos){
1236   int thisblock,lastblock=0;
1237   int ret=ov_pcm_seek_page(vf,pos);
1238   if(ret<0)return(ret);
1239   _make_decode_ready(vf);
1240
1241   /* discard leading packets we don't need for the lapping of the
1242      position we want; don't decode them */
1243
1244   while(1){
1245     ogg_packet op;
1246     ogg_page og;
1247
1248     int ret=ogg_stream_packetpeek(&vf->os,&op);
1249     if(ret>0){
1250       thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op);
1251       if(thisblock<0){
1252         ogg_stream_packetout(&vf->os,NULL);
1253         continue; /* non audio packet */
1254       }
1255       if(lastblock)vf->pcm_offset+=(lastblock+thisblock)>>2;
1256       
1257       if(vf->pcm_offset+((thisblock+
1258                           vorbis_info_blocksize(vf->vi,1))>>2)>=pos)break;
1259       
1260       /* remove the packet from packet queue and track its granulepos */
1261       ogg_stream_packetout(&vf->os,NULL);
1262       vorbis_synthesis_trackonly(&vf->vb,&op);  /* set up a vb with
1263                                                    only tracking, no
1264                                                    pcm_decode */
1265       vorbis_synthesis_blockin(&vf->vd,&vf->vb); 
1266       
1267       /* end of logical stream case is hard, especially with exact
1268          length positioning. */
1269       
1270       if(op.granulepos>-1){
1271         int i;
1272         /* always believe the stream markers */
1273         vf->pcm_offset=op.granulepos-vf->pcmlengths[vf->current_link*2];
1274         if(vf->pcm_offset<0)vf->pcm_offset=0;
1275         for(i=0;i<vf->current_link;i++)
1276           vf->pcm_offset+=vf->pcmlengths[i*2+1];
1277       }
1278         
1279       lastblock=thisblock;
1280       
1281     }else{
1282       if(ret<0 && ret!=OV_HOLE)break;
1283       
1284       /* suck in a new page */
1285       if(_get_next_page(vf,&og,-1)<0)break;
1286       if(vf->current_serialno!=ogg_page_serialno(&og))_decode_clear(vf);
1287       
1288       if(vf->ready_state<STREAMSET){
1289         int link;
1290         
1291         vf->current_serialno=ogg_page_serialno(&og);
1292         for(link=0;link<vf->links;link++)
1293           if(vf->serialnos[link]==vf->current_serialno)break;
1294         if(link==vf->links)return(OV_EBADLINK);
1295         vf->current_link=link;
1296         
1297         ogg_stream_reset_serialno(&vf->os,vf->current_serialno); 
1298         vf->ready_state=STREAMSET;      
1299         _make_decode_ready(vf);
1300         lastblock=0;
1301       }
1302
1303       ogg_stream_pagein(&vf->os,&og);
1304     }
1305   }
1306
1307   /* discard samples until we reach the desired position. Crossing a
1308      logical bitstream boundary with abandon is OK. */
1309   while(vf->pcm_offset<pos){
1310     ogg_int64_t target=pos-vf->pcm_offset;
1311     long samples=vorbis_synthesis_pcmout(&vf->vd,NULL);
1312
1313     if(samples>target)samples=target;
1314     vorbis_synthesis_read(&vf->vd,samples);
1315     vf->pcm_offset+=samples;
1316     
1317     if(samples<target)
1318       if(_fetch_and_process_packet(vf,NULL,1,1)<=0)
1319         vf->pcm_offset=ov_pcm_total(vf,-1); /* eof */
1320   }
1321   return 0;
1322 }
1323
1324 /* seek to a playback time relative to the decompressed pcm stream 
1325    returns zero on success, nonzero on failure */
1326 int ov_time_seek(OggVorbis_File *vf,double seconds){
1327   /* translate time to PCM position and call ov_pcm_seek */
1328
1329   int link=-1;
1330   ogg_int64_t pcm_total=ov_pcm_total(vf,-1);
1331   double time_total=ov_time_total(vf,-1);
1332
1333   if(vf->ready_state<OPENED)return(OV_EINVAL);
1334   if(!vf->seekable)return(OV_ENOSEEK);
1335   if(seconds<0 || seconds>time_total)return(OV_EINVAL);
1336   
1337   /* which bitstream section does this time offset occur in? */
1338   for(link=vf->links-1;link>=0;link--){
1339     pcm_total-=vf->pcmlengths[link*2+1];
1340     time_total-=ov_time_total(vf,link);
1341     if(seconds>=time_total)break;
1342   }
1343
1344   /* enough information to convert time offset to pcm offset */
1345   {
1346     ogg_int64_t target=pcm_total+(seconds-time_total)*vf->vi[link].rate;
1347     return(ov_pcm_seek(vf,target));
1348   }
1349 }
1350
1351 /* page-granularity version of ov_time_seek 
1352    returns zero on success, nonzero on failure */
1353 int ov_time_seek_page(OggVorbis_File *vf,double seconds){
1354   /* translate time to PCM position and call ov_pcm_seek */
1355
1356   int link=-1;
1357   ogg_int64_t pcm_total=ov_pcm_total(vf,-1);
1358   double time_total=ov_time_total(vf,-1);
1359
1360   if(vf->ready_state<OPENED)return(OV_EINVAL);
1361   if(!vf->seekable)return(OV_ENOSEEK);
1362   if(seconds<0 || seconds>time_total)return(OV_EINVAL);
1363   
1364   /* which bitstream section does this time offset occur in? */
1365   for(link=vf->links-1;link>=0;link--){
1366     pcm_total-=vf->pcmlengths[link*2+1];
1367     time_total-=ov_time_total(vf,link);
1368     if(seconds>=time_total)break;
1369   }
1370
1371   /* enough information to convert time offset to pcm offset */
1372   {
1373     ogg_int64_t target=pcm_total+(seconds-time_total)*vf->vi[link].rate;
1374     return(ov_pcm_seek_page(vf,target));
1375   }
1376 }
1377
1378 /* tell the current stream offset cursor.  Note that seek followed by
1379    tell will likely not give the set offset due to caching */
1380 ogg_int64_t ov_raw_tell(OggVorbis_File *vf){
1381   if(vf->ready_state<OPENED)return(OV_EINVAL);
1382   return(vf->offset);
1383 }
1384
1385 /* return PCM offset (sample) of next PCM sample to be read */
1386 ogg_int64_t ov_pcm_tell(OggVorbis_File *vf){
1387   if(vf->ready_state<OPENED)return(OV_EINVAL);
1388   return(vf->pcm_offset);
1389 }
1390
1391 /* return time offset (seconds) of next PCM sample to be read */
1392 double ov_time_tell(OggVorbis_File *vf){
1393   int link=0;
1394   ogg_int64_t pcm_total=0;
1395   double time_total=0.f;
1396   
1397   if(vf->ready_state<OPENED)return(OV_EINVAL);
1398   if(vf->seekable){
1399     pcm_total=ov_pcm_total(vf,-1);
1400     time_total=ov_time_total(vf,-1);
1401   
1402     /* which bitstream section does this time offset occur in? */
1403     for(link=vf->links-1;link>=0;link--){
1404       pcm_total-=vf->pcmlengths[link*2+1];
1405       time_total-=ov_time_total(vf,link);
1406       if(vf->pcm_offset>=pcm_total)break;
1407     }
1408   }
1409
1410   return((double)time_total+(double)(vf->pcm_offset-pcm_total)/vf->vi[link].rate);
1411 }
1412
1413 /*  link:   -1) return the vorbis_info struct for the bitstream section
1414                 currently being decoded
1415            0-n) to request information for a specific bitstream section
1416     
1417     In the case of a non-seekable bitstream, any call returns the
1418     current bitstream.  NULL in the case that the machine is not
1419     initialized */
1420
1421 vorbis_info *ov_info(OggVorbis_File *vf,int link){
1422   if(vf->seekable){
1423     if(link<0)
1424       if(vf->ready_state>=STREAMSET)
1425         return vf->vi+vf->current_link;
1426       else
1427       return vf->vi;
1428     else
1429       if(link>=vf->links)
1430         return NULL;
1431       else
1432         return vf->vi+link;
1433   }else{
1434     return vf->vi;
1435   }
1436 }
1437
1438 /* grr, strong typing, grr, no templates/inheritence, grr */
1439 vorbis_comment *ov_comment(OggVorbis_File *vf,int link){
1440   if(vf->seekable){
1441     if(link<0)
1442       if(vf->ready_state>=STREAMSET)
1443         return vf->vc+vf->current_link;
1444       else
1445         return vf->vc;
1446     else
1447       if(link>=vf->links)
1448         return NULL;
1449       else
1450         return vf->vc+link;
1451   }else{
1452     return vf->vc;
1453   }
1454 }
1455
1456 static int host_is_big_endian() {
1457   ogg_int32_t pattern = 0xfeedface; /* deadbeef */
1458   unsigned char *bytewise = (unsigned char *)&pattern;
1459   if (bytewise[0] == 0xfe) return 1;
1460   return 0;
1461 }
1462
1463 /* up to this point, everything could more or less hide the multiple
1464    logical bitstream nature of chaining from the toplevel application
1465    if the toplevel application didn't particularly care.  However, at
1466    the point that we actually read audio back, the multiple-section
1467    nature must surface: Multiple bitstream sections do not necessarily
1468    have to have the same number of channels or sampling rate.
1469
1470    ov_read returns the sequential logical bitstream number currently
1471    being decoded along with the PCM data in order that the toplevel
1472    application can take action on channel/sample rate changes.  This
1473    number will be incremented even for streamed (non-seekable) streams
1474    (for seekable streams, it represents the actual logical bitstream
1475    index within the physical bitstream.  Note that the accessor
1476    functions above are aware of this dichotomy).
1477
1478    input values: buffer) a buffer to hold packed PCM data for return
1479                  length) the byte length requested to be placed into buffer
1480                  bigendianp) should the data be packed LSB first (0) or
1481                              MSB first (1)
1482                  word) word size for output.  currently 1 (byte) or 
1483                        2 (16 bit short)
1484
1485    return values: <0) error/hole in data (OV_HOLE), partial open (OV_EINVAL)
1486                    0) EOF
1487                    n) number of bytes of PCM actually returned.  The
1488                    below works on a packet-by-packet basis, so the
1489                    return length is not related to the 'length' passed
1490                    in, just guaranteed to fit.
1491
1492             *section) set to the logical bitstream number */
1493
1494 long ov_read(OggVorbis_File *vf,char *buffer,int length,
1495                     int bigendianp,int word,int sgned,int *bitstream){
1496   int i,j;
1497   int host_endian = host_is_big_endian();
1498
1499   float **pcm;
1500   long samples;
1501
1502   if(vf->ready_state<OPENED)return(OV_EINVAL);
1503
1504   while(1){
1505     if(vf->ready_state==INITSET){
1506       samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
1507       if(samples)break;
1508     }
1509
1510     /* suck in another packet */
1511     {
1512       int ret=_fetch_and_process_packet(vf,NULL,1,1);
1513       if(ret==OV_EOF)
1514         return(0);
1515       if(ret<=0)
1516         return(ret);
1517     }
1518
1519   }
1520
1521   if(samples>0){
1522   
1523     /* yay! proceed to pack data into the byte buffer */
1524     
1525     long channels=ov_info(vf,-1)->channels;
1526     long bytespersample=word * channels;
1527     vorbis_fpu_control fpu;
1528     if(samples>length/bytespersample)samples=length/bytespersample;
1529
1530     if(samples <= 0)
1531       return OV_EINVAL;
1532     
1533     /* a tight loop to pack each size */
1534     {
1535       int val;
1536       if(word==1){
1537         int off=(sgned?0:128);
1538         vorbis_fpu_setround(&fpu);
1539         for(j=0;j<samples;j++)
1540           for(i=0;i<channels;i++){
1541             val=vorbis_ftoi(pcm[i][j]*128.f);
1542             if(val>127)val=127;
1543             else if(val<-128)val=-128;
1544             *buffer++=val+off;
1545           }
1546         vorbis_fpu_restore(fpu);
1547       }else{
1548         int off=(sgned?0:32768);
1549         
1550         if(host_endian==bigendianp){
1551           if(sgned){
1552             
1553             vorbis_fpu_setround(&fpu);
1554             for(i=0;i<channels;i++) { /* It's faster in this order */
1555               float *src=pcm[i];
1556               short *dest=((short *)buffer)+i;
1557               for(j=0;j<samples;j++) {
1558                 val=vorbis_ftoi(src[j]*32768.f);
1559                 if(val>32767)val=32767;
1560                 else if(val<-32768)val=-32768;
1561                 *dest=val;
1562                 dest+=channels;
1563               }
1564             }
1565             vorbis_fpu_restore(fpu);
1566             
1567           }else{
1568             
1569             vorbis_fpu_setround(&fpu);
1570             for(i=0;i<channels;i++) {
1571               float *src=pcm[i];
1572               short *dest=((short *)buffer)+i;
1573               for(j=0;j<samples;j++) {
1574                 val=vorbis_ftoi(src[j]*32768.f);
1575                 if(val>32767)val=32767;
1576                 else if(val<-32768)val=-32768;
1577                 *dest=val+off;
1578                 dest+=channels;
1579               }
1580             }
1581             vorbis_fpu_restore(fpu);
1582             
1583           }
1584         }else if(bigendianp){
1585           
1586           vorbis_fpu_setround(&fpu);
1587           for(j=0;j<samples;j++)
1588             for(i=0;i<channels;i++){
1589               val=vorbis_ftoi(pcm[i][j]*32768.f);
1590               if(val>32767)val=32767;
1591               else if(val<-32768)val=-32768;
1592               val+=off;
1593               *buffer++=(val>>8);
1594               *buffer++=(val&0xff);
1595             }
1596           vorbis_fpu_restore(fpu);
1597           
1598         }else{
1599           int val;
1600           vorbis_fpu_setround(&fpu);
1601           for(j=0;j<samples;j++)
1602             for(i=0;i<channels;i++){
1603               val=vorbis_ftoi(pcm[i][j]*32768.f);
1604               if(val>32767)val=32767;
1605               else if(val<-32768)val=-32768;
1606               val+=off;
1607               *buffer++=(val&0xff);
1608               *buffer++=(val>>8);
1609                 }
1610           vorbis_fpu_restore(fpu);  
1611           
1612         }
1613       }
1614     }
1615     
1616     vorbis_synthesis_read(&vf->vd,samples);
1617     vf->pcm_offset+=samples;
1618     if(bitstream)*bitstream=vf->current_link;
1619     return(samples*bytespersample);
1620   }else{
1621     return(samples);
1622   }
1623 }
1624
1625 /* input values: pcm_channels) a float vector per channel of output
1626                  length) the sample length being read by the app
1627
1628    return values: <0) error/hole in data (OV_HOLE), partial open (OV_EINVAL)
1629                    0) EOF
1630                    n) number of samples of PCM actually returned.  The
1631                    below works on a packet-by-packet basis, so the
1632                    return length is not related to the 'length' passed
1633                    in, just guaranteed to fit.
1634
1635             *section) set to the logical bitstream number */
1636
1637
1638
1639 long ov_read_float(OggVorbis_File *vf,float ***pcm_channels,int length,
1640                    int *bitstream){
1641
1642   if(vf->ready_state<OPENED)return(OV_EINVAL);
1643
1644   while(1){
1645     if(vf->ready_state==INITSET){
1646       float **pcm;
1647       long samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
1648       if(samples){
1649         if(pcm_channels)*pcm_channels=pcm;
1650         if(samples>length)samples=length;
1651         vorbis_synthesis_read(&vf->vd,samples);
1652         vf->pcm_offset+=samples;
1653         if(bitstream)*bitstream=vf->current_link;
1654         return samples;
1655
1656       }
1657     }
1658
1659     /* suck in another packet */
1660     {
1661       int ret=_fetch_and_process_packet(vf,NULL,1,1);
1662       if(ret==OV_EOF)return(0);
1663       if(ret<=0)return(ret);
1664     }
1665
1666   }
1667 }
1668
1669 extern float *vorbis_window(vorbis_dsp_state *v,int W);
1670
1671 static void _vorbis_splice(float *d,float *s,
1672                           vorbis_dsp_state *v,int W){
1673   
1674   vorbis_info *vi=v->vi;
1675   int n=vorbis_info_blocksize(vi,0)/2;
1676   float *w=vorbis_window(v,W);
1677   int i;
1678
1679   for(i=0;i<n;i++){
1680     float wd=w[i]*w[i];
1681     float ws=1.-wd;
1682     d[i]=d[i]*wd + s[i]*ws;
1683   }
1684 }
1685         
1686
1687         
1688 /* this sets up crosslapping of a sample by using trailing data from
1689    sample 1 and lapping it into the windowing buffer of the second */
1690
1691 int ov_crosslap(OggVorbis_File *vf1, OggVorbis_File *vf2){
1692   vorbis_info *vi1,*vi2;
1693   vorbis_dsp_state *vd1=&vf1->vd;
1694   vorbis_dsp_state *vd2=&vf2->vd;
1695   float **lappcm;
1696   float **pcm;
1697   vorbis_dsp_state *winstate;
1698   int lapsize,lapcount=0,i,j;
1699
1700   /* first enforce some level of sanity... */
1701   /* we need to know that sample rate & channels match.  To do that,
1702      we need to verify the streams are actually initialized; the call
1703      is not just to be used for end-to-beginning lapping */
1704
1705   if(vf1->ready_state<OPENED)return(OV_EINVAL);
1706   if(vf2->ready_state<OPENED)return(OV_EINVAL);
1707
1708   /* make sure vf1 is INITSET */
1709   while(1){
1710     if(vf1->ready_state==INITSET)break;
1711     /* suck in another packet */
1712     {
1713       int ret=_fetch_and_process_packet(vf1,NULL,1,0);
1714       if(ret<0)return(ret);
1715     }
1716   }
1717
1718   /* make sure vf2 is INITSET and that we have a primed buffer; if
1719      we're crosslapping at a stream section boundary, this also makes
1720      sure we're sanity checking against the right stream information */
1721
1722   while(1){
1723     if(vf2->ready_state==INITSET)
1724       if(vorbis_synthesis_pcmout(vd2,NULL))break;
1725
1726     /* suck in another packet */
1727     {
1728       int ret=_fetch_and_process_packet(vf2,NULL,1,0);
1729       if(ret<0)return(ret);
1730     }
1731   }
1732
1733   /* sanity-check settings */
1734   vi1=ov_info(vf1,-1);
1735   vi2=ov_info(vf2,-1);
1736   if(vi1->channels != vi2->channels ||
1737      vi1->rate     != vi2->rate) return OV_EINVAL;
1738   
1739   /* begin by grabbing enough data for lapping from vf1; this may be
1740      in the form of unreturned, already-decoded pcm, remaining PCM we
1741      will need to decode, or synthetic postextrapolation from last
1742      packets. */
1743
1744   lappcm=alloca(sizeof(*lappcm)*vi1->channels);
1745   lapsize=vorbis_info_blocksize(vi1,0);
1746   if(vorbis_info_blocksize(vi2,0)<lapsize){
1747     lapsize=vorbis_info_blocksize(vi2,0)/2;
1748     winstate=vd2;
1749   }else{
1750     lapsize/=2;
1751     winstate=vd1;
1752   }
1753
1754   for(i=0;i<vi1->channels;i++)
1755     lappcm[i]=alloca(sizeof(**lappcm)*lapsize);
1756
1757   /* try first to decode the lapping data */
1758   while(lapcount<lapsize){
1759     int samples=vorbis_synthesis_pcmout(vd1,&pcm);
1760     if(samples){
1761       if(samples>lapsize-lapcount)samples=lapsize-lapcount;
1762       for(i=0;i<vi1->channels;i++)
1763         memcpy(lappcm[i]+lapcount,pcm[i],sizeof(**pcm)*samples);
1764       lapcount+=samples;
1765       vorbis_synthesis_read(vd1,samples);
1766     }else{
1767     /* suck in another packet */
1768       int ret=_fetch_and_process_packet(vf1,NULL,1,0); /* do *not* span */
1769       if(ret==OV_EOF)break;
1770     }
1771   }
1772   if(lapcount<lapsize){
1773     /* failed to get lapping data from normal decode; pry it from the
1774        postextrapolation buffering, or the second half of the MDCT
1775        from the last packet */
1776     int samples=vorbis_synthesis_lapout(&vf1->vd,&pcm);
1777     if(samples>lapsize-lapcount)samples=lapsize-lapcount;
1778     for(i=0;i<vi1->channels;i++)
1779       memcpy(lappcm[i]+lapcount,pcm[i],sizeof(**pcm)*samples);
1780     lapcount+=samples;
1781
1782     if(lapcount<lapsize)return OV_EFAULT;
1783   }
1784
1785   /* have a lapping buffer from vf1; now to splice it into the lapping
1786      buffer of vf2 */
1787
1788   /* consolidate and expose the buffer. */
1789   if(vorbis_synthesis_lapout(vd2,&pcm)<lapsize)return OV_EFAULT;
1790
1791   /* splice */
1792   for(j=0;j<vi1->channels;j++){
1793     float *s=lappcm[j];
1794     float *d=pcm[j];
1795     _vorbis_splice(d,s,winstate,0);
1796   }
1797
1798   /* done */
1799   return(0);
1800 }
1801
1802