Vorbisfile raw seeking failed unit tests on a one-audio-page saple;
[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.69 2003/03/11 23:52:02 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   vf->bittrack=0.f;
400   vf->samptrack=0.f;
401   return;
402 }
403
404 static int _open_seekable2(OggVorbis_File *vf){
405   long serialno=vf->current_serialno;
406   ogg_int64_t dataoffset=vf->offset, end;
407   ogg_page og;
408
409   /* we're partially open and have a first link header state in
410      storage in vf */
411   /* we can seek, so set out learning all about this file */
412   (vf->callbacks.seek_func)(vf->datasource,0,SEEK_END);
413   vf->offset=vf->end=(vf->callbacks.tell_func)(vf->datasource);
414   
415   /* We get the offset for the last page of the physical bitstream.
416      Most OggVorbis files will contain a single logical bitstream */
417   end=_get_prev_page(vf,&og);
418   if(end<0)return(end);
419
420   /* more than one logical bitstream? */
421   if(ogg_page_serialno(&og)!=serialno){
422
423     /* Chained bitstream. Bisect-search each logical bitstream
424        section.  Do so based on serial number only */
425     if(_bisect_forward_serialno(vf,0,0,end+1,serialno,0)<0)return(OV_EREAD);
426
427   }else{
428
429     /* Only one logical bitstream */
430     if(_bisect_forward_serialno(vf,0,end,end+1,serialno,0))return(OV_EREAD);
431
432   }
433
434   /* the initial header memory is referenced by vf after; don't free it */
435   _prefetch_all_headers(vf,dataoffset);
436   return(ov_raw_seek(vf,0));
437 }
438
439 /* clear out the current logical bitstream decoder */ 
440 static void _decode_clear(OggVorbis_File *vf){
441   vorbis_dsp_clear(&vf->vd);
442   vorbis_block_clear(&vf->vb);
443   vf->ready_state=OPENED;
444 }
445
446 /* fetch and process a packet.  Handles the case where we're at a
447    bitstream boundary and dumps the decoding machine.  If the decoding
448    machine is unloaded, it loads it.  It also keeps pcm_offset up to
449    date (seek and read both use this.  seek uses a special hack with
450    readp). 
451
452    return: <0) error, OV_HOLE (lost packet) or OV_EOF
453             0) need more data (only if readp==0)
454             1) got a packet 
455 */
456
457 static int _fetch_and_process_packet(OggVorbis_File *vf,
458                                      ogg_packet *op_in,
459                                      int readp,
460                                      int spanp){
461   ogg_page og;
462
463   /* handle one packet.  Try to fetch it from current stream state */
464   /* extract packets from page */
465   while(1){
466     
467     /* process a packet if we can.  If the machine isn't loaded,
468        neither is a page */
469     if(vf->ready_state==INITSET){
470       while(1) {
471         ogg_packet op;
472         ogg_packet *op_ptr=(op_in?op_in:&op);
473         int result=ogg_stream_packetout(&vf->os,op_ptr);
474         ogg_int64_t granulepos;
475
476         op_in=NULL;
477         if(result==-1)return(OV_HOLE); /* hole in the data. */
478         if(result>0){
479           /* got a packet.  process it */
480           granulepos=op_ptr->granulepos;
481           if(!vorbis_synthesis(&vf->vb,op_ptr)){ /* lazy check for lazy
482                                                     header handling.  The
483                                                     header packets aren't
484                                                     audio, so if/when we
485                                                     submit them,
486                                                     vorbis_synthesis will
487                                                     reject them */
488
489             /* suck in the synthesis data and track bitrate */
490             {
491               int oldsamples=vorbis_synthesis_pcmout(&vf->vd,NULL);
492               /* for proper use of libvorbis within libvorbisfile,
493                  oldsamples will always be zero. */
494               if(oldsamples)return(OV_EFAULT);
495               
496               vorbis_synthesis_blockin(&vf->vd,&vf->vb);
497               vf->samptrack+=vorbis_synthesis_pcmout(&vf->vd,NULL)-oldsamples;
498               vf->bittrack+=op_ptr->bytes*8;
499             }
500           
501             /* update the pcm offset. */
502             if(granulepos!=-1 && !op_ptr->e_o_s){
503               int link=(vf->seekable?vf->current_link:0);
504               int i,samples;
505             
506               /* this packet has a pcm_offset on it (the last packet
507                  completed on a page carries the offset) After processing
508                  (above), we know the pcm position of the *last* sample
509                  ready to be returned. Find the offset of the *first*
510
511                  As an aside, this trick is inaccurate if we begin
512                  reading anew right at the last page; the end-of-stream
513                  granulepos declares the last frame in the stream, and the
514                  last packet of the last page may be a partial frame.
515                  So, we need a previous granulepos from an in-sequence page
516                  to have a reference point.  Thus the !op_ptr->e_o_s clause
517                  above */
518
519               if(vf->seekable && link>0)
520                 granulepos-=vf->pcmlengths[link*2];
521               if(granulepos<0)granulepos=0; /* actually, this
522                                                shouldn't be possible
523                                                here unless the stream
524                                                is very broken */
525
526               samples=vorbis_synthesis_pcmout(&vf->vd,NULL);
527             
528               granulepos-=samples;
529               for(i=0;i<link;i++)
530                 granulepos+=vf->pcmlengths[i*2+1];
531               vf->pcm_offset=granulepos;
532             }
533             return(1);
534           }
535         }
536         else 
537           break;
538       }
539     }
540
541     if(vf->ready_state>=OPENED){
542       int ret;
543       if(!readp)return(0);
544       if((ret=_get_next_page(vf,&og,-1))<0){
545         return(OV_EOF); /* eof. 
546                            leave unitialized */
547       }
548
549         /* bitrate tracking; add the header's bytes here, the body bytes
550            are done by packet above */
551       vf->bittrack+=og.header_len*8;
552       
553       /* has our decoding just traversed a bitstream boundary? */
554       if(vf->ready_state==INITSET){
555         if(vf->current_serialno!=ogg_page_serialno(&og)){
556           if(!spanp)
557             return(OV_EOF);
558
559           _decode_clear(vf);
560           
561           if(!vf->seekable){
562             vorbis_info_clear(vf->vi);
563             vorbis_comment_clear(vf->vc);
564           }
565         }
566       }
567     }
568
569     /* Do we need to load a new machine before submitting the page? */
570     /* This is different in the seekable and non-seekable cases.  
571
572        In the seekable case, we already have all the header
573        information loaded and cached; we just initialize the machine
574        with it and continue on our merry way.
575
576        In the non-seekable (streaming) case, we'll only be at a
577        boundary if we just left the previous logical bitstream and
578        we're now nominally at the header of the next bitstream
579     */
580
581     if(vf->ready_state!=INITSET){ 
582       int link;
583
584       if(vf->ready_state<STREAMSET){
585         if(vf->seekable){
586           vf->current_serialno=ogg_page_serialno(&og);
587           
588           /* match the serialno to bitstream section.  We use this rather than
589              offset positions to avoid problems near logical bitstream
590              boundaries */
591           for(link=0;link<vf->links;link++)
592             if(vf->serialnos[link]==vf->current_serialno)break;
593           if(link==vf->links)return(OV_EBADLINK); /* sign of a bogus
594                                                      stream.  error out,
595                                                      leave machine
596                                                      uninitialized */
597           
598           vf->current_link=link;
599           
600           ogg_stream_reset_serialno(&vf->os,vf->current_serialno);
601           vf->ready_state=STREAMSET;
602           
603         }else{
604           /* we're streaming */
605           /* fetch the three header packets, build the info struct */
606           
607           int ret=_fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno,&og);
608           if(ret)return(ret);
609           vf->current_link++;
610           link=0;
611         }
612       }
613       
614       _make_decode_ready(vf);
615     }
616     ogg_stream_pagein(&vf->os,&og);
617   }
618 }
619
620 /* if, eg, 64 bit stdio is configured by default, this will build with
621    fseek64 */
622 static int _fseek64_wrap(FILE *f,ogg_int64_t off,int whence){
623   if(f==NULL)return(-1);
624   return fseek(f,off,whence);
625 }
626
627 static int _ov_open1(void *f,OggVorbis_File *vf,char *initial,
628                      long ibytes, ov_callbacks callbacks){
629   int offsettest=(f?callbacks.seek_func(f,0,SEEK_CUR):-1);
630   int ret;
631
632   memset(vf,0,sizeof(*vf));
633   vf->datasource=f;
634   vf->callbacks = callbacks;
635
636   /* init the framing state */
637   ogg_sync_init(&vf->oy);
638
639   /* perhaps some data was previously read into a buffer for testing
640      against other stream types.  Allow initialization from this
641      previously read data (as we may be reading from a non-seekable
642      stream) */
643   if(initial){
644     char *buffer=ogg_sync_buffer(&vf->oy,ibytes);
645     memcpy(buffer,initial,ibytes);
646     ogg_sync_wrote(&vf->oy,ibytes);
647   }
648
649   /* can we seek? Stevens suggests the seek test was portable */
650   if(offsettest!=-1)vf->seekable=1;
651
652   /* No seeking yet; Set up a 'single' (current) logical bitstream
653      entry for partial open */
654   vf->links=1;
655   vf->vi=_ogg_calloc(vf->links,sizeof(*vf->vi));
656   vf->vc=_ogg_calloc(vf->links,sizeof(*vf->vc));
657   ogg_stream_init(&vf->os,-1); /* fill in the serialno later */
658
659   /* Try to fetch the headers, maintaining all the storage */
660   if((ret=_fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno,NULL))<0){
661     vf->datasource=NULL;
662     ov_clear(vf);
663   }else if(vf->ready_state < PARTOPEN)
664     vf->ready_state=PARTOPEN;
665   return(ret);
666 }
667
668 static int _ov_open2(OggVorbis_File *vf){
669   if(vf->ready_state < OPENED)
670     vf->ready_state=OPENED;
671   if(vf->seekable){
672     int ret=_open_seekable2(vf);
673     if(ret){
674       vf->datasource=NULL;
675       ov_clear(vf);
676     }
677     return(ret);
678   }
679   return 0;
680 }
681
682
683 /* clear out the OggVorbis_File struct */
684 int ov_clear(OggVorbis_File *vf){
685   if(vf){
686     vorbis_block_clear(&vf->vb);
687     vorbis_dsp_clear(&vf->vd);
688     ogg_stream_clear(&vf->os);
689     
690     if(vf->vi && vf->links){
691       int i;
692       for(i=0;i<vf->links;i++){
693         vorbis_info_clear(vf->vi+i);
694         vorbis_comment_clear(vf->vc+i);
695       }
696       _ogg_free(vf->vi);
697       _ogg_free(vf->vc);
698     }
699     if(vf->dataoffsets)_ogg_free(vf->dataoffsets);
700     if(vf->pcmlengths)_ogg_free(vf->pcmlengths);
701     if(vf->serialnos)_ogg_free(vf->serialnos);
702     if(vf->offsets)_ogg_free(vf->offsets);
703     ogg_sync_clear(&vf->oy);
704     if(vf->datasource)(vf->callbacks.close_func)(vf->datasource);
705     memset(vf,0,sizeof(*vf));
706   }
707 #ifdef DEBUG_LEAKS
708   _VDBG_dump();
709 #endif
710   return(0);
711 }
712
713 /* inspects the OggVorbis file and finds/documents all the logical
714    bitstreams contained in it.  Tries to be tolerant of logical
715    bitstream sections that are truncated/woogie. 
716
717    return: -1) error
718             0) OK
719 */
720
721 int ov_open_callbacks(void *f,OggVorbis_File *vf,char *initial,long ibytes,
722     ov_callbacks callbacks){
723   int ret=_ov_open1(f,vf,initial,ibytes,callbacks);
724   if(ret)return ret;
725   return _ov_open2(vf);
726 }
727
728 int ov_open(FILE *f,OggVorbis_File *vf,char *initial,long ibytes){
729   ov_callbacks callbacks = {
730     (size_t (*)(void *, size_t, size_t, void *))  fread,
731     (int (*)(void *, ogg_int64_t, int))              _fseek64_wrap,
732     (int (*)(void *))                             fclose,
733     (long (*)(void *))                            ftell
734   };
735
736   return ov_open_callbacks((void *)f, vf, initial, ibytes, callbacks);
737 }
738   
739 /* Only partially open the vorbis file; test for Vorbisness, and load
740    the headers for the first chain.  Do not seek (although test for
741    seekability).  Use ov_test_open to finish opening the file, else
742    ov_clear to close/free it. Same return codes as open. */
743
744 int ov_test_callbacks(void *f,OggVorbis_File *vf,char *initial,long ibytes,
745     ov_callbacks callbacks)
746 {
747   return _ov_open1(f,vf,initial,ibytes,callbacks);
748 }
749
750 int ov_test(FILE *f,OggVorbis_File *vf,char *initial,long ibytes){
751   ov_callbacks callbacks = {
752     (size_t (*)(void *, size_t, size_t, void *))  fread,
753     (int (*)(void *, ogg_int64_t, int))              _fseek64_wrap,
754     (int (*)(void *))                             fclose,
755     (long (*)(void *))                            ftell
756   };
757
758   return ov_test_callbacks((void *)f, vf, initial, ibytes, callbacks);
759 }
760   
761 int ov_test_open(OggVorbis_File *vf){
762   if(vf->ready_state!=PARTOPEN)return(OV_EINVAL);
763   return _ov_open2(vf);
764 }
765
766 /* How many logical bitstreams in this physical bitstream? */
767 long ov_streams(OggVorbis_File *vf){
768   return vf->links;
769 }
770
771 /* Is the FILE * associated with vf seekable? */
772 long ov_seekable(OggVorbis_File *vf){
773   return vf->seekable;
774 }
775
776 /* returns the bitrate for a given logical bitstream or the entire
777    physical bitstream.  If the file is open for random access, it will
778    find the *actual* average bitrate.  If the file is streaming, it
779    returns the nominal bitrate (if set) else the average of the
780    upper/lower bounds (if set) else -1 (unset).
781
782    If you want the actual bitrate field settings, get them from the
783    vorbis_info structs */
784
785 long ov_bitrate(OggVorbis_File *vf,int i){
786   if(vf->ready_state<OPENED)return(OV_EINVAL);
787   if(i>=vf->links)return(OV_EINVAL);
788   if(!vf->seekable && i!=0)return(ov_bitrate(vf,0));
789   if(i<0){
790     ogg_int64_t bits=0;
791     int i;
792     float br;
793     for(i=0;i<vf->links;i++)
794       bits+=(vf->offsets[i+1]-vf->dataoffsets[i])*8;
795     /* This once read: return(rint(bits/ov_time_total(vf,-1)));
796      * gcc 3.x on x86 miscompiled this at optimisation level 2 and above,
797      * so this is slightly transformed to make it work.
798      */
799     br = bits/ov_time_total(vf,-1);
800     return(rint(br));
801   }else{
802     if(vf->seekable){
803       /* return the actual bitrate */
804       return(rint((vf->offsets[i+1]-vf->dataoffsets[i])*8/ov_time_total(vf,i)));
805     }else{
806       /* return nominal if set */
807       if(vf->vi[i].bitrate_nominal>0){
808         return vf->vi[i].bitrate_nominal;
809       }else{
810         if(vf->vi[i].bitrate_upper>0){
811           if(vf->vi[i].bitrate_lower>0){
812             return (vf->vi[i].bitrate_upper+vf->vi[i].bitrate_lower)/2;
813           }else{
814             return vf->vi[i].bitrate_upper;
815           }
816         }
817         return(OV_FALSE);
818       }
819     }
820   }
821 }
822
823 /* returns the actual bitrate since last call.  returns -1 if no
824    additional data to offer since last call (or at beginning of stream),
825    EINVAL if stream is only partially open 
826 */
827 long ov_bitrate_instant(OggVorbis_File *vf){
828   int link=(vf->seekable?vf->current_link:0);
829   long ret;
830   if(vf->ready_state<OPENED)return(OV_EINVAL);
831   if(vf->samptrack==0)return(OV_FALSE);
832   ret=vf->bittrack/vf->samptrack*vf->vi[link].rate+.5;
833   vf->bittrack=0.f;
834   vf->samptrack=0.f;
835   return(ret);
836 }
837
838 /* Guess */
839 long ov_serialnumber(OggVorbis_File *vf,int i){
840   if(i>=vf->links)return(ov_serialnumber(vf,vf->links-1));
841   if(!vf->seekable && i>=0)return(ov_serialnumber(vf,-1));
842   if(i<0){
843     return(vf->current_serialno);
844   }else{
845     return(vf->serialnos[i]);
846   }
847 }
848
849 /* returns: total raw (compressed) length of content if i==-1
850             raw (compressed) length of that logical bitstream for i==0 to n
851             OV_EINVAL if the stream is not seekable (we can't know the length)
852             or if stream is only partially open
853 */
854 ogg_int64_t ov_raw_total(OggVorbis_File *vf,int i){
855   if(vf->ready_state<OPENED)return(OV_EINVAL);
856   if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
857   if(i<0){
858     ogg_int64_t acc=0;
859     int i;
860     for(i=0;i<vf->links;i++)
861       acc+=ov_raw_total(vf,i);
862     return(acc);
863   }else{
864     return(vf->offsets[i+1]-vf->offsets[i]);
865   }
866 }
867
868 /* returns: total PCM length (samples) of content if i==-1 PCM length
869             (samples) of that logical bitstream for i==0 to n
870             OV_EINVAL if the stream is not seekable (we can't know the
871             length) or only partially open 
872 */
873 ogg_int64_t ov_pcm_total(OggVorbis_File *vf,int i){
874   if(vf->ready_state<OPENED)return(OV_EINVAL);
875   if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
876   if(i<0){
877     ogg_int64_t acc=0;
878     int i;
879     for(i=0;i<vf->links;i++)
880       acc+=ov_pcm_total(vf,i);
881     return(acc);
882   }else{
883     return(vf->pcmlengths[i*2+1]);
884   }
885 }
886
887 /* returns: total seconds of content if i==-1
888             seconds in that logical bitstream for i==0 to n
889             OV_EINVAL if the stream is not seekable (we can't know the
890             length) or only partially open 
891 */
892 double ov_time_total(OggVorbis_File *vf,int i){
893   if(vf->ready_state<OPENED)return(OV_EINVAL);
894   if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
895   if(i<0){
896     double acc=0;
897     int i;
898     for(i=0;i<vf->links;i++)
899       acc+=ov_time_total(vf,i);
900     return(acc);
901   }else{
902     return((double)(vf->pcmlengths[i*2+1])/vf->vi[i].rate);
903   }
904 }
905
906 /* seek to an offset relative to the *compressed* data. This also
907    scans packets to update the PCM cursor. It will cross a logical
908    bitstream boundary, but only if it can't get any packets out of the
909    tail of the bitstream we seek to (so no surprises).
910
911    returns zero on success, nonzero on failure */
912
913 int ov_raw_seek(OggVorbis_File *vf,ogg_int64_t pos){
914   ogg_stream_state work_os;
915
916   if(vf->ready_state<OPENED)return(OV_EINVAL);
917   if(!vf->seekable)
918     return(OV_ENOSEEK); /* don't dump machine if we can't seek */
919
920   if(pos<0 || pos>vf->end)return(OV_EINVAL);
921
922   /* don't yet clear out decoding machine (if it's initialized), in
923      the case we're in the same link.  Restart the decode lapping, and
924      let _fetch_and_process_packet deal with a potential bitstream
925      boundary */
926   vf->pcm_offset=-1;
927   ogg_stream_reset_serialno(&vf->os,
928                             vf->current_serialno); /* must set serialno */
929   vorbis_synthesis_restart(&vf->vd);
930     
931   _seek_helper(vf,pos);
932
933   /* we need to make sure the pcm_offset is set, but we don't want to
934      advance the raw cursor past good packets just to get to the first
935      with a granulepos.  That's not equivalent behavior to beginning
936      decoding as immediately after the seek position as possible.
937
938      So, a hack.  We use two stream states; a local scratch state and
939      the shared vf->os stream state.  We use the local state to
940      scan, and the shared state as a buffer for later decode. 
941
942      Unfortuantely, on the last page we still advance to last packet
943      because the granulepos on the last page is not necessarily on a
944      packet boundary, and we need to make sure the granpos is
945      correct. 
946   */
947
948   {
949     ogg_page og;
950     ogg_packet op;
951     int lastblock=0;
952     int accblock=0;
953     int thisblock;
954     int eosflag;
955
956     ogg_stream_init(&work_os,vf->current_serialno); /* get the memory ready */
957     ogg_stream_reset(&work_os); /* eliminate the spurious OV_HOLE
958                                    return from not necessarily
959                                    starting from the beginning */
960
961     while(1){
962       if(vf->ready_state>=STREAMSET){
963         /* snarf/scan a packet if we can */
964         int result=ogg_stream_packetout(&work_os,&op);
965       
966         if(result>0){
967
968           if(vf->vi[vf->current_link].codec_setup){
969             thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op);
970             if(thisblock<0){
971               ogg_stream_packetout(&vf->os,NULL);
972               thisblock=0;
973             }else{
974               
975               if(eosflag)
976               ogg_stream_packetout(&vf->os,NULL);
977               else
978                 if(lastblock)accblock+=(lastblock+thisblock)>>2;
979             }       
980
981             if(op.granulepos!=-1){
982               int i,link=vf->current_link;
983               ogg_int64_t granulepos=op.granulepos-vf->pcmlengths[link*2];
984               if(granulepos<0)granulepos=0;
985               
986               for(i=0;i<link;i++)
987                 granulepos+=vf->pcmlengths[i*2+1];
988               vf->pcm_offset=granulepos-accblock;
989               break;
990             }
991             lastblock=thisblock;
992             continue;
993           }else
994             ogg_stream_packetout(&vf->os,NULL);
995         }
996       }
997       
998       if(!lastblock){
999         if(_get_next_page(vf,&og,-1)<0){
1000           vf->pcm_offset=ov_pcm_total(vf,-1);
1001           break;
1002         }
1003       }else{
1004         /* huh?  Bogus stream with packets but no granulepos */
1005         vf->pcm_offset=-1;
1006         break;
1007       }
1008       
1009       /* has our decoding just traversed a bitstream boundary? */
1010       if(vf->ready_state>=STREAMSET)
1011         if(vf->current_serialno!=ogg_page_serialno(&og)){
1012           _decode_clear(vf); /* clear out stream state */
1013           ogg_stream_clear(&work_os);
1014         }
1015
1016       if(vf->ready_state<STREAMSET){
1017         int link;
1018         
1019         vf->current_serialno=ogg_page_serialno(&og);
1020         for(link=0;link<vf->links;link++)
1021           if(vf->serialnos[link]==vf->current_serialno)break;
1022         if(link==vf->links)goto seek_error; /* sign of a bogus stream.
1023                                                error out, leave
1024                                                machine uninitialized */
1025         vf->current_link=link;
1026         
1027         ogg_stream_reset_serialno(&vf->os,vf->current_serialno);
1028         ogg_stream_reset_serialno(&work_os,vf->current_serialno); 
1029         vf->ready_state=STREAMSET;
1030         
1031       }
1032     
1033       ogg_stream_pagein(&vf->os,&og);
1034       ogg_stream_pagein(&work_os,&og);
1035       eosflag=ogg_page_eos(&og);
1036     }
1037   }
1038
1039   ogg_stream_clear(&work_os);
1040   vf->bittrack=0.f;
1041   vf->samptrack=0.f;
1042   return(0);
1043
1044  seek_error:
1045   /* dump the machine so we're in a known state */
1046   vf->pcm_offset=-1;
1047   ogg_stream_clear(&work_os);
1048   _decode_clear(vf);
1049   return OV_EBADLINK;
1050 }
1051
1052 /* Page granularity seek (faster than sample granularity because we
1053    don't do the last bit of decode to find a specific sample).
1054
1055    Seek to the last [granule marked] page preceeding the specified pos
1056    location, such that decoding past the returned point will quickly
1057    arrive at the requested position. */
1058 int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos){
1059   int link=-1;
1060   ogg_int64_t result=0;
1061   ogg_int64_t total=ov_pcm_total(vf,-1);
1062
1063   if(vf->ready_state<OPENED)return(OV_EINVAL);
1064   if(!vf->seekable)return(OV_ENOSEEK);
1065
1066   if(pos<0 || pos>total)return(OV_EINVAL);
1067  
1068   /* which bitstream section does this pcm offset occur in? */
1069   for(link=vf->links-1;link>=0;link--){
1070     total-=vf->pcmlengths[link*2+1];
1071     if(pos>=total)break;
1072   }
1073
1074   /* search within the logical bitstream for the page with the highest
1075      pcm_pos preceeding (or equal to) pos.  There is a danger here;
1076      missing pages or incorrect frame number information in the
1077      bitstream could make our task impossible.  Account for that (it
1078      would be an error condition) */
1079
1080   /* new search algorithm by HB (Nicholas Vinen) */
1081   {
1082     ogg_int64_t end=vf->offsets[link+1];
1083     ogg_int64_t begin=vf->offsets[link];
1084     ogg_int64_t begintime = vf->pcmlengths[link*2];
1085     ogg_int64_t endtime = vf->pcmlengths[link*2+1]+begintime;
1086     ogg_int64_t target=pos-total+begintime;
1087     ogg_int64_t best=begin;
1088     
1089     ogg_page og;
1090     while(begin<end){
1091       ogg_int64_t bisect;
1092       
1093       if(end-begin<CHUNKSIZE){
1094         bisect=begin;
1095       }else{
1096         /* take a (pretty decent) guess. */
1097         bisect=begin + 
1098           (target-begintime)*(end-begin)/(endtime-begintime) - CHUNKSIZE;
1099         if(bisect<=begin)
1100           bisect=begin+1;
1101       }
1102       
1103       _seek_helper(vf,bisect);
1104     
1105       while(begin<end){
1106         result=_get_next_page(vf,&og,end-vf->offset);
1107         if(result==OV_EREAD) goto seek_error;
1108         if(result<0){
1109           if(bisect<=begin+1)
1110             end=begin; /* found it */
1111           else{
1112             if(bisect==0) goto seek_error;
1113             bisect-=CHUNKSIZE;
1114             if(bisect<=begin)bisect=begin+1;
1115             _seek_helper(vf,bisect);
1116           }
1117         }else{
1118           ogg_int64_t granulepos=ogg_page_granulepos(&og);
1119           if(granulepos==-1)continue;
1120           if(granulepos<target){
1121             best=result;  /* raw offset of packet with granulepos */ 
1122             begin=vf->offset; /* raw offset of next page */
1123             begintime=granulepos;
1124             
1125             if(target-begintime>44100)break;
1126             bisect=begin; /* *not* begin + 1 */
1127           }else{
1128             if(bisect<=begin+1)
1129               end=begin;  /* found it */
1130             else{
1131               if(end==vf->offset){ /* we're pretty close - we'd be stuck in */
1132                 end=result;
1133                 bisect-=CHUNKSIZE; /* an endless loop otherwise. */
1134                 if(bisect<=begin)bisect=begin+1;
1135                 _seek_helper(vf,bisect);
1136               }else{
1137                 end=result;
1138                 endtime=granulepos;
1139                 break;
1140               }
1141             }
1142           }
1143         }
1144       }
1145     }
1146
1147     /* found our page. seek to it, update pcm offset. Easier case than
1148        raw_seek, don't keep packets preceeding granulepos. */
1149     {
1150       ogg_page og;
1151       ogg_packet op;
1152       
1153       /* seek */
1154       _seek_helper(vf,best);
1155       vf->pcm_offset=-1;
1156       
1157       if(_get_next_page(vf,&og,-1)<0)return(OV_EOF); /* shouldn't happen */
1158       
1159       if(link!=vf->current_link){
1160         /* Different link; dump entire decode machine */
1161         _decode_clear(vf);  
1162         
1163         vf->current_link=link;
1164         vf->current_serialno=ogg_page_serialno(&og);
1165         vf->ready_state=STREAMSET;
1166         
1167       }else{
1168         vorbis_synthesis_restart(&vf->vd);
1169       }
1170
1171       ogg_stream_reset_serialno(&vf->os,vf->current_serialno);
1172       ogg_stream_pagein(&vf->os,&og);
1173
1174       /* pull out all but last packet; the one with granulepos */
1175       while(1){
1176         result=ogg_stream_packetpeek(&vf->os,&op);
1177         if(result==0){
1178           /* !!! the packet finishing this page originated on a
1179              preceeding page. Keep fetching previous pages until we
1180              get one with a granulepos or without the 'continued' flag
1181              set.  Then just use raw_seek for simplicity. */
1182           
1183           _seek_helper(vf,best);
1184           
1185           while(1){
1186             result=_get_prev_page(vf,&og);
1187             if(result<0) goto seek_error;
1188             if(ogg_page_granulepos(&og)>-1 ||
1189                !ogg_page_continued(&og)){
1190               return ov_raw_seek(vf,result);
1191             }
1192             vf->offset=result;
1193           }
1194         }
1195         if(result<0){
1196           result = OV_EBADPACKET; 
1197           goto seek_error;
1198         }
1199         if(op.granulepos!=-1){
1200           vf->pcm_offset=op.granulepos-vf->pcmlengths[vf->current_link*2];
1201           if(vf->pcm_offset<0)vf->pcm_offset=0;
1202           vf->pcm_offset+=total;
1203           break;
1204         }else
1205           result=ogg_stream_packetout(&vf->os,NULL);
1206       }
1207     }
1208   }
1209   
1210   /* verify result */
1211   if(vf->pcm_offset>pos || pos>ov_pcm_total(vf,-1)){
1212     result=OV_EFAULT;
1213     goto seek_error;
1214   }
1215   vf->bittrack=0.f;
1216   vf->samptrack=0.f;
1217   return(0);
1218   
1219  seek_error:
1220   /* dump machine so we're in a known state */
1221   vf->pcm_offset=-1;
1222   _decode_clear(vf);
1223   return (int)result;
1224 }
1225
1226 /* seek to a sample offset relative to the decompressed pcm stream 
1227    returns zero on success, nonzero on failure */
1228
1229 int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos){
1230   int thisblock,lastblock=0;
1231   int ret=ov_pcm_seek_page(vf,pos);
1232   if(ret<0)return(ret);
1233   _make_decode_ready(vf);
1234
1235   /* discard leading packets we don't need for the lapping of the
1236      position we want; don't decode them */
1237
1238   while(1){
1239     ogg_packet op;
1240     ogg_page og;
1241
1242     int ret=ogg_stream_packetpeek(&vf->os,&op);
1243     if(ret>0){
1244       thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op);
1245       if(thisblock<0){
1246         ogg_stream_packetout(&vf->os,NULL);
1247         continue; /* non audio packet */
1248       }
1249       if(lastblock)vf->pcm_offset+=(lastblock+thisblock)>>2;
1250       
1251       if(vf->pcm_offset+((thisblock+
1252                           vorbis_info_blocksize(vf->vi,1))>>2)>=pos)break;
1253       
1254       /* remove the packet from packet queue and track its granulepos */
1255       ogg_stream_packetout(&vf->os,NULL);
1256       vorbis_synthesis_trackonly(&vf->vb,&op);  /* set up a vb with
1257                                                    only tracking, no
1258                                                    pcm_decode */
1259       vorbis_synthesis_blockin(&vf->vd,&vf->vb); 
1260       
1261       /* end of logical stream case is hard, especially with exact
1262          length positioning. */
1263       
1264       if(op.granulepos>-1){
1265         int i;
1266         /* always believe the stream markers */
1267         vf->pcm_offset=op.granulepos-vf->pcmlengths[vf->current_link*2];
1268         if(vf->pcm_offset<0)vf->pcm_offset=0;
1269         for(i=0;i<vf->current_link;i++)
1270           vf->pcm_offset+=vf->pcmlengths[i*2+1];
1271       }
1272         
1273       lastblock=thisblock;
1274       
1275     }else{
1276       if(ret<0 && ret!=OV_HOLE)break;
1277       
1278       /* suck in a new page */
1279       if(_get_next_page(vf,&og,-1)<0)break;
1280       if(vf->current_serialno!=ogg_page_serialno(&og))_decode_clear(vf);
1281       
1282       if(vf->ready_state<STREAMSET){
1283         int link;
1284         
1285         vf->current_serialno=ogg_page_serialno(&og);
1286         for(link=0;link<vf->links;link++)
1287           if(vf->serialnos[link]==vf->current_serialno)break;
1288         if(link==vf->links)return(OV_EBADLINK);
1289         vf->current_link=link;
1290         
1291         ogg_stream_reset_serialno(&vf->os,vf->current_serialno); 
1292         vf->ready_state=STREAMSET;      
1293         _make_decode_ready(vf);
1294         lastblock=0;
1295       }
1296
1297       ogg_stream_pagein(&vf->os,&og);
1298     }
1299   }
1300
1301   vf->bittrack=0.f;
1302   vf->samptrack=0.f;
1303   /* discard samples until we reach the desired position. Crossing a
1304      logical bitstream boundary with abandon is OK. */
1305   while(vf->pcm_offset<pos){
1306     ogg_int64_t target=pos-vf->pcm_offset;
1307     long samples=vorbis_synthesis_pcmout(&vf->vd,NULL);
1308
1309     if(samples>target)samples=target;
1310     vorbis_synthesis_read(&vf->vd,samples);
1311     vf->pcm_offset+=samples;
1312     
1313     if(samples<target)
1314       if(_fetch_and_process_packet(vf,NULL,1,1)<=0)
1315         vf->pcm_offset=ov_pcm_total(vf,-1); /* eof */
1316   }
1317   return 0;
1318 }
1319
1320 /* seek to a playback time relative to the decompressed pcm stream 
1321    returns zero on success, nonzero on failure */
1322 int ov_time_seek(OggVorbis_File *vf,double seconds){
1323   /* translate time to PCM position and call ov_pcm_seek */
1324
1325   int link=-1;
1326   ogg_int64_t pcm_total=ov_pcm_total(vf,-1);
1327   double time_total=ov_time_total(vf,-1);
1328
1329   if(vf->ready_state<OPENED)return(OV_EINVAL);
1330   if(!vf->seekable)return(OV_ENOSEEK);
1331   if(seconds<0 || seconds>time_total)return(OV_EINVAL);
1332   
1333   /* which bitstream section does this time offset occur in? */
1334   for(link=vf->links-1;link>=0;link--){
1335     pcm_total-=vf->pcmlengths[link*2+1];
1336     time_total-=ov_time_total(vf,link);
1337     if(seconds>=time_total)break;
1338   }
1339
1340   /* enough information to convert time offset to pcm offset */
1341   {
1342     ogg_int64_t target=pcm_total+(seconds-time_total)*vf->vi[link].rate;
1343     return(ov_pcm_seek(vf,target));
1344   }
1345 }
1346
1347 /* page-granularity version of ov_time_seek 
1348    returns zero on success, nonzero on failure */
1349 int ov_time_seek_page(OggVorbis_File *vf,double seconds){
1350   /* translate time to PCM position and call ov_pcm_seek */
1351
1352   int link=-1;
1353   ogg_int64_t pcm_total=ov_pcm_total(vf,-1);
1354   double time_total=ov_time_total(vf,-1);
1355
1356   if(vf->ready_state<OPENED)return(OV_EINVAL);
1357   if(!vf->seekable)return(OV_ENOSEEK);
1358   if(seconds<0 || seconds>time_total)return(OV_EINVAL);
1359   
1360   /* which bitstream section does this time offset occur in? */
1361   for(link=vf->links-1;link>=0;link--){
1362     pcm_total-=vf->pcmlengths[link*2+1];
1363     time_total-=ov_time_total(vf,link);
1364     if(seconds>=time_total)break;
1365   }
1366
1367   /* enough information to convert time offset to pcm offset */
1368   {
1369     ogg_int64_t target=pcm_total+(seconds-time_total)*vf->vi[link].rate;
1370     return(ov_pcm_seek_page(vf,target));
1371   }
1372 }
1373
1374 /* tell the current stream offset cursor.  Note that seek followed by
1375    tell will likely not give the set offset due to caching */
1376 ogg_int64_t ov_raw_tell(OggVorbis_File *vf){
1377   if(vf->ready_state<OPENED)return(OV_EINVAL);
1378   return(vf->offset);
1379 }
1380
1381 /* return PCM offset (sample) of next PCM sample to be read */
1382 ogg_int64_t ov_pcm_tell(OggVorbis_File *vf){
1383   if(vf->ready_state<OPENED)return(OV_EINVAL);
1384   return(vf->pcm_offset);
1385 }
1386
1387 /* return time offset (seconds) of next PCM sample to be read */
1388 double ov_time_tell(OggVorbis_File *vf){
1389   int link=0;
1390   ogg_int64_t pcm_total=0;
1391   double time_total=0.f;
1392   
1393   if(vf->ready_state<OPENED)return(OV_EINVAL);
1394   if(vf->seekable){
1395     pcm_total=ov_pcm_total(vf,-1);
1396     time_total=ov_time_total(vf,-1);
1397   
1398     /* which bitstream section does this time offset occur in? */
1399     for(link=vf->links-1;link>=0;link--){
1400       pcm_total-=vf->pcmlengths[link*2+1];
1401       time_total-=ov_time_total(vf,link);
1402       if(vf->pcm_offset>=pcm_total)break;
1403     }
1404   }
1405
1406   return((double)time_total+(double)(vf->pcm_offset-pcm_total)/vf->vi[link].rate);
1407 }
1408
1409 /*  link:   -1) return the vorbis_info struct for the bitstream section
1410                 currently being decoded
1411            0-n) to request information for a specific bitstream section
1412     
1413     In the case of a non-seekable bitstream, any call returns the
1414     current bitstream.  NULL in the case that the machine is not
1415     initialized */
1416
1417 vorbis_info *ov_info(OggVorbis_File *vf,int link){
1418   if(vf->seekable){
1419     if(link<0)
1420       if(vf->ready_state>=STREAMSET)
1421         return vf->vi+vf->current_link;
1422       else
1423       return vf->vi;
1424     else
1425       if(link>=vf->links)
1426         return NULL;
1427       else
1428         return vf->vi+link;
1429   }else{
1430     return vf->vi;
1431   }
1432 }
1433
1434 /* grr, strong typing, grr, no templates/inheritence, grr */
1435 vorbis_comment *ov_comment(OggVorbis_File *vf,int link){
1436   if(vf->seekable){
1437     if(link<0)
1438       if(vf->ready_state>=STREAMSET)
1439         return vf->vc+vf->current_link;
1440       else
1441         return vf->vc;
1442     else
1443       if(link>=vf->links)
1444         return NULL;
1445       else
1446         return vf->vc+link;
1447   }else{
1448     return vf->vc;
1449   }
1450 }
1451
1452 static int host_is_big_endian() {
1453   ogg_int32_t pattern = 0xfeedface; /* deadbeef */
1454   unsigned char *bytewise = (unsigned char *)&pattern;
1455   if (bytewise[0] == 0xfe) return 1;
1456   return 0;
1457 }
1458
1459 /* up to this point, everything could more or less hide the multiple
1460    logical bitstream nature of chaining from the toplevel application
1461    if the toplevel application didn't particularly care.  However, at
1462    the point that we actually read audio back, the multiple-section
1463    nature must surface: Multiple bitstream sections do not necessarily
1464    have to have the same number of channels or sampling rate.
1465
1466    ov_read returns the sequential logical bitstream number currently
1467    being decoded along with the PCM data in order that the toplevel
1468    application can take action on channel/sample rate changes.  This
1469    number will be incremented even for streamed (non-seekable) streams
1470    (for seekable streams, it represents the actual logical bitstream
1471    index within the physical bitstream.  Note that the accessor
1472    functions above are aware of this dichotomy).
1473
1474    input values: buffer) a buffer to hold packed PCM data for return
1475                  length) the byte length requested to be placed into buffer
1476                  bigendianp) should the data be packed LSB first (0) or
1477                              MSB first (1)
1478                  word) word size for output.  currently 1 (byte) or 
1479                        2 (16 bit short)
1480
1481    return values: <0) error/hole in data (OV_HOLE), partial open (OV_EINVAL)
1482                    0) EOF
1483                    n) number of bytes of PCM actually returned.  The
1484                    below works on a packet-by-packet basis, so the
1485                    return length is not related to the 'length' passed
1486                    in, just guaranteed to fit.
1487
1488             *section) set to the logical bitstream number */
1489
1490 long ov_read(OggVorbis_File *vf,char *buffer,int length,
1491                     int bigendianp,int word,int sgned,int *bitstream){
1492   int i,j;
1493   int host_endian = host_is_big_endian();
1494
1495   float **pcm;
1496   long samples;
1497
1498   if(vf->ready_state<OPENED)return(OV_EINVAL);
1499
1500   while(1){
1501     if(vf->ready_state==INITSET){
1502       samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
1503       if(samples)break;
1504     }
1505
1506     /* suck in another packet */
1507     {
1508       int ret=_fetch_and_process_packet(vf,NULL,1,1);
1509       if(ret==OV_EOF)
1510         return(0);
1511       if(ret<=0)
1512         return(ret);
1513     }
1514
1515   }
1516
1517   if(samples>0){
1518   
1519     /* yay! proceed to pack data into the byte buffer */
1520     
1521     long channels=ov_info(vf,-1)->channels;
1522     long bytespersample=word * channels;
1523     vorbis_fpu_control fpu;
1524     if(samples>length/bytespersample)samples=length/bytespersample;
1525
1526     if(samples <= 0)
1527       return OV_EINVAL;
1528     
1529     /* a tight loop to pack each size */
1530     {
1531       int val;
1532       if(word==1){
1533         int off=(sgned?0:128);
1534         vorbis_fpu_setround(&fpu);
1535         for(j=0;j<samples;j++)
1536           for(i=0;i<channels;i++){
1537             val=vorbis_ftoi(pcm[i][j]*128.f);
1538             if(val>127)val=127;
1539             else if(val<-128)val=-128;
1540             *buffer++=val+off;
1541           }
1542         vorbis_fpu_restore(fpu);
1543       }else{
1544         int off=(sgned?0:32768);
1545         
1546         if(host_endian==bigendianp){
1547           if(sgned){
1548             
1549             vorbis_fpu_setround(&fpu);
1550             for(i=0;i<channels;i++) { /* It's faster in this order */
1551               float *src=pcm[i];
1552               short *dest=((short *)buffer)+i;
1553               for(j=0;j<samples;j++) {
1554                 val=vorbis_ftoi(src[j]*32768.f);
1555                 if(val>32767)val=32767;
1556                 else if(val<-32768)val=-32768;
1557                 *dest=val;
1558                 dest+=channels;
1559               }
1560             }
1561             vorbis_fpu_restore(fpu);
1562             
1563           }else{
1564             
1565             vorbis_fpu_setround(&fpu);
1566             for(i=0;i<channels;i++) {
1567               float *src=pcm[i];
1568               short *dest=((short *)buffer)+i;
1569               for(j=0;j<samples;j++) {
1570                 val=vorbis_ftoi(src[j]*32768.f);
1571                 if(val>32767)val=32767;
1572                 else if(val<-32768)val=-32768;
1573                 *dest=val+off;
1574                 dest+=channels;
1575               }
1576             }
1577             vorbis_fpu_restore(fpu);
1578             
1579           }
1580         }else if(bigendianp){
1581           
1582           vorbis_fpu_setround(&fpu);
1583           for(j=0;j<samples;j++)
1584             for(i=0;i<channels;i++){
1585               val=vorbis_ftoi(pcm[i][j]*32768.f);
1586               if(val>32767)val=32767;
1587               else if(val<-32768)val=-32768;
1588               val+=off;
1589               *buffer++=(val>>8);
1590               *buffer++=(val&0xff);
1591             }
1592           vorbis_fpu_restore(fpu);
1593           
1594         }else{
1595           int val;
1596           vorbis_fpu_setround(&fpu);
1597           for(j=0;j<samples;j++)
1598             for(i=0;i<channels;i++){
1599               val=vorbis_ftoi(pcm[i][j]*32768.f);
1600               if(val>32767)val=32767;
1601               else if(val<-32768)val=-32768;
1602               val+=off;
1603               *buffer++=(val&0xff);
1604               *buffer++=(val>>8);
1605                 }
1606           vorbis_fpu_restore(fpu);  
1607           
1608         }
1609       }
1610     }
1611     
1612     vorbis_synthesis_read(&vf->vd,samples);
1613     vf->pcm_offset+=samples;
1614     if(bitstream)*bitstream=vf->current_link;
1615     return(samples*bytespersample);
1616   }else{
1617     return(samples);
1618   }
1619 }
1620
1621 /* input values: pcm_channels) a float vector per channel of output
1622                  length) the sample length being read by the app
1623
1624    return values: <0) error/hole in data (OV_HOLE), partial open (OV_EINVAL)
1625                    0) EOF
1626                    n) number of samples of PCM actually returned.  The
1627                    below works on a packet-by-packet basis, so the
1628                    return length is not related to the 'length' passed
1629                    in, just guaranteed to fit.
1630
1631             *section) set to the logical bitstream number */
1632
1633
1634
1635 long ov_read_float(OggVorbis_File *vf,float ***pcm_channels,int length,
1636                    int *bitstream){
1637
1638   if(vf->ready_state<OPENED)return(OV_EINVAL);
1639
1640   while(1){
1641     if(vf->ready_state==INITSET){
1642       float **pcm;
1643       long samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
1644       if(samples){
1645         if(pcm_channels)*pcm_channels=pcm;
1646         if(samples>length)samples=length;
1647         vorbis_synthesis_read(&vf->vd,samples);
1648         vf->pcm_offset+=samples;
1649         if(bitstream)*bitstream=vf->current_link;
1650         return samples;
1651
1652       }
1653     }
1654
1655     /* suck in another packet */
1656     {
1657       int ret=_fetch_and_process_packet(vf,NULL,1,1);
1658       if(ret==OV_EOF)return(0);
1659       if(ret<=0)return(ret);
1660     }
1661
1662   }
1663 }
1664
1665 extern float *vorbis_window(vorbis_dsp_state *v,int W);
1666
1667 static void _ov_splice(float **pcm,float **lappcm,
1668                        int n1, int n2,
1669                        int ch1, int ch2,
1670                        float *w1, float *w2){
1671   int i,j;
1672   float *w=w1;
1673   int n=n1;
1674
1675   if(n1>n2){
1676     n=n2;
1677     w=w2;
1678   }
1679
1680   /* splice */
1681   for(j=0;j<ch1 && j<ch2;j++){
1682     float *s=lappcm[j];
1683     float *d=pcm[j];
1684     for(i=0;i<n;i++){
1685       float wd=w[i]*w[i];
1686       float ws=1.-wd;
1687       d[i]=d[i]*wd + s[i]*ws;
1688     }
1689   }
1690   /* window from zero */
1691   for(;j<ch2;j++){
1692     float *d=pcm[j];
1693     for(i=0;i<n;i++){
1694       float wd=w[i]*w[i];
1695       d[i]=d[i]*wd;
1696     }
1697   }
1698 }
1699                 
1700 /* make sure vf is INITSET */
1701 static int _ov_initset(OggVorbis_File *vf){
1702   while(1){
1703     if(vf->ready_state==INITSET)break;
1704     /* suck in another packet */
1705     {
1706       int ret=_fetch_and_process_packet(vf,NULL,1,0);
1707       if(ret<0 && ret!=OV_HOLE)return(ret);
1708     }
1709   }
1710   return 0;
1711 }
1712
1713 /* make sure vf is INITSET and that we have a primed buffer; if
1714    we're crosslapping at a stream section boundary, this also makes
1715    sure we're sanity checking against the right stream information */
1716 static int _ov_initprime(OggVorbis_File *vf){
1717   vorbis_dsp_state *vd=&vf->vd;
1718   while(1){
1719     if(vf->ready_state==INITSET)
1720       if(vorbis_synthesis_pcmout(vd,NULL))break;
1721     
1722     /* suck in another packet */
1723     {
1724       int ret=_fetch_and_process_packet(vf,NULL,1,0);
1725       if(ret<0 && ret!=OV_HOLE)return(ret);
1726     }
1727   }  
1728   return 0;
1729 }
1730
1731 /* grab enough data for lapping from vf; this may be in the form of
1732    unreturned, already-decoded pcm, remaining PCM we will need to
1733    decode, or synthetic postextrapolation from last packets. */
1734 static void _ov_getlap(OggVorbis_File *vf,vorbis_info *vi,vorbis_dsp_state *vd,
1735                        float **lappcm,int lapsize){
1736   int lapcount=0,i;
1737   float **pcm;
1738
1739   /* try first to decode the lapping data */
1740   while(lapcount<lapsize){
1741     int samples=vorbis_synthesis_pcmout(vd,&pcm);
1742     if(samples){
1743       if(samples>lapsize-lapcount)samples=lapsize-lapcount;
1744       for(i=0;i<vi->channels;i++)
1745         memcpy(lappcm[i]+lapcount,pcm[i],sizeof(**pcm)*samples);
1746       lapcount+=samples;
1747       vorbis_synthesis_read(vd,samples);
1748     }else{
1749     /* suck in another packet */
1750       int ret=_fetch_and_process_packet(vf,NULL,1,0); /* do *not* span */
1751       if(ret==OV_EOF)break;
1752     }
1753   }
1754   if(lapcount<lapsize){
1755     /* failed to get lapping data from normal decode; pry it from the
1756        postextrapolation buffering, or the second half of the MDCT
1757        from the last packet */
1758     int samples=vorbis_synthesis_lapout(&vf->vd,&pcm);
1759     if(samples>lapsize-lapcount)samples=lapsize-lapcount;
1760     for(i=0;i<vi->channels;i++)
1761       memcpy(lappcm[i]+lapcount,pcm[i],sizeof(**pcm)*samples);
1762     lapcount+=samples;
1763
1764   }
1765 }
1766
1767 /* this sets up crosslapping of a sample by using trailing data from
1768    sample 1 and lapping it into the windowing buffer of sample 2 */
1769 int ov_crosslap(OggVorbis_File *vf1, OggVorbis_File *vf2){
1770   vorbis_info *vi1,*vi2;
1771   float **lappcm;
1772   float **pcm;
1773   float *w1,*w2;
1774   int n1,n2,i,ret;
1775
1776   if(vf1==vf2)return(0); /* degenerate case */
1777   if(vf1->ready_state<OPENED)return(OV_EINVAL);
1778   if(vf2->ready_state<OPENED)return(OV_EINVAL);
1779
1780   /* the relevant overlap buffers must be pre-checked and pre-primed
1781      before looking at settings in the event that priming would cross
1782      a bitstream boundary.  So, do it now */
1783
1784   ret=_ov_initset(vf1);
1785   if(ret)return(ret);
1786   ret=_ov_initprime(vf2);
1787   if(ret)return(ret);
1788
1789   vi1=ov_info(vf1,-1);
1790   vi2=ov_info(vf2,-1);
1791   
1792   lappcm=alloca(sizeof(*lappcm)*vi1->channels);
1793   n1=vorbis_info_blocksize(vi1,0)/2;
1794   n2=vorbis_info_blocksize(vi2,0)/2;
1795   w1=vorbis_window(&vf1->vd,0);
1796   w2=vorbis_window(&vf2->vd,0);
1797
1798   for(i=0;i<vi1->channels;i++)
1799     lappcm[i]=alloca(sizeof(**lappcm)*n1);
1800
1801   _ov_getlap(vf1,vi1,&vf1->vd,lappcm,n1);
1802
1803   /* have a lapping buffer from vf1; now to splice it into the lapping
1804      buffer of vf2 */
1805   /* consolidate and expose the buffer. */
1806   vorbis_synthesis_lapout(&vf2->vd,&pcm);
1807
1808   /* splice */
1809   _ov_splice(pcm,lappcm,n1,n2,vi1->channels,vi2->channels,w1,w2);
1810   
1811   /* done */
1812   return(0);
1813 }
1814
1815 static int _ov_64_seek_lap(OggVorbis_File *vf,ogg_int64_t pos,
1816                            int (*localseek)(OggVorbis_File *,ogg_int64_t)){
1817   vorbis_info *vi;
1818   float **lappcm;
1819   float **pcm;
1820   float *w1,*w2;
1821   int n1,n2,ch1,ch2;
1822   int i,ret;
1823
1824   if(vf->ready_state<OPENED)return(OV_EINVAL);
1825   ret=_ov_initset(vf);
1826   if(ret)return(ret);
1827   vi=ov_info(vf,-1);
1828   
1829   ch1=vi->channels;
1830   n1=vorbis_info_blocksize(vi,0)/2;
1831   w1=vorbis_window(&vf->vd,0);  /* window arrays from libvorbis are
1832                                    persistent; even if the decode state
1833                                    from this link gets dumped, this
1834                                    window array continues to exist */
1835
1836   lappcm=alloca(sizeof(*lappcm)*ch1);
1837   for(i=0;i<ch1;i++)
1838     lappcm[i]=alloca(sizeof(**lappcm)*n1);
1839   _ov_getlap(vf,vi,&vf->vd,lappcm,n1);
1840
1841   /* have lapping data; seek and prime the buffer */
1842   ret=localseek(vf,pos);
1843   if(ret)return ret;
1844   ret=_ov_initprime(vf);
1845   if(ret)return(ret);
1846
1847  /* Guard against cross-link changes; they're perfectly legal */
1848   vi=ov_info(vf,-1);
1849   ch2=vi->channels;
1850   n2=vorbis_info_blocksize(vi,0)/2;
1851   w2=vorbis_window(&vf->vd,0);
1852
1853   /* consolidate and expose the buffer. */
1854   vorbis_synthesis_lapout(&vf->vd,&pcm);
1855
1856   /* splice */
1857   _ov_splice(pcm,lappcm,n1,n2,ch1,ch2,w1,w2);
1858
1859   /* done */
1860   return(0);
1861 }
1862
1863 int ov_raw_seek_lap(OggVorbis_File *vf,ogg_int64_t pos){
1864   return _ov_64_seek_lap(vf,pos,ov_raw_seek);
1865 }
1866
1867 int ov_pcm_seek_lap(OggVorbis_File *vf,ogg_int64_t pos){
1868   return _ov_64_seek_lap(vf,pos,ov_pcm_seek);
1869 }
1870
1871 int ov_pcm_seek_page_lap(OggVorbis_File *vf,ogg_int64_t pos){
1872   return _ov_64_seek_lap(vf,pos,ov_pcm_seek_page);
1873 }
1874
1875 static int _ov_d_seek_lap(OggVorbis_File *vf,double pos,
1876                            int (*localseek)(OggVorbis_File *,double)){
1877   vorbis_info *vi;
1878   float **lappcm;
1879   float **pcm;
1880   float *w1,*w2;
1881   int n1,n2,ch1,ch2;
1882   int i,ret;
1883
1884   if(vf->ready_state<OPENED)return(OV_EINVAL);
1885   ret=_ov_initset(vf);
1886   if(ret)return(ret);
1887   vi=ov_info(vf,-1);
1888   
1889   ch1=vi->channels;
1890   n1=vorbis_info_blocksize(vi,0)/2;
1891   w1=vorbis_window(&vf->vd,0);  /* window arrays from libvorbis are
1892                                    persistent; even if the decode state
1893                                    from this link gets dumped, this
1894                                    window array continues to exist */
1895
1896   lappcm=alloca(sizeof(*lappcm)*ch1);
1897   for(i=0;i<ch1;i++)
1898     lappcm[i]=alloca(sizeof(**lappcm)*n1);
1899   _ov_getlap(vf,vi,&vf->vd,lappcm,n1);
1900
1901   /* have lapping data; seek and prime the buffer */
1902   ret=localseek(vf,pos);
1903   if(ret)return ret;
1904   ret=_ov_initprime(vf);
1905   if(ret)return(ret);
1906
1907  /* Guard against cross-link changes; they're perfectly legal */
1908   vi=ov_info(vf,-1);
1909   ch2=vi->channels;
1910   n2=vorbis_info_blocksize(vi,0)/2;
1911   w2=vorbis_window(&vf->vd,0);
1912
1913   /* consolidate and expose the buffer. */
1914   vorbis_synthesis_lapout(&vf->vd,&pcm);
1915
1916   /* splice */
1917   _ov_splice(pcm,lappcm,n1,n2,ch1,ch2,w1,w2);
1918
1919   /* done */
1920   return(0);
1921 }
1922
1923 int ov_time_seek_lap(OggVorbis_File *vf,double pos){
1924   return _ov_d_seek_lap(vf,pos,ov_time_seek);
1925 }
1926
1927 int ov_time_seek_page_lap(OggVorbis_File *vf,double pos){
1928   return _ov_d_seek_lap(vf,pos,ov_time_seek_page);
1929 }