fix one more beginning of stream braino; chained files pass seeking
[platform/upstream/libvorbis.git] / lib / vorbisfile.c
1 /********************************************************************
2  *                                                                  *
3  * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
4  * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
5  * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
6  * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
7  *                                                                  *
8  * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-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.57 2002/02/28 07:12:20 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,long 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 long _get_next_page(OggVorbis_File *vf,ogg_page *og,int boundary){
101   if(boundary>0)boundary+=vf->offset;
102   while(1){
103     long more;
104
105     if(boundary>0 && vf->offset>=boundary)return(OV_FALSE);
106     more=ogg_sync_pageseek(&vf->oy,og);
107     
108     if(more<0){
109       /* skipped n bytes */
110       vf->offset-=more;
111     }else{
112       if(more==0){
113         /* send more paramedics */
114         if(!boundary)return(OV_FALSE);
115         {
116           long ret=_get_data(vf);
117           if(ret==0)return(OV_EOF);
118           if(ret<0)return(OV_EREAD);
119         }
120       }else{
121         /* got a page.  Return the offset at the page beginning,
122            advance the internal offset past the page end */
123         long ret=vf->offset;
124         vf->offset+=more;
125         return(ret);
126         
127       }
128     }
129   }
130 }
131
132 /* find the latest page beginning before the current stream cursor
133    position. Much dirtier than the above as Ogg doesn't have any
134    backward search linkage.  no 'readp' as it will certainly have to
135    read. */
136 /* returns offset or OV_EREAD, OV_FAULT */
137 static long _get_prev_page(OggVorbis_File *vf,ogg_page *og){
138   long begin=vf->offset;
139   long end=begin;
140   long ret;
141   int offset=-1;
142
143   while(offset==-1){
144     begin-=CHUNKSIZE;
145     if(begin<0)
146       begin=0;
147     _seek_helper(vf,begin);
148     while(vf->offset<end){
149       ret=_get_next_page(vf,og,end-vf->offset);
150       if(ret==OV_EREAD)return(OV_EREAD);
151       if(ret<0){
152         break;
153       }else{
154         offset=ret;
155       }
156     }
157   }
158
159   /* we have the offset.  Actually snork and hold the page now */
160   _seek_helper(vf,offset);
161   ret=_get_next_page(vf,og,CHUNKSIZE);
162   if(ret<0)
163     /* this shouldn't be possible */
164     return(OV_EFAULT);
165
166   return(offset);
167 }
168
169 /* finds each bitstream link one at a time using a bisection search
170    (has to begin by knowing the offset of the lb's initial page).
171    Recurses for each link so it can alloc the link storage after
172    finding them all, then unroll and fill the cache at the same time */
173 static int _bisect_forward_serialno(OggVorbis_File *vf,
174                                     long begin,
175                                     long searched,
176                                     long end,
177                                     long currentno,
178                                     long m){
179   long endsearched=end;
180   long next=end;
181   ogg_page og;
182   long ret;
183   
184   /* the below guards against garbage seperating the last and
185      first pages of two links. */
186   while(searched<endsearched){
187     long bisect;
188     
189     if(endsearched-searched<CHUNKSIZE){
190       bisect=searched;
191     }else{
192       bisect=(searched+endsearched)/2;
193     }
194     
195     _seek_helper(vf,bisect);
196     ret=_get_next_page(vf,&og,-1);
197     if(ret==OV_EREAD)return(OV_EREAD);
198     if(ret<0 || ogg_page_serialno(&og)!=currentno){
199       endsearched=bisect;
200       if(ret>=0)next=ret;
201     }else{
202       searched=ret+og.header_len+og.body_len;
203     }
204   }
205
206   _seek_helper(vf,next);
207   ret=_get_next_page(vf,&og,-1);
208   if(ret==OV_EREAD)return(OV_EREAD);
209   
210   if(searched>=end || ret<0){
211     vf->links=m+1;
212     vf->offsets=_ogg_malloc((m+2)*sizeof(*vf->offsets));
213     vf->offsets[m+1]=searched;
214   }else{
215     ret=_bisect_forward_serialno(vf,next,vf->offset,
216                                  end,ogg_page_serialno(&og),m+1);
217     if(ret==OV_EREAD)return(OV_EREAD);
218   }
219   
220   vf->offsets[m]=begin;
221   return(0);
222 }
223
224 /* uses the local ogg_stream storage in vf; this is important for
225    non-streaming input sources */
226 static int _fetch_headers(OggVorbis_File *vf,vorbis_info *vi,vorbis_comment *vc,
227                           long *serialno,ogg_page *og_ptr){
228   ogg_page og;
229   ogg_packet op;
230   int i,ret=0;
231   
232   if(!og_ptr){
233     ret=_get_next_page(vf,&og,CHUNKSIZE);
234     if(ret==OV_EREAD)return(OV_EREAD);
235     if(ret<0)return OV_ENOTVORBIS;
236     og_ptr=&og;
237   }
238
239   if(serialno)*serialno=ogg_page_serialno(og_ptr);
240   ogg_stream_init(&vf->os,ogg_page_serialno(og_ptr));
241   vf->ready_state=STREAMSET;
242   
243   /* extract the initial header from the first page and verify that the
244      Ogg bitstream is in fact Vorbis data */
245   
246   vorbis_info_init(vi);
247   vorbis_comment_init(vc);
248   
249   i=0;
250   while(i<3){
251     ogg_stream_pagein(&vf->os,og_ptr);
252     while(i<3){
253       int result=ogg_stream_packetout(&vf->os,&op);
254       if(result==0)break;
255       if(result==-1){
256         ret=OV_EBADHEADER;
257         goto bail_header;
258       }
259       if((ret=vorbis_synthesis_headerin(vi,vc,&op))){
260         goto bail_header;
261       }
262       i++;
263     }
264     if(i<3)
265       if(_get_next_page(vf,og_ptr,CHUNKSIZE)<0){
266         ret=OV_EBADHEADER;
267         goto bail_header;
268       }
269   }
270   return 0; 
271
272  bail_header:
273   vorbis_info_clear(vi);
274   vorbis_comment_clear(vc);
275   ogg_stream_clear(&vf->os);
276   vf->ready_state=OPENED;
277
278   return ret;
279 }
280
281 /* last step of the OggVorbis_File initialization; get all the
282    vorbis_info structs and PCM positions.  Only called by the seekable
283    initialization (local stream storage is hacked slightly; pay
284    attention to how that's done) */
285
286 /* this is void and does not propogate errors up because we want to be
287    able to open and use damaged bitstreams as well as we can.  Just
288    watch out for missing information for links in the OggVorbis_File
289    struct */
290 static void _prefetch_all_headers(OggVorbis_File *vf, long dataoffset){
291   ogg_page og;
292   int i,ret;
293   
294   vf->vi=_ogg_realloc(vf->vi,vf->links*sizeof(*vf->vi));
295   vf->vc=_ogg_realloc(vf->vc,vf->links*sizeof(*vf->vc));
296   vf->dataoffsets=_ogg_malloc(vf->links*sizeof(*vf->dataoffsets));
297   vf->pcmlengths=_ogg_malloc(vf->links*sizeof(*vf->pcmlengths));
298   vf->serialnos=_ogg_malloc(vf->links*sizeof(*vf->serialnos));
299   
300   for(i=0;i<vf->links;i++){
301     if(i==0){
302       /* we already grabbed the initial header earlier.  Just set the offset */
303       vf->dataoffsets[i]=dataoffset;
304     }else{
305
306       /* seek to the location of the initial header */
307
308       _seek_helper(vf,vf->offsets[i]);
309       if(_fetch_headers(vf,vf->vi+i,vf->vc+i,NULL,NULL)<0){
310         vf->dataoffsets[i]=-1;
311       }else{
312         vf->dataoffsets[i]=vf->offset;
313         ogg_stream_clear(&vf->os);
314       }
315     }
316
317     /* get the serial number and PCM length of this link. To do this,
318        get the last page of the stream */
319     {
320       long end=vf->offsets[i+1];
321       _seek_helper(vf,end);
322
323       while(1){
324         ret=_get_prev_page(vf,&og);
325         if(ret<0){
326           /* this should not be possible */
327           vorbis_info_clear(vf->vi+i);
328           vorbis_comment_clear(vf->vc+i);
329           break;
330         }
331         if(ogg_page_granulepos(&og)!=-1){
332           vf->serialnos[i]=ogg_page_serialno(&og);
333           vf->pcmlengths[i]=ogg_page_granulepos(&og);
334           break;
335         }
336         vf->offset=ret;
337       }
338     }
339   }
340 }
341
342 static void _make_decode_ready(OggVorbis_File *vf){
343   if(vf->ready_state!=STREAMSET)return;
344   if(vf->seekable){
345     vorbis_synthesis_init(&vf->vd,vf->vi+vf->current_link);
346   }else{
347     vorbis_synthesis_init(&vf->vd,vf->vi);
348   }    
349   vorbis_block_init(&vf->vd,&vf->vb);
350   vf->ready_state=INITSET;
351   return;
352 }
353
354 static int _open_seekable2(OggVorbis_File *vf){
355   long serialno=vf->current_serialno,end;
356   long dataoffset=vf->offset;
357   ogg_page og;
358
359   /* we're partially open and have a first link header state in
360      storage in vf */
361   /* we can seek, so set out learning all about this file */
362   (vf->callbacks.seek_func)(vf->datasource,0,SEEK_END);
363   vf->offset=vf->end=(vf->callbacks.tell_func)(vf->datasource);
364   
365   /* We get the offset for the last page of the physical bitstream.
366      Most OggVorbis files will contain a single logical bitstream */
367   end=_get_prev_page(vf,&og);
368   if(end<0){
369     ov_clear(vf);
370     return(end);
371   }
372
373   /* more than one logical bitstream? */
374   if(ogg_page_serialno(&og)!=serialno){
375
376     /* Chained bitstream. Bisect-search each logical bitstream
377        section.  Do so based on serial number only */
378     if(_bisect_forward_serialno(vf,0,0,end+1,serialno,0)<0){
379       ov_clear(vf);
380       return(OV_EREAD);
381     }
382
383   }else{
384
385     /* Only one logical bitstream */
386     if(_bisect_forward_serialno(vf,0,end,end+1,serialno,0)){
387       ov_clear(vf);
388       return(OV_EREAD);
389     }
390
391   }
392
393   /* the initial header memory is referenced by vf after; don't free it */
394   _prefetch_all_headers(vf,dataoffset);
395   return(ov_raw_seek(vf,0));
396 }
397
398 /* clear out the current logical bitstream decoder */ 
399 static void _decode_clear(OggVorbis_File *vf){
400   ogg_stream_clear(&vf->os);
401   vorbis_dsp_clear(&vf->vd);
402   vorbis_block_clear(&vf->vb);
403   vf->ready_state=OPENED;
404
405   vf->bittrack=0.f;
406   vf->samptrack=0.f;
407 }
408
409 /* fetch and process a packet.  Handles the case where we're at a
410    bitstream boundary and dumps the decoding machine.  If the decoding
411    machine is unloaded, it loads it.  It also keeps pcm_offset up to
412    date (seek and read both use this.  seek uses a special hack with
413    readp). 
414
415    return: <0) error, OV_HOLE (lost packet) or OV_EOF
416             0) need more data (only if readp==0)
417             1) got a packet 
418 */
419
420 static int _fetch_and_process_packet(OggVorbis_File *vf,
421                                      ogg_packet *op_in,
422                                      int readp){
423   ogg_page og;
424
425   /* handle one packet.  Try to fetch it from current stream state */
426   /* extract packets from page */
427   while(1){
428     
429     /* process a packet if we can.  If the machine isn't loaded,
430        neither is a page */
431     if(vf->ready_state==INITSET){
432       while(1) {
433         ogg_packet op;
434         ogg_packet *op_ptr=(op_in?op_in:&op);
435         int result=ogg_stream_packetout(&vf->os,op_ptr);
436         ogg_int64_t granulepos;
437
438         op_in=NULL;
439         if(result==-1)return(OV_HOLE); /* hole in the data. */
440         if(result>0){
441           /* got a packet.  process it */
442           granulepos=op_ptr->granulepos;
443           if(!vorbis_synthesis(&vf->vb,op_ptr)){ /* lazy check for lazy
444                                                     header handling.  The
445                                                     header packets aren't
446                                                     audio, so if/when we
447                                                     submit them,
448                                                     vorbis_synthesis will
449                                                     reject them */
450
451             /* suck in the synthesis data and track bitrate */
452             {
453               int oldsamples=vorbis_synthesis_pcmout(&vf->vd,NULL);
454               /* for proper use of libvorbis within libvorbisfile,
455                  oldsamples will always be zero. */
456               if(oldsamples)return(OV_EFAULT);
457               
458               vorbis_synthesis_blockin(&vf->vd,&vf->vb);
459               vf->samptrack+=vorbis_synthesis_pcmout(&vf->vd,NULL)-oldsamples;
460               vf->bittrack+=op_ptr->bytes*8;
461             }
462           
463             /* update the pcm offset. */
464             if(granulepos!=-1 && !op_ptr->e_o_s){
465               int link=(vf->seekable?vf->current_link:0);
466               int i,samples;
467             
468               /* this packet has a pcm_offset on it (the last packet
469                  completed on a page carries the offset) After processing
470                  (above), we know the pcm position of the *last* sample
471                  ready to be returned. Find the offset of the *first*
472
473                  As an aside, this trick is inaccurate if we begin
474                  reading anew right at the last page; the end-of-stream
475                  granulepos declares the last frame in the stream, and the
476                  last packet of the last page may be a partial frame.
477                  So, we need a previous granulepos from an in-sequence page
478                  to have a reference point.  Thus the !op_ptr->e_o_s clause
479                  above */
480             
481               samples=vorbis_synthesis_pcmout(&vf->vd,NULL);
482             
483               granulepos-=samples;
484               for(i=0;i<link;i++)
485                 granulepos+=vf->pcmlengths[i];
486               vf->pcm_offset=granulepos;
487             }
488             return(1);
489           }
490         }
491         else 
492           break;
493       }
494     }
495
496     if(vf->ready_state>=OPENED){
497       if(!readp)return(0);
498       if(_get_next_page(vf,&og,-1)<0)return(OV_EOF); /* eof. 
499                                                         leave unitialized */
500       /* bitrate tracking; add the header's bytes here, the body bytes
501          are done by packet above */
502       vf->bittrack+=og.header_len*8;
503       
504       /* has our decoding just traversed a bitstream boundary? */
505       if(vf->ready_state==INITSET){
506         if(vf->current_serialno!=ogg_page_serialno(&og)){
507           _decode_clear(vf);
508           
509           if(!vf->seekable){
510             vorbis_info_clear(vf->vi);
511             vorbis_comment_clear(vf->vc);
512           }
513         }
514       }
515     }
516
517     /* Do we need to load a new machine before submitting the page? */
518     /* This is different in the seekable and non-seekable cases.  
519
520        In the seekable case, we already have all the header
521        information loaded and cached; we just initialize the machine
522        with it and continue on our merry way.
523
524        In the non-seekable (streaming) case, we'll only be at a
525        boundary if we just left the previous logical bitstream and
526        we're now nominally at the header of the next bitstream
527     */
528
529     if(vf->ready_state!=INITSET){ 
530       int link;
531
532       if(vf->ready_state<STREAMSET){
533         if(vf->seekable){
534           vf->current_serialno=ogg_page_serialno(&og);
535           
536           /* match the serialno to bitstream section.  We use this rather than
537              offset positions to avoid problems near logical bitstream
538              boundaries */
539           for(link=0;link<vf->links;link++)
540             if(vf->serialnos[link]==vf->current_serialno)break;
541           if(link==vf->links)return(OV_EBADLINK); /* sign of a bogus
542                                                      stream.  error out,
543                                                      leave machine
544                                                      uninitialized */
545           
546           vf->current_link=link;
547           
548           ogg_stream_init(&vf->os,vf->current_serialno);
549           ogg_stream_reset(&vf->os); 
550           vf->ready_state=STREAMSET;
551           
552         }else{
553           /* we're streaming */
554           /* fetch the three header packets, build the info struct */
555           
556           int ret=_fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno,&og);
557           if(ret)return(ret);
558           vf->current_link++;
559           link=0;
560         }
561       }
562       
563       _make_decode_ready(vf);
564     }
565     ogg_stream_pagein(&vf->os,&og);
566   }
567 }
568
569 static int _fseek64_wrap(FILE *f,ogg_int64_t off,int whence){
570   if(f==NULL)return(-1);
571   return fseek(f,(int)off,whence);
572 }
573
574 static int _ov_open1(void *f,OggVorbis_File *vf,char *initial,
575                      long ibytes, ov_callbacks callbacks){
576   long offset=(f?callbacks.seek_func(f,0,SEEK_CUR):-1);
577   int ret;
578
579   memset(vf,0,sizeof(*vf));
580   vf->datasource=f;
581   vf->callbacks = callbacks;
582
583   /* init the framing state */
584   ogg_sync_init(&vf->oy);
585
586   /* perhaps some data was previously read into a buffer for testing
587      against other stream types.  Allow initialization from this
588      previously read data (as we may be reading from a non-seekable
589      stream) */
590   if(initial){
591     char *buffer=ogg_sync_buffer(&vf->oy,ibytes);
592     memcpy(buffer,initial,ibytes);
593     ogg_sync_wrote(&vf->oy,ibytes);
594   }
595
596   /* can we seek? Stevens suggests the seek test was portable */
597   if(offset!=-1)vf->seekable=1;
598
599   /* No seeking yet; Set up a 'single' (current) logical bitstream
600      entry for partial open */
601   vf->links=1;
602   vf->vi=_ogg_calloc(vf->links,sizeof(*vf->vi));
603   vf->vc=_ogg_calloc(vf->links,sizeof(*vf->vc));
604   
605   /* Try to fetch the headers, maintaining all the storage */
606   if((ret=_fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno,NULL))<0){
607     vf->datasource=NULL;
608     ov_clear(vf);
609   }else if(vf->ready_state < PARTOPEN)
610     vf->ready_state=PARTOPEN;
611   return(ret);
612 }
613
614 static int _ov_open2(OggVorbis_File *vf){
615   if(vf->ready_state < OPENED)
616     vf->ready_state=OPENED;
617   if(vf->seekable){
618     int ret=_open_seekable2(vf);
619     if(ret){
620       vf->datasource=NULL;
621       ov_clear(vf);
622     }
623     return(ret);
624   }
625   return 0;
626 }
627
628
629 /* clear out the OggVorbis_File struct */
630 int ov_clear(OggVorbis_File *vf){
631   if(vf){
632     vorbis_block_clear(&vf->vb);
633     vorbis_dsp_clear(&vf->vd);
634     ogg_stream_clear(&vf->os);
635     
636     if(vf->vi && vf->links){
637       int i;
638       for(i=0;i<vf->links;i++){
639         vorbis_info_clear(vf->vi+i);
640         vorbis_comment_clear(vf->vc+i);
641       }
642       _ogg_free(vf->vi);
643       _ogg_free(vf->vc);
644     }
645     if(vf->dataoffsets)_ogg_free(vf->dataoffsets);
646     if(vf->pcmlengths)_ogg_free(vf->pcmlengths);
647     if(vf->serialnos)_ogg_free(vf->serialnos);
648     if(vf->offsets)_ogg_free(vf->offsets);
649     ogg_sync_clear(&vf->oy);
650     if(vf->datasource)(vf->callbacks.close_func)(vf->datasource);
651     memset(vf,0,sizeof(*vf));
652   }
653 #ifdef DEBUG_LEAKS
654   _VDBG_dump();
655 #endif
656   return(0);
657 }
658
659 /* inspects the OggVorbis file and finds/documents all the logical
660    bitstreams contained in it.  Tries to be tolerant of logical
661    bitstream sections that are truncated/woogie. 
662
663    return: -1) error
664             0) OK
665 */
666
667 int ov_open_callbacks(void *f,OggVorbis_File *vf,char *initial,long ibytes,
668     ov_callbacks callbacks){
669   int ret=_ov_open1(f,vf,initial,ibytes,callbacks);
670   if(ret)return ret;
671   return _ov_open2(vf);
672 }
673
674 int ov_open(FILE *f,OggVorbis_File *vf,char *initial,long ibytes){
675   ov_callbacks callbacks = {
676     (size_t (*)(void *, size_t, size_t, void *))  fread,
677     (int (*)(void *, ogg_int64_t, int))              _fseek64_wrap,
678     (int (*)(void *))                             fclose,
679     (long (*)(void *))                            ftell
680   };
681
682   return ov_open_callbacks((void *)f, vf, initial, ibytes, callbacks);
683 }
684   
685 /* Only partially open the vorbis file; test for Vorbisness, and load
686    the headers for the first chain.  Do not seek (although test for
687    seekability).  Use ov_test_open to finish opening the file, else
688    ov_clear to close/free it. Same return codes as open. */
689
690 int ov_test_callbacks(void *f,OggVorbis_File *vf,char *initial,long ibytes,
691     ov_callbacks callbacks)
692 {
693   return _ov_open1(f,vf,initial,ibytes,callbacks);
694 }
695
696 int ov_test(FILE *f,OggVorbis_File *vf,char *initial,long ibytes){
697   ov_callbacks callbacks = {
698     (size_t (*)(void *, size_t, size_t, void *))  fread,
699     (int (*)(void *, ogg_int64_t, int))              _fseek64_wrap,
700     (int (*)(void *))                             fclose,
701     (long (*)(void *))                            ftell
702   };
703
704   return ov_test_callbacks((void *)f, vf, initial, ibytes, callbacks);
705 }
706   
707 int ov_test_open(OggVorbis_File *vf){
708   if(vf->ready_state!=PARTOPEN)return(OV_EINVAL);
709   return _ov_open2(vf);
710 }
711
712 /* How many logical bitstreams in this physical bitstream? */
713 long ov_streams(OggVorbis_File *vf){
714   return vf->links;
715 }
716
717 /* Is the FILE * associated with vf seekable? */
718 long ov_seekable(OggVorbis_File *vf){
719   return vf->seekable;
720 }
721
722 /* returns the bitrate for a given logical bitstream or the entire
723    physical bitstream.  If the file is open for random access, it will
724    find the *actual* average bitrate.  If the file is streaming, it
725    returns the nominal bitrate (if set) else the average of the
726    upper/lower bounds (if set) else -1 (unset).
727
728    If you want the actual bitrate field settings, get them from the
729    vorbis_info structs */
730
731 long ov_bitrate(OggVorbis_File *vf,int i){
732   if(vf->ready_state<OPENED)return(OV_EINVAL);
733   if(i>=vf->links)return(OV_EINVAL);
734   if(!vf->seekable && i!=0)return(ov_bitrate(vf,0));
735   if(i<0){
736     ogg_int64_t bits=0;
737     int i;
738     for(i=0;i<vf->links;i++)
739       bits+=(vf->offsets[i+1]-vf->dataoffsets[i])*8;
740     return(rint(bits/ov_time_total(vf,-1)));
741   }else{
742     if(vf->seekable){
743       /* return the actual bitrate */
744       return(rint((vf->offsets[i+1]-vf->dataoffsets[i])*8/ov_time_total(vf,i)));
745     }else{
746       /* return nominal if set */
747       if(vf->vi[i].bitrate_nominal>0){
748         return vf->vi[i].bitrate_nominal;
749       }else{
750         if(vf->vi[i].bitrate_upper>0){
751           if(vf->vi[i].bitrate_lower>0){
752             return (vf->vi[i].bitrate_upper+vf->vi[i].bitrate_lower)/2;
753           }else{
754             return vf->vi[i].bitrate_upper;
755           }
756         }
757         return(OV_FALSE);
758       }
759     }
760   }
761 }
762
763 /* returns the actual bitrate since last call.  returns -1 if no
764    additional data to offer since last call (or at beginning of stream),
765    EINVAL if stream is only partially open 
766 */
767 long ov_bitrate_instant(OggVorbis_File *vf){
768   int link=(vf->seekable?vf->current_link:0);
769   long ret;
770   if(vf->ready_state<OPENED)return(OV_EINVAL);
771   if(vf->samptrack==0)return(OV_FALSE);
772   ret=vf->bittrack/vf->samptrack*vf->vi[link].rate+.5;
773   vf->bittrack=0.f;
774   vf->samptrack=0.f;
775   return(ret);
776 }
777
778 /* Guess */
779 long ov_serialnumber(OggVorbis_File *vf,int i){
780   if(i>=vf->links)return(ov_serialnumber(vf,vf->links-1));
781   if(!vf->seekable && i>=0)return(ov_serialnumber(vf,-1));
782   if(i<0){
783     return(vf->current_serialno);
784   }else{
785     return(vf->serialnos[i]);
786   }
787 }
788
789 /* returns: total raw (compressed) length of content if i==-1
790             raw (compressed) length of that logical bitstream for i==0 to n
791             OV_EINVAL if the stream is not seekable (we can't know the length)
792             or if stream is only partially open
793 */
794 ogg_int64_t ov_raw_total(OggVorbis_File *vf,int i){
795   if(vf->ready_state<OPENED)return(OV_EINVAL);
796   if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
797   if(i<0){
798     long acc=0;
799     int i;
800     for(i=0;i<vf->links;i++)
801       acc+=ov_raw_total(vf,i);
802     return(acc);
803   }else{
804     return(vf->offsets[i+1]-vf->offsets[i]);
805   }
806 }
807
808 /* returns: total PCM length (samples) of content if i==-1 PCM length
809             (samples) of that logical bitstream for i==0 to n
810             OV_EINVAL if the stream is not seekable (we can't know the
811             length) or only partially open 
812 */
813 ogg_int64_t ov_pcm_total(OggVorbis_File *vf,int i){
814   if(vf->ready_state<OPENED)return(OV_EINVAL);
815   if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
816   if(i<0){
817     ogg_int64_t acc=0;
818     int i;
819     for(i=0;i<vf->links;i++)
820       acc+=ov_pcm_total(vf,i);
821     return(acc);
822   }else{
823     return(vf->pcmlengths[i]);
824   }
825 }
826
827 /* returns: total seconds of content if i==-1
828             seconds in that logical bitstream for i==0 to n
829             OV_EINVAL if the stream is not seekable (we can't know the
830             length) or only partially open 
831 */
832 double ov_time_total(OggVorbis_File *vf,int i){
833   if(vf->ready_state<OPENED)return(OV_EINVAL);
834   if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
835   if(i<0){
836     double acc=0;
837     int i;
838     for(i=0;i<vf->links;i++)
839       acc+=ov_time_total(vf,i);
840     return(acc);
841   }else{
842     return((float)(vf->pcmlengths[i])/vf->vi[i].rate);
843   }
844 }
845
846 /* seek to an offset relative to the *compressed* data. This also
847    scans packets to update the PCM cursor. It will cross a logical
848    bitstream boundary, but only if it can't get any packets out of the
849    tail of the bitstream we seek to (so no surprises).
850
851    returns zero on success, nonzero on failure */
852
853 int ov_raw_seek(OggVorbis_File *vf,long pos){
854   ogg_stream_state work_os;
855
856   if(vf->ready_state<OPENED)return(OV_EINVAL);
857   if(!vf->seekable)
858     return(OV_ENOSEEK); /* don't dump machine if we can't seek */
859
860   if(pos<0 || pos>vf->offsets[vf->links])return(OV_EINVAL);
861
862   /* clear out decoding machine state */
863   vf->pcm_offset=-1;
864   _decode_clear(vf);
865   
866   _seek_helper(vf,pos);
867
868   /* we need to make sure the pcm_offset is set, but we don't want to
869      advance the raw cursor past good packets just to get to the first
870      with a granulepos.  That's not equivalent behavior to beginning
871      decoding as immediately after the seek position as possible.
872
873      So, a hack.  We use two stream states; a local scratch state and
874      a the shared vf->os stream state.  We use the local state to
875      scan, and the shared state as a buffer for later decode. 
876
877      Unfortuantely, on the last page we still advance to last packet
878      because the granulepos on the last page is not necessarily on a
879      packet boundary, and we need to make sure the granpos is
880      correct. 
881   */
882
883   {
884     ogg_page og;
885     ogg_packet op;
886     int lastblock=0;
887     int accblock=0;
888     int thisblock;
889     int eosflag;
890
891     memset(&work_os,0,sizeof(work_os));/* so that it's safe to clear
892                                           it later even if we don't
893                                           init it */
894
895     while(1){
896       if(vf->ready_state==STREAMSET){
897         /* snarf/scan a packet if we can */
898         int result=ogg_stream_packetout(&work_os,&op);
899       
900         if(result>0){
901
902           if(vf->vi[vf->current_link].codec_setup)
903             thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op);
904           if(eosflag)
905             ogg_stream_packetout(&vf->os,NULL);
906           else
907             if(lastblock)accblock+=(lastblock+thisblock)>>2;
908
909           if(op.granulepos!=-1){
910             int i,link=vf->current_link;
911             ogg_int64_t granulepos=op.granulepos;
912             
913             for(i=0;i<link;i++)
914               granulepos+=vf->pcmlengths[i];
915             vf->pcm_offset=granulepos-accblock;
916             break;
917           }
918           lastblock=thisblock;
919           continue;
920         }
921       }
922       
923       if(!lastblock){
924         if(_get_next_page(vf,&og,-1)<0){
925           vf->pcm_offset=ov_pcm_total(vf,-1);
926           break;
927         }
928       }else{
929         /* huh?  Bogus stream with packets but no granulepos */
930         vf->pcm_offset=-1;
931         break;
932       }
933       
934       /* has our decoding just traversed a bitstream boundary? */
935       if(vf->ready_state==STREAMSET)
936         if(vf->current_serialno!=ogg_page_serialno(&og)){
937         _decode_clear(vf); /* clear out stream state */
938         ogg_stream_clear(&work_os);
939       }
940
941       if(vf->ready_state<STREAMSET){
942         int link;
943         
944         vf->current_serialno=ogg_page_serialno(&og);
945         for(link=0;link<vf->links;link++)
946           if(vf->serialnos[link]==vf->current_serialno)break;
947         if(link==vf->links)goto seek_error; /* sign of a bogus stream.
948                                                error out, leave
949                                                machine uninitialized */
950         vf->current_link=link;
951         
952         ogg_stream_init(&vf->os,vf->current_serialno);
953         ogg_stream_reset(&vf->os); 
954         ogg_stream_init(&work_os,vf->current_serialno);
955         ogg_stream_reset(&work_os); 
956         vf->ready_state=STREAMSET;
957         
958       }
959     
960       ogg_stream_pagein(&vf->os,&og);
961       ogg_stream_pagein(&work_os,&og);
962       eosflag=ogg_page_eos(&og);
963     }
964   }
965
966   ogg_stream_clear(&work_os);
967   return(0);
968
969  seek_error:
970   /* dump the machine so we're in a known state */
971   vf->pcm_offset=-1;
972   ogg_stream_clear(&work_os);
973   _decode_clear(vf);
974   return OV_EBADLINK;
975 }
976
977 /* Page granularity seek (faster than sample granularity because we
978    don't do the last bit of decode to find a specific sample).
979
980    Seek to the last [granule marked] page preceeding the specified pos
981    location, such that decoding past the returned point will quickly
982    arrive at the requested position. */
983 int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos){
984   int link=-1;
985   long ret;
986   ogg_int64_t total=ov_pcm_total(vf,-1);
987
988   if(vf->ready_state<OPENED)return(OV_EINVAL);
989   if(!vf->seekable)return(OV_ENOSEEK);
990   if(pos<0 || pos>total)return(OV_EINVAL);
991  
992   /* which bitstream section does this pcm offset occur in? */
993   for(link=vf->links-1;link>=0;link--){
994     total-=vf->pcmlengths[link];
995     if(pos>=total)break;
996   }
997
998   /* search within the logical bitstream for the page with the highest
999      pcm_pos preceeding (or equal to) pos.  There is a danger here;
1000      missing pages or incorrect frame number information in the
1001      bitstream could make our task impossible.  Account for that (it
1002      would be an error condition) */
1003
1004   /* new search algorithm by HB (Nicholas Vinen) */
1005   {
1006     ogg_int64_t target=pos-total;
1007     long end=vf->offsets[link+1];
1008     long begin=vf->offsets[link];
1009     ogg_int64_t endtime = vf->pcmlengths[link];
1010     ogg_int64_t begintime = 0;
1011     long best=begin;
1012     
1013     ogg_page og;
1014     while(begin<end){
1015       long bisect;
1016       
1017       if(end-begin<CHUNKSIZE){
1018         bisect=begin;
1019       }else{
1020         /* take a (pretty decent) guess. */
1021         bisect=begin + 
1022           (target-begintime)*(end-begin)/(endtime-begintime) - CHUNKSIZE;
1023         if(bisect<=begin)
1024           bisect=begin+1;
1025       }
1026       _seek_helper(vf,bisect);
1027     
1028       while(begin<end){
1029         ret=_get_next_page(vf,&og,end-bisect);
1030         if(ret==OV_EREAD) goto seek_error;
1031         if(ret<0){
1032           if(bisect<=begin+1)
1033             end=begin; /* found it */
1034           else{
1035             if(bisect==0)goto seek_error;
1036             bisect-=CHUNKSIZE;
1037             if(bisect<=begin)bisect=begin+1;
1038             _seek_helper(vf,bisect);
1039           }
1040         }else{
1041           ogg_int64_t granulepos=ogg_page_granulepos(&og);
1042           if(granulepos<target){
1043             best=ret;  /* raw offset of packet with granulepos */ 
1044             begin=vf->offset; /* raw offset of next page */
1045             begintime=granulepos;
1046             
1047             if(target-begin>44100)break;
1048             bisect=begin; /* *not* begin + 1 */
1049           }else{
1050             if(bisect<=begin+1)
1051               end=begin;  /* found it */
1052             else{
1053               if(end==vf->offset){ /* we're pretty close - we'd be stuck in */
1054                 end=ret;
1055                 bisect-=CHUNKSIZE; /* an endless loop otherwise. */
1056                 if(bisect<=begin)bisect=begin+1;
1057                 _seek_helper(vf,bisect);
1058               }else{
1059                 end=ret;
1060                 endtime=granulepos;
1061                 break;
1062               }
1063             }
1064           }
1065         }
1066       }
1067     }
1068
1069     /* found our page. seek to it, update pcm offset. Easier case than
1070        raw_seek, don't keep packets preceeding granulepos. */
1071     {
1072       ogg_page og;
1073       ogg_packet op;
1074       /* clear out decoding machine state */
1075       _decode_clear(vf);  
1076       /* seek */
1077       _seek_helper(vf,best);
1078       
1079       if(_get_next_page(vf,&og,-1)<0)return(OV_EOF); /* shouldn't happen */
1080       vf->current_serialno=ogg_page_serialno(&og);
1081       vf->current_link=link;
1082       
1083       ogg_stream_init(&vf->os,vf->current_serialno);
1084       ogg_stream_reset(&vf->os); 
1085       vf->ready_state=STREAMSET;
1086       ogg_stream_pagein(&vf->os,&og);
1087
1088       /* pull out all but last packet; the one with granulepos */
1089       while(1){
1090         ret=ogg_stream_packetpeek(&vf->os,&op);
1091         if(ret==0){
1092           /* !!! the packet finishing this page originated on a
1093              preceeding page. Keep fetching previous pages until we
1094              get one with a granulepos or without the 'continued' flag
1095              set.  Then just use raw_seek for simplicity. */
1096
1097           _decode_clear(vf);  
1098           _seek_helper(vf,best);
1099
1100           while(1){
1101             ret=_get_prev_page(vf,&og);
1102             if(ret<0)goto seek_error;
1103             if(ogg_page_granulepos(&og)>-1 ||
1104                !ogg_page_continued(&og)){
1105               return ov_raw_seek(vf,ret);
1106             }
1107             vf->offset=ret;
1108           }
1109         }
1110         if(ret<0)goto seek_error;
1111         if(op.granulepos!=-1){
1112           vf->pcm_offset=op.granulepos+total;
1113           break;
1114         }else
1115           ret=ogg_stream_packetout(&vf->os,NULL);
1116       }
1117     }
1118   }
1119   
1120   /* verify result */
1121   if(vf->pcm_offset>pos || pos>ov_pcm_total(vf,-1)){
1122     ret=OV_EFAULT;
1123     goto seek_error;
1124   }
1125   return(0);
1126   
1127  seek_error:
1128   /* dump machine so we're in a known state */
1129   vf->pcm_offset=-1;
1130   _decode_clear(vf);
1131   return ret;
1132 }
1133
1134 /* seek to a sample offset relative to the decompressed pcm stream 
1135    returns zero on success, nonzero on failure */
1136
1137 int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos){
1138   int thisblock,lastblock=0;
1139   int ret=ov_pcm_seek_page(vf,pos);
1140   if(ret<0)return(ret);
1141   _make_decode_ready(vf);
1142
1143   /* discard leading packets we don't need for the lapping of the
1144      position we want; don't decode them */
1145
1146   while(1){
1147     ogg_packet op;
1148     ogg_page og;
1149
1150     int ret=ogg_stream_packetpeek(&vf->os,&op);
1151     if(ret>0){
1152       thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op);
1153       if(thisblock<0)thisblock=0; /* non audio packet */
1154       if(lastblock)vf->pcm_offset+=(lastblock+thisblock)>>2;
1155       
1156       if(vf->pcm_offset+((thisblock+
1157                           vorbis_info_blocksize(vf->vi,1))>>2)>=pos)break;
1158       
1159       /* remove the packet from packet queue and track its granulepos */
1160       ogg_stream_packetout(&vf->os,NULL);
1161       vorbis_synthesis_trackonly(&vf->vb,&op);  /* set up a vb with
1162                                                    only tracking, no
1163                                                    pcm_decode */
1164       vorbis_synthesis_blockin(&vf->vd,&vf->vb); 
1165       
1166       /* end of logical stream case is hard, especially with exact
1167          length positioning. */
1168       
1169       if(op.granulepos>-1){
1170         int i;
1171         /* always believe the stream markers */
1172         vf->pcm_offset=op.granulepos;
1173         for(i=0;i<vf->current_link;i++)
1174           vf->pcm_offset+=vf->pcmlengths[i];
1175       }
1176         
1177       lastblock=thisblock;
1178       
1179     }else{
1180       if(ret<0 && ret!=OV_HOLE)break;
1181       
1182       /* suck in a new page */
1183       if(_get_next_page(vf,&og,-1)<0)break;
1184       if(vf->current_serialno!=ogg_page_serialno(&og))_decode_clear(vf);
1185       
1186       if(vf->ready_state<STREAMSET){
1187         int link;
1188         
1189         vf->current_serialno=ogg_page_serialno(&og);
1190         for(link=0;link<vf->links;link++)
1191           if(vf->serialnos[link]==vf->current_serialno)break;
1192         if(link==vf->links)return(OV_EBADLINK);
1193         vf->current_link=link;
1194         
1195         ogg_stream_init(&vf->os,vf->current_serialno);
1196         ogg_stream_reset(&vf->os); 
1197         vf->ready_state=STREAMSET;      
1198         _make_decode_ready(vf);
1199         lastblock=0;
1200       }
1201
1202       ogg_stream_pagein(&vf->os,&og);
1203     }
1204   }
1205
1206   /* discard samples until we reach the desired position. Crossing a
1207      logical bitstream boundary with abandon is OK. */
1208   while(vf->pcm_offset<pos){
1209     float **pcm;
1210     long target=pos-vf->pcm_offset;
1211     long samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
1212
1213     if(samples>target)samples=target;
1214     vorbis_synthesis_read(&vf->vd,samples);
1215     vf->pcm_offset+=samples;
1216     
1217     if(samples<target)
1218       if(_fetch_and_process_packet(vf,NULL,1)<=0)
1219         vf->pcm_offset=ov_pcm_total(vf,-1); /* eof */
1220   }
1221   return 0;
1222 }
1223
1224 /* seek to a playback time relative to the decompressed pcm stream 
1225    returns zero on success, nonzero on failure */
1226 int ov_time_seek(OggVorbis_File *vf,double seconds){
1227   /* translate time to PCM position and call ov_pcm_seek */
1228
1229   int link=-1;
1230   ogg_int64_t pcm_total=ov_pcm_total(vf,-1);
1231   double time_total=ov_time_total(vf,-1);
1232
1233   if(vf->ready_state<OPENED)return(OV_EINVAL);
1234   if(!vf->seekable)return(OV_ENOSEEK);
1235   if(seconds<0 || seconds>time_total)return(OV_EINVAL);
1236   
1237   /* which bitstream section does this time offset occur in? */
1238   for(link=vf->links-1;link>=0;link--){
1239     pcm_total-=vf->pcmlengths[link];
1240     time_total-=ov_time_total(vf,link);
1241     if(seconds>=time_total)break;
1242   }
1243
1244   /* enough information to convert time offset to pcm offset */
1245   {
1246     ogg_int64_t target=pcm_total+(seconds-time_total)*vf->vi[link].rate;
1247     return(ov_pcm_seek(vf,target));
1248   }
1249 }
1250
1251 /* page-granularity version of ov_time_seek 
1252    returns zero on success, nonzero on failure */
1253 int ov_time_seek_page(OggVorbis_File *vf,double seconds){
1254   /* translate time to PCM position and call ov_pcm_seek */
1255
1256   int link=-1;
1257   ogg_int64_t pcm_total=ov_pcm_total(vf,-1);
1258   double time_total=ov_time_total(vf,-1);
1259
1260   if(vf->ready_state<OPENED)return(OV_EINVAL);
1261   if(!vf->seekable)return(OV_ENOSEEK);
1262   if(seconds<0 || seconds>time_total)return(OV_EINVAL);
1263   
1264   /* which bitstream section does this time offset occur in? */
1265   for(link=vf->links-1;link>=0;link--){
1266     pcm_total-=vf->pcmlengths[link];
1267     time_total-=ov_time_total(vf,link);
1268     if(seconds>=time_total)break;
1269   }
1270
1271   /* enough information to convert time offset to pcm offset */
1272   {
1273     ogg_int64_t target=pcm_total+(seconds-time_total)*vf->vi[link].rate;
1274     return(ov_pcm_seek_page(vf,target));
1275   }
1276 }
1277
1278 /* tell the current stream offset cursor.  Note that seek followed by
1279    tell will likely not give the set offset due to caching */
1280 ogg_int64_t ov_raw_tell(OggVorbis_File *vf){
1281   if(vf->ready_state<OPENED)return(OV_EINVAL);
1282   return(vf->offset);
1283 }
1284
1285 /* return PCM offset (sample) of next PCM sample to be read */
1286 ogg_int64_t ov_pcm_tell(OggVorbis_File *vf){
1287   if(vf->ready_state<OPENED)return(OV_EINVAL);
1288   return(vf->pcm_offset);
1289 }
1290
1291 /* return time offset (seconds) of next PCM sample to be read */
1292 double ov_time_tell(OggVorbis_File *vf){
1293   /* translate time to PCM position and call ov_pcm_seek */
1294
1295   int link=-1;
1296   ogg_int64_t pcm_total=0;
1297   double time_total=0.f;
1298   
1299   if(vf->ready_state<OPENED)return(OV_EINVAL);
1300   if(vf->seekable){
1301     pcm_total=ov_pcm_total(vf,-1);
1302     time_total=ov_time_total(vf,-1);
1303   
1304     /* which bitstream section does this time offset occur in? */
1305     for(link=vf->links-1;link>=0;link--){
1306       pcm_total-=vf->pcmlengths[link];
1307       time_total-=ov_time_total(vf,link);
1308       if(vf->pcm_offset>=pcm_total)break;
1309     }
1310   }
1311
1312   return((double)time_total+(double)(vf->pcm_offset-pcm_total)/vf->vi[link].rate);
1313 }
1314
1315 /*  link:   -1) return the vorbis_info struct for the bitstream section
1316                 currently being decoded
1317            0-n) to request information for a specific bitstream section
1318     
1319     In the case of a non-seekable bitstream, any call returns the
1320     current bitstream.  NULL in the case that the machine is not
1321     initialized */
1322
1323 vorbis_info *ov_info(OggVorbis_File *vf,int link){
1324   if(vf->seekable){
1325     if(link<0)
1326       if(vf->ready_state>=STREAMSET)
1327         return vf->vi+vf->current_link;
1328       else
1329       return vf->vi;
1330     else
1331       if(link>=vf->links)
1332         return NULL;
1333       else
1334         return vf->vi+link;
1335   }else{
1336     return vf->vi;
1337   }
1338 }
1339
1340 /* grr, strong typing, grr, no templates/inheritence, grr */
1341 vorbis_comment *ov_comment(OggVorbis_File *vf,int link){
1342   if(vf->seekable){
1343     if(link<0)
1344       if(vf->ready_state>=STREAMSET)
1345         return vf->vc+vf->current_link;
1346       else
1347         return vf->vc;
1348     else
1349       if(link>=vf->links)
1350         return NULL;
1351       else
1352         return vf->vc+link;
1353   }else{
1354     return vf->vc;
1355   }
1356 }
1357
1358 static int host_is_big_endian() {
1359   ogg_int32_t pattern = 0xfeedface; /* deadbeef */
1360   unsigned char *bytewise = (unsigned char *)&pattern;
1361   if (bytewise[0] == 0xfe) return 1;
1362   return 0;
1363 }
1364
1365 /* up to this point, everything could more or less hide the multiple
1366    logical bitstream nature of chaining from the toplevel application
1367    if the toplevel application didn't particularly care.  However, at
1368    the point that we actually read audio back, the multiple-section
1369    nature must surface: Multiple bitstream sections do not necessarily
1370    have to have the same number of channels or sampling rate.
1371
1372    ov_read returns the sequential logical bitstream number currently
1373    being decoded along with the PCM data in order that the toplevel
1374    application can take action on channel/sample rate changes.  This
1375    number will be incremented even for streamed (non-seekable) streams
1376    (for seekable streams, it represents the actual logical bitstream
1377    index within the physical bitstream.  Note that the accessor
1378    functions above are aware of this dichotomy).
1379
1380    input values: buffer) a buffer to hold packed PCM data for return
1381                  length) the byte length requested to be placed into buffer
1382                  bigendianp) should the data be packed LSB first (0) or
1383                              MSB first (1)
1384                  word) word size for output.  currently 1 (byte) or 
1385                        2 (16 bit short)
1386
1387    return values: <0) error/hole in data (OV_HOLE), partial open (OV_EINVAL)
1388                    0) EOF
1389                    n) number of bytes of PCM actually returned.  The
1390                    below works on a packet-by-packet basis, so the
1391                    return length is not related to the 'length' passed
1392                    in, just guaranteed to fit.
1393
1394             *section) set to the logical bitstream number */
1395
1396 long ov_read_float(OggVorbis_File *vf,float ***pcm_channels,int *bitstream){
1397
1398   if(vf->ready_state<OPENED)return(OV_EINVAL);
1399
1400   while(1){
1401     if(vf->ready_state>=STREAMSET){
1402       float **pcm;
1403       long samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
1404       if(samples){
1405         if(pcm_channels)*pcm_channels=pcm;
1406         vorbis_synthesis_read(&vf->vd,samples);
1407         vf->pcm_offset+=samples;
1408         if(bitstream)*bitstream=vf->current_link;
1409         return samples;
1410
1411       }
1412     }
1413
1414     /* suck in another packet */
1415     {
1416       int ret=_fetch_and_process_packet(vf,NULL,1);
1417       if(ret==OV_EOF)return(0);
1418       if(ret<=0)return(ret);
1419     }
1420
1421   }
1422 }
1423
1424 long ov_read(OggVorbis_File *vf,char *buffer,int length,
1425                     int bigendianp,int word,int sgned,int *bitstream){
1426   int i,j;
1427   int host_endian = host_is_big_endian();
1428
1429   float **pcm;
1430   long samples;
1431
1432   if(vf->ready_state<OPENED)return(OV_EINVAL);
1433
1434   while(1){
1435     if(vf->ready_state>=STREAMSET){
1436       samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
1437       if(samples)break;
1438     }
1439
1440     /* suck in another packet */
1441     {
1442       int ret=_fetch_and_process_packet(vf,NULL,1);
1443       if(ret==OV_EOF)return(0);
1444       if(ret<=0)return(ret);
1445     }
1446
1447   }
1448
1449   if(samples>0){
1450   
1451     /* yay! proceed to pack data into the byte buffer */
1452     
1453     long channels=ov_info(vf,-1)->channels;
1454     long bytespersample=word * channels;
1455     vorbis_fpu_control fpu;
1456     if(samples>length/bytespersample)samples=length/bytespersample;
1457     
1458     /* a tight loop to pack each size */
1459     {
1460       int val;
1461       if(word==1){
1462         int off=(sgned?0:128);
1463         vorbis_fpu_setround(&fpu);
1464         for(j=0;j<samples;j++)
1465           for(i=0;i<channels;i++){
1466             val=vorbis_ftoi(pcm[i][j]*128.f);
1467             if(val>127)val=127;
1468             else if(val<-128)val=-128;
1469             *buffer++=val+off;
1470           }
1471         vorbis_fpu_restore(fpu);
1472       }else{
1473         int off=(sgned?0:32768);
1474         
1475         if(host_endian==bigendianp){
1476           if(sgned){
1477             
1478             vorbis_fpu_setround(&fpu);
1479             for(i=0;i<channels;i++) { /* It's faster in this order */
1480               float *src=pcm[i];
1481               short *dest=((short *)buffer)+i;
1482               for(j=0;j<samples;j++) {
1483                 val=vorbis_ftoi(src[j]*32768.f);
1484                 if(val>32767)val=32767;
1485                 else if(val<-32768)val=-32768;
1486                 *dest=val;
1487                 dest+=channels;
1488               }
1489             }
1490             vorbis_fpu_restore(fpu);
1491             
1492           }else{
1493             
1494             vorbis_fpu_setround(&fpu);
1495             for(i=0;i<channels;i++) {
1496               float *src=pcm[i];
1497               short *dest=((short *)buffer)+i;
1498               for(j=0;j<samples;j++) {
1499                 val=vorbis_ftoi(src[j]*32768.f);
1500                 if(val>32767)val=32767;
1501                 else if(val<-32768)val=-32768;
1502                 *dest=val+off;
1503                 dest+=channels;
1504               }
1505             }
1506             vorbis_fpu_restore(fpu);
1507             
1508           }
1509         }else if(bigendianp){
1510           
1511           vorbis_fpu_setround(&fpu);
1512           for(j=0;j<samples;j++)
1513             for(i=0;i<channels;i++){
1514               val=vorbis_ftoi(pcm[i][j]*32768.f);
1515               if(val>32767)val=32767;
1516               else if(val<-32768)val=-32768;
1517               val+=off;
1518               *buffer++=(val>>8);
1519               *buffer++=(val&0xff);
1520             }
1521           vorbis_fpu_restore(fpu);
1522           
1523         }else{
1524           int val;
1525           vorbis_fpu_setround(&fpu);
1526           for(j=0;j<samples;j++)
1527             for(i=0;i<channels;i++){
1528               val=vorbis_ftoi(pcm[i][j]*32768.f);
1529               if(val>32767)val=32767;
1530               else if(val<-32768)val=-32768;
1531               val+=off;
1532               *buffer++=(val&0xff);
1533               *buffer++=(val>>8);
1534                 }
1535           vorbis_fpu_restore(fpu);  
1536           
1537         }
1538       }
1539     }
1540     
1541     vorbis_synthesis_read(&vf->vd,samples);
1542     vf->pcm_offset+=samples;
1543     if(bitstream)*bitstream=vf->current_link;
1544     return(samples*bytespersample);
1545   }else{
1546     return(samples);
1547   }
1548 }
1549
1550
1551
1552