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