doom3-gpl
Doom 3 GPL source release
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros 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-2002 *
9  * by the XIPHOPHORUS Company http://www.xiph.org/ *
10  * *
11  ********************************************************************
12 
13  function: stdio-based convenience library for opening/seeking/decoding
14  last mod: $Id: vorbisfile.c,v 1.75 2003/09/16 20:28:14 xiphmont Exp $
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 #include "../vorbis/vorbisfile.h"
26 
27 #include "os.h"
28 #include "misc.h"
29 
30 /* A 'chained bitstream' is a Vorbis bitstream that contains more than
31  one logical bitstream arranged end to end (the only form of Ogg
32  multiplexing allowed in a Vorbis bitstream; grouping [parallel
33  multiplexing] is not allowed in Vorbis) */
34 
35 /* A Vorbis file can be played beginning to end (streamed) without
36  worrying ahead of time about chaining (see decoder_example.c). If
37  we have the whole file, however, and want random access
38  (seeking/scrubbing) or desire to know the total length/time of a
39  file, we need to account for the possibility of chaining. */
40 
41 /* We can handle things a number of ways; we can determine the entire
42  bitstream structure right off the bat, or find pieces on demand.
43  This example determines and caches structure for the entire
44  bitstream, but builds a virtual decoder on the fly when moving
45  between links in the chain. */
46 
47 /* There are also different ways to implement seeking. Enough
48  information exists in an Ogg bitstream to seek to
49  sample-granularity positions in the output. Or, one can seek by
50  picking some portion of the stream roughly in the desired area if
51  we only want coarse navigation through the stream. */
52 
53 /*************************************************************************
54  * Many, many internal helpers. The intention is not to be confusing;
55  * rampant duplication and monolithic function implementation would be
56  * harder to understand anyway. The high level functions are last. Begin
57  * grokking near the end of the file */
58 
59 /* read a little more data from the file/pipe into the ogg_sync framer
60 */
61 #define CHUNKSIZE 8500 /* a shade over 8k; anyone using pages well
62  over 8k gets what they deserve */
63 static long _get_data(OggVorbis_File *vf){
64  errno=0;
65  if(vf->datasource){
66  char *buffer=ogg_sync_buffer(&vf->oy,CHUNKSIZE);
67  long bytes=(vf->callbacks.read_func)(buffer,1,CHUNKSIZE,vf->datasource);
68  if(bytes>0)ogg_sync_wrote(&vf->oy,bytes);
69  if(bytes==0 && errno)return(-1);
70  return(bytes);
71  }else
72  return(0);
73 }
74 
75 /* save a tiny smidge of verbosity to make the code more readable */
76 static void _seek_helper(OggVorbis_File *vf,ogg_int64_t offset){
77  if(vf->datasource){
78  (vf->callbacks.seek_func)(vf->datasource, offset, SEEK_SET);
79  vf->offset=offset;
80  ogg_sync_reset(&vf->oy);
81  }else{
82  /* shouldn't happen unless someone writes a broken callback */
83  return;
84  }
85 }
86 
87 /* The read/seek functions track absolute position within the stream */
88 
89 /* from the head of the stream, get the next page. boundary specifies
90  if the function is allowed to fetch more data from the stream (and
91  how much) or only use internally buffered data.
92 
93  boundary: -1) unbounded search
94  0) read no additional data; use cached only
95  n) search for a new page beginning for n bytes
96 
97  return: <0) did not find a page (OV_FALSE, OV_EOF, OV_EREAD)
98  n) found a page at absolute offset n */
99 
100 static ogg_int64_t _get_next_page(OggVorbis_File *vf,ogg_page *og,
101  ogg_int64_t boundary){
102  if(boundary>0)boundary+=vf->offset;
103  while(1){
104  long more;
105 
106  if(boundary>0 && vf->offset>=boundary)return(OV_FALSE);
107  more=ogg_sync_pageseek(&vf->oy,og);
108 
109  if(more<0){
110  /* skipped n bytes */
111  vf->offset-=more;
112  }else{
113  if(more==0){
114  /* send more paramedics */
115  if(!boundary)return(OV_FALSE);
116  {
117  long ret=_get_data(vf);
118  if(ret==0)return(OV_EOF);
119  if(ret<0)return(OV_EREAD);
120  }
121  }else{
122  /* got a page. Return the offset at the page beginning,
123  advance the internal offset past the page end */
124  ogg_int64_t ret=vf->offset;
125  vf->offset+=more;
126  return(ret);
127 
128  }
129  }
130  }
131 }
132 
133 /* find the latest page beginning before the current stream cursor
134  position. Much dirtier than the above as Ogg doesn't have any
135  backward search linkage. no 'readp' as it will certainly have to
136  read. */
137 /* returns offset or OV_EREAD, OV_FAULT */
138 static ogg_int64_t _get_prev_page(OggVorbis_File *vf,ogg_page *og){
139  ogg_int64_t begin=vf->offset;
140  ogg_int64_t end=begin;
141  ogg_int64_t ret;
142  ogg_int64_t offset=-1;
143 
144  while(offset==-1){
145  begin-=CHUNKSIZE;
146  if(begin<0)
147  begin=0;
148  _seek_helper(vf,begin);
149  while(vf->offset<end){
150  ret=_get_next_page(vf,og,end-vf->offset);
151  if(ret==OV_EREAD)return(OV_EREAD);
152  if(ret<0){
153  break;
154  }else{
155  offset=ret;
156  }
157  }
158  }
159 
160  /* we have the offset. Actually snork and hold the page now */
161  _seek_helper(vf,offset);
162  ret=_get_next_page(vf,og,CHUNKSIZE);
163  if(ret<0)
164  /* this shouldn't be possible */
165  return(OV_EFAULT);
166 
167  return(offset);
168 }
169 
170 /* finds each bitstream link one at a time using a bisection search
171  (has to begin by knowing the offset of the lb's initial page).
172  Recurses for each link so it can alloc the link storage after
173  finding them all, then unroll and fill the cache at the same time */
174 static int _bisect_forward_serialno(OggVorbis_File *vf,
175  ogg_int64_t begin,
176  ogg_int64_t searched,
177  ogg_int64_t end,
178  long currentno,
179  long m){
180  ogg_int64_t endsearched=end;
181  ogg_int64_t next=end;
182  ogg_page og;
183  ogg_int64_t ret;
184 
185  /* the below guards against garbage seperating the last and
186  first pages of two links. */
187  while(searched<endsearched){
188  ogg_int64_t bisect;
189 
190  if(endsearched-searched<CHUNKSIZE){
191  bisect=searched;
192  }else{
193  bisect=(searched+endsearched)/2;
194  }
195 
196  _seek_helper(vf,bisect);
197  ret=_get_next_page(vf,&og,-1);
198  if(ret==OV_EREAD)return(OV_EREAD);
199  if(ret<0 || ogg_page_serialno(&og)!=currentno){
200  endsearched=bisect;
201  if(ret>=0)next=ret;
202  }else{
203  searched=ret+og.header_len+og.body_len;
204  }
205  }
206 
207  _seek_helper(vf,next);
208  ret=_get_next_page(vf,&og,-1);
209  if(ret==OV_EREAD)return(OV_EREAD);
210 
211  if(searched>=end || ret<0){
212  vf->links=m+1;
213  vf->offsets=_ogg_malloc((vf->links+1)*sizeof(*vf->offsets));
214  vf->serialnos=_ogg_malloc(vf->links*sizeof(*vf->serialnos));
215  vf->offsets[m+1]=searched;
216  }else{
217  ret=_bisect_forward_serialno(vf,next,vf->offset,
218  end,ogg_page_serialno(&og),m+1);
219  if(ret==OV_EREAD)return(OV_EREAD);
220  }
221 
222  vf->offsets[m]=begin;
223  vf->serialnos[m]=currentno;
224  return(0);
225 }
226 
227 /* uses the local ogg_stream storage in vf; this is important for
228  non-streaming input sources */
229 static int _fetch_headers(OggVorbis_File *vf,vorbis_info *vi,vorbis_comment *vc,
230  long *serialno,ogg_page *og_ptr){
231  ogg_page og;
232  ogg_packet op;
233  int i,ret;
234 
235  if(!og_ptr){
236  ogg_int64_t llret=_get_next_page(vf,&og,CHUNKSIZE);
237  if(llret==OV_EREAD)return(OV_EREAD);
238  if(llret<0)return OV_ENOTVORBIS;
239  og_ptr=&og;
240  }
241 
243  if(serialno)*serialno=vf->os.serialno;
245 
246  /* extract the initial header from the first page and verify that the
247  Ogg bitstream is in fact Vorbis data */
248 
249  vorbis_info_init(vi);
251 
252  i=0;
253  while(i<3){
254  ogg_stream_pagein(&vf->os,og_ptr);
255  while(i<3){
256  int result=ogg_stream_packetout(&vf->os,&op);
257  if(result==0)break;
258  if(result==-1){
259  ret=OV_EBADHEADER;
260  goto bail_header;
261  }
262  if((ret=vorbis_synthesis_headerin(vi,vc,&op))){
263  goto bail_header;
264  }
265  i++;
266  }
267  if(i<3)
268  if(_get_next_page(vf,og_ptr,CHUNKSIZE)<0){
269  ret=OV_EBADHEADER;
270  goto bail_header;
271  }
272  }
273  return 0;
274 
275  bail_header:
276  vorbis_info_clear(vi);
278  vf->ready_state=OPENED;
279 
280  return ret;
281 }
282 
283 /* last step of the OggVorbis_File initialization; get all the
284  vorbis_info structs and PCM positions. Only called by the seekable
285  initialization (local stream storage is hacked slightly; pay
286  attention to how that's done) */
287 
288 /* this is void and does not propogate errors up because we want to be
289  able to open and use damaged bitstreams as well as we can. Just
290  watch out for missing information for links in the OggVorbis_File
291  struct */
292 static void _prefetch_all_headers(OggVorbis_File *vf, ogg_int64_t dataoffset){
293  ogg_page og;
294  int i;
295  ogg_int64_t ret;
296 
297  vf->vi=_ogg_realloc(vf->vi,vf->links*sizeof(*vf->vi));
298  vf->vc=_ogg_realloc(vf->vc,vf->links*sizeof(*vf->vc));
299  vf->dataoffsets=_ogg_malloc(vf->links*sizeof(*vf->dataoffsets));
300  vf->pcmlengths=_ogg_malloc(vf->links*2*sizeof(*vf->pcmlengths));
301 
302  for(i=0;i<vf->links;i++){
303  if(i==0){
304  /* we already grabbed the initial header earlier. Just set the offset */
305  vf->dataoffsets[i]=dataoffset;
306  _seek_helper(vf,dataoffset);
307 
308  }else{
309 
310  /* seek to the location of the initial header */
311 
312  _seek_helper(vf,vf->offsets[i]);
313  if(_fetch_headers(vf,vf->vi+i,vf->vc+i,NULL,NULL)<0){
314  vf->dataoffsets[i]=-1;
315  }else{
316  vf->dataoffsets[i]=vf->offset;
317  }
318  }
319 
320  /* fetch beginning PCM offset */
321 
322  if(vf->dataoffsets[i]!=-1){
323  ogg_int64_t accumulated=0;
324  long lastblock=-1;
325  int result;
326 
328 
329  while(1){
330  ogg_packet op;
331 
332  ret=_get_next_page(vf,&og,-1);
333  if(ret<0)
334  /* this should not be possible unless the file is
335  truncated/mangled */
336  break;
337 
338  if(ogg_page_serialno(&og)!=vf->serialnos[i])
339  break;
340 
341  /* count blocksizes of all frames in the page */
342  ogg_stream_pagein(&vf->os,&og);
343  while((result=ogg_stream_packetout(&vf->os,&op))){
344  if(result>0){ /* ignore holes */
345  long thisblock=vorbis_packet_blocksize(vf->vi+i,&op);
346  if(lastblock!=-1)
347  accumulated+=(lastblock+thisblock)>>2;
348  lastblock=thisblock;
349  }
350  }
351 
352  if(ogg_page_granulepos(&og)!=-1){
353  /* pcm offset of last packet on the first audio page */
354  accumulated= ogg_page_granulepos(&og)-accumulated;
355  break;
356  }
357  }
358 
359  /* less than zero? This is a stream with samples trimmed off
360  the beginning, a normal occurrence; set the offset to zero */
361  if(accumulated<0)accumulated=0;
362 
363  vf->pcmlengths[i*2]=accumulated;
364  }
365 
366  /* get the PCM length of this link. To do this,
367  get the last page of the stream */
368  {
369  ogg_int64_t end=vf->offsets[i+1];
370  _seek_helper(vf,end);
371 
372  while(1){
373  ret=_get_prev_page(vf,&og);
374  if(ret<0){
375  /* this should not be possible */
376  vorbis_info_clear(vf->vi+i);
377  vorbis_comment_clear(vf->vc+i);
378  break;
379  }
380  if(ogg_page_granulepos(&og)!=-1){
381  vf->pcmlengths[i*2+1]=ogg_page_granulepos(&og)-vf->pcmlengths[i*2];
382  break;
383  }
384  vf->offset=ret;
385  }
386  }
387  }
388 }
389 
390 static int _make_decode_ready(OggVorbis_File *vf){
391  if(vf->ready_state>STREAMSET)return 0;
392  if(vf->ready_state<STREAMSET)return OV_EFAULT;
393  if(vf->seekable){
394  if(vorbis_synthesis_init(&vf->vd,vf->vi+vf->current_link))
395  return OV_EBADLINK;
396  }else{
397  if(vorbis_synthesis_init(&vf->vd,vf->vi))
398  return OV_EBADLINK;
399  }
400  vorbis_block_init(&vf->vd,&vf->vb);
401  vf->ready_state=INITSET;
402  vf->bittrack=0.f;
403  vf->samptrack=0.f;
404  return 0;
405 }
406 
407 static int _open_seekable2(OggVorbis_File *vf){
408  long serialno=vf->current_serialno;
409  ogg_int64_t dataoffset=vf->offset, end;
410  ogg_page og;
411 
412  /* we're partially open and have a first link header state in
413  storage in vf */
414  /* we can seek, so set out learning all about this file */
415  (vf->callbacks.seek_func)(vf->datasource,0,SEEK_END);
416  vf->offset=vf->end=(vf->callbacks.tell_func)(vf->datasource);
417 
418  /* We get the offset for the last page of the physical bitstream.
419  Most OggVorbis files will contain a single logical bitstream */
420  end=_get_prev_page(vf,&og);
421  if(end<0)return(end);
422 
423  /* more than one logical bitstream? */
424  if(ogg_page_serialno(&og)!=serialno){
425 
426  /* Chained bitstream. Bisect-search each logical bitstream
427  section. Do so based on serial number only */
428  if(_bisect_forward_serialno(vf,0,0,end+1,serialno,0)<0)return(OV_EREAD);
429 
430  }else{
431 
432  /* Only one logical bitstream */
433  if(_bisect_forward_serialno(vf,0,end,end+1,serialno,0))return(OV_EREAD);
434 
435  }
436 
437  /* the initial header memory is referenced by vf after; don't free it */
438  _prefetch_all_headers(vf,dataoffset);
439  return(ov_raw_seek(vf,0));
440 }
441 
442 /* clear out the current logical bitstream decoder */
443 static void _decode_clear(OggVorbis_File *vf){
444  vorbis_dsp_clear(&vf->vd);
445  vorbis_block_clear(&vf->vb);
446  vf->ready_state=OPENED;
447 }
448 
449 /* fetch and process a packet. Handles the case where we're at a
450  bitstream boundary and dumps the decoding machine. If the decoding
451  machine is unloaded, it loads it. It also keeps pcm_offset up to
452  date (seek and read both use this. seek uses a special hack with
453  readp).
454 
455  return: <0) error, OV_HOLE (lost packet) or OV_EOF
456  0) need more data (only if readp==0)
457  1) got a packet
458 */
459 
460 static int _fetch_and_process_packet(OggVorbis_File *vf,
461  ogg_packet *op_in,
462  int readp,
463  int spanp){
464  ogg_page og;
465 
466  /* handle one packet. Try to fetch it from current stream state */
467  /* extract packets from page */
468  while(1){
469 
470  /* process a packet if we can. If the machine isn't loaded,
471  neither is a page */
472  if(vf->ready_state==INITSET){
473  while(1) {
474  ogg_packet op;
475  ogg_packet *op_ptr=(op_in?op_in:&op);
476  int result=ogg_stream_packetout(&vf->os,op_ptr);
477  ogg_int64_t granulepos;
478 
479  op_in=NULL;
480  if(result==-1)return(OV_HOLE); /* hole in the data. */
481  if(result>0){
482  /* got a packet. process it */
483  granulepos=op_ptr->granulepos;
484  if(!vorbis_synthesis(&vf->vb,op_ptr)){ /* lazy check for lazy
485  header handling. The
486  header packets aren't
487  audio, so if/when we
488  submit them,
489  vorbis_synthesis will
490  reject them */
491 
492  /* suck in the synthesis data and track bitrate */
493  {
494  int oldsamples=vorbis_synthesis_pcmout(&vf->vd,NULL);
495  /* for proper use of libvorbis within libvorbisfile,
496  oldsamples will always be zero. */
497  if(oldsamples)return(OV_EFAULT);
498 
499  vorbis_synthesis_blockin(&vf->vd,&vf->vb);
500  vf->samptrack+=vorbis_synthesis_pcmout(&vf->vd,NULL)-oldsamples;
501  vf->bittrack+=op_ptr->bytes*8;
502  }
503 
504  /* update the pcm offset. */
505  if(granulepos!=-1 && !op_ptr->e_o_s){
506  int link=(vf->seekable?vf->current_link:0);
507  int i,samples;
508 
509  /* this packet has a pcm_offset on it (the last packet
510  completed on a page carries the offset) After processing
511  (above), we know the pcm position of the *last* sample
512  ready to be returned. Find the offset of the *first*
513 
514  As an aside, this trick is inaccurate if we begin
515  reading anew right at the last page; the end-of-stream
516  granulepos declares the last frame in the stream, and the
517  last packet of the last page may be a partial frame.
518  So, we need a previous granulepos from an in-sequence page
519  to have a reference point. Thus the !op_ptr->e_o_s clause
520  above */
521 
522  if(vf->seekable && link>0)
523  granulepos-=vf->pcmlengths[link*2];
524  if(granulepos<0)granulepos=0; /* actually, this
525  shouldn't be possible
526  here unless the stream
527  is very broken */
528 
529  samples=vorbis_synthesis_pcmout(&vf->vd,NULL);
530 
531  granulepos-=samples;
532  for(i=0;i<link;i++)
533  granulepos+=vf->pcmlengths[i*2+1];
534  vf->pcm_offset=granulepos;
535  }
536  return(1);
537  }
538  }
539  else
540  break;
541  }
542  }
543 
544  if(vf->ready_state>=OPENED){
545  int ret;
546  if(!readp)return(0);
547  if((ret=_get_next_page(vf,&og,-1))<0){
548  return(OV_EOF); /* eof.
549  leave unitialized */
550  }
551 
552  /* bitrate tracking; add the header's bytes here, the body bytes
553  are done by packet above */
554  vf->bittrack+=og.header_len*8;
555 
556  /* has our decoding just traversed a bitstream boundary? */
557  if(vf->ready_state==INITSET){
558  if(vf->current_serialno!=ogg_page_serialno(&og)){
559  if(!spanp)
560  return(OV_EOF);
561 
562  _decode_clear(vf);
563 
564  if(!vf->seekable){
565  vorbis_info_clear(vf->vi);
567  }
568  }
569  }
570  }
571 
572  /* Do we need to load a new machine before submitting the page? */
573  /* This is different in the seekable and non-seekable cases.
574 
575  In the seekable case, we already have all the header
576  information loaded and cached; we just initialize the machine
577  with it and continue on our merry way.
578 
579  In the non-seekable (streaming) case, we'll only be at a
580  boundary if we just left the previous logical bitstream and
581  we're now nominally at the header of the next bitstream
582  */
583 
584  if(vf->ready_state!=INITSET){
585  int link;
586 
587  if(vf->ready_state<STREAMSET){
588  if(vf->seekable){
590 
591  /* match the serialno to bitstream section. We use this rather than
592  offset positions to avoid problems near logical bitstream
593  boundaries */
594  for(link=0;link<vf->links;link++)
595  if(vf->serialnos[link]==vf->current_serialno)break;
596  if(link==vf->links)return(OV_EBADLINK); /* sign of a bogus
597  stream. error out,
598  leave machine
599  uninitialized */
600 
601  vf->current_link=link;
602 
605 
606  }else{
607  /* we're streaming */
608  /* fetch the three header packets, build the info struct */
609 
610  int ret=_fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno,&og);
611  if(ret)return(ret);
612  vf->current_link++;
613  link=0;
614  }
615  }
616 
617  {
618  int ret=_make_decode_ready(vf);
619  if(ret<0)return ret;
620  }
621  }
622  ogg_stream_pagein(&vf->os,&og);
623  }
624 }
625 
626 /* if, eg, 64 bit stdio is configured by default, this will build with
627  fseek64 */
628 static int _fseek64_wrap(FILE *f,ogg_int64_t off,int whence){
629  if(f==NULL)return(-1);
630  return fseek(f,off,whence);
631 }
632 
633 static int _ov_open1(void *f,OggVorbis_File *vf,char *initial,
634  long ibytes, ov_callbacks callbacks){
635  int offsettest=(f?callbacks.seek_func(f,0,SEEK_CUR):-1);
636  int ret;
637 
638  memset(vf,0,sizeof(*vf));
639  vf->datasource=f;
640  vf->callbacks = callbacks;
641 
642  /* init the framing state */
643  ogg_sync_init(&vf->oy);
644 
645  /* perhaps some data was previously read into a buffer for testing
646  against other stream types. Allow initialization from this
647  previously read data (as we may be reading from a non-seekable
648  stream) */
649  if(initial){
650  char *buffer=ogg_sync_buffer(&vf->oy,ibytes);
651  memcpy(buffer,initial,ibytes);
652  ogg_sync_wrote(&vf->oy,ibytes);
653  }
654 
655  /* can we seek? Stevens suggests the seek test was portable */
656  if(offsettest!=-1)vf->seekable=1;
657 
658  /* No seeking yet; Set up a 'single' (current) logical bitstream
659  entry for partial open */
660  vf->links=1;
661  vf->vi=_ogg_calloc(vf->links,sizeof(*vf->vi));
662  vf->vc=_ogg_calloc(vf->links,sizeof(*vf->vc));
663  ogg_stream_init(&vf->os,-1); /* fill in the serialno later */
664 
665  /* Try to fetch the headers, maintaining all the storage */
666  if((ret=_fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno,NULL))<0){
667  vf->datasource=NULL;
668  ov_clear(vf);
669  }else
670  vf->ready_state=PARTOPEN;
671  return(ret);
672 }
673 
674 static int _ov_open2(OggVorbis_File *vf){
675  if(vf->ready_state != PARTOPEN) return OV_EINVAL;
676  vf->ready_state=OPENED;
677  if(vf->seekable){
678  int ret=_open_seekable2(vf);
679  if(ret){
680  vf->datasource=NULL;
681  ov_clear(vf);
682  }
683  return(ret);
684  }else
686 
687  return 0;
688 }
689 
690 
691 /* clear out the OggVorbis_File struct */
693  if(vf){
694  vorbis_block_clear(&vf->vb);
695  vorbis_dsp_clear(&vf->vd);
696  ogg_stream_clear(&vf->os);
697 
698  if(vf->vi && vf->links){
699  int i;
700  for(i=0;i<vf->links;i++){
701  vorbis_info_clear(vf->vi+i);
702  vorbis_comment_clear(vf->vc+i);
703  }
704  _ogg_free(vf->vi);
705  _ogg_free(vf->vc);
706  }
707  if(vf->dataoffsets)_ogg_free(vf->dataoffsets);
708  if(vf->pcmlengths)_ogg_free(vf->pcmlengths);
709  if(vf->serialnos)_ogg_free(vf->serialnos);
710  if(vf->offsets)_ogg_free(vf->offsets);
711  ogg_sync_clear(&vf->oy);
712  if(vf->datasource)(vf->callbacks.close_func)(vf->datasource);
713  memset(vf,0,sizeof(*vf));
714  }
715 #ifdef DEBUG_LEAKS
716  _VDBG_dump();
717 #endif
718  return(0);
719 }
720 
721 /* inspects the OggVorbis file and finds/documents all the logical
722  bitstreams contained in it. Tries to be tolerant of logical
723  bitstream sections that are truncated/woogie.
724 
725  return: -1) error
726  0) OK
727 */
728 
729 int ov_open_callbacks(void *f,OggVorbis_File *vf,char *initial,long ibytes,
730  ov_callbacks callbacks){
731  int ret=_ov_open1(f,vf,initial,ibytes,callbacks);
732  if(ret)return ret;
733  return _ov_open2(vf);
734 }
735 
736 int ov_open(FILE *f,OggVorbis_File *vf,char *initial,long ibytes){
737  ov_callbacks callbacks = {
738  (size_t (*)(void *, size_t, size_t, void *)) fread,
739  (int (*)(void *, ogg_int64_t, int)) _fseek64_wrap,
740  (int (*)(void *)) fclose,
741  (long (*)(void *)) ftell
742  };
743 
744  return ov_open_callbacks((void *)f, vf, initial, ibytes, callbacks);
745 }
746 
747 /* cheap hack for game usage where downsampling is desirable; there's
748  no need for SRC as we can just do it cheaply in libvorbis. */
749 
750 int ov_halfrate(OggVorbis_File *vf,int flag){
751  int i;
752  if(vf->vi==NULL)return OV_EINVAL;
753  if(!vf->seekable)return OV_EINVAL;
754  if(vf->ready_state>=STREAMSET)
755  _decode_clear(vf); /* clear out stream state; later on libvorbis
756  will be able to swap this on the fly, but
757  for now dumping the decode machine is needed
758  to reinit the MDCT lookups. 1.1 libvorbis
759  is planned to be able to switch on the fly */
760 
761  for(i=0;i<vf->links;i++){
762  if(vorbis_synthesis_halfrate(vf->vi+i,flag)){
763  ov_halfrate(vf,0);
764  return OV_EINVAL;
765  }
766  }
767  return 0;
768 }
769 
771  if(vf->vi==NULL)return OV_EINVAL;
772  return vorbis_synthesis_halfrate_p(vf->vi);
773 }
774 
775 /* Only partially open the vorbis file; test for Vorbisness, and load
776  the headers for the first chain. Do not seek (although test for
777  seekability). Use ov_test_open to finish opening the file, else
778  ov_clear to close/free it. Same return codes as open. */
779 
780 int ov_test_callbacks(void *f,OggVorbis_File *vf,char *initial,long ibytes,
781  ov_callbacks callbacks)
782 {
783  return _ov_open1(f,vf,initial,ibytes,callbacks);
784 }
785 
786 int ov_test(FILE *f,OggVorbis_File *vf,char *initial,long ibytes){
787  ov_callbacks callbacks = {
788  (size_t (*)(void *, size_t, size_t, void *)) fread,
789  (int (*)(void *, ogg_int64_t, int)) _fseek64_wrap,
790  (int (*)(void *)) fclose,
791  (long (*)(void *)) ftell
792  };
793 
794  return ov_test_callbacks((void *)f, vf, initial, ibytes, callbacks);
795 }
796 
798  if(vf->ready_state!=PARTOPEN)return(OV_EINVAL);
799  return _ov_open2(vf);
800 }
801 
802 /* How many logical bitstreams in this physical bitstream? */
804  return vf->links;
805 }
806 
807 /* Is the FILE * associated with vf seekable? */
809  return vf->seekable;
810 }
811 
812 /* returns the bitrate for a given logical bitstream or the entire
813  physical bitstream. If the file is open for random access, it will
814  find the *actual* average bitrate. If the file is streaming, it
815  returns the nominal bitrate (if set) else the average of the
816  upper/lower bounds (if set) else -1 (unset).
817 
818  If you want the actual bitrate field settings, get them from the
819  vorbis_info structs */
820 
821 long ov_bitrate(OggVorbis_File *vf,int i){
822  if(vf->ready_state<OPENED)return(OV_EINVAL);
823  if(i>=vf->links)return(OV_EINVAL);
824  if(!vf->seekable && i!=0)return(ov_bitrate(vf,0));
825  if(i<0){
826  ogg_int64_t bits=0;
827  int i;
828  float br;
829  for(i=0;i<vf->links;i++)
830  bits+=(vf->offsets[i+1]-vf->dataoffsets[i])*8;
831  /* This once read: return(rint(bits/ov_TIME_Total(vf,-1)));
832  * gcc 3.x on x86 miscompiled this at optimisation level 2 and above,
833  * so this is slightly transformed to make it work.
834  */
835  br = bits/ov_TIME_Total(vf,-1);
836  return(rint(br));
837  }else{
838  if(vf->seekable){
839  /* return the actual bitrate */
840  return(rint((vf->offsets[i+1]-vf->dataoffsets[i])*8/ov_TIME_Total(vf,i)));
841  }else{
842  /* return nominal if set */
843  if(vf->vi[i].bitrate_nominal>0){
844  return vf->vi[i].bitrate_nominal;
845  }else{
846  if(vf->vi[i].bitrate_upper>0){
847  if(vf->vi[i].bitrate_lower>0){
848  return (vf->vi[i].bitrate_upper+vf->vi[i].bitrate_lower)/2;
849  }else{
850  return vf->vi[i].bitrate_upper;
851  }
852  }
853  return(OV_FALSE);
854  }
855  }
856  }
857 }
858 
859 /* returns the actual bitrate since last call. returns -1 if no
860  additional data to offer since last call (or at beginning of stream),
861  EINVAL if stream is only partially open
862 */
864  int link=(vf->seekable?vf->current_link:0);
865  long ret;
866  if(vf->ready_state<OPENED)return(OV_EINVAL);
867  if(vf->samptrack==0)return(OV_FALSE);
868  ret=vf->bittrack/vf->samptrack*vf->vi[link].rate+.5;
869  vf->bittrack=0.f;
870  vf->samptrack=0.f;
871  return(ret);
872 }
873 
874 /* Guess */
876  if(i>=vf->links)return(ov_serialnumber(vf,vf->links-1));
877  if(!vf->seekable && i>=0)return(ov_serialnumber(vf,-1));
878  if(i<0){
879  return(vf->current_serialno);
880  }else{
881  return(vf->serialnos[i]);
882  }
883 }
884 
885 /* returns: total raw (compressed) length of content if i==-1
886  raw (compressed) length of that logical bitstream for i==0 to n
887  OV_EINVAL if the stream is not seekable (we can't know the length)
888  or if stream is only partially open
889 */
891  if(vf->ready_state<OPENED)return(OV_EINVAL);
892  if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
893  if(i<0){
894  ogg_int64_t acc=0;
895  int i;
896  for(i=0;i<vf->links;i++)
897  acc+=ov_raw_total(vf,i);
898  return(acc);
899  }else{
900  return(vf->offsets[i+1]-vf->offsets[i]);
901  }
902 }
903 
904 /* returns: total PCM length (samples) of content if i==-1 PCM length
905  (samples) of that logical bitstream for i==0 to n
906  OV_EINVAL if the stream is not seekable (we can't know the
907  length) or only partially open
908 */
910  if(vf->ready_state<OPENED)return(OV_EINVAL);
911  if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
912  if(i<0){
913  ogg_int64_t acc=0;
914  int i;
915  for(i=0;i<vf->links;i++)
916  acc+=ov_pcm_total(vf,i);
917  return(acc);
918  }else{
919  return(vf->pcmlengths[i*2+1]);
920  }
921 }
922 
923 /* returns: total seconds of content if i==-1
924  seconds in that logical bitstream for i==0 to n
925  OV_EINVAL if the stream is not seekable (we can't know the
926  length) or only partially open
927 */
928 double ov_TIME_Total(OggVorbis_File *vf,int i){
929  if(vf->ready_state<OPENED)return(OV_EINVAL);
930  if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
931  if(i<0){
932  double acc=0;
933  int i;
934  for(i=0;i<vf->links;i++)
935  acc+=ov_TIME_Total(vf,i);
936  return(acc);
937  }else{
938  return((double)(vf->pcmlengths[i*2+1])/vf->vi[i].rate);
939  }
940 }
941 
942 /* seek to an offset relative to the *compressed* data. This also
943  scans packets to update the PCM cursor. It will cross a logical
944  bitstream boundary, but only if it can't get any packets out of the
945  tail of the bitstream we seek to (so no surprises).
946 
947  returns zero on success, nonzero on failure */
948 
950  ogg_stream_state work_os;
951 
952  if(vf->ready_state<OPENED)return(OV_EINVAL);
953  if(!vf->seekable)
954  return(OV_ENOSEEK); /* don't dump machine if we can't seek */
955 
956  if(pos<0 || pos>vf->end)return(OV_EINVAL);
957 
958  /* don't yet clear out decoding machine (if it's initialized), in
959  the case we're in the same link. Restart the decode lapping, and
960  let _fetch_and_process_packet deal with a potential bitstream
961  boundary */
962  vf->pcm_offset=-1;
964  vf->current_serialno); /* must set serialno */
966 
967  _seek_helper(vf,pos);
968 
969  /* we need to make sure the pcm_offset is set, but we don't want to
970  advance the raw cursor past good packets just to get to the first
971  with a granulepos. That's not equivalent behavior to beginning
972  decoding as immediately after the seek position as possible.
973 
974  So, a hack. We use two stream states; a local scratch state and
975  the shared vf->os stream state. We use the local state to
976  scan, and the shared state as a buffer for later decode.
977 
978  Unfortuantely, on the last page we still advance to last packet
979  because the granulepos on the last page is not necessarily on a
980  packet boundary, and we need to make sure the granpos is
981  correct.
982  */
983 
984  {
985  ogg_page og;
986  ogg_packet op;
987  int lastblock=0;
988  int accblock=0;
989  int thisblock;
990  int eosflag;
991 
992  ogg_stream_init(&work_os,vf->current_serialno); /* get the memory ready */
993  ogg_stream_reset(&work_os); /* eliminate the spurious OV_HOLE
994  return from not necessarily
995  starting from the beginning */
996 
997  while(1){
998  if(vf->ready_state>=STREAMSET){
999  /* snarf/scan a packet if we can */
1000  int result=ogg_stream_packetout(&work_os,&op);
1001 
1002  if(result>0){
1003 
1004  if(vf->vi[vf->current_link].codec_setup){
1005  thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op);
1006  if(thisblock<0){
1008  thisblock=0;
1009  }else{
1010 
1011  if(eosflag)
1013  else
1014  if(lastblock)accblock+=(lastblock+thisblock)>>2;
1015  }
1016 
1017  if(op.granulepos!=-1){
1018  int i,link=vf->current_link;
1019  ogg_int64_t granulepos=op.granulepos-vf->pcmlengths[link*2];
1020  if(granulepos<0)granulepos=0;
1021 
1022  for(i=0;i<link;i++)
1023  granulepos+=vf->pcmlengths[i*2+1];
1024  vf->pcm_offset=granulepos-accblock;
1025  break;
1026  }
1027  lastblock=thisblock;
1028  continue;
1029  }else
1031  }
1032  }
1033 
1034  if(!lastblock){
1035  if(_get_next_page(vf,&og,-1)<0){
1036  vf->pcm_offset=ov_pcm_total(vf,-1);
1037  break;
1038  }
1039  }else{
1040  /* huh? Bogus stream with packets but no granulepos */
1041  vf->pcm_offset=-1;
1042  break;
1043  }
1044 
1045  /* has our decoding just traversed a bitstream boundary? */
1046  if(vf->ready_state>=STREAMSET)
1047  if(vf->current_serialno!=ogg_page_serialno(&og)){
1048  _decode_clear(vf); /* clear out stream state */
1049  ogg_stream_clear(&work_os);
1050  }
1051 
1052  if(vf->ready_state<STREAMSET){
1053  int link;
1054 
1056  for(link=0;link<vf->links;link++)
1057  if(vf->serialnos[link]==vf->current_serialno)break;
1058  if(link==vf->links)goto seek_error; /* sign of a bogus stream.
1059  error out, leave
1060  machine uninitialized */
1061  vf->current_link=link;
1062 
1065  vf->ready_state=STREAMSET;
1066 
1067  }
1068 
1069  ogg_stream_pagein(&vf->os,&og);
1070  ogg_stream_pagein(&work_os,&og);
1071  eosflag=ogg_page_eos(&og);
1072  }
1073  }
1074 
1075  ogg_stream_clear(&work_os);
1076  vf->bittrack=0.f;
1077  vf->samptrack=0.f;
1078  return(0);
1079 
1080  seek_error:
1081  /* dump the machine so we're in a known state */
1082  vf->pcm_offset=-1;
1083  ogg_stream_clear(&work_os);
1084  _decode_clear(vf);
1085  return OV_EBADLINK;
1086 }
1087 
1088 /* Page granularity seek (faster than sample granularity because we
1089  don't do the last bit of decode to find a specific sample).
1090 
1091  Seek to the last [granule marked] page preceeding the specified pos
1092  location, such that decoding past the returned point will quickly
1093  arrive at the requested position. */
1095  int link=-1;
1096  ogg_int64_t result=0;
1097  ogg_int64_t total=ov_pcm_total(vf,-1);
1098 
1099  if(vf->ready_state<OPENED)return(OV_EINVAL);
1100  if(!vf->seekable)return(OV_ENOSEEK);
1101 
1102  if(pos<0 || pos>total)return(OV_EINVAL);
1103 
1104  /* which bitstream section does this pcm offset occur in? */
1105  for(link=vf->links-1;link>=0;link--){
1106  total-=vf->pcmlengths[link*2+1];
1107  if(pos>=total)break;
1108  }
1109 
1110  /* search within the logical bitstream for the page with the highest
1111  pcm_pos preceeding (or equal to) pos. There is a danger here;
1112  missing pages or incorrect frame number information in the
1113  bitstream could make our task impossible. Account for that (it
1114  would be an error condition) */
1115 
1116  /* new search algorithm by HB (Nicholas Vinen) */
1117  {
1118  ogg_int64_t end=vf->offsets[link+1];
1119  ogg_int64_t begin=vf->offsets[link];
1120  ogg_int64_t begintime = vf->pcmlengths[link*2];
1121  ogg_int64_t endtime = vf->pcmlengths[link*2+1]+begintime;
1122  ogg_int64_t target=pos-total+begintime;
1123  ogg_int64_t best=begin;
1124 
1125  ogg_page og;
1126  while(begin<end){
1127  ogg_int64_t bisect;
1128 
1129  if(end-begin<CHUNKSIZE){
1130  bisect=begin;
1131  }else{
1132  /* take a (pretty decent) guess. */
1133  bisect=begin +
1134  (target-begintime)*(end-begin)/(endtime-begintime) - CHUNKSIZE;
1135  if(bisect<=begin)
1136  bisect=begin+1;
1137  }
1138 
1139  _seek_helper(vf,bisect);
1140 
1141  while(begin<end){
1142  result=_get_next_page(vf,&og,end-vf->offset);
1143  if(result==OV_EREAD) goto seek_error;
1144  if(result<0){
1145  if(bisect<=begin+1)
1146  end=begin; /* found it */
1147  else{
1148  if(bisect==0) goto seek_error;
1149  bisect-=CHUNKSIZE;
1150  if(bisect<=begin)bisect=begin+1;
1151  _seek_helper(vf,bisect);
1152  }
1153  }else{
1154  ogg_int64_t granulepos=ogg_page_granulepos(&og);
1155  if(granulepos==-1)continue;
1156  if(granulepos<target){
1157  best=result; /* raw offset of packet with granulepos */
1158  begin=vf->offset; /* raw offset of next page */
1159  begintime=granulepos;
1160 
1161  if(target-begintime>44100)break;
1162  bisect=begin; /* *not* begin + 1 */
1163  }else{
1164  if(bisect<=begin+1)
1165  end=begin; /* found it */
1166  else{
1167  if(end==vf->offset){ /* we're pretty close - we'd be stuck in */
1168  end=result;
1169  bisect-=CHUNKSIZE; /* an endless loop otherwise. */
1170  if(bisect<=begin)bisect=begin+1;
1171  _seek_helper(vf,bisect);
1172  }else{
1173  end=result;
1174  endtime=granulepos;
1175  break;
1176  }
1177  }
1178  }
1179  }
1180  }
1181  }
1182 
1183  /* found our page. seek to it, update pcm offset. Easier case than
1184  raw_seek, don't keep packets preceeding granulepos. */
1185  {
1186  ogg_page og;
1187  ogg_packet op;
1188 
1189  /* seek */
1190  _seek_helper(vf,best);
1191  vf->pcm_offset=-1;
1192 
1193  if(_get_next_page(vf,&og,-1)<0)return(OV_EOF); /* shouldn't happen */
1194 
1195  if(link!=vf->current_link){
1196  /* Different link; dump entire decode machine */
1197  _decode_clear(vf);
1198 
1199  vf->current_link=link;
1201  vf->ready_state=STREAMSET;
1202 
1203  }else{
1205  }
1206 
1208  ogg_stream_pagein(&vf->os,&og);
1209 
1210  /* pull out all but last packet; the one with granulepos */
1211  while(1){
1212  result=ogg_stream_packetpeek(&vf->os,&op);
1213  if(result==0){
1214  /* !!! the packet finishing this page originated on a
1215  preceeding page. Keep fetching previous pages until we
1216  get one with a granulepos or without the 'continued' flag
1217  set. Then just use raw_seek for simplicity. */
1218 
1219  _seek_helper(vf,best);
1220 
1221  while(1){
1222  result=_get_prev_page(vf,&og);
1223  if(result<0) goto seek_error;
1224  if(ogg_page_granulepos(&og)>-1 ||
1225  !ogg_page_continued(&og)){
1226  return ov_raw_seek(vf,result);
1227  }
1228  vf->offset=result;
1229  }
1230  }
1231  if(result<0){
1232  result = OV_EBADPACKET;
1233  goto seek_error;
1234  }
1235  if(op.granulepos!=-1){
1236  vf->pcm_offset=op.granulepos-vf->pcmlengths[vf->current_link*2];
1237  if(vf->pcm_offset<0)vf->pcm_offset=0;
1238  vf->pcm_offset+=total;
1239  break;
1240  }else
1241  result=ogg_stream_packetout(&vf->os,NULL);
1242  }
1243  }
1244  }
1245 
1246  /* verify result */
1247  if(vf->pcm_offset>pos || pos>ov_pcm_total(vf,-1)){
1248  result=OV_EFAULT;
1249  goto seek_error;
1250  }
1251  vf->bittrack=0.f;
1252  vf->samptrack=0.f;
1253  return(0);
1254 
1255  seek_error:
1256  /* dump machine so we're in a known state */
1257  vf->pcm_offset=-1;
1258  _decode_clear(vf);
1259  return (int)result;
1260 }
1261 
1262 /* seek to a sample offset relative to the decompressed pcm stream
1263  returns zero on success, nonzero on failure */
1264 
1266  int thisblock,lastblock=0;
1267  int ret=ov_pcm_seek_page(vf,pos);
1268  if(ret<0)return(ret);
1269  if((ret=_make_decode_ready(vf)))return ret;
1270 
1271  /* discard leading packets we don't need for the lapping of the
1272  position we want; don't decode them */
1273 
1274  while(1){
1275  ogg_packet op;
1276  ogg_page og;
1277 
1278  int ret=ogg_stream_packetpeek(&vf->os,&op);
1279  if(ret>0){
1280  thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op);
1281  if(thisblock<0){
1283  continue; /* non audio packet */
1284  }
1285  if(lastblock)vf->pcm_offset+=(lastblock+thisblock)>>2;
1286 
1287  if(vf->pcm_offset+((thisblock+
1288  vorbis_info_blocksize(vf->vi,1))>>2)>=pos)break;
1289 
1290  /* remove the packet from packet queue and track its granulepos */
1292  vorbis_synthesis_trackonly(&vf->vb,&op); /* set up a vb with
1293  only tracking, no
1294  pcm_decode */
1295  vorbis_synthesis_blockin(&vf->vd,&vf->vb);
1296 
1297  /* end of logical stream case is hard, especially with exact
1298  length positioning. */
1299 
1300  if(op.granulepos>-1){
1301  int i;
1302  /* always believe the stream markers */
1303  vf->pcm_offset=op.granulepos-vf->pcmlengths[vf->current_link*2];
1304  if(vf->pcm_offset<0)vf->pcm_offset=0;
1305  for(i=0;i<vf->current_link;i++)
1306  vf->pcm_offset+=vf->pcmlengths[i*2+1];
1307  }
1308 
1309  lastblock=thisblock;
1310 
1311  }else{
1312  if(ret<0 && ret!=OV_HOLE)break;
1313 
1314  /* suck in a new page */
1315  if(_get_next_page(vf,&og,-1)<0)break;
1316  if(vf->current_serialno!=ogg_page_serialno(&og))_decode_clear(vf);
1317 
1318  if(vf->ready_state<STREAMSET){
1319  int link;
1320 
1322  for(link=0;link<vf->links;link++)
1323  if(vf->serialnos[link]==vf->current_serialno)break;
1324  if(link==vf->links)return(OV_EBADLINK);
1325  vf->current_link=link;
1326 
1328  vf->ready_state=STREAMSET;
1329  ret=_make_decode_ready(vf);
1330  if(ret)return ret;
1331  lastblock=0;
1332  }
1333 
1334  ogg_stream_pagein(&vf->os,&og);
1335  }
1336  }
1337 
1338  vf->bittrack=0.f;
1339  vf->samptrack=0.f;
1340  /* discard samples until we reach the desired position. Crossing a
1341  logical bitstream boundary with abandon is OK. */
1342  while(vf->pcm_offset<pos){
1343  ogg_int64_t target=pos-vf->pcm_offset;
1344  long samples=vorbis_synthesis_pcmout(&vf->vd,NULL);
1345 
1346  if(samples>target)samples=target;
1347  vorbis_synthesis_read(&vf->vd,samples);
1348  vf->pcm_offset+=samples;
1349 
1350  if(samples<target)
1351  if(_fetch_and_process_packet(vf,NULL,1,1)<=0)
1352  vf->pcm_offset=ov_pcm_total(vf,-1); /* eof */
1353  }
1354  return 0;
1355 }
1356 
1357 /* seek to a playback time relative to the decompressed pcm stream
1358  returns zero on success, nonzero on failure */
1359 int ov_time_seek(OggVorbis_File *vf,double seconds){
1360  /* translate time to PCM position and call ov_pcm_seek */
1361 
1362  int link=-1;
1363  ogg_int64_t pcm_total=ov_pcm_total(vf,-1);
1364  double TIME_Total=ov_TIME_Total(vf,-1);
1365 
1366  if(vf->ready_state<OPENED)return(OV_EINVAL);
1367  if(!vf->seekable)return(OV_ENOSEEK);
1368  if(seconds<0 || seconds>TIME_Total)return(OV_EINVAL);
1369 
1370  /* which bitstream section does this time offset occur in? */
1371  for(link=vf->links-1;link>=0;link--){
1372  pcm_total-=vf->pcmlengths[link*2+1];
1373  TIME_Total-=ov_TIME_Total(vf,link);
1374  if(seconds>=TIME_Total)break;
1375  }
1376 
1377  /* enough information to convert time offset to pcm offset */
1378  {
1379  ogg_int64_t target=pcm_total+(seconds-TIME_Total)*vf->vi[link].rate;
1380  return(ov_pcm_seek(vf,target));
1381  }
1382 }
1383 
1384 /* page-granularity version of ov_time_seek
1385  returns zero on success, nonzero on failure */
1386 int ov_time_seek_page(OggVorbis_File *vf,double seconds){
1387  /* translate time to PCM position and call ov_pcm_seek */
1388 
1389  int link=-1;
1390  ogg_int64_t pcm_total=ov_pcm_total(vf,-1);
1391  double TIME_Total=ov_TIME_Total(vf,-1);
1392 
1393  if(vf->ready_state<OPENED)return(OV_EINVAL);
1394  if(!vf->seekable)return(OV_ENOSEEK);
1395  if(seconds<0 || seconds>TIME_Total)return(OV_EINVAL);
1396 
1397  /* which bitstream section does this time offset occur in? */
1398  for(link=vf->links-1;link>=0;link--){
1399  pcm_total-=vf->pcmlengths[link*2+1];
1400  TIME_Total-=ov_TIME_Total(vf,link);
1401  if(seconds>=TIME_Total)break;
1402  }
1403 
1404  /* enough information to convert time offset to pcm offset */
1405  {
1406  ogg_int64_t target=pcm_total+(seconds-TIME_Total)*vf->vi[link].rate;
1407  return(ov_pcm_seek_page(vf,target));
1408  }
1409 }
1410 
1411 /* tell the current stream offset cursor. Note that seek followed by
1412  tell will likely not give the set offset due to caching */
1414  if(vf->ready_state<OPENED)return(OV_EINVAL);
1415  return(vf->offset);
1416 }
1417 
1418 /* return PCM offset (sample) of next PCM sample to be read */
1420  if(vf->ready_state<OPENED)return(OV_EINVAL);
1421  return(vf->pcm_offset);
1422 }
1423 
1424 /* return time offset (seconds) of next PCM sample to be read */
1426  int link=0;
1427  ogg_int64_t pcm_total=0;
1428  double TIME_Total=0.f;
1429 
1430  if(vf->ready_state<OPENED)return(OV_EINVAL);
1431  if(vf->seekable){
1432  pcm_total=ov_pcm_total(vf,-1);
1433  TIME_Total=ov_TIME_Total(vf,-1);
1434 
1435  /* which bitstream section does this time offset occur in? */
1436  for(link=vf->links-1;link>=0;link--){
1437  pcm_total-=vf->pcmlengths[link*2+1];
1438  TIME_Total-=ov_TIME_Total(vf,link);
1439  if(vf->pcm_offset>=pcm_total)break;
1440  }
1441  }
1442 
1443  return((double)TIME_Total+(double)(vf->pcm_offset-pcm_total)/vf->vi[link].rate);
1444 }
1445 
1446 /* link: -1) return the vorbis_info struct for the bitstream section
1447  currently being decoded
1448  0-n) to request information for a specific bitstream section
1449 
1450  In the case of a non-seekable bitstream, any call returns the
1451  current bitstream. NULL in the case that the machine is not
1452  initialized */
1453 
1455  if(vf->seekable){
1456  if(link<0)
1457  if(vf->ready_state>=STREAMSET)
1458  return vf->vi+vf->current_link;
1459  else
1460  return vf->vi;
1461  else
1462  if(link>=vf->links)
1463  return NULL;
1464  else
1465  return vf->vi+link;
1466  }else{
1467  return vf->vi;
1468  }
1469 }
1470 
1471 /* grr, strong typing, grr, no templates/inheritence, grr */
1473  if(vf->seekable){
1474  if(link<0)
1475  if(vf->ready_state>=STREAMSET)
1476  return vf->vc+vf->current_link;
1477  else
1478  return vf->vc;
1479  else
1480  if(link>=vf->links)
1481  return NULL;
1482  else
1483  return vf->vc+link;
1484  }else{
1485  return vf->vc;
1486  }
1487 }
1488 
1489 static int host_is_big_endian() {
1490  ogg_int32_t pattern = 0xfeedface; /* deadbeef */
1491  unsigned char *bytewise = (unsigned char *)&pattern;
1492  if (bytewise[0] == 0xfe) return 1;
1493  return 0;
1494 }
1495 
1496 /* up to this point, everything could more or less hide the multiple
1497  logical bitstream nature of chaining from the toplevel application
1498  if the toplevel application didn't particularly care. However, at
1499  the point that we actually read audio back, the multiple-section
1500  nature must surface: Multiple bitstream sections do not necessarily
1501  have to have the same number of channels or sampling rate.
1502 
1503  ov_read returns the sequential logical bitstream number currently
1504  being decoded along with the PCM data in order that the toplevel
1505  application can take action on channel/sample rate changes. This
1506  number will be incremented even for streamed (non-seekable) streams
1507  (for seekable streams, it represents the actual logical bitstream
1508  index within the physical bitstream. Note that the accessor
1509  functions above are aware of this dichotomy).
1510 
1511  input values: buffer) a buffer to hold packed PCM data for return
1512  length) the byte length requested to be placed into buffer
1513  bigendianp) should the data be packed LSB first (0) or
1514  MSB first (1)
1515  word) word size for output. currently 1 (byte) or
1516  2 (16 bit short)
1517 
1518  return values: <0) error/hole in data (OV_HOLE), partial open (OV_EINVAL)
1519  0) EOF
1520  n) number of bytes of PCM actually returned. The
1521  below works on a packet-by-packet basis, so the
1522  return length is not related to the 'length' passed
1523  in, just guaranteed to fit.
1524 
1525  *section) set to the logical bitstream number */
1526 
1528  int bigendianp,int word,int sgned,int *bitstream){
1529  int i,j;
1530  int host_endian = host_is_big_endian();
1531 
1532  float **pcm;
1533  long samples;
1534 
1535  if(vf->ready_state<OPENED)return(OV_EINVAL);
1536 
1537  while(1){
1538  if(vf->ready_state==INITSET){
1539  samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
1540  if(samples)break;
1541  }
1542 
1543  /* suck in another packet */
1544  {
1545  int ret=_fetch_and_process_packet(vf,NULL,1,1);
1546  if(ret==OV_EOF)
1547  return(0);
1548  if(ret<=0)
1549  return(ret);
1550  }
1551 
1552  }
1553 
1554  if(samples>0){
1555 
1556  /* yay! proceed to pack data into the byte buffer */
1557 
1558  long channels=ov_info(vf,-1)->channels;
1559  long bytespersample=word * channels;
1560  vorbis_fpu_control fpu;
1561  if(samples>length/bytespersample)samples=length/bytespersample;
1562 
1563  if(samples <= 0)
1564  return OV_EINVAL;
1565 
1566  /* a tight loop to pack each size */
1567  {
1568  int val;
1569  if(word==1){
1570  int off=(sgned?0:128);
1571  vorbis_fpu_setround(&fpu);
1572  for(j=0;j<samples;j++)
1573  for(i=0;i<channels;i++){
1574  val=vorbis_ftoi(pcm[i][j]*128.f);
1575  if(val>127)val=127;
1576  else if(val<-128)val=-128;
1577  *buffer++=val+off;
1578  }
1579  vorbis_fpu_restore(fpu);
1580  }else{
1581  int off=(sgned?0:32768);
1582 
1583  if(host_endian==bigendianp){
1584  if(sgned){
1585 
1586  vorbis_fpu_setround(&fpu);
1587  for(i=0;i<channels;i++) { /* It's faster in this order */
1588  float *src=pcm[i];
1589  short *dest=((short *)buffer)+i;
1590  for(j=0;j<samples;j++) {
1591  val=vorbis_ftoi(src[j]*32768.f);
1592  if(val>32767)val=32767;
1593  else if(val<-32768)val=-32768;
1594  *dest=val;
1595  dest+=channels;
1596  }
1597  }
1598  vorbis_fpu_restore(fpu);
1599 
1600  }else{
1601 
1602  vorbis_fpu_setround(&fpu);
1603  for(i=0;i<channels;i++) {
1604  float *src=pcm[i];
1605  short *dest=((short *)buffer)+i;
1606  for(j=0;j<samples;j++) {
1607  val=vorbis_ftoi(src[j]*32768.f);
1608  if(val>32767)val=32767;
1609  else if(val<-32768)val=-32768;
1610  *dest=val+off;
1611  dest+=channels;
1612  }
1613  }
1614  vorbis_fpu_restore(fpu);
1615 
1616  }
1617  }else if(bigendianp){
1618 
1619  vorbis_fpu_setround(&fpu);
1620  for(j=0;j<samples;j++)
1621  for(i=0;i<channels;i++){
1622  val=vorbis_ftoi(pcm[i][j]*32768.f);
1623  if(val>32767)val=32767;
1624  else if(val<-32768)val=-32768;
1625  val+=off;
1626  *buffer++=(val>>8);
1627  *buffer++=(val&0xff);
1628  }
1629  vorbis_fpu_restore(fpu);
1630 
1631  }else{
1632  int val;
1633  vorbis_fpu_setround(&fpu);
1634  for(j=0;j<samples;j++)
1635  for(i=0;i<channels;i++){
1636  val=vorbis_ftoi(pcm[i][j]*32768.f);
1637  if(val>32767)val=32767;
1638  else if(val<-32768)val=-32768;
1639  val+=off;
1640  *buffer++=(val&0xff);
1641  *buffer++=(val>>8);
1642  }
1643  vorbis_fpu_restore(fpu);
1644 
1645  }
1646  }
1647  }
1648 
1649  vorbis_synthesis_read(&vf->vd,samples);
1650  vf->pcm_offset+=samples;
1651  if(bitstream)*bitstream=vf->current_link;
1652  return(samples*bytespersample);
1653  }else{
1654  return(samples);
1655  }
1656 }
1657 
1658 /* input values: pcm_channels) a float vector per channel of output
1659  length) the sample length being read by the app
1660 
1661  return values: <0) error/hole in data (OV_HOLE), partial open (OV_EINVAL)
1662  0) EOF
1663  n) number of samples of PCM actually returned. The
1664  below works on a packet-by-packet basis, so the
1665  return length is not related to the 'length' passed
1666  in, just guaranteed to fit.
1667 
1668  *section) set to the logical bitstream number */
1669 
1670 
1671 
1672 long ov_read_float(OggVorbis_File *vf,float ***pcm_channels,int length,
1673  int *bitstream){
1674 
1675  if(vf->ready_state<OPENED)return(OV_EINVAL);
1676 
1677  while(1){
1678  if(vf->ready_state==INITSET){
1679  float **pcm;
1680  long samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
1681  if(samples){
1682  if(pcm_channels)*pcm_channels=pcm;
1683  if(samples>length)samples=length;
1684  vorbis_synthesis_read(&vf->vd,samples);
1685  vf->pcm_offset+=samples;
1686  if(bitstream)*bitstream=vf->current_link;
1687  return samples;
1688 
1689  }
1690  }
1691 
1692  /* suck in another packet */
1693  {
1694  int ret=_fetch_and_process_packet(vf,NULL,1,1);
1695  if(ret==OV_EOF)return(0);
1696  if(ret<=0)return(ret);
1697  }
1698 
1699  }
1700 }
1701 
1702 extern float *vorbis_window(vorbis_dsp_state *v,int W);
1703 extern void _analysis_output_always(char *base,int i,float *v,int n,int bark,int dB,
1704  ogg_int64_t off);
1705 
1706 static void _ov_splice(float **pcm,float **lappcm,
1707  int n1, int n2,
1708  int ch1, int ch2,
1709  float *w1, float *w2){
1710  int i,j;
1711  float *w=w1;
1712  int n=n1;
1713 
1714  if(n1>n2){
1715  n=n2;
1716  w=w2;
1717  }
1718 
1719  /* splice */
1720  for(j=0;j<ch1 && j<ch2;j++){
1721  float *s=lappcm[j];
1722  float *d=pcm[j];
1723 
1724  for(i=0;i<n;i++){
1725  float wd=w[i]*w[i];
1726  float ws=1.-wd;
1727  d[i]=d[i]*wd + s[i]*ws;
1728  }
1729  }
1730  /* window from zero */
1731  for(;j<ch2;j++){
1732  float *d=pcm[j];
1733  for(i=0;i<n;i++){
1734  float wd=w[i]*w[i];
1735  d[i]=d[i]*wd;
1736  }
1737  }
1738 
1739 }
1740 
1741 /* make sure vf is INITSET */
1742 static int _ov_initset(OggVorbis_File *vf){
1743  while(1){
1744  if(vf->ready_state==INITSET)break;
1745  /* suck in another packet */
1746  {
1747  int ret=_fetch_and_process_packet(vf,NULL,1,0);
1748  if(ret<0 && ret!=OV_HOLE)return(ret);
1749  }
1750  }
1751  return 0;
1752 }
1753 
1754 /* make sure vf is INITSET and that we have a primed buffer; if
1755  we're crosslapping at a stream section boundary, this also makes
1756  sure we're sanity checking against the right stream information */
1757 static int _ov_initprime(OggVorbis_File *vf){
1758  vorbis_dsp_state *vd=&vf->vd;
1759  while(1){
1760  if(vf->ready_state==INITSET)
1761  if(vorbis_synthesis_pcmout(vd,NULL))break;
1762 
1763  /* suck in another packet */
1764  {
1765  int ret=_fetch_and_process_packet(vf,NULL,1,0);
1766  if(ret<0 && ret!=OV_HOLE)return(ret);
1767  }
1768  }
1769  return 0;
1770 }
1771 
1772 /* grab enough data for lapping from vf; this may be in the form of
1773  unreturned, already-decoded pcm, remaining PCM we will need to
1774  decode, or synthetic postextrapolation from last packets. */
1775 static void _ov_getlap(OggVorbis_File *vf,vorbis_info *vi,vorbis_dsp_state *vd,
1776  float **lappcm,int lapsize){
1777  int lapcount=0,i;
1778  float **pcm;
1779 
1780  /* try first to decode the lapping data */
1781  while(lapcount<lapsize){
1782  int samples=vorbis_synthesis_pcmout(vd,&pcm);
1783  if(samples){
1784  if(samples>lapsize-lapcount)samples=lapsize-lapcount;
1785  for(i=0;i<vi->channels;i++)
1786  memcpy(lappcm[i]+lapcount,pcm[i],sizeof(**pcm)*samples);
1787  lapcount+=samples;
1788  vorbis_synthesis_read(vd,samples);
1789  }else{
1790  /* suck in another packet */
1791  int ret=_fetch_and_process_packet(vf,NULL,1,0); /* do *not* span */
1792  if(ret==OV_EOF)break;
1793  }
1794  }
1795  if(lapcount<lapsize){
1796  /* failed to get lapping data from normal decode; pry it from the
1797  postextrapolation buffering, or the second half of the MDCT
1798  from the last packet */
1799  int samples=vorbis_synthesis_lapout(&vf->vd,&pcm);
1800  if(samples==0){
1801  for(i=0;i<vi->channels;i++)
1802  memset(lappcm[i]+lapcount,0,sizeof(**pcm)*lapsize-lapcount);
1803  lapcount=lapsize;
1804  }else{
1805  if(samples>lapsize-lapcount)samples=lapsize-lapcount;
1806  for(i=0;i<vi->channels;i++)
1807  memcpy(lappcm[i]+lapcount,pcm[i],sizeof(**pcm)*samples);
1808  lapcount+=samples;
1809  }
1810  }
1811 }
1812 
1813 /* this sets up crosslapping of a sample by using trailing data from
1814  sample 1 and lapping it into the windowing buffer of sample 2 */
1816  vorbis_info *vi1,*vi2;
1817  float **lappcm;
1818  float **pcm;
1819  float *w1,*w2;
1820  int n1,n2,i,ret,hs1,hs2;
1821 
1822  if(vf1==vf2)return(0); /* degenerate case */
1823  if(vf1->ready_state<OPENED)return(OV_EINVAL);
1824  if(vf2->ready_state<OPENED)return(OV_EINVAL);
1825 
1826  /* the relevant overlap buffers must be pre-checked and pre-primed
1827  before looking at settings in the event that priming would cross
1828  a bitstream boundary. So, do it now */
1829 
1830  ret=_ov_initset(vf1);
1831  if(ret)return(ret);
1832  ret=_ov_initprime(vf2);
1833  if(ret)return(ret);
1834 
1835  vi1=ov_info(vf1,-1);
1836  vi2=ov_info(vf2,-1);
1837  hs1=ov_halfrate_p(vf1);
1838  hs2=ov_halfrate_p(vf2);
1839 
1840  lappcm=alloca(sizeof(*lappcm)*vi1->channels);
1841  n1=vorbis_info_blocksize(vi1,0)>>(1+hs1);
1842  n2=vorbis_info_blocksize(vi2,0)>>(1+hs2);
1843  w1=vorbis_window(&vf1->vd,0);
1844  w2=vorbis_window(&vf2->vd,0);
1845 
1846  for(i=0;i<vi1->channels;i++)
1847  lappcm[i]=alloca(sizeof(**lappcm)*n1);
1848 
1849  _ov_getlap(vf1,vi1,&vf1->vd,lappcm,n1);
1850 
1851  /* have a lapping buffer from vf1; now to splice it into the lapping
1852  buffer of vf2 */
1853  /* consolidate and expose the buffer. */
1854  vorbis_synthesis_lapout(&vf2->vd,&pcm);
1855  _analysis_output_always("pcmL",0,pcm[0],n1*2,0,0,0);
1856  _analysis_output_always("pcmR",0,pcm[1],n1*2,0,0,0);
1857 
1858  /* splice */
1859  _ov_splice(pcm,lappcm,n1,n2,vi1->channels,vi2->channels,w1,w2);
1860 
1861  /* done */
1862  return(0);
1863 }
1864 
1865 static int _ov_64_seek_lap(OggVorbis_File *vf,ogg_int64_t pos,
1866  int (*localseek)(OggVorbis_File *,ogg_int64_t)){
1867  vorbis_info *vi;
1868  float **lappcm;
1869  float **pcm;
1870  float *w1,*w2;
1871  int n1,n2,ch1,ch2,hs;
1872  int i,ret;
1873 
1874  if(vf->ready_state<OPENED)return(OV_EINVAL);
1875  ret=_ov_initset(vf);
1876  if(ret)return(ret);
1877  vi=ov_info(vf,-1);
1878  hs=ov_halfrate_p(vf);
1879 
1880  ch1=vi->channels;
1881  n1=vorbis_info_blocksize(vi,0)>>(1+hs);
1882  w1=vorbis_window(&vf->vd,0); /* window arrays from libvorbis are
1883  persistent; even if the decode state
1884  from this link gets dumped, this
1885  window array continues to exist */
1886 
1887  lappcm=alloca(sizeof(*lappcm)*ch1);
1888  for(i=0;i<ch1;i++)
1889  lappcm[i]=alloca(sizeof(**lappcm)*n1);
1890  _ov_getlap(vf,vi,&vf->vd,lappcm,n1);
1891 
1892  /* have lapping data; seek and prime the buffer */
1893  ret=localseek(vf,pos);
1894  if(ret)return ret;
1895  ret=_ov_initprime(vf);
1896  if(ret)return(ret);
1897 
1898  /* Guard against cross-link changes; they're perfectly legal */
1899  vi=ov_info(vf,-1);
1900  ch2=vi->channels;
1901  n2=vorbis_info_blocksize(vi,0)>>(1+hs);
1902  w2=vorbis_window(&vf->vd,0);
1903 
1904  /* consolidate and expose the buffer. */
1905  vorbis_synthesis_lapout(&vf->vd,&pcm);
1906 
1907  /* splice */
1908  _ov_splice(pcm,lappcm,n1,n2,ch1,ch2,w1,w2);
1909 
1910  /* done */
1911  return(0);
1912 }
1913 
1915  return _ov_64_seek_lap(vf,pos,ov_raw_seek);
1916 }
1917 
1919  return _ov_64_seek_lap(vf,pos,ov_pcm_seek);
1920 }
1921 
1923  return _ov_64_seek_lap(vf,pos,ov_pcm_seek_page);
1924 }
1925 
1926 static int _ov_d_seek_lap(OggVorbis_File *vf,double pos,
1927  int (*localseek)(OggVorbis_File *,double)){
1928  vorbis_info *vi;
1929  float **lappcm;
1930  float **pcm;
1931  float *w1,*w2;
1932  int n1,n2,ch1,ch2,hs;
1933  int i,ret;
1934 
1935  if(vf->ready_state<OPENED)return(OV_EINVAL);
1936  ret=_ov_initset(vf);
1937  if(ret)return(ret);
1938  vi=ov_info(vf,-1);
1939  hs=ov_halfrate_p(vf);
1940 
1941  ch1=vi->channels;
1942  n1=vorbis_info_blocksize(vi,0)>>(1+hs);
1943  w1=vorbis_window(&vf->vd,0); /* window arrays from libvorbis are
1944  persistent; even if the decode state
1945  from this link gets dumped, this
1946  window array continues to exist */
1947 
1948  lappcm=alloca(sizeof(*lappcm)*ch1);
1949  for(i=0;i<ch1;i++)
1950  lappcm[i]=alloca(sizeof(**lappcm)*n1);
1951  _ov_getlap(vf,vi,&vf->vd,lappcm,n1);
1952 
1953  /* have lapping data; seek and prime the buffer */
1954  ret=localseek(vf,pos);
1955  if(ret)return ret;
1956  ret=_ov_initprime(vf);
1957  if(ret)return(ret);
1958 
1959  /* Guard against cross-link changes; they're perfectly legal */
1960  vi=ov_info(vf,-1);
1961  ch2=vi->channels;
1962  n2=vorbis_info_blocksize(vi,0)>>(1+hs);
1963  w2=vorbis_window(&vf->vd,0);
1964 
1965  /* consolidate and expose the buffer. */
1966  vorbis_synthesis_lapout(&vf->vd,&pcm);
1967 
1968  /* splice */
1969  _ov_splice(pcm,lappcm,n1,n2,ch1,ch2,w1,w2);
1970 
1971  /* done */
1972  return(0);
1973 }
1974 
1975 int ov_time_seek_lap(OggVorbis_File *vf,double pos){
1976  return _ov_d_seek_lap(vf,pos,ov_time_seek);
1977 }
1978 
1980  return _ov_d_seek_lap(vf,pos,ov_time_seek_page);
1981 }
ogg_int64_t pcm_offset
Definition: vorbisfile.h:72
double ov_TIME_Tell(OggVorbis_File *vf)
Definition: vorbisfile.c:1425
int(* close_func)(void *datasource)
Definition: vorbisfile.h:42
int vorbis_synthesis_halfrate(vorbis_info *v, int flag)
Definition: synthesis.c:155
int vorbis_synthesis(vorbis_block *vb, ogg_packet *op)
Definition: synthesis.c:26
int ov_time_seek_lap(OggVorbis_File *vf, double pos)
Definition: vorbisfile.c:1975
#define OV_HOLE
Definition: codec.h:221
long ov_bitrate(OggVorbis_File *vf, int i)
Definition: vorbisfile.c:821
void vorbis_comment_clear(vorbis_comment *vc)
Definition: info.c:130
void _analysis_output_always(char *base, int i, float *v, int n, int bark, int dB, ogg_int64_t off)
Definition: analysis.c:67
Definition: ogg.h:37
int vorbis_synthesis_trackonly(vorbis_block *vb, ogg_packet *op)
Definition: synthesis.c:82
vorbis_comment * vc
Definition: vorbisfile.h:69
int vorbis_synthesis_read(vorbis_dsp_state *v, int samples)
Definition: block.c:876
const GLdouble * v
Definition: glext.h:2936
ov_callbacks callbacks
Definition: vorbisfile.h:85
#define OV_EBADPACKET
Definition: codec.h:231
ogg_int64_t ogg_page_granulepos(ogg_page *og)
Definition: framing.c:45
ogg_int64_t end
Definition: vorbisfile.h:56
int vorbis_synthesis_halfrate_p(vorbis_info *v)
Definition: synthesis.c:165
Definition: ogg.h:84
#define OV_EFAULT
Definition: codec.h:224
#define CHUNKSIZE
Definition: vorbisfile.c:61
GLenum GLsizei n
Definition: glext.h:3705
case const int
Definition: Callbacks.cpp:52
long header_len
Definition: ogg.h:39
int ov_clear(OggVorbis_File *vf)
Definition: vorbisfile.c:692
long ov_bitrate_instant(OggVorbis_File *vf)
Definition: vorbisfile.c:863
ogg_int64_t offset
Definition: vorbisfile.h:55
ogg_stream_state os
Definition: vorbisfile.h:80
int ogg_page_serialno(ogg_page *og)
Definition: framing.c:58
vorbis_dsp_state vd
Definition: vorbisfile.h:82
int ov_time_seek_page_lap(OggVorbis_File *vf, double pos)
Definition: vorbisfile.c:1979
#define _ogg_free
Definition: os_types.h:41
#define OV_EBADLINK
Definition: codec.h:232
vorbis_info * ov_info(OggVorbis_File *vf, int link)
Definition: vorbisfile.c:1454
vorbis_block vb
Definition: vorbisfile.h:83
int ogg_sync_wrote(ogg_sync_state *oy, long bytes)
Definition: framing.c:531
GLdouble s
Definition: glext.h:2935
size_t(* read_func)(void *ptr, size_t size, size_t nmemb, void *datasource)
Definition: vorbisfile.h:40
GLuint src
Definition: glext.h:5390
#define vorbis_fpu_setround(vorbis_fpu_control)
Definition: os.h:142
ogg_int64_t ov_pcm_total(OggVorbis_File *vf, int i)
Definition: vorbisfile.c:909
int ov_test_open(OggVorbis_File *vf)
Definition: vorbisfile.c:797
ogg_int64_t ov_raw_tell(OggVorbis_File *vf)
Definition: vorbisfile.c:1413
int i
Definition: process.py:33
GLintptr offset
Definition: glext.h:3113
ogg_int64_t * pcmlengths
Definition: vorbisfile.h:65
Boolean result
double ov_TIME_Total(OggVorbis_File *vf, int i)
Definition: vorbisfile.c:928
long bitrate_lower
Definition: codec.h:50
#define PARTOPEN
Definition: vorbisfile.h:47
vorbis_comment * ov_comment(OggVorbis_File *vf, int link)
Definition: vorbisfile.c:1472
long serialno
Definition: ogg.h:70
int ov_raw_seek(OggVorbis_File *vf, ogg_int64_t pos)
Definition: vorbisfile.c:949
void vorbis_comment_init(vorbis_comment *vc)
Definition: info.c:58
double bittrack
Definition: vorbisfile.h:77
int vorbis_synthesis_headerin(vorbis_info *vi, vorbis_comment *vc, ogg_packet *op)
Definition: info.c:336
void * codec_setup
Definition: codec.h:53
long bitrate_upper
Definition: codec.h:48
int channels
Definition: codec.h:30
char * ogg_sync_buffer(ogg_sync_state *oy, long size)
Definition: framing.c:506
#define SEEK_END
Definition: Unzip.cpp:131
int vorbis_fpu_control
Definition: os.h:135
int ov_open_callbacks(void *f, OggVorbis_File *vf, char *initial, long ibytes, ov_callbacks callbacks)
Definition: vorbisfile.c:729
int ogg_sync_reset(ogg_sync_state *oy)
Definition: framing.c:798
long bitrate_nominal
Definition: codec.h:49
int ov_time_seek(OggVorbis_File *vf, double seconds)
Definition: vorbisfile.c:1359
int ov_time_seek_page(OggVorbis_File *vf, double seconds)
Definition: vorbisfile.c:1386
GLubyte GLubyte GLubyte GLubyte w
Definition: glext.h:3454
int vorbis_synthesis_restart(vorbis_dsp_state *v)
Definition: block.c:640
int ov_crosslap(OggVorbis_File *vf1, OggVorbis_File *vf2)
Definition: vorbisfile.c:1815
GLuint GLuint end
Definition: glext.h:2845
long bytes
Definition: ogg.h:86
#define OV_EREAD
Definition: codec.h:223
long * serialnos
Definition: vorbisfile.h:64
#define NULL
Definition: Lib.h:88
#define OV_FALSE
Definition: codec.h:219
int ogg_stream_packetpeek(ogg_stream_state *os, ogg_packet *op)
Definition: framing.c:890
void vorbis_info_init(vorbis_info *vi)
Definition: info.c:150
ogg_int64_t * offsets
Definition: vorbisfile.h:62
int vorbis_synthesis_pcmout(vorbis_dsp_state *v, float ***pcm)
Definition: block.c:861
GLuint buffer
Definition: glext.h:3108
int ogg_stream_pagein(ogg_stream_state *os, ogg_page *og)
Definition: framing.c:674
#define SEEK_CUR
Definition: Unzip.cpp:130
int ov_pcm_seek_lap(OggVorbis_File *vf, ogg_int64_t pos)
Definition: vorbisfile.c:1918
float * vorbis_window(vorbis_dsp_state *v, int W)
Definition: block.c:962
#define OV_EBADHEADER
Definition: codec.h:228
int ov_pcm_seek_page(OggVorbis_File *vf, ogg_int64_t pos)
Definition: vorbisfile.c:1094
int ov_test_callbacks(void *f, OggVorbis_File *vf, char *initial, long ibytes, ov_callbacks callbacks)
Definition: vorbisfile.c:780
int ogg_sync_clear(ogg_sync_state *oy)
Definition: framing.c:490
#define OV_EINVAL
Definition: codec.h:226
void vorbis_info_clear(vorbis_info *vi)
Definition: info.c:155
int ov_pcm_seek_page_lap(OggVorbis_File *vf, ogg_int64_t pos)
Definition: vorbisfile.c:1922
int ov_test(FILE *f, OggVorbis_File *vf, char *initial, long ibytes)
Definition: vorbisfile.c:786
ogg_int64_t ov_raw_total(OggVorbis_File *vf, int i)
Definition: vorbisfile.c:890
ogg_int64_t ov_pcm_tell(OggVorbis_File *vf)
Definition: vorbisfile.c:1419
int vorbis_synthesis_init(vorbis_dsp_state *v, vorbis_info *vi)
Definition: block.c:663
#define _ogg_realloc
Definition: os_types.h:40
long ov_seekable(OggVorbis_File *vf)
Definition: vorbisfile.c:808
long current_serialno
Definition: vorbisfile.h:74
int vorbis_block_clear(vorbis_block *vb)
Definition: block.c:149
long(* tell_func)(void *datasource)
Definition: vorbisfile.h:43
long ov_read(OggVorbis_File *vf, char *buffer, int length, int bigendianp, int word, int sgned, int *bitstream)
Definition: vorbisfile.c:1527
GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint GLdouble GLdouble w2
Definition: glext.h:4080
double samptrack
Definition: vorbisfile.h:78
int(* seek_func)(void *datasource, ogg_int64_t offset, int whence)
Definition: vorbisfile.h:41
int ogg_stream_clear(ogg_stream_state *os)
Definition: framing.c:207
int ov_open(FILE *f, OggVorbis_File *vf, char *initial, long ibytes)
Definition: vorbisfile.c:736
long ov_streams(OggVorbis_File *vf)
Definition: vorbisfile.c:803
#define bits
Definition: Unzip.cpp:3797
#define vorbis_fpu_restore(vorbis_fpu_control)
Definition: os.h:143
void vorbis_dsp_clear(vorbis_dsp_state *v)
Definition: block.c:285
ogg_int64_t * dataoffsets
Definition: vorbisfile.h:63
#define OV_ENOTVORBIS
Definition: codec.h:227
size_t fread(void *, size_t, size_t, FILE *)
#define OPENED
Definition: vorbisfile.h:48
long ov_read_float(OggVorbis_File *vf, float ***pcm_channels, int length, int *bitstream)
Definition: vorbisfile.c:1672
#define SEEK_SET
Definition: Unzip.cpp:129
long ogg_sync_pageseek(ogg_sync_state *oy, ogg_page *og)
Definition: framing.c:547
tuple f
Definition: idal.py:89
long vorbis_packet_blocksize(vorbis_info *vi, ogg_packet *op)
Definition: synthesis.c:127
unsigned short word
Definition: Lib.h:76
int ogg_page_continued(ogg_page *og)
Definition: framing.c:33
long rate
Definition: codec.h:31
int vorbis_block_init(vorbis_dsp_state *v, vorbis_block *vb)
Definition: block.c:88
#define OV_EOF
Definition: codec.h:220
#define _ogg_calloc
Definition: os_types.h:39
GLushort pattern
Definition: qgl.h:331
ogg_int64_t granulepos
Definition: ogg.h:90
#define STREAMSET
Definition: vorbisfile.h:49
ogg_sync_state oy
Definition: vorbisfile.h:57
int ogg_stream_packetout(ogg_stream_state *os, ogg_packet *op)
Definition: framing.c:886
GLsizei const GLcharARB const GLint * length
Definition: glext.h:3599
int ov_pcm_seek(OggVorbis_File *vf, ogg_int64_t pos)
Definition: vorbisfile.c:1265
long ov_serialnumber(OggVorbis_File *vf, int i)
Definition: vorbisfile.c:875
int ov_raw_seek_lap(OggVorbis_File *vf, ogg_int64_t pos)
Definition: vorbisfile.c:1914
int ov_halfrate(OggVorbis_File *vf, int flag)
Definition: vorbisfile.c:750
int ogg_page_eos(ogg_page *og)
Definition: framing.c:41
int vorbis_info_blocksize(vorbis_info *vi, int zo)
Definition: info.c:144
int ogg_stream_reset(ogg_stream_state *os)
Definition: framing.c:807
int ogg_sync_init(ogg_sync_state *oy)
Definition: framing.c:482
vorbis_info * vi
Definition: vorbisfile.h:68
GLint j
Definition: qgl.h:264
int ogg_stream_reset_serialno(ogg_stream_state *os, int serialno)
Definition: framing.c:826
long body_len
Definition: ogg.h:41
#define INITSET
Definition: vorbisfile.h:50
int64_t ogg_int64_t
Definition: os_types.h:140
#define OV_ENOSEEK
Definition: codec.h:233
long e_o_s
Definition: ogg.h:88
int32_t ogg_int32_t
Definition: os_types.h:138
int ov_halfrate_p(OggVorbis_File *vf)
Definition: vorbisfile.c:770
int ogg_stream_init(ogg_stream_state *os, int serialno)
Definition: framing.c:188
void * datasource
Definition: vorbisfile.h:53
int vorbis_synthesis_blockin(vorbis_dsp_state *v, vorbis_block *vb)
Definition: block.c:674
GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint GLdouble w1
Definition: glext.h:4080
#define _ogg_malloc
Definition: os_types.h:38
int vorbis_synthesis_lapout(vorbis_dsp_state *v, float ***pcm)
Definition: block.c:887