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