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