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