vorbisfile.c revision 8e01cdce135d5d816f92d7bb83f9a930aa1b45ae
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: vorbisfile.c 17012 2010-03-24 07:37:36Z xiphmont $
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
67static 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 */
81static 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
108static 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 */
146static 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
188static 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 */
202static 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
212static 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.  */
223static 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 */
281static 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. */
421static 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 */
465static 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
596static 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
613static 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 */
655static 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
672static 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 */
867static 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
872static 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
932static 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 */
950int 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
988int 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
995int 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
1006int 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
1020int 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
1040int 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
1050int 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
1056int 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
1067int 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? */
1073long ov_streams(OggVorbis_File *vf){
1074  return vf->links;
1075}
1076
1077/* Is the FILE * associated with vf seekable? */
1078long 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
1091long 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*/
1133long 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 */
1145long 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*/
1160ogg_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*/
1179ogg_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*/
1198double 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
1219int 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. */
1388int 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)
1431          bisect=begin+1;
1432      }
1433
1434      result=_seek_helper(vf,bisect);
1435      if(result) goto seek_error;
1436
1437      while(begin<end){
1438        result=_get_next_page(vf,&og,end-vf->offset);
1439        if(result==OV_EREAD) goto seek_error;
1440        if(result<0){
1441          if(bisect<=begin+1)
1442            end=begin; /* found it */
1443          else{
1444            if(bisect==0) goto seek_error;
1445            bisect-=CHUNKSIZE;
1446            if(bisect<=begin)bisect=begin+1;
1447            result=_seek_helper(vf,bisect);
1448            if(result) goto seek_error;
1449          }
1450        }else{
1451          ogg_int64_t granulepos;
1452
1453          if(ogg_page_serialno(&og)!=vf->serialnos[link])
1454            continue;
1455
1456          granulepos=ogg_page_granulepos(&og);
1457          if(granulepos==-1)continue;
1458
1459          if(granulepos<target){
1460            best=result;  /* raw offset of packet with granulepos */
1461            begin=vf->offset; /* raw offset of next page */
1462            begintime=granulepos;
1463
1464            if(target-begintime>44100)break;
1465            bisect=begin; /* *not* begin + 1 */
1466          }else{
1467            if(bisect<=begin+1)
1468              end=begin;  /* found it */
1469            else{
1470              if(end==vf->offset){ /* we're pretty close - we'd be stuck in */
1471                end=result;
1472                bisect-=CHUNKSIZE; /* an endless loop otherwise. */
1473                if(bisect<=begin)bisect=begin+1;
1474                result=_seek_helper(vf,bisect);
1475                if(result) goto seek_error;
1476              }else{
1477                end=bisect;
1478                endtime=granulepos;
1479                break;
1480              }
1481            }
1482          }
1483        }
1484      }
1485    }
1486
1487    /* found our page. seek to it, update pcm offset. Easier case than
1488       raw_seek, don't keep packets preceeding granulepos. */
1489    {
1490      ogg_page og;
1491      ogg_packet op;
1492
1493      /* seek */
1494      result=_seek_helper(vf,best);
1495      vf->pcm_offset=-1;
1496      if(result) goto seek_error;
1497      result=_get_next_page(vf,&og,-1);
1498      if(result<0) goto seek_error;
1499
1500      if(link!=vf->current_link){
1501        /* Different link; dump entire decode machine */
1502        _decode_clear(vf);
1503
1504        vf->current_link=link;
1505        vf->current_serialno=vf->serialnos[link];
1506        vf->ready_state=STREAMSET;
1507
1508      }else{
1509        vorbis_synthesis_restart(&vf->vd);
1510      }
1511
1512      ogg_stream_reset_serialno(&vf->os,vf->current_serialno);
1513      ogg_stream_pagein(&vf->os,&og);
1514
1515      /* pull out all but last packet; the one with granulepos */
1516      while(1){
1517        result=ogg_stream_packetpeek(&vf->os,&op);
1518        if(result==0){
1519          /* !!! the packet finishing this page originated on a
1520             preceeding page. Keep fetching previous pages until we
1521             get one with a granulepos or without the 'continued' flag
1522             set.  Then just use raw_seek for simplicity. */
1523
1524          result=_seek_helper(vf,best);
1525          if(result<0) goto seek_error;
1526
1527          while(1){
1528            result=_get_prev_page(vf,&og);
1529            if(result<0) goto seek_error;
1530            if(ogg_page_serialno(&og)==vf->current_serialno &&
1531               (ogg_page_granulepos(&og)>-1 ||
1532                !ogg_page_continued(&og))){
1533              return ov_raw_seek(vf,result);
1534            }
1535            vf->offset=result;
1536          }
1537        }
1538        if(result<0){
1539          result = OV_EBADPACKET;
1540          goto seek_error;
1541        }
1542        if(op.granulepos!=-1){
1543          vf->pcm_offset=op.granulepos-vf->pcmlengths[vf->current_link*2];
1544          if(vf->pcm_offset<0)vf->pcm_offset=0;
1545          vf->pcm_offset+=total;
1546          break;
1547        }else
1548          result=ogg_stream_packetout(&vf->os,NULL);
1549      }
1550    }
1551  }
1552
1553  /* verify result */
1554  if(vf->pcm_offset>pos || pos>ov_pcm_total(vf,-1)){
1555    result=OV_EFAULT;
1556    goto seek_error;
1557  }
1558  vf->bittrack=0.f;
1559  vf->samptrack=0.f;
1560  return(0);
1561
1562 seek_error:
1563  /* dump machine so we're in a known state */
1564  vf->pcm_offset=-1;
1565  _decode_clear(vf);
1566  return (int)result;
1567}
1568
1569/* seek to a sample offset relative to the decompressed pcm stream
1570   returns zero on success, nonzero on failure */
1571
1572int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos){
1573  int thisblock,lastblock=0;
1574  int ret=ov_pcm_seek_page(vf,pos);
1575  if(ret<0)return(ret);
1576  if((ret=_make_decode_ready(vf)))return ret;
1577
1578  /* discard leading packets we don't need for the lapping of the
1579     position we want; don't decode them */
1580
1581  while(1){
1582    ogg_packet op;
1583    ogg_page og;
1584
1585    int ret=ogg_stream_packetpeek(&vf->os,&op);
1586    if(ret>0){
1587      thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op);
1588      if(thisblock<0){
1589        ogg_stream_packetout(&vf->os,NULL);
1590        continue; /* non audio packet */
1591      }
1592      if(lastblock)vf->pcm_offset+=(lastblock+thisblock)>>2;
1593
1594      if(vf->pcm_offset+((thisblock+
1595                          vorbis_info_blocksize(vf->vi,1))>>2)>=pos)break;
1596
1597      /* remove the packet from packet queue and track its granulepos */
1598      ogg_stream_packetout(&vf->os,NULL);
1599      vorbis_synthesis_trackonly(&vf->vb,&op);  /* set up a vb with
1600                                                   only tracking, no
1601                                                   pcm_decode */
1602      vorbis_synthesis_blockin(&vf->vd,&vf->vb);
1603
1604      /* end of logical stream case is hard, especially with exact
1605         length positioning. */
1606
1607      if(op.granulepos>-1){
1608        int i;
1609        /* always believe the stream markers */
1610        vf->pcm_offset=op.granulepos-vf->pcmlengths[vf->current_link*2];
1611        if(vf->pcm_offset<0)vf->pcm_offset=0;
1612        for(i=0;i<vf->current_link;i++)
1613          vf->pcm_offset+=vf->pcmlengths[i*2+1];
1614      }
1615
1616      lastblock=thisblock;
1617
1618    }else{
1619      if(ret<0 && ret!=OV_HOLE)break;
1620
1621      /* suck in a new page */
1622      if(_get_next_page(vf,&og,-1)<0)break;
1623      if(ogg_page_bos(&og))_decode_clear(vf);
1624
1625      if(vf->ready_state<STREAMSET){
1626        long serialno=ogg_page_serialno(&og);
1627        int link;
1628
1629        for(link=0;link<vf->links;link++)
1630          if(vf->serialnos[link]==serialno)break;
1631        if(link==vf->links) continue;
1632        vf->current_link=link;
1633
1634        vf->ready_state=STREAMSET;
1635        vf->current_serialno=ogg_page_serialno(&og);
1636        ogg_stream_reset_serialno(&vf->os,serialno);
1637        ret=_make_decode_ready(vf);
1638        if(ret)return ret;
1639        lastblock=0;
1640      }
1641
1642      ogg_stream_pagein(&vf->os,&og);
1643    }
1644  }
1645
1646  vf->bittrack=0.f;
1647  vf->samptrack=0.f;
1648  /* discard samples until we reach the desired position. Crossing a
1649     logical bitstream boundary with abandon is OK. */
1650  while(vf->pcm_offset<pos){
1651    ogg_int64_t target=pos-vf->pcm_offset;
1652    long samples=vorbis_synthesis_pcmout(&vf->vd,NULL);
1653
1654    if(samples>target)samples=target;
1655    vorbis_synthesis_read(&vf->vd,samples);
1656    vf->pcm_offset+=samples;
1657
1658    if(samples<target)
1659      if(_fetch_and_process_packet(vf,NULL,1,1)<=0)
1660        vf->pcm_offset=ov_pcm_total(vf,-1); /* eof */
1661  }
1662  return 0;
1663}
1664
1665/* seek to a playback time relative to the decompressed pcm stream
1666   returns zero on success, nonzero on failure */
1667int ov_time_seek(OggVorbis_File *vf,double seconds){
1668  /* translate time to PCM position and call ov_pcm_seek */
1669
1670  int link=-1;
1671  ogg_int64_t pcm_total=0;
1672  double time_total=0.;
1673
1674  if(vf->ready_state<OPENED)return(OV_EINVAL);
1675  if(!vf->seekable)return(OV_ENOSEEK);
1676  if(seconds<0)return(OV_EINVAL);
1677
1678  /* which bitstream section does this time offset occur in? */
1679  for(link=0;link<vf->links;link++){
1680    double addsec = ov_time_total(vf,link);
1681    if(seconds<time_total+addsec)break;
1682    time_total+=addsec;
1683    pcm_total+=vf->pcmlengths[link*2+1];
1684  }
1685
1686  if(link==vf->links)return(OV_EINVAL);
1687
1688  /* enough information to convert time offset to pcm offset */
1689  {
1690    ogg_int64_t target=pcm_total+(seconds-time_total)*vf->vi[link].rate;
1691    return(ov_pcm_seek(vf,target));
1692  }
1693}
1694
1695/* page-granularity version of ov_time_seek
1696   returns zero on success, nonzero on failure */
1697int ov_time_seek_page(OggVorbis_File *vf,double seconds){
1698  /* translate time to PCM position and call ov_pcm_seek */
1699
1700  int link=-1;
1701  ogg_int64_t pcm_total=0;
1702  double time_total=0.;
1703
1704  if(vf->ready_state<OPENED)return(OV_EINVAL);
1705  if(!vf->seekable)return(OV_ENOSEEK);
1706  if(seconds<0)return(OV_EINVAL);
1707
1708  /* which bitstream section does this time offset occur in? */
1709  for(link=0;link<vf->links;link++){
1710    double addsec = ov_time_total(vf,link);
1711    if(seconds<time_total+addsec)break;
1712    time_total+=addsec;
1713    pcm_total+=vf->pcmlengths[link*2+1];
1714  }
1715
1716  if(link==vf->links)return(OV_EINVAL);
1717
1718  /* enough information to convert time offset to pcm offset */
1719  {
1720    ogg_int64_t target=pcm_total+(seconds-time_total)*vf->vi[link].rate;
1721    return(ov_pcm_seek_page(vf,target));
1722  }
1723}
1724
1725/* tell the current stream offset cursor.  Note that seek followed by
1726   tell will likely not give the set offset due to caching */
1727ogg_int64_t ov_raw_tell(OggVorbis_File *vf){
1728  if(vf->ready_state<OPENED)return(OV_EINVAL);
1729  return(vf->offset);
1730}
1731
1732/* return PCM offset (sample) of next PCM sample to be read */
1733ogg_int64_t ov_pcm_tell(OggVorbis_File *vf){
1734  if(vf->ready_state<OPENED)return(OV_EINVAL);
1735  return(vf->pcm_offset);
1736}
1737
1738/* return time offset (seconds) of next PCM sample to be read */
1739double ov_time_tell(OggVorbis_File *vf){
1740  int link=0;
1741  ogg_int64_t pcm_total=0;
1742  double time_total=0.f;
1743
1744  if(vf->ready_state<OPENED)return(OV_EINVAL);
1745  if(vf->seekable){
1746    pcm_total=ov_pcm_total(vf,-1);
1747    time_total=ov_time_total(vf,-1);
1748
1749    /* which bitstream section does this time offset occur in? */
1750    for(link=vf->links-1;link>=0;link--){
1751      pcm_total-=vf->pcmlengths[link*2+1];
1752      time_total-=ov_time_total(vf,link);
1753      if(vf->pcm_offset>=pcm_total)break;
1754    }
1755  }
1756
1757  return((double)time_total+(double)(vf->pcm_offset-pcm_total)/vf->vi[link].rate);
1758}
1759
1760/*  link:   -1) return the vorbis_info struct for the bitstream section
1761                currently being decoded
1762           0-n) to request information for a specific bitstream section
1763
1764    In the case of a non-seekable bitstream, any call returns the
1765    current bitstream.  NULL in the case that the machine is not
1766    initialized */
1767
1768vorbis_info *ov_info(OggVorbis_File *vf,int link){
1769  if(vf->seekable){
1770    if(link<0)
1771      if(vf->ready_state>=STREAMSET)
1772        return vf->vi+vf->current_link;
1773      else
1774      return vf->vi;
1775    else
1776      if(link>=vf->links)
1777        return NULL;
1778      else
1779        return vf->vi+link;
1780  }else{
1781    return vf->vi;
1782  }
1783}
1784
1785/* grr, strong typing, grr, no templates/inheritence, grr */
1786vorbis_comment *ov_comment(OggVorbis_File *vf,int link){
1787  if(vf->seekable){
1788    if(link<0)
1789      if(vf->ready_state>=STREAMSET)
1790        return vf->vc+vf->current_link;
1791      else
1792        return vf->vc;
1793    else
1794      if(link>=vf->links)
1795        return NULL;
1796      else
1797        return vf->vc+link;
1798  }else{
1799    return vf->vc;
1800  }
1801}
1802
1803static int host_is_big_endian() {
1804  ogg_int32_t pattern = 0xfeedface; /* deadbeef */
1805  unsigned char *bytewise = (unsigned char *)&pattern;
1806  if (bytewise[0] == 0xfe) return 1;
1807  return 0;
1808}
1809
1810/* up to this point, everything could more or less hide the multiple
1811   logical bitstream nature of chaining from the toplevel application
1812   if the toplevel application didn't particularly care.  However, at
1813   the point that we actually read audio back, the multiple-section
1814   nature must surface: Multiple bitstream sections do not necessarily
1815   have to have the same number of channels or sampling rate.
1816
1817   ov_read returns the sequential logical bitstream number currently
1818   being decoded along with the PCM data in order that the toplevel
1819   application can take action on channel/sample rate changes.  This
1820   number will be incremented even for streamed (non-seekable) streams
1821   (for seekable streams, it represents the actual logical bitstream
1822   index within the physical bitstream.  Note that the accessor
1823   functions above are aware of this dichotomy).
1824
1825   ov_read_filter is exactly the same as ov_read except that it processes
1826   the decoded audio data through a filter before packing it into the
1827   requested format. This gives greater accuracy than applying a filter
1828   after the audio has been converted into integral PCM.
1829
1830   input values: buffer) a buffer to hold packed PCM data for return
1831                 length) the byte length requested to be placed into buffer
1832                 bigendianp) should the data be packed LSB first (0) or
1833                             MSB first (1)
1834                 word) word size for output.  currently 1 (byte) or
1835                       2 (16 bit short)
1836
1837   return values: <0) error/hole in data (OV_HOLE), partial open (OV_EINVAL)
1838                   0) EOF
1839                   n) number of bytes of PCM actually returned.  The
1840                   below works on a packet-by-packet basis, so the
1841                   return length is not related to the 'length' passed
1842                   in, just guaranteed to fit.
1843
1844            *section) set to the logical bitstream number */
1845
1846long ov_read_filter(OggVorbis_File *vf,char *buffer,int length,
1847                    int bigendianp,int word,int sgned,int *bitstream,
1848                    void (*filter)(float **pcm,long channels,long samples,void *filter_param),void *filter_param){
1849  int i,j;
1850  int host_endian = host_is_big_endian();
1851
1852  float **pcm;
1853  long samples;
1854
1855  if(vf->ready_state<OPENED)return(OV_EINVAL);
1856
1857  while(1){
1858    if(vf->ready_state==INITSET){
1859      samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
1860      if(samples)break;
1861    }
1862
1863    /* suck in another packet */
1864    {
1865      int ret=_fetch_and_process_packet(vf,NULL,1,1);
1866      if(ret==OV_EOF)
1867        return(0);
1868      if(ret<=0)
1869        return(ret);
1870    }
1871
1872  }
1873
1874  if(samples>0){
1875
1876    /* yay! proceed to pack data into the byte buffer */
1877
1878    long channels=ov_info(vf,-1)->channels;
1879    long bytespersample=word * channels;
1880    vorbis_fpu_control fpu;
1881    if(samples>length/bytespersample)samples=length/bytespersample;
1882
1883    if(samples <= 0)
1884      return OV_EINVAL;
1885
1886    /* Here. */
1887    if(filter)
1888      filter(pcm,channels,samples,filter_param);
1889
1890    /* a tight loop to pack each size */
1891    {
1892      int val;
1893      if(word==1){
1894        int off=(sgned?0:128);
1895        vorbis_fpu_setround(&fpu);
1896        for(j=0;j<samples;j++)
1897          for(i=0;i<channels;i++){
1898            val=vorbis_ftoi(pcm[i][j]*128.f);
1899            if(val>127)val=127;
1900            else if(val<-128)val=-128;
1901            *buffer++=val+off;
1902          }
1903        vorbis_fpu_restore(fpu);
1904      }else{
1905        int off=(sgned?0:32768);
1906
1907        if(host_endian==bigendianp){
1908          if(sgned){
1909
1910            vorbis_fpu_setround(&fpu);
1911            for(i=0;i<channels;i++) { /* It's faster in this order */
1912              float *src=pcm[i];
1913              short *dest=((short *)buffer)+i;
1914              for(j=0;j<samples;j++) {
1915                val=vorbis_ftoi(src[j]*32768.f);
1916                if(val>32767)val=32767;
1917                else if(val<-32768)val=-32768;
1918                *dest=val;
1919                dest+=channels;
1920              }
1921            }
1922            vorbis_fpu_restore(fpu);
1923
1924          }else{
1925
1926            vorbis_fpu_setround(&fpu);
1927            for(i=0;i<channels;i++) {
1928              float *src=pcm[i];
1929              short *dest=((short *)buffer)+i;
1930              for(j=0;j<samples;j++) {
1931                val=vorbis_ftoi(src[j]*32768.f);
1932                if(val>32767)val=32767;
1933                else if(val<-32768)val=-32768;
1934                *dest=val+off;
1935                dest+=channels;
1936              }
1937            }
1938            vorbis_fpu_restore(fpu);
1939
1940          }
1941        }else if(bigendianp){
1942
1943          vorbis_fpu_setround(&fpu);
1944          for(j=0;j<samples;j++)
1945            for(i=0;i<channels;i++){
1946              val=vorbis_ftoi(pcm[i][j]*32768.f);
1947              if(val>32767)val=32767;
1948              else if(val<-32768)val=-32768;
1949              val+=off;
1950              *buffer++=(val>>8);
1951              *buffer++=(val&0xff);
1952            }
1953          vorbis_fpu_restore(fpu);
1954
1955        }else{
1956          int val;
1957          vorbis_fpu_setround(&fpu);
1958          for(j=0;j<samples;j++)
1959            for(i=0;i<channels;i++){
1960              val=vorbis_ftoi(pcm[i][j]*32768.f);
1961              if(val>32767)val=32767;
1962              else if(val<-32768)val=-32768;
1963              val+=off;
1964              *buffer++=(val&0xff);
1965              *buffer++=(val>>8);
1966                  }
1967          vorbis_fpu_restore(fpu);
1968
1969        }
1970      }
1971    }
1972
1973    vorbis_synthesis_read(&vf->vd,samples);
1974    vf->pcm_offset+=samples;
1975    if(bitstream)*bitstream=vf->current_link;
1976    return(samples*bytespersample);
1977  }else{
1978    return(samples);
1979  }
1980}
1981
1982long ov_read(OggVorbis_File *vf,char *buffer,int length,
1983             int bigendianp,int word,int sgned,int *bitstream){
1984  return ov_read_filter(vf, buffer, length, bigendianp, word, sgned, bitstream, NULL, NULL);
1985}
1986
1987/* input values: pcm_channels) a float vector per channel of output
1988                 length) the sample length being read by the app
1989
1990   return values: <0) error/hole in data (OV_HOLE), partial open (OV_EINVAL)
1991                   0) EOF
1992                   n) number of samples of PCM actually returned.  The
1993                   below works on a packet-by-packet basis, so the
1994                   return length is not related to the 'length' passed
1995                   in, just guaranteed to fit.
1996
1997            *section) set to the logical bitstream number */
1998
1999
2000
2001long ov_read_float(OggVorbis_File *vf,float ***pcm_channels,int length,
2002                   int *bitstream){
2003
2004  if(vf->ready_state<OPENED)return(OV_EINVAL);
2005
2006  while(1){
2007    if(vf->ready_state==INITSET){
2008      float **pcm;
2009      long samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
2010      if(samples){
2011        if(pcm_channels)*pcm_channels=pcm;
2012        if(samples>length)samples=length;
2013        vorbis_synthesis_read(&vf->vd,samples);
2014        vf->pcm_offset+=samples;
2015        if(bitstream)*bitstream=vf->current_link;
2016        return samples;
2017
2018      }
2019    }
2020
2021    /* suck in another packet */
2022    {
2023      int ret=_fetch_and_process_packet(vf,NULL,1,1);
2024      if(ret==OV_EOF)return(0);
2025      if(ret<=0)return(ret);
2026    }
2027
2028  }
2029}
2030
2031extern float *vorbis_window(vorbis_dsp_state *v,int W);
2032
2033static void _ov_splice(float **pcm,float **lappcm,
2034                       int n1, int n2,
2035                       int ch1, int ch2,
2036                       float *w1, float *w2){
2037  int i,j;
2038  float *w=w1;
2039  int n=n1;
2040
2041  if(n1>n2){
2042    n=n2;
2043    w=w2;
2044  }
2045
2046  /* splice */
2047  for(j=0;j<ch1 && j<ch2;j++){
2048    float *s=lappcm[j];
2049    float *d=pcm[j];
2050
2051    for(i=0;i<n;i++){
2052      float wd=w[i]*w[i];
2053      float ws=1.-wd;
2054      d[i]=d[i]*wd + s[i]*ws;
2055    }
2056  }
2057  /* window from zero */
2058  for(;j<ch2;j++){
2059    float *d=pcm[j];
2060    for(i=0;i<n;i++){
2061      float wd=w[i]*w[i];
2062      d[i]=d[i]*wd;
2063    }
2064  }
2065
2066}
2067
2068/* make sure vf is INITSET */
2069static int _ov_initset(OggVorbis_File *vf){
2070  while(1){
2071    if(vf->ready_state==INITSET)break;
2072    /* suck in another packet */
2073    {
2074      int ret=_fetch_and_process_packet(vf,NULL,1,0);
2075      if(ret<0 && ret!=OV_HOLE)return(ret);
2076    }
2077  }
2078  return 0;
2079}
2080
2081/* make sure vf is INITSET and that we have a primed buffer; if
2082   we're crosslapping at a stream section boundary, this also makes
2083   sure we're sanity checking against the right stream information */
2084static int _ov_initprime(OggVorbis_File *vf){
2085  vorbis_dsp_state *vd=&vf->vd;
2086  while(1){
2087    if(vf->ready_state==INITSET)
2088      if(vorbis_synthesis_pcmout(vd,NULL))break;
2089
2090    /* suck in another packet */
2091    {
2092      int ret=_fetch_and_process_packet(vf,NULL,1,0);
2093      if(ret<0 && ret!=OV_HOLE)return(ret);
2094    }
2095  }
2096  return 0;
2097}
2098
2099/* grab enough data for lapping from vf; this may be in the form of
2100   unreturned, already-decoded pcm, remaining PCM we will need to
2101   decode, or synthetic postextrapolation from last packets. */
2102static void _ov_getlap(OggVorbis_File *vf,vorbis_info *vi,vorbis_dsp_state *vd,
2103                       float **lappcm,int lapsize){
2104  int lapcount=0,i;
2105  float **pcm;
2106
2107  /* try first to decode the lapping data */
2108  while(lapcount<lapsize){
2109    int samples=vorbis_synthesis_pcmout(vd,&pcm);
2110    if(samples){
2111      if(samples>lapsize-lapcount)samples=lapsize-lapcount;
2112      for(i=0;i<vi->channels;i++)
2113        memcpy(lappcm[i]+lapcount,pcm[i],sizeof(**pcm)*samples);
2114      lapcount+=samples;
2115      vorbis_synthesis_read(vd,samples);
2116    }else{
2117    /* suck in another packet */
2118      int ret=_fetch_and_process_packet(vf,NULL,1,0); /* do *not* span */
2119      if(ret==OV_EOF)break;
2120    }
2121  }
2122  if(lapcount<lapsize){
2123    /* failed to get lapping data from normal decode; pry it from the
2124       postextrapolation buffering, or the second half of the MDCT
2125       from the last packet */
2126    int samples=vorbis_synthesis_lapout(&vf->vd,&pcm);
2127    if(samples==0){
2128      for(i=0;i<vi->channels;i++)
2129        memset(lappcm[i]+lapcount,0,sizeof(**pcm)*lapsize-lapcount);
2130      lapcount=lapsize;
2131    }else{
2132      if(samples>lapsize-lapcount)samples=lapsize-lapcount;
2133      for(i=0;i<vi->channels;i++)
2134        memcpy(lappcm[i]+lapcount,pcm[i],sizeof(**pcm)*samples);
2135      lapcount+=samples;
2136    }
2137  }
2138}
2139
2140/* this sets up crosslapping of a sample by using trailing data from
2141   sample 1 and lapping it into the windowing buffer of sample 2 */
2142int ov_crosslap(OggVorbis_File *vf1, OggVorbis_File *vf2){
2143  vorbis_info *vi1,*vi2;
2144  float **lappcm;
2145  float **pcm;
2146  float *w1,*w2;
2147  int n1,n2,i,ret,hs1,hs2;
2148
2149  if(vf1==vf2)return(0); /* degenerate case */
2150  if(vf1->ready_state<OPENED)return(OV_EINVAL);
2151  if(vf2->ready_state<OPENED)return(OV_EINVAL);
2152
2153  /* the relevant overlap buffers must be pre-checked and pre-primed
2154     before looking at settings in the event that priming would cross
2155     a bitstream boundary.  So, do it now */
2156
2157  ret=_ov_initset(vf1);
2158  if(ret)return(ret);
2159  ret=_ov_initprime(vf2);
2160  if(ret)return(ret);
2161
2162  vi1=ov_info(vf1,-1);
2163  vi2=ov_info(vf2,-1);
2164  hs1=ov_halfrate_p(vf1);
2165  hs2=ov_halfrate_p(vf2);
2166
2167  lappcm=alloca(sizeof(*lappcm)*vi1->channels);
2168  n1=vorbis_info_blocksize(vi1,0)>>(1+hs1);
2169  n2=vorbis_info_blocksize(vi2,0)>>(1+hs2);
2170  w1=vorbis_window(&vf1->vd,0);
2171  w2=vorbis_window(&vf2->vd,0);
2172
2173  for(i=0;i<vi1->channels;i++)
2174    lappcm[i]=alloca(sizeof(**lappcm)*n1);
2175
2176  _ov_getlap(vf1,vi1,&vf1->vd,lappcm,n1);
2177
2178  /* have a lapping buffer from vf1; now to splice it into the lapping
2179     buffer of vf2 */
2180  /* consolidate and expose the buffer. */
2181  vorbis_synthesis_lapout(&vf2->vd,&pcm);
2182
2183#if 0
2184  _analysis_output_always("pcmL",0,pcm[0],n1*2,0,0,0);
2185  _analysis_output_always("pcmR",0,pcm[1],n1*2,0,0,0);
2186#endif
2187
2188  /* splice */
2189  _ov_splice(pcm,lappcm,n1,n2,vi1->channels,vi2->channels,w1,w2);
2190
2191  /* done */
2192  return(0);
2193}
2194
2195static int _ov_64_seek_lap(OggVorbis_File *vf,ogg_int64_t pos,
2196                           int (*localseek)(OggVorbis_File *,ogg_int64_t)){
2197  vorbis_info *vi;
2198  float **lappcm;
2199  float **pcm;
2200  float *w1,*w2;
2201  int n1,n2,ch1,ch2,hs;
2202  int i,ret;
2203
2204  if(vf->ready_state<OPENED)return(OV_EINVAL);
2205  ret=_ov_initset(vf);
2206  if(ret)return(ret);
2207  vi=ov_info(vf,-1);
2208  hs=ov_halfrate_p(vf);
2209
2210  ch1=vi->channels;
2211  n1=vorbis_info_blocksize(vi,0)>>(1+hs);
2212  w1=vorbis_window(&vf->vd,0);  /* window arrays from libvorbis are
2213                                   persistent; even if the decode state
2214                                   from this link gets dumped, this
2215                                   window array continues to exist */
2216
2217  lappcm=alloca(sizeof(*lappcm)*ch1);
2218  for(i=0;i<ch1;i++)
2219    lappcm[i]=alloca(sizeof(**lappcm)*n1);
2220  _ov_getlap(vf,vi,&vf->vd,lappcm,n1);
2221
2222  /* have lapping data; seek and prime the buffer */
2223  ret=localseek(vf,pos);
2224  if(ret)return ret;
2225  ret=_ov_initprime(vf);
2226  if(ret)return(ret);
2227
2228 /* Guard against cross-link changes; they're perfectly legal */
2229  vi=ov_info(vf,-1);
2230  ch2=vi->channels;
2231  n2=vorbis_info_blocksize(vi,0)>>(1+hs);
2232  w2=vorbis_window(&vf->vd,0);
2233
2234  /* consolidate and expose the buffer. */
2235  vorbis_synthesis_lapout(&vf->vd,&pcm);
2236
2237  /* splice */
2238  _ov_splice(pcm,lappcm,n1,n2,ch1,ch2,w1,w2);
2239
2240  /* done */
2241  return(0);
2242}
2243
2244int ov_raw_seek_lap(OggVorbis_File *vf,ogg_int64_t pos){
2245  return _ov_64_seek_lap(vf,pos,ov_raw_seek);
2246}
2247
2248int ov_pcm_seek_lap(OggVorbis_File *vf,ogg_int64_t pos){
2249  return _ov_64_seek_lap(vf,pos,ov_pcm_seek);
2250}
2251
2252int ov_pcm_seek_page_lap(OggVorbis_File *vf,ogg_int64_t pos){
2253  return _ov_64_seek_lap(vf,pos,ov_pcm_seek_page);
2254}
2255
2256static int _ov_d_seek_lap(OggVorbis_File *vf,double pos,
2257                           int (*localseek)(OggVorbis_File *,double)){
2258  vorbis_info *vi;
2259  float **lappcm;
2260  float **pcm;
2261  float *w1,*w2;
2262  int n1,n2,ch1,ch2,hs;
2263  int i,ret;
2264
2265  if(vf->ready_state<OPENED)return(OV_EINVAL);
2266  ret=_ov_initset(vf);
2267  if(ret)return(ret);
2268  vi=ov_info(vf,-1);
2269  hs=ov_halfrate_p(vf);
2270
2271  ch1=vi->channels;
2272  n1=vorbis_info_blocksize(vi,0)>>(1+hs);
2273  w1=vorbis_window(&vf->vd,0);  /* window arrays from libvorbis are
2274                                   persistent; even if the decode state
2275                                   from this link gets dumped, this
2276                                   window array continues to exist */
2277
2278  lappcm=alloca(sizeof(*lappcm)*ch1);
2279  for(i=0;i<ch1;i++)
2280    lappcm[i]=alloca(sizeof(**lappcm)*n1);
2281  _ov_getlap(vf,vi,&vf->vd,lappcm,n1);
2282
2283  /* have lapping data; seek and prime the buffer */
2284  ret=localseek(vf,pos);
2285  if(ret)return ret;
2286  ret=_ov_initprime(vf);
2287  if(ret)return(ret);
2288
2289 /* Guard against cross-link changes; they're perfectly legal */
2290  vi=ov_info(vf,-1);
2291  ch2=vi->channels;
2292  n2=vorbis_info_blocksize(vi,0)>>(1+hs);
2293  w2=vorbis_window(&vf->vd,0);
2294
2295  /* consolidate and expose the buffer. */
2296  vorbis_synthesis_lapout(&vf->vd,&pcm);
2297
2298  /* splice */
2299  _ov_splice(pcm,lappcm,n1,n2,ch1,ch2,w1,w2);
2300
2301  /* done */
2302  return(0);
2303}
2304
2305int ov_time_seek_lap(OggVorbis_File *vf,double pos){
2306  return _ov_d_seek_lap(vf,pos,ov_time_seek);
2307}
2308
2309int ov_time_seek_page_lap(OggVorbis_File *vf,double pos){
2310  return _ov_d_seek_lap(vf,pos,ov_time_seek_page);
2311}
2312