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