Readded seeking_example.c to the build
[platform/upstream/libvorbis.git] / lib / vorbisfile.c
1 /********************************************************************
2  *                                                                  *
3  * THIS FILE IS PART OF THE Ogg Vorbis SOFTWARE CODEC SOURCE CODE.  *
4  * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
5  * THE GNU PUBLIC LICENSE 2, WHICH IS INCLUDED WITH THIS SOURCE.    *
6  * PLEASE READ THESE TERMS DISTRIBUTING.                            *
7  *                                                                  *
8  * THE OggSQUISH SOURCE CODE IS (C) COPYRIGHT 1994-2000             *
9  * by Monty <monty@xiph.org> and The XIPHOPHORUS Company            *
10  * http://www.xiph.org/                                             *
11  *                                                                  *
12  ********************************************************************
13
14  function: stdio-based convenience library for opening/seeking/decoding
15  last mod: $Id: vorbisfile.c,v 1.30 2000/10/13 19:48:03 xiphmont Exp $
16
17  ********************************************************************/
18
19 #include <stdlib.h>
20 #include <stdio.h>
21 #include <string.h>
22 #include <math.h>
23 #include <assert.h>
24
25 #include "vorbis/codec.h"
26 #include "vorbis/vorbisfile.h"
27
28 #include "os.h"
29 #include "misc.h"
30
31 /* A 'chained bitstream' is a Vorbis bitstream that contains more than
32    one logical bitstream arranged end to end (the only form of Ogg
33    multiplexing allowed in a Vorbis bitstream; grouping [parallel
34    multiplexing] is not allowed in Vorbis) */
35
36 /* A Vorbis file can be played beginning to end (streamed) without
37    worrying ahead of time about chaining (see decoder_example.c).  If
38    we have the whole file, however, and want random access
39    (seeking/scrubbing) or desire to know the total length/time of a
40    file, we need to account for the possibility of chaining. */
41
42 /* We can handle things a number of ways; we can determine the entire
43    bitstream structure right off the bat, or find pieces on demand.
44    This example determines and caches structure for the entire
45    bitstream, but builds a virtual decoder on the fly when moving
46    between links in the chain. */
47
48 /* There are also different ways to implement seeking.  Enough
49    information exists in an Ogg bitstream to seek to
50    sample-granularity positions in the output.  Or, one can seek by
51    picking some portion of the stream roughly in the desired area if
52    we only want course navigation through the stream. */
53
54 /*************************************************************************
55  * Many, many internal helpers.  The intention is not to be confusing; 
56  * rampant duplication and monolithic function implementation would be 
57  * harder to understand anyway.  The high level functions are last.  Begin
58  * grokking near the end of the file */
59
60 /* read a little more data from the file/pipe into the ogg_sync framer */
61 #define CHUNKSIZE 4096
62 static long _get_data(OggVorbis_File *vf){
63   char *buffer=ogg_sync_buffer(&vf->oy,CHUNKSIZE);
64   long bytes=(vf->callbacks.read_func)(buffer,1,CHUNKSIZE,vf->datasource);
65   ogg_sync_wrote(&vf->oy,bytes);
66   return(bytes);
67 }
68
69 /* save a tiny smidge of verbosity to make the code more readable */
70 static void _seek_helper(OggVorbis_File *vf,long offset){
71   (vf->callbacks.seek_func)(vf->datasource, offset, SEEK_SET);
72   vf->offset=offset;
73   ogg_sync_reset(&vf->oy);
74 }
75
76 /* The read/seek functions track absolute position within the stream */
77
78 /* from the head of the stream, get the next page.  boundary specifies
79    if the function is allowed to fetch more data from the stream (and
80    how much) or only use internally buffered data.
81
82    boundary: -1) unbounded search
83               0) read no additional data; use cached only
84               n) search for a new page beginning for n bytes
85
86    return:   -1) did not find a page 
87               n) found a page at absolute offset n */
88
89 static long _get_next_page(OggVorbis_File *vf,ogg_page *og,int boundary){
90   if(boundary>0)boundary+=vf->offset;
91   while(1){
92     long more;
93
94     if(boundary>0 && vf->offset>=boundary)return(-1);
95     more=ogg_sync_pageseek(&vf->oy,og);
96     
97     if(more<0){
98       /* skipped n bytes */
99       vf->offset-=more;
100     }else{
101       if(more==0){
102         /* send more paramedics */
103         if(!boundary)return(-1);
104         if(_get_data(vf)<=0)return(-1);
105       }else{
106         /* got a page.  Return the offset at the page beginning,
107            advance the internal offset past the page end */
108         long ret=vf->offset;
109         vf->offset+=more;
110         return(ret);
111         
112       }
113     }
114   }
115 }
116
117 /* find the latest page beginning before the current stream cursor
118    position. Much dirtier than the above as Ogg doesn't have any
119    backward search linkage.  no 'readp' as it will certainly have to
120    read. */
121 static long _get_prev_page(OggVorbis_File *vf,ogg_page *og){
122   long begin=vf->offset;
123   long ret;
124   int offset=-1;
125
126   while(offset==-1){
127     begin-=CHUNKSIZE;
128     _seek_helper(vf,begin);
129     while(vf->offset<begin+CHUNKSIZE){
130       ret=_get_next_page(vf,og,begin+CHUNKSIZE-vf->offset);
131       if(ret==-1){
132         break;
133       }else{
134         offset=ret;
135       }
136     }
137   }
138
139   /* we have the offset.  Actually snork and hold the page now */
140   _seek_helper(vf,offset);
141   ret=_get_next_page(vf,og,CHUNKSIZE);
142   if(ret==-1){
143     /* this shouldn't be possible */
144     fprintf(stderr,"Missed page fencepost at end of logical bitstream. "
145             "Exiting.\n");
146     exit(1);
147   }
148   return(offset);
149 }
150
151 /* finds each bitstream link one at a time using a bisection search
152    (has to begin by knowing the offset of the lb's initial page).
153    Recurses for each link so it can alloc the link storage after
154    finding them all, then unroll and fill the cache at the same time */
155 static void _bisect_forward_serialno(OggVorbis_File *vf,
156                                      long begin,
157                                      long searched,
158                                      long end,
159                                      long currentno,
160                                      long m){
161   long endsearched=end;
162   long next=end;
163   ogg_page og;
164   long ret;
165   
166   /* the below guards against garbage seperating the last and
167      first pages of two links. */
168   while(searched<endsearched){
169     long bisect;
170     
171     if(endsearched-searched<CHUNKSIZE){
172       bisect=searched;
173     }else{
174       bisect=(searched+endsearched)/2;
175     }
176     
177     _seek_helper(vf,bisect);
178     ret=_get_next_page(vf,&og,-1);
179     if(ret<0 || ogg_page_serialno(&og)!=currentno){
180       endsearched=bisect;
181       if(ret>=0)next=ret;
182     }else{
183       searched=ret+og.header_len+og.body_len;
184     }
185   }
186
187   _seek_helper(vf,next);
188   ret=_get_next_page(vf,&og,-1);
189   
190   if(searched>=end || ret==-1){
191     vf->links=m+1;
192     vf->offsets=malloc((m+2)*sizeof(ogg_int64_t));
193     vf->offsets[m+1]=searched;
194   }else{
195     _bisect_forward_serialno(vf,next,vf->offset,
196                              end,ogg_page_serialno(&og),m+1);
197   }
198   
199   vf->offsets[m]=begin;
200 }
201
202 /* uses the local ogg_stream storage in vf; this is important for
203    non-streaming input sources */
204 static int _fetch_headers(OggVorbis_File *vf,vorbis_info *vi,vorbis_comment *vc,
205                           long *serialno,ogg_page *og_ptr){
206   ogg_page og;
207   ogg_packet op;
208   int i,ret;
209   
210   if(!og_ptr){
211     ret=_get_next_page(vf,&og,CHUNKSIZE);
212     if(ret==-1){
213       fprintf(stderr,"Did not find initial header for bitstream.\n");
214       return -1;
215     }
216     og_ptr=&og;
217   }
218
219   if(serialno)*serialno=ogg_page_serialno(og_ptr);
220   ogg_stream_init(&vf->os,ogg_page_serialno(og_ptr));
221   
222   /* extract the initial header from the first page and verify that the
223      Ogg bitstream is in fact Vorbis data */
224   
225   vorbis_info_init(vi);
226   vorbis_comment_init(vc);
227   
228   i=0;
229   while(i<3){
230     ogg_stream_pagein(&vf->os,og_ptr);
231     while(i<3){
232       int result=ogg_stream_packetout(&vf->os,&op);
233       if(result==0)break;
234       if(result==-1){
235         fprintf(stderr,"Corrupt header in logical bitstream.\n");
236         goto bail_header;
237       }
238       if(vorbis_synthesis_headerin(vi,vc,&op)){
239         fprintf(stderr,"Illegal header in logical bitstream.\n");
240         goto bail_header;
241       }
242       i++;
243     }
244     if(i<3)
245       if(_get_next_page(vf,og_ptr,1)<0){
246         fprintf(stderr,"Missing header in logical bitstream.\n");
247         goto bail_header;
248       }
249   }
250   return 0; 
251
252  bail_header:
253   vorbis_info_clear(vi);
254   vorbis_comment_clear(vc);
255   ogg_stream_clear(&vf->os);
256   return -1;
257 }
258
259 /* last step of the OggVorbis_File initialization; get all the
260    vorbis_info structs and PCM positions.  Only called by the seekable
261    initialization (local stream storage is hacked slightly; pay
262    attention to how that's done) */
263 static void _prefetch_all_headers(OggVorbis_File *vf,vorbis_info *first_i,
264                                   vorbis_comment *first_c,
265                                   long dataoffset){
266   ogg_page og;
267   int i,ret;
268   
269   vf->vi=calloc(vf->links,sizeof(vorbis_info));
270   vf->vc=calloc(vf->links,sizeof(vorbis_info));
271   vf->dataoffsets=malloc(vf->links*sizeof(ogg_int64_t));
272   vf->pcmlengths=malloc(vf->links*sizeof(ogg_int64_t));
273   vf->serialnos=malloc(vf->links*sizeof(long));
274   
275   for(i=0;i<vf->links;i++){
276     if(first_i && first_c && i==0){
277       /* we already grabbed the initial header earlier.  This just
278          saves the waste of grabbing it again */
279       memcpy(vf->vi+i,first_i,sizeof(vorbis_info));
280       memcpy(vf->vc+i,first_c,sizeof(vorbis_comment));
281       vf->dataoffsets[i]=dataoffset;
282     }else{
283
284       /* seek to the location of the initial header */
285
286       _seek_helper(vf,vf->offsets[i]);
287       if(_fetch_headers(vf,vf->vi+i,vf->vc+i,NULL,NULL)==-1){
288         fprintf(stderr,"Error opening logical bitstream #%d.\n\n",i+1);
289         vf->dataoffsets[i]=-1;
290       }else{
291         vf->dataoffsets[i]=vf->offset;
292         ogg_stream_clear(&vf->os);
293       }
294     }
295
296     /* get the serial number and PCM length of this link. To do this,
297        get the last page of the stream */
298     {
299       long end=vf->offsets[i+1];
300       _seek_helper(vf,end);
301
302       while(1){
303         ret=_get_prev_page(vf,&og);
304         if(ret==-1){
305           /* this should not be possible */
306           fprintf(stderr,"Could not find last page of logical "
307                   "bitstream #%d\n\n",i);
308           vorbis_info_clear(vf->vi+i);
309           vorbis_comment_clear(vf->vc+i);
310           break;
311         }
312         if(ogg_page_granulepos(&og)!=-1){
313           vf->serialnos[i]=ogg_page_serialno(&og);
314           vf->pcmlengths[i]=ogg_page_granulepos(&og);
315           break;
316         }
317       }
318     }
319   }
320 }
321
322 static int _make_decode_ready(OggVorbis_File *vf){
323   if(vf->decode_ready)exit(1);
324   if(vf->seekable){
325     vorbis_synthesis_init(&vf->vd,vf->vi+vf->current_link);
326   }else{
327     vorbis_synthesis_init(&vf->vd,vf->vi);
328   }    
329   vorbis_block_init(&vf->vd,&vf->vb);
330   vf->decode_ready=1;
331   return(0);
332 }
333
334 static int _open_seekable(OggVorbis_File *vf){
335   vorbis_info initial_i;
336   vorbis_comment initial_c;
337   long serialno,end;
338   int ret;
339   long dataoffset;
340   ogg_page og;
341   
342   /* is this even vorbis...? */
343   ret=_fetch_headers(vf,&initial_i,&initial_c,&serialno,NULL);
344   dataoffset=vf->offset;
345   ogg_stream_clear(&vf->os);
346   if(ret==-1)return(-1);
347   
348   /* we can seek, so set out learning all about this file */
349   vf->seekable=1;
350   (vf->callbacks.seek_func)(vf->datasource,0,SEEK_END);
351   vf->offset=vf->end=(vf->callbacks.tell_func)(vf->datasource);
352   
353   /* We get the offset for the last page of the physical bitstream.
354      Most OggVorbis files will contain a single logical bitstream */
355   end=_get_prev_page(vf,&og);
356
357   /* moer than one logical bitstream? */
358   if(ogg_page_serialno(&og)!=serialno){
359
360     /* Chained bitstream. Bisect-search each logical bitstream
361        section.  Do so based on serial number only */
362     _bisect_forward_serialno(vf,0,0,end+1,serialno,0);
363
364   }else{
365
366     /* Only one logical bitstream */
367     _bisect_forward_serialno(vf,0,end,end+1,serialno,0);
368
369   }
370
371   _prefetch_all_headers(vf,&initial_i,&initial_c,dataoffset);
372   return(ov_raw_seek(vf,0));
373
374 }
375
376 static int _open_nonseekable(OggVorbis_File *vf){
377   /* we cannot seek. Set up a 'single' (current) logical bitstream entry  */
378   vf->links=1;
379   vf->vi=calloc(vf->links,sizeof(vorbis_info));
380   vf->vc=calloc(vf->links,sizeof(vorbis_info));
381
382   /* Try to fetch the headers, maintaining all the storage */
383   if(_fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno,NULL)==-1)return(-1);
384   _make_decode_ready(vf);
385
386   return 0;
387 }
388
389 /* clear out the current logical bitstream decoder */ 
390 static void _decode_clear(OggVorbis_File *vf){
391   ogg_stream_clear(&vf->os);
392   vorbis_dsp_clear(&vf->vd);
393   vorbis_block_clear(&vf->vb);
394   vf->decode_ready=0;
395
396   vf->bittrack=0.;
397   vf->samptrack=0.;
398 }
399
400 /* fetch and process a packet.  Handles the case where we're at a
401    bitstream boundary and dumps the decoding machine.  If the decoding
402    machine is unloaded, it loads it.  It also keeps pcm_offset up to
403    date (seek and read both use this.  seek uses a special hack with
404    readp). 
405
406    return: -1) hole in the data (lost packet) 
407             0) need more date (only if readp==0)/eof
408             1) got a packet 
409 */
410
411 static int _process_packet(OggVorbis_File *vf,int readp){
412   ogg_page og;
413
414   /* handle one packet.  Try to fetch it from current stream state */
415   /* extract packets from page */
416   while(1){
417     
418     /* process a packet if we can.  If the machine isn't loaded,
419        neither is a page */
420     if(vf->decode_ready){
421       ogg_packet op;
422       int result=ogg_stream_packetout(&vf->os,&op);
423       ogg_int64_t granulepos;
424       
425       /* if(result==-1)return(-1); hole in the data. For now, swallow
426                                    and go. We'll need to add a real
427                                    error code in a bit. */
428       if(result>0){
429         /* got a packet.  process it */
430         granulepos=op.granulepos;
431         if(!vorbis_synthesis(&vf->vb,&op)){ /* lazy check for lazy
432                                                header handling.  The
433                                                header packets aren't
434                                                audio, so if/when we
435                                                submit them,
436                                                vorbis_synthesis will
437                                                reject them */
438
439           /* suck in the synthesis data and track bitrate */
440           {
441             int oldsamples=vorbis_synthesis_pcmout(&vf->vd,NULL);
442             vorbis_synthesis_blockin(&vf->vd,&vf->vb);
443             vf->samptrack+=vorbis_synthesis_pcmout(&vf->vd,NULL)-oldsamples;
444             vf->bittrack+=op.bytes*8;
445           }
446           
447           /* update the pcm offset. */
448           if(granulepos!=-1 && !op.e_o_s){
449             int link=(vf->seekable?vf->current_link:0);
450             int i,samples;
451             
452             /* this packet has a pcm_offset on it (the last packet
453                completed on a page carries the offset) After processing
454                (above), we know the pcm position of the *last* sample
455                ready to be returned. Find the offset of the *first*
456
457                As an aside, this trick is inaccurate if we begin
458                reading anew right at the last page; the end-of-stream
459                granulepos declares the last frame in the stream, and the
460                last packet of the last page may be a partial frame.
461                So, we need a previous granulepos from an in-sequence page
462                to have a reference point.  Thus the !op.e_o_s clause
463                above */
464             
465             samples=vorbis_synthesis_pcmout(&vf->vd,NULL);
466             
467             granulepos-=samples;
468             for(i=0;i<link;i++)
469               granulepos+=vf->pcmlengths[i];
470             vf->pcm_offset=granulepos;
471           }
472           return(1);
473         }
474       }
475     }
476
477     if(!readp)return(0);
478     if(_get_next_page(vf,&og,-1)<0)return(0); /* eof. leave unitialized */
479
480     /* bitrate tracking; add the header's bytes here, the body bytes
481        are done by packet above */
482     vf->bittrack+=og.header_len*8;
483
484     /* has our decoding just traversed a bitstream boundary? */
485     if(vf->decode_ready){
486       if(vf->current_serialno!=ogg_page_serialno(&og)){
487         _decode_clear(vf);
488       }
489     }
490
491     /* Do we need to load a new machine before submitting the page? */
492     /* This is different in the seekable and non-seekable cases.  
493
494        In the seekable case, we already have all the header
495        information loaded and cached; we just initialize the machine
496        with it and continue on our merry way.
497
498        In the non-seekable (streaming) case, we'll only be at a
499        boundary if we just left the previous logical bitstream and
500        we're now nominally at the header of the next bitstream
501     */
502
503     if(!vf->decode_ready){
504       int link;
505       if(vf->seekable){
506         vf->current_serialno=ogg_page_serialno(&og);
507         
508         /* match the serialno to bitstream section.  We use this rather than
509            offset positions to avoid problems near logical bitstream
510            boundaries */
511         for(link=0;link<vf->links;link++)
512           if(vf->serialnos[link]==vf->current_serialno)break;
513         if(link==vf->links)return(-1); /* sign of a bogus stream.  error out,
514                                           leave machine uninitialized */
515         
516         vf->current_link=link;
517
518         ogg_stream_init(&vf->os,vf->current_serialno);
519         ogg_stream_reset(&vf->os); 
520
521       }else{
522         /* we're streaming */
523         /* fetch the three header packets, build the info struct */
524         
525         _fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno,&og);
526         vf->current_link++;
527         link=0;
528       }
529       
530       _make_decode_ready(vf);
531     }
532     ogg_stream_pagein(&vf->os,&og);
533   }
534 }
535
536 /**********************************************************************
537  * The helpers are over; it's all toplevel interface from here on out */
538  
539 /* clear out the OggVorbis_File struct */
540 int ov_clear(OggVorbis_File *vf){
541   if(vf){
542     vorbis_block_clear(&vf->vb);
543     vorbis_dsp_clear(&vf->vd);
544     ogg_stream_clear(&vf->os);
545     
546     if(vf->vi && vf->links){
547       int i;
548       for(i=0;i<vf->links;i++){
549         vorbis_info_clear(vf->vi+i);
550         vorbis_comment_clear(vf->vc+i);
551       }
552       free(vf->vi);
553       free(vf->vc);
554     }
555     if(vf->dataoffsets)free(vf->dataoffsets);
556     if(vf->pcmlengths)free(vf->pcmlengths);
557     if(vf->serialnos)free(vf->serialnos);
558     if(vf->offsets)free(vf->offsets);
559     ogg_sync_clear(&vf->oy);
560     if(vf->datasource)(vf->callbacks.close_func)(vf->datasource);
561     memset(vf,0,sizeof(OggVorbis_File));
562   }
563 #ifdef DEBUG_LEAKS
564   _VDBG_dump();
565 #endif
566   return(0);
567 }
568
569 static int _fseek64_wrap(FILE *f,ogg_int64_t off,int whence){
570   return fseek(f,(int)off,whence);
571 }
572
573 /* inspects the OggVorbis file and finds/documents all the logical
574    bitstreams contained in it.  Tries to be tolerant of logical
575    bitstream sections that are truncated/woogie. 
576
577    return: -1) error
578             0) OK
579 */
580
581 int ov_open(FILE *f,OggVorbis_File *vf,char *initial,long ibytes){
582   ov_callbacks callbacks = {
583     (size_t (*)(void *, size_t, size_t, void *))  fread,
584     (int (*)(void *, ogg_int64_t, int))              _fseek64_wrap,
585     (int (*)(void *))                             fclose,
586     (long (*)(void *))                            ftell
587   };
588
589   return ov_open_callbacks((void *)f, vf, initial, ibytes, callbacks);
590 }
591   
592
593 int ov_open_callbacks(void *f,OggVorbis_File *vf,char *initial,long ibytes,
594     ov_callbacks callbacks)
595 {
596   long offset=callbacks.seek_func(f,0,SEEK_CUR);
597   int ret;
598
599   memset(vf,0,sizeof(OggVorbis_File));
600   vf->datasource=f;
601   vf->callbacks = callbacks;
602
603   /* init the framing state */
604   ogg_sync_init(&vf->oy);
605
606   /* perhaps some data was previously read into a buffer for testing
607      against other stream types.  Allow initialization from this
608      previously read data (as we may be reading from a non-seekable
609      stream) */
610   if(initial){
611     char *buffer=ogg_sync_buffer(&vf->oy,ibytes);
612     memcpy(buffer,initial,ibytes);
613     ogg_sync_wrote(&vf->oy,ibytes);
614   }
615
616   /* can we seek? Stevens suggests the seek test was portable */
617   if(offset!=-1){
618     ret=_open_seekable(vf);
619   }else{
620     ret=_open_nonseekable(vf);
621   }
622   if(ret){
623     vf->datasource=NULL;
624     ov_clear(vf);
625   }
626   return(ret);
627 }
628
629 /* How many logical bitstreams in this physical bitstream? */
630 long ov_streams(OggVorbis_File *vf){
631   return vf->links;
632 }
633
634 /* Is the FILE * associated with vf seekable? */
635 long ov_seekable(OggVorbis_File *vf){
636   return vf->seekable;
637 }
638
639 /* returns the bitrate for a given logical bitstream or the entire
640    physical bitstream.  If the file is open for random access, it will
641    find the *actual* average bitrate.  If the file is streaming, it
642    returns the nominal bitrate (if set) else the average of the
643    upper/lower bounds (if set) else -1 (unset).
644
645    If you want the actual bitrate field settings, get them from the
646    vorbis_info structs */
647
648 long ov_bitrate(OggVorbis_File *vf,int i){
649   if(i>=vf->links)return(-1);
650   if(!vf->seekable && i!=0)return(ov_bitrate(vf,0));
651   if(i<0){
652     ogg_int64_t bits=0;
653     int i;
654     for(i=0;i<vf->links;i++)
655       bits+=(vf->offsets[i+1]-vf->dataoffsets[i])*8;
656     return(rint(bits/ov_time_total(vf,-1)));
657   }else{
658     if(vf->seekable){
659       /* return the actual bitrate */
660       return(rint((vf->offsets[i+1]-vf->dataoffsets[i])*8/ov_time_total(vf,i)));
661     }else{
662       /* return nominal if set */
663       if(vf->vi[i].bitrate_nominal>0){
664         return vf->vi[i].bitrate_nominal;
665       }else{
666         if(vf->vi[i].bitrate_upper>0){
667           if(vf->vi[i].bitrate_lower>0){
668             return (vf->vi[i].bitrate_upper+vf->vi[i].bitrate_lower)/2;
669           }else{
670             return vf->vi[i].bitrate_upper;
671           }
672         }
673         return(-1);
674       }
675     }
676   }
677 }
678
679 /* returns the actual bitrate since last call.  returns -1 if no
680    additional data to offer since last call (or at beginning of stream) */
681 long ov_bitrate_instant(OggVorbis_File *vf){
682   int link=(vf->seekable?vf->current_link:0);
683   long ret;
684   if(vf->samptrack==0)return(-1);
685   ret=vf->bittrack/vf->samptrack*vf->vi[link].rate+.5;
686   vf->bittrack=0.;
687   vf->samptrack=0.;
688   return(ret);
689 }
690
691 /* Guess */
692 long ov_serialnumber(OggVorbis_File *vf,int i){
693   if(i>=vf->links)return(-1);
694   if(!vf->seekable && i>=0)return(ov_serialnumber(vf,-1));
695   if(i<0){
696     return(vf->current_serialno);
697   }else{
698     return(vf->serialnos[i]);
699   }
700 }
701
702 /* returns: total raw (compressed) length of content if i==-1
703             raw (compressed) length of that logical bitstream for i==0 to n
704             -1 if the stream is not seekable (we can't know the length)
705 */
706 ogg_int64_t ov_raw_total(OggVorbis_File *vf,int i){
707   if(!vf->seekable || i>=vf->links)return(-1);
708   if(i<0){
709     long acc=0;
710     int i;
711     for(i=0;i<vf->links;i++)
712       acc+=ov_raw_total(vf,i);
713     return(acc);
714   }else{
715     return(vf->offsets[i+1]-vf->offsets[i]);
716   }
717 }
718
719 /* returns: total PCM length (samples) of content if i==-1
720             PCM length (samples) of that logical bitstream for i==0 to n
721             -1 if the stream is not seekable (we can't know the length)
722 */
723 ogg_int64_t ov_pcm_total(OggVorbis_File *vf,int i){
724   if(!vf->seekable || i>=vf->links)return(-1);
725   if(i<0){
726     ogg_int64_t acc=0;
727     int i;
728     for(i=0;i<vf->links;i++)
729       acc+=ov_pcm_total(vf,i);
730     return(acc);
731   }else{
732     return(vf->pcmlengths[i]);
733   }
734 }
735
736 /* returns: total seconds of content if i==-1
737             seconds in that logical bitstream for i==0 to n
738             -1 if the stream is not seekable (we can't know the length)
739 */
740 double ov_time_total(OggVorbis_File *vf,int i){
741   if(!vf->seekable || i>=vf->links)return(-1);
742   if(i<0){
743     double acc=0;
744     int i;
745     for(i=0;i<vf->links;i++)
746       acc+=ov_time_total(vf,i);
747     return(acc);
748   }else{
749     return((float)(vf->pcmlengths[i])/vf->vi[i].rate);
750   }
751 }
752
753 /* seek to an offset relative to the *compressed* data. This also
754    immediately sucks in and decodes pages to update the PCM cursor. It
755    will cross a logical bitstream boundary, but only if it can't get
756    any packets out of the tail of the bitstream we seek to (so no
757    surprises). 
758
759    returns zero on success, nonzero on failure */
760
761 int ov_raw_seek(OggVorbis_File *vf,long pos){
762
763   if(!vf->seekable)return(-1); /* don't dump machine if we can't seek */
764   if(pos<0 || pos>vf->offsets[vf->links])goto seek_error;
765
766   /* clear out decoding machine state */
767   vf->pcm_offset=-1;
768   _decode_clear(vf);
769
770   /* seek */
771   _seek_helper(vf,pos);
772
773   /* we need to make sure the pcm_offset is set.  We use the
774      _fetch_packet helper to process one packet with readp set, then
775      call it until it returns '0' with readp not set (the last packet
776      from a page has the 'granulepos' field set, and that's how the
777      helper updates the offset */
778
779   switch(_process_packet(vf,1)){
780   case 0:
781     /* oh, eof. There are no packets remaining.  Set the pcm offset to
782        the end of file */
783     vf->pcm_offset=ov_pcm_total(vf,-1);
784     return(0);
785   case -1:
786     /* error! missing data or invalid bitstream structure */
787     goto seek_error;
788   default:
789     /* all OK */
790     break;
791   }
792
793   while(1){
794     switch(_process_packet(vf,0)){
795     case 0:
796       /* the offset is set.  If it's a bogus bitstream with no offset
797          information, it's not but that's not our fault.  We still run
798          gracefully, we're just missing the offset */
799       return(0);
800     case -1:
801       /* error! missing data or invalid bitstream structure */
802       goto seek_error;
803     default:
804       /* continue processing packets */
805       break;
806     }
807   }
808   
809  seek_error:
810   /* dump the machine so we're in a known state */
811   vf->pcm_offset=-1;
812   _decode_clear(vf);
813   return -1;
814 }
815
816 /* Page granularity seek (faster than sample granularity because we
817    don't do the last bit of decode to find a specific sample).
818
819    Seek to the last [granule marked] page preceeding the specified pos
820    location, such that decoding past the returned point will quickly
821    arrive at the requested position. */
822 int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos){
823   int link=-1;
824   ogg_int64_t total=ov_pcm_total(vf,-1);
825
826   if(!vf->seekable)return(-1); /* don't dump machine if we can't seek */  
827   if(pos<0 || pos>total)goto seek_error;
828
829   /* which bitstream section does this pcm offset occur in? */
830   for(link=vf->links-1;link>=0;link--){
831     total-=vf->pcmlengths[link];
832     if(pos>=total)break;
833   }
834
835   /* search within the logical bitstream for the page with the highest
836      pcm_pos preceeding (or equal to) pos.  There is a danger here;
837      missing pages or incorrect frame number information in the
838      bitstream could make our task impossible.  Account for that (it
839      would be an error condition) */
840   {
841     ogg_int64_t target=pos-total;
842     long end=vf->offsets[link+1];
843     long begin=vf->offsets[link];
844     long best=begin;
845
846     ogg_page og;
847     while(begin<end){
848       long bisect;
849       long ret;
850     
851       if(end-begin<CHUNKSIZE){
852         bisect=begin;
853       }else{
854         bisect=(end+begin)/2;
855       }
856     
857       _seek_helper(vf,bisect);
858       ret=_get_next_page(vf,&og,end-bisect);
859       
860       if(ret==-1){
861         end=bisect;
862       }else{
863         ogg_int64_t granulepos=ogg_page_granulepos(&og);
864         if(granulepos<target){
865           best=ret;  /* raw offset of packet with granulepos */ 
866           begin=vf->offset; /* raw offset of next packet */
867         }else{
868           end=bisect;
869         }
870       }
871     }
872
873     /* found our page. seek to it (call raw_seek). */
874     
875     if(ov_raw_seek(vf,best))goto seek_error;
876   }
877
878   /* verify result */
879   if(vf->pcm_offset>=pos)goto seek_error;
880   if(pos>ov_pcm_total(vf,-1))goto seek_error;
881   return(0);
882
883  seek_error:
884   /* dump machine so we're in a known state */
885   vf->pcm_offset=-1;
886   _decode_clear(vf);
887   return -1;
888 }
889
890 /* seek to a sample offset relative to the decompressed pcm stream 
891    returns zero on success, nonzero on failure */
892
893 int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos){
894   if(ov_pcm_seek_page(vf,pos))return(-1);
895
896   /* discard samples until we reach the desired position. Crossing a
897      logical bitstream boundary with abandon is OK. */
898   while(vf->pcm_offset<pos){
899     float **pcm;
900     long target=pos-vf->pcm_offset;
901     long samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
902
903     if(samples>target)samples=target;
904     vorbis_synthesis_read(&vf->vd,samples);
905     vf->pcm_offset+=samples;
906     
907     if(samples<target)
908       if(_process_packet(vf,1)==0)
909         vf->pcm_offset=ov_pcm_total(vf,-1); /* eof */
910   }
911   return 0;
912 }
913
914 /* seek to a playback time relative to the decompressed pcm stream 
915    returns zero on success, nonzero on failure */
916 int ov_time_seek(OggVorbis_File *vf,double seconds){
917   /* translate time to PCM position and call ov_pcm_seek */
918
919   int link=-1;
920   ogg_int64_t pcm_total=ov_pcm_total(vf,-1);
921   double time_total=ov_time_total(vf,-1);
922
923   if(!vf->seekable)return(-1); /* don't dump machine if we can't seek */  
924   if(seconds<0 || seconds>time_total)goto seek_error;
925   
926   /* which bitstream section does this time offset occur in? */
927   for(link=vf->links-1;link>=0;link--){
928     pcm_total-=vf->pcmlengths[link];
929     time_total-=ov_time_total(vf,link);
930     if(seconds>=time_total)break;
931   }
932
933   /* enough information to convert time offset to pcm offset */
934   {
935     ogg_int64_t target=pcm_total+(seconds-time_total)*vf->vi[link].rate;
936     return(ov_pcm_seek(vf,target));
937   }
938
939  seek_error:
940   /* dump machine so we're in a known state */
941   vf->pcm_offset=-1;
942   _decode_clear(vf);
943   return -1;
944 }
945
946 /* page-granularity version of ov_time_seek 
947    returns zero on success, nonzero on failure */
948 int ov_time_seek_page(OggVorbis_File *vf,double seconds){
949   /* translate time to PCM position and call ov_pcm_seek */
950
951   int link=-1;
952   ogg_int64_t pcm_total=ov_pcm_total(vf,-1);
953   double time_total=ov_time_total(vf,-1);
954
955   if(!vf->seekable)return(-1); /* don't dump machine if we can't seek */  
956   if(seconds<0 || seconds>time_total)goto seek_error;
957   
958   /* which bitstream section does this time offset occur in? */
959   for(link=vf->links-1;link>=0;link--){
960     pcm_total-=vf->pcmlengths[link];
961     time_total-=ov_time_total(vf,link);
962     if(seconds>=time_total)break;
963   }
964
965   /* enough information to convert time offset to pcm offset */
966   {
967     ogg_int64_t target=pcm_total+(seconds-time_total)*vf->vi[link].rate;
968     return(ov_pcm_seek_page(vf,target));
969   }
970
971  seek_error:
972   /* dump machine so we're in a known state */
973   vf->pcm_offset=-1;
974   _decode_clear(vf);
975   return -1;
976 }
977
978 /* tell the current stream offset cursor.  Note that seek followed by
979    tell will likely not give the set offset due to caching */
980 ogg_int64_t ov_raw_tell(OggVorbis_File *vf){
981   return(vf->offset);
982 }
983
984 /* return PCM offset (sample) of next PCM sample to be read */
985 ogg_int64_t ov_pcm_tell(OggVorbis_File *vf){
986   return(vf->pcm_offset);
987 }
988
989 /* return time offset (seconds) of next PCM sample to be read */
990 double ov_time_tell(OggVorbis_File *vf){
991   /* translate time to PCM position and call ov_pcm_seek */
992
993   int link=-1;
994   ogg_int64_t pcm_total=0;
995   double time_total=0.;
996   
997   if(vf->seekable){
998     pcm_total=ov_pcm_total(vf,-1);
999     time_total=ov_time_total(vf,-1);
1000   
1001     /* which bitstream section does this time offset occur in? */
1002     for(link=vf->links-1;link>=0;link--){
1003       pcm_total-=vf->pcmlengths[link];
1004       time_total-=ov_time_total(vf,link);
1005       if(vf->pcm_offset>=pcm_total)break;
1006     }
1007   }
1008
1009   return((double)time_total+(double)(vf->pcm_offset-pcm_total)/vf->vi[link].rate);
1010 }
1011
1012 /*  link:   -1) return the vorbis_info struct for the bitstream section
1013                 currently being decoded
1014            0-n) to request information for a specific bitstream section
1015     
1016     In the case of a non-seekable bitstream, any call returns the
1017     current bitstream.  NULL in the case that the machine is not
1018     initialized */
1019
1020 vorbis_info *ov_info(OggVorbis_File *vf,int link){
1021   if(vf->seekable){
1022     if(link<0)
1023       if(vf->decode_ready)
1024         return vf->vi+vf->current_link;
1025       else
1026         return NULL;
1027     else
1028       if(link>=vf->links)
1029         return NULL;
1030       else
1031         return vf->vi+link;
1032   }else{
1033     if(vf->decode_ready)
1034       return vf->vi;
1035     else
1036       return NULL;
1037   }
1038 }
1039
1040 /* grr, strong typing, grr, no templates/inheritence, grr */
1041 vorbis_comment *ov_comment(OggVorbis_File *vf,int link){
1042   if(vf->seekable){
1043     if(link<0)
1044       if(vf->decode_ready)
1045         return vf->vc+vf->current_link;
1046       else
1047         return NULL;
1048     else
1049       if(link>=vf->links)
1050         return NULL;
1051       else
1052         return vf->vc+link;
1053   }else{
1054     if(vf->decode_ready)
1055       return vf->vc;
1056     else
1057       return NULL;
1058   }
1059 }
1060
1061 int host_is_big_endian() {
1062   short pattern = 0xbabe;
1063   unsigned char *bytewise = (unsigned char *)&pattern;
1064   if (bytewise[0] == 0xba) return 1;
1065
1066   assert(bytewise[0] == 0xbe);
1067   return 0;
1068 }
1069
1070 /* up to this point, everything could more or less hide the multiple
1071    logical bitstream nature of chaining from the toplevel application
1072    if the toplevel application didn't particularly care.  However, at
1073    the point that we actually read audio back, the multiple-section
1074    nature must surface: Multiple bitstream sections do not necessarily
1075    have to have the same number of channels or sampling rate.
1076
1077    ov_read returns the sequential logical bitstream number currently
1078    being decoded along with the PCM data in order that the toplevel
1079    application can take action on channel/sample rate changes.  This
1080    number will be incremented even for streamed (non-seekable) streams
1081    (for seekable streams, it represents the actual logical bitstream
1082    index within the physical bitstream.  Note that the accessor
1083    functions above are aware of this dichotomy).
1084
1085    input values: buffer) a buffer to hold packed PCM data for return
1086                  length) the byte length requested to be placed into buffer
1087                  bigendianp) should the data be packed LSB first (0) or
1088                              MSB first (1)
1089                  word) word size for output.  currently 1 (byte) or 
1090                        2 (16 bit short)
1091
1092    return values: -1) error/hole in data
1093                    0) EOF
1094                    n) number of bytes of PCM actually returned.  The
1095                    below works on a packet-by-packet basis, so the
1096                    return length is not related to the 'length' passed
1097                    in, just guaranteed to fit.
1098
1099             *section) set to the logical bitstream number */
1100
1101 long ov_read(OggVorbis_File *vf,char *buffer,int length,
1102                     int bigendianp,int word,int sgned,int *bitstream){
1103   int i,j;
1104   int host_endian = host_is_big_endian();
1105
1106   while(1){
1107     if(vf->decode_ready){
1108       float **pcm;
1109       long samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
1110       if(samples){
1111         /* yay! proceed to pack data into the byte buffer */
1112
1113         long channels=ov_info(vf,-1)->channels;
1114         long bytespersample=word * channels;
1115         if(samples>length/bytespersample)samples=length/bytespersample;
1116         
1117         /* a tight loop to pack each size */
1118         {
1119           int val;
1120           if(word==1){
1121             int off=(sgned?0:128);
1122             for(j=0;j<samples;j++)
1123               for(i=0;i<channels;i++){
1124                 val=(int)(pcm[i][j]*128. + 0.5);
1125                 if(val>127)val=127;
1126                 else if(val<-128)val=-128;
1127                 *buffer++=val+off;
1128               }
1129           }else{
1130             int off=(sgned?0:32768);
1131
1132             if(host_endian==bigendianp){
1133               if(sgned){
1134                 for(i=0;i<channels;i++) { /* It's faster in this order */
1135                   float *src=pcm[i];
1136                   short *dest=((short *)buffer)+i;
1137                   for(j=0;j<samples;j++) {
1138                     val=(int)(src[j]*32768. + 0.5);
1139                     if(val>32767)val=32767;
1140                     else if(val<-32768)val=-32768;
1141                     *dest=val;
1142                     dest+=channels;
1143                   }
1144                 }
1145               }else{
1146                 for(i=0;i<channels;i++) {
1147                   float *src=pcm[i];
1148                   short *dest=((short *)buffer)+i;
1149                   for(j=0;j<samples;j++) {
1150                     val=(int)(src[j]*32768. + 0.5);
1151                     if(val>32767)val=32767;
1152                     else if(val<-32768)val=-32768;
1153                     *dest=val+off;
1154                     dest+=channels;
1155                   }
1156                 }
1157               }
1158             }else if(bigendianp){
1159               for(j=0;j<samples;j++)
1160                 for(i=0;i<channels;i++){
1161                   val=(int)(pcm[i][j]*32768. + 0.5);
1162                   if(val>32767)val=32767;
1163                   else if(val<-32768)val=-32768;
1164                   val+=off;
1165                   *buffer++=(val>>8);
1166                   *buffer++=(val&0xff);
1167                 }
1168             }else{
1169               int val;
1170               for(j=0;j<samples;j++)
1171                 for(i=0;i<channels;i++){
1172                   val=(int)(pcm[i][j]*32768. + 0.5);
1173                   if(val>32767)val=32767;
1174                   else if(val<-32768)val=-32768;
1175                   val+=off;
1176                   *buffer++=(val&0xff);
1177                   *buffer++=(val>>8);
1178                 }
1179
1180             }
1181           }
1182         }
1183         
1184         vorbis_synthesis_read(&vf->vd,samples);
1185         vf->pcm_offset+=samples;
1186         if(bitstream)*bitstream=vf->current_link;
1187         return(samples*bytespersample);
1188       }
1189     }
1190
1191     /* suck in another packet */
1192     switch(_process_packet(vf,1)){
1193     case 0:
1194       return(0);
1195     case -1:
1196       return -1;
1197     default:
1198       break;
1199     }
1200   }
1201 }
1202
1203
1204
1205