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