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