Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/thirdparty/libvorbis/block.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: PCM data vector blocking, windowing and dis/reassembly
14
15
Handle windowing, overlap-add, etc of the PCM vectors. This is made
16
more amusing by Vorbis' current two allowed block sizes.
17
18
********************************************************************/
19
20
#include <stdio.h>
21
#include <stdlib.h>
22
#include <string.h>
23
#include <ogg/ogg.h>
24
#include "vorbis/codec.h"
25
#include "codec_internal.h"
26
27
#include "window.h"
28
#include "mdct.h"
29
#include "lpc.h"
30
#include "registry.h"
31
#include "misc.h"
32
33
/* pcm accumulator examples (not exhaustive):
34
35
<-------------- lW ---------------->
36
<--------------- W ---------------->
37
: .....|..... _______________ |
38
: .''' | '''_--- | |\ |
39
:.....''' |_____--- '''......| | \_______|
40
:.................|__________________|_______|__|______|
41
|<------ Sl ------>| > Sr < |endW
42
|beginSl |endSl | |endSr
43
|beginW |endlW |beginSr
44
45
46
|< lW >|
47
<--------------- W ---------------->
48
| | .. ______________ |
49
| | ' `/ | ---_ |
50
|___.'___/`. | ---_____|
51
|_______|__|_______|_________________|
52
| >|Sl|< |<------ Sr ----->|endW
53
| | |endSl |beginSr |endSr
54
|beginW | |endlW
55
mult[0] |beginSl mult[n]
56
57
<-------------- lW ----------------->
58
|<--W-->|
59
: .............. ___ | |
60
: .''' |`/ \ | |
61
:.....''' |/`....\|...|
62
:.........................|___|___|___|
63
|Sl |Sr |endW
64
| | |endSr
65
| |beginSr
66
| |endSl
67
|beginSl
68
|beginW
69
*/
70
71
/* block abstraction setup *********************************************/
72
73
#ifndef WORD_ALIGN
74
#define WORD_ALIGN 8
75
#endif
76
77
int vorbis_block_init(vorbis_dsp_state *v, vorbis_block *vb){
78
int i;
79
memset(vb,0,sizeof(*vb));
80
vb->vd=v;
81
vb->localalloc=0;
82
vb->localstore=NULL;
83
if(v->analysisp){
84
vorbis_block_internal *vbi=
85
vb->internal=_ogg_calloc(1,sizeof(vorbis_block_internal));
86
vbi->ampmax=-9999;
87
88
for(i=0;i<PACKETBLOBS;i++){
89
if(i==PACKETBLOBS/2){
90
vbi->packetblob[i]=&vb->opb;
91
}else{
92
vbi->packetblob[i]=
93
_ogg_calloc(1,sizeof(oggpack_buffer));
94
}
95
oggpack_writeinit(vbi->packetblob[i]);
96
}
97
}
98
99
return(0);
100
}
101
102
void *_vorbis_block_alloc(vorbis_block *vb,long bytes){
103
bytes=(bytes+(WORD_ALIGN-1)) & ~(WORD_ALIGN-1);
104
if(bytes+vb->localtop>vb->localalloc){
105
/* can't just _ogg_realloc... there are outstanding pointers */
106
if(vb->localstore){
107
struct alloc_chain *link=_ogg_malloc(sizeof(*link));
108
vb->totaluse+=vb->localtop;
109
link->next=vb->reap;
110
link->ptr=vb->localstore;
111
vb->reap=link;
112
}
113
/* highly conservative */
114
vb->localalloc=bytes;
115
vb->localstore=_ogg_malloc(vb->localalloc);
116
vb->localtop=0;
117
}
118
{
119
void *ret=(void *)(((char *)vb->localstore)+vb->localtop);
120
vb->localtop+=bytes;
121
return ret;
122
}
123
}
124
125
/* reap the chain, pull the ripcord */
126
void _vorbis_block_ripcord(vorbis_block *vb){
127
/* reap the chain */
128
struct alloc_chain *reap=vb->reap;
129
while(reap){
130
struct alloc_chain *next=reap->next;
131
_ogg_free(reap->ptr);
132
memset(reap,0,sizeof(*reap));
133
_ogg_free(reap);
134
reap=next;
135
}
136
/* consolidate storage */
137
if(vb->totaluse){
138
vb->localstore=_ogg_realloc(vb->localstore,vb->totaluse+vb->localalloc);
139
vb->localalloc+=vb->totaluse;
140
vb->totaluse=0;
141
}
142
143
/* pull the ripcord */
144
vb->localtop=0;
145
vb->reap=NULL;
146
}
147
148
int vorbis_block_clear(vorbis_block *vb){
149
int i;
150
vorbis_block_internal *vbi=vb->internal;
151
152
_vorbis_block_ripcord(vb);
153
if(vb->localstore)_ogg_free(vb->localstore);
154
155
if(vbi){
156
for(i=0;i<PACKETBLOBS;i++){
157
oggpack_writeclear(vbi->packetblob[i]);
158
if(i!=PACKETBLOBS/2)_ogg_free(vbi->packetblob[i]);
159
}
160
_ogg_free(vbi);
161
}
162
memset(vb,0,sizeof(*vb));
163
return(0);
164
}
165
166
/* Analysis side code, but directly related to blocking. Thus it's
167
here and not in analysis.c (which is for analysis transforms only).
168
The init is here because some of it is shared */
169
170
static int _vds_shared_init(vorbis_dsp_state *v,vorbis_info *vi,int encp){
171
int i;
172
codec_setup_info *ci=vi->codec_setup;
173
private_state *b=NULL;
174
int hs;
175
176
if(ci==NULL||
177
ci->modes<=0||
178
ci->blocksizes[0]<64||
179
ci->blocksizes[1]<ci->blocksizes[0]){
180
return 1;
181
}
182
hs=ci->halfrate_flag;
183
184
memset(v,0,sizeof(*v));
185
b=v->backend_state=_ogg_calloc(1,sizeof(*b));
186
187
v->vi=vi;
188
b->modebits=ov_ilog(ci->modes-1);
189
190
b->transform[0]=_ogg_calloc(VI_TRANSFORMB,sizeof(*b->transform[0]));
191
b->transform[1]=_ogg_calloc(VI_TRANSFORMB,sizeof(*b->transform[1]));
192
193
/* MDCT is tranform 0 */
194
195
b->transform[0][0]=_ogg_calloc(1,sizeof(mdct_lookup));
196
b->transform[1][0]=_ogg_calloc(1,sizeof(mdct_lookup));
197
mdct_init(b->transform[0][0],ci->blocksizes[0]>>hs);
198
mdct_init(b->transform[1][0],ci->blocksizes[1]>>hs);
199
200
/* Vorbis I uses only window type 0 */
201
/* note that the correct computation below is technically:
202
b->window[0]=ov_ilog(ci->blocksizes[0]-1)-6;
203
b->window[1]=ov_ilog(ci->blocksizes[1]-1)-6;
204
but since blocksizes are always powers of two,
205
the below is equivalent.
206
*/
207
b->window[0]=ov_ilog(ci->blocksizes[0])-7;
208
b->window[1]=ov_ilog(ci->blocksizes[1])-7;
209
210
if(encp){ /* encode/decode differ here */
211
212
/* analysis always needs an fft */
213
drft_init(&b->fft_look[0],ci->blocksizes[0]);
214
drft_init(&b->fft_look[1],ci->blocksizes[1]);
215
216
/* finish the codebooks */
217
if(!ci->fullbooks){
218
ci->fullbooks=_ogg_calloc(ci->books,sizeof(*ci->fullbooks));
219
for(i=0;i<ci->books;i++)
220
vorbis_book_init_encode(ci->fullbooks+i,ci->book_param[i]);
221
}
222
223
b->psy=_ogg_calloc(ci->psys,sizeof(*b->psy));
224
for(i=0;i<ci->psys;i++){
225
_vp_psy_init(b->psy+i,
226
ci->psy_param[i],
227
&ci->psy_g_param,
228
ci->blocksizes[ci->psy_param[i]->blockflag]/2,
229
vi->rate);
230
}
231
232
v->analysisp=1;
233
}else{
234
/* finish the codebooks */
235
if(!ci->fullbooks){
236
ci->fullbooks=_ogg_calloc(ci->books,sizeof(*ci->fullbooks));
237
for(i=0;i<ci->books;i++){
238
if(ci->book_param[i]==NULL)
239
goto abort_books;
240
if(vorbis_book_init_decode(ci->fullbooks+i,ci->book_param[i]))
241
goto abort_books;
242
/* decode codebooks are now standalone after init */
243
vorbis_staticbook_destroy(ci->book_param[i]);
244
ci->book_param[i]=NULL;
245
}
246
}
247
}
248
249
/* initialize the storage vectors. blocksize[1] is small for encode,
250
but the correct size for decode */
251
v->pcm_storage=ci->blocksizes[1];
252
v->pcm=_ogg_malloc(vi->channels*sizeof(*v->pcm));
253
v->pcmret=_ogg_malloc(vi->channels*sizeof(*v->pcmret));
254
{
255
int i;
256
for(i=0;i<vi->channels;i++)
257
v->pcm[i]=_ogg_calloc(v->pcm_storage,sizeof(*v->pcm[i]));
258
}
259
260
/* all 1 (large block) or 0 (small block) */
261
/* explicitly set for the sake of clarity */
262
v->lW=0; /* previous window size */
263
v->W=0; /* current window size */
264
265
/* all vector indexes */
266
v->centerW=ci->blocksizes[1]/2;
267
268
v->pcm_current=v->centerW;
269
270
/* initialize all the backend lookups */
271
b->flr=_ogg_calloc(ci->floors,sizeof(*b->flr));
272
b->residue=_ogg_calloc(ci->residues,sizeof(*b->residue));
273
274
for(i=0;i<ci->floors;i++)
275
b->flr[i]=_floor_P[ci->floor_type[i]]->
276
look(v,ci->floor_param[i]);
277
278
for(i=0;i<ci->residues;i++)
279
b->residue[i]=_residue_P[ci->residue_type[i]]->
280
look(v,ci->residue_param[i]);
281
282
return 0;
283
abort_books:
284
for(i=0;i<ci->books;i++){
285
if(ci->book_param[i]!=NULL){
286
vorbis_staticbook_destroy(ci->book_param[i]);
287
ci->book_param[i]=NULL;
288
}
289
}
290
vorbis_dsp_clear(v);
291
return -1;
292
}
293
294
/* arbitrary settings and spec-mandated numbers get filled in here */
295
int vorbis_analysis_init(vorbis_dsp_state *v,vorbis_info *vi){
296
private_state *b=NULL;
297
298
if(_vds_shared_init(v,vi,1))return 1;
299
b=v->backend_state;
300
b->psy_g_look=_vp_global_look(vi);
301
302
/* Initialize the envelope state storage */
303
b->ve=_ogg_calloc(1,sizeof(*b->ve));
304
_ve_envelope_init(b->ve,vi);
305
306
vorbis_bitrate_init(vi,&b->bms);
307
308
/* compressed audio packets start after the headers
309
with sequence number 3 */
310
v->sequence=3;
311
312
return(0);
313
}
314
315
void vorbis_dsp_clear(vorbis_dsp_state *v){
316
int i;
317
if(v){
318
vorbis_info *vi=v->vi;
319
codec_setup_info *ci=(vi?vi->codec_setup:NULL);
320
private_state *b=v->backend_state;
321
322
if(b){
323
324
if(b->ve){
325
_ve_envelope_clear(b->ve);
326
_ogg_free(b->ve);
327
}
328
329
if(b->transform[0]){
330
mdct_clear(b->transform[0][0]);
331
_ogg_free(b->transform[0][0]);
332
_ogg_free(b->transform[0]);
333
}
334
if(b->transform[1]){
335
mdct_clear(b->transform[1][0]);
336
_ogg_free(b->transform[1][0]);
337
_ogg_free(b->transform[1]);
338
}
339
340
if(b->flr){
341
if(ci)
342
for(i=0;i<ci->floors;i++)
343
_floor_P[ci->floor_type[i]]->
344
free_look(b->flr[i]);
345
_ogg_free(b->flr);
346
}
347
if(b->residue){
348
if(ci)
349
for(i=0;i<ci->residues;i++)
350
_residue_P[ci->residue_type[i]]->
351
free_look(b->residue[i]);
352
_ogg_free(b->residue);
353
}
354
if(b->psy){
355
if(ci)
356
for(i=0;i<ci->psys;i++)
357
_vp_psy_clear(b->psy+i);
358
_ogg_free(b->psy);
359
}
360
361
if(b->psy_g_look)_vp_global_free(b->psy_g_look);
362
vorbis_bitrate_clear(&b->bms);
363
364
drft_clear(&b->fft_look[0]);
365
drft_clear(&b->fft_look[1]);
366
367
}
368
369
if(v->pcm){
370
if(vi)
371
for(i=0;i<vi->channels;i++)
372
if(v->pcm[i])_ogg_free(v->pcm[i]);
373
_ogg_free(v->pcm);
374
if(v->pcmret)_ogg_free(v->pcmret);
375
}
376
377
if(b){
378
/* free header, header1, header2 */
379
if(b->header)_ogg_free(b->header);
380
if(b->header1)_ogg_free(b->header1);
381
if(b->header2)_ogg_free(b->header2);
382
_ogg_free(b);
383
}
384
385
memset(v,0,sizeof(*v));
386
}
387
}
388
389
float **vorbis_analysis_buffer(vorbis_dsp_state *v, int vals){
390
int i;
391
vorbis_info *vi=v->vi;
392
private_state *b=v->backend_state;
393
394
/* free header, header1, header2 */
395
if(b->header)_ogg_free(b->header);b->header=NULL;
396
if(b->header1)_ogg_free(b->header1);b->header1=NULL;
397
if(b->header2)_ogg_free(b->header2);b->header2=NULL;
398
399
/* Do we have enough storage space for the requested buffer? If not,
400
expand the PCM (and envelope) storage */
401
402
if(v->pcm_current+vals>=v->pcm_storage){
403
v->pcm_storage=v->pcm_current+vals*2;
404
405
for(i=0;i<vi->channels;i++){
406
v->pcm[i]=_ogg_realloc(v->pcm[i],v->pcm_storage*sizeof(*v->pcm[i]));
407
}
408
}
409
410
for(i=0;i<vi->channels;i++)
411
v->pcmret[i]=v->pcm[i]+v->pcm_current;
412
413
return(v->pcmret);
414
}
415
416
static void _preextrapolate_helper(vorbis_dsp_state *v){
417
int i;
418
int order=16;
419
float *lpc=alloca(order*sizeof(*lpc));
420
float *work=alloca(v->pcm_current*sizeof(*work));
421
long j;
422
v->preextrapolate=1;
423
424
if(v->pcm_current-v->centerW>order*2){ /* safety */
425
for(i=0;i<v->vi->channels;i++){
426
/* need to run the extrapolation in reverse! */
427
for(j=0;j<v->pcm_current;j++)
428
work[j]=v->pcm[i][v->pcm_current-j-1];
429
430
/* prime as above */
431
vorbis_lpc_from_data(work,lpc,v->pcm_current-v->centerW,order);
432
433
#if 0
434
if(v->vi->channels==2){
435
if(i==0)
436
_analysis_output("predataL",0,work,v->pcm_current-v->centerW,0,0,0);
437
else
438
_analysis_output("predataR",0,work,v->pcm_current-v->centerW,0,0,0);
439
}else{
440
_analysis_output("predata",0,work,v->pcm_current-v->centerW,0,0,0);
441
}
442
#endif
443
444
/* run the predictor filter */
445
vorbis_lpc_predict(lpc,work+v->pcm_current-v->centerW-order,
446
order,
447
work+v->pcm_current-v->centerW,
448
v->centerW);
449
450
for(j=0;j<v->pcm_current;j++)
451
v->pcm[i][v->pcm_current-j-1]=work[j];
452
453
}
454
}
455
}
456
457
458
/* call with val<=0 to set eof */
459
460
int vorbis_analysis_wrote(vorbis_dsp_state *v, int vals){
461
vorbis_info *vi=v->vi;
462
codec_setup_info *ci=vi->codec_setup;
463
464
if(vals<=0){
465
int order=32;
466
int i;
467
float *lpc=alloca(order*sizeof(*lpc));
468
469
/* if it wasn't done earlier (very short sample) */
470
if(!v->preextrapolate)
471
_preextrapolate_helper(v);
472
473
/* We're encoding the end of the stream. Just make sure we have
474
[at least] a few full blocks of zeroes at the end. */
475
/* actually, we don't want zeroes; that could drop a large
476
amplitude off a cliff, creating spread spectrum noise that will
477
suck to encode. Extrapolate for the sake of cleanliness. */
478
479
vorbis_analysis_buffer(v,ci->blocksizes[1]*3);
480
v->eofflag=v->pcm_current;
481
v->pcm_current+=ci->blocksizes[1]*3;
482
483
for(i=0;i<vi->channels;i++){
484
if(v->eofflag>order*2){
485
/* extrapolate with LPC to fill in */
486
long n;
487
488
/* make a predictor filter */
489
n=v->eofflag;
490
if(n>ci->blocksizes[1])n=ci->blocksizes[1];
491
vorbis_lpc_from_data(v->pcm[i]+v->eofflag-n,lpc,n,order);
492
493
/* run the predictor filter */
494
vorbis_lpc_predict(lpc,v->pcm[i]+v->eofflag-order,order,
495
v->pcm[i]+v->eofflag,v->pcm_current-v->eofflag);
496
}else{
497
/* not enough data to extrapolate (unlikely to happen due to
498
guarding the overlap, but bulletproof in case that
499
assumtion goes away). zeroes will do. */
500
memset(v->pcm[i]+v->eofflag,0,
501
(v->pcm_current-v->eofflag)*sizeof(*v->pcm[i]));
502
503
}
504
}
505
}else{
506
507
if(v->pcm_current+vals>v->pcm_storage)
508
return(OV_EINVAL);
509
510
v->pcm_current+=vals;
511
512
/* we may want to reverse extrapolate the beginning of a stream
513
too... in case we're beginning on a cliff! */
514
/* clumsy, but simple. It only runs once, so simple is good. */
515
if(!v->preextrapolate && v->pcm_current-v->centerW>ci->blocksizes[1])
516
_preextrapolate_helper(v);
517
518
}
519
return(0);
520
}
521
522
/* do the deltas, envelope shaping, pre-echo and determine the size of
523
the next block on which to continue analysis */
524
int vorbis_analysis_blockout(vorbis_dsp_state *v,vorbis_block *vb){
525
int i;
526
vorbis_info *vi=v->vi;
527
codec_setup_info *ci=vi->codec_setup;
528
private_state *b=v->backend_state;
529
vorbis_look_psy_global *g=b->psy_g_look;
530
long beginW=v->centerW-ci->blocksizes[v->W]/2,centerNext;
531
vorbis_block_internal *vbi=(vorbis_block_internal *)vb->internal;
532
533
/* check to see if we're started... */
534
if(!v->preextrapolate)return(0);
535
536
/* check to see if we're done... */
537
if(v->eofflag==-1)return(0);
538
539
/* By our invariant, we have lW, W and centerW set. Search for
540
the next boundary so we can determine nW (the next window size)
541
which lets us compute the shape of the current block's window */
542
543
/* we do an envelope search even on a single blocksize; we may still
544
be throwing more bits at impulses, and envelope search handles
545
marking impulses too. */
546
{
547
long bp=_ve_envelope_search(v);
548
if(bp==-1){
549
550
if(v->eofflag==0)return(0); /* not enough data currently to search for a
551
full long block */
552
v->nW=0;
553
}else{
554
555
if(ci->blocksizes[0]==ci->blocksizes[1])
556
v->nW=0;
557
else
558
v->nW=bp;
559
}
560
}
561
562
centerNext=v->centerW+ci->blocksizes[v->W]/4+ci->blocksizes[v->nW]/4;
563
564
{
565
/* center of next block + next block maximum right side. */
566
567
long blockbound=centerNext+ci->blocksizes[v->nW]/2;
568
if(v->pcm_current<blockbound)return(0); /* not enough data yet;
569
although this check is
570
less strict that the
571
_ve_envelope_search,
572
the search is not run
573
if we only use one
574
block size */
575
576
577
}
578
579
/* fill in the block. Note that for a short window, lW and nW are *short*
580
regardless of actual settings in the stream */
581
582
_vorbis_block_ripcord(vb);
583
vb->lW=v->lW;
584
vb->W=v->W;
585
vb->nW=v->nW;
586
587
if(v->W){
588
if(!v->lW || !v->nW){
589
vbi->blocktype=BLOCKTYPE_TRANSITION;
590
/*fprintf(stderr,"-");*/
591
}else{
592
vbi->blocktype=BLOCKTYPE_LONG;
593
/*fprintf(stderr,"_");*/
594
}
595
}else{
596
if(_ve_envelope_mark(v)){
597
vbi->blocktype=BLOCKTYPE_IMPULSE;
598
/*fprintf(stderr,"|");*/
599
600
}else{
601
vbi->blocktype=BLOCKTYPE_PADDING;
602
/*fprintf(stderr,".");*/
603
604
}
605
}
606
607
vb->vd=v;
608
vb->sequence=v->sequence++;
609
vb->granulepos=v->granulepos;
610
vb->pcmend=ci->blocksizes[v->W];
611
612
/* copy the vectors; this uses the local storage in vb */
613
614
/* this tracks 'strongest peak' for later psychoacoustics */
615
/* moved to the global psy state; clean this mess up */
616
if(vbi->ampmax>g->ampmax)g->ampmax=vbi->ampmax;
617
g->ampmax=_vp_ampmax_decay(g->ampmax,v);
618
vbi->ampmax=g->ampmax;
619
620
vb->pcm=_vorbis_block_alloc(vb,sizeof(*vb->pcm)*vi->channels);
621
vbi->pcmdelay=_vorbis_block_alloc(vb,sizeof(*vbi->pcmdelay)*vi->channels);
622
for(i=0;i<vi->channels;i++){
623
vbi->pcmdelay[i]=
624
_vorbis_block_alloc(vb,(vb->pcmend+beginW)*sizeof(*vbi->pcmdelay[i]));
625
memcpy(vbi->pcmdelay[i],v->pcm[i],(vb->pcmend+beginW)*sizeof(*vbi->pcmdelay[i]));
626
vb->pcm[i]=vbi->pcmdelay[i]+beginW;
627
628
/* before we added the delay
629
vb->pcm[i]=_vorbis_block_alloc(vb,vb->pcmend*sizeof(*vb->pcm[i]));
630
memcpy(vb->pcm[i],v->pcm[i]+beginW,ci->blocksizes[v->W]*sizeof(*vb->pcm[i]));
631
*/
632
633
}
634
635
/* handle eof detection: eof==0 means that we've not yet received EOF
636
eof>0 marks the last 'real' sample in pcm[]
637
eof<0 'no more to do'; doesn't get here */
638
639
if(v->eofflag){
640
if(v->centerW>=v->eofflag){
641
v->eofflag=-1;
642
vb->eofflag=1;
643
return(1);
644
}
645
}
646
647
/* advance storage vectors and clean up */
648
{
649
int new_centerNext=ci->blocksizes[1]/2;
650
int movementW=centerNext-new_centerNext;
651
652
if(movementW>0){
653
654
_ve_envelope_shift(b->ve,movementW);
655
v->pcm_current-=movementW;
656
657
for(i=0;i<vi->channels;i++)
658
memmove(v->pcm[i],v->pcm[i]+movementW,
659
v->pcm_current*sizeof(*v->pcm[i]));
660
661
662
v->lW=v->W;
663
v->W=v->nW;
664
v->centerW=new_centerNext;
665
666
if(v->eofflag){
667
v->eofflag-=movementW;
668
if(v->eofflag<=0)v->eofflag=-1;
669
/* do not add padding to end of stream! */
670
if(v->centerW>=v->eofflag){
671
v->granulepos+=movementW-(v->centerW-v->eofflag);
672
}else{
673
v->granulepos+=movementW;
674
}
675
}else{
676
v->granulepos+=movementW;
677
}
678
}
679
}
680
681
/* done */
682
return(1);
683
}
684
685
int vorbis_synthesis_restart(vorbis_dsp_state *v){
686
vorbis_info *vi=v->vi;
687
codec_setup_info *ci;
688
int hs;
689
690
if(!v->backend_state)return -1;
691
if(!vi)return -1;
692
ci=vi->codec_setup;
693
if(!ci)return -1;
694
hs=ci->halfrate_flag;
695
696
v->centerW=ci->blocksizes[1]>>(hs+1);
697
v->pcm_current=v->centerW>>hs;
698
699
v->pcm_returned=-1;
700
v->granulepos=-1;
701
v->sequence=-1;
702
v->eofflag=0;
703
((private_state *)(v->backend_state))->sample_count=-1;
704
705
return(0);
706
}
707
708
int vorbis_synthesis_init(vorbis_dsp_state *v,vorbis_info *vi){
709
if(_vds_shared_init(v,vi,0)){
710
vorbis_dsp_clear(v);
711
return 1;
712
}
713
vorbis_synthesis_restart(v);
714
return 0;
715
}
716
717
/* Unlike in analysis, the window is only partially applied for each
718
block. The time domain envelope is not yet handled at the point of
719
calling (as it relies on the previous block). */
720
721
int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb){
722
vorbis_info *vi=v->vi;
723
codec_setup_info *ci=vi->codec_setup;
724
private_state *b=v->backend_state;
725
int hs=ci->halfrate_flag;
726
int i,j;
727
728
if(!vb)return(OV_EINVAL);
729
if(v->pcm_current>v->pcm_returned && v->pcm_returned!=-1)return(OV_EINVAL);
730
731
v->lW=v->W;
732
v->W=vb->W;
733
v->nW=-1;
734
735
if((v->sequence==-1)||
736
(v->sequence+1 != vb->sequence)){
737
v->granulepos=-1; /* out of sequence; lose count */
738
b->sample_count=-1;
739
}
740
741
v->sequence=vb->sequence;
742
743
if(vb->pcm){ /* no pcm to process if vorbis_synthesis_trackonly
744
was called on block */
745
int n=ci->blocksizes[v->W]>>(hs+1);
746
int n0=ci->blocksizes[0]>>(hs+1);
747
int n1=ci->blocksizes[1]>>(hs+1);
748
749
int thisCenter;
750
int prevCenter;
751
752
v->glue_bits+=vb->glue_bits;
753
v->time_bits+=vb->time_bits;
754
v->floor_bits+=vb->floor_bits;
755
v->res_bits+=vb->res_bits;
756
757
if(v->centerW){
758
thisCenter=n1;
759
prevCenter=0;
760
}else{
761
thisCenter=0;
762
prevCenter=n1;
763
}
764
765
/* v->pcm is now used like a two-stage double buffer. We don't want
766
to have to constantly shift *or* adjust memory usage. Don't
767
accept a new block until the old is shifted out */
768
769
for(j=0;j<vi->channels;j++){
770
/* the overlap/add section */
771
if(v->lW){
772
if(v->W){
773
/* large/large */
774
const float *w=_vorbis_window_get(b->window[1]-hs);
775
float *pcm=v->pcm[j]+prevCenter;
776
float *p=vb->pcm[j];
777
for(i=0;i<n1;i++)
778
pcm[i]=pcm[i]*w[n1-i-1] + p[i]*w[i];
779
}else{
780
/* large/small */
781
const float *w=_vorbis_window_get(b->window[0]-hs);
782
float *pcm=v->pcm[j]+prevCenter+n1/2-n0/2;
783
float *p=vb->pcm[j];
784
for(i=0;i<n0;i++)
785
pcm[i]=pcm[i]*w[n0-i-1] +p[i]*w[i];
786
}
787
}else{
788
if(v->W){
789
/* small/large */
790
const float *w=_vorbis_window_get(b->window[0]-hs);
791
float *pcm=v->pcm[j]+prevCenter;
792
float *p=vb->pcm[j]+n1/2-n0/2;
793
for(i=0;i<n0;i++)
794
pcm[i]=pcm[i]*w[n0-i-1] +p[i]*w[i];
795
for(;i<n1/2+n0/2;i++)
796
pcm[i]=p[i];
797
}else{
798
/* small/small */
799
const float *w=_vorbis_window_get(b->window[0]-hs);
800
float *pcm=v->pcm[j]+prevCenter;
801
float *p=vb->pcm[j];
802
for(i=0;i<n0;i++)
803
pcm[i]=pcm[i]*w[n0-i-1] +p[i]*w[i];
804
}
805
}
806
807
/* the copy section */
808
{
809
float *pcm=v->pcm[j]+thisCenter;
810
float *p=vb->pcm[j]+n;
811
for(i=0;i<n;i++)
812
pcm[i]=p[i];
813
}
814
}
815
816
if(v->centerW)
817
v->centerW=0;
818
else
819
v->centerW=n1;
820
821
/* deal with initial packet state; we do this using the explicit
822
pcm_returned==-1 flag otherwise we're sensitive to first block
823
being short or long */
824
825
if(v->pcm_returned==-1){
826
v->pcm_returned=thisCenter;
827
v->pcm_current=thisCenter;
828
}else{
829
v->pcm_returned=prevCenter;
830
v->pcm_current=prevCenter+
831
((ci->blocksizes[v->lW]/4+
832
ci->blocksizes[v->W]/4)>>hs);
833
}
834
835
}
836
837
/* track the frame number... This is for convenience, but also
838
making sure our last packet doesn't end with added padding. If
839
the last packet is partial, the number of samples we'll have to
840
return will be past the vb->granulepos.
841
842
This is not foolproof! It will be confused if we begin
843
decoding at the last page after a seek or hole. In that case,
844
we don't have a starting point to judge where the last frame
845
is. For this reason, vorbisfile will always try to make sure
846
it reads the last two marked pages in proper sequence */
847
848
if(b->sample_count==-1){
849
b->sample_count=0;
850
}else{
851
b->sample_count+=ci->blocksizes[v->lW]/4+ci->blocksizes[v->W]/4;
852
}
853
854
if(v->granulepos==-1){
855
if(vb->granulepos!=-1){ /* only set if we have a position to set to */
856
857
v->granulepos=vb->granulepos;
858
859
/* is this a short page? */
860
if(b->sample_count>v->granulepos){
861
/* corner case; if this is both the first and last audio page,
862
then spec says the end is cut, not beginning */
863
long extra=b->sample_count-vb->granulepos;
864
865
/* we use ogg_int64_t for granule positions because a
866
uint64 isn't universally available. Unfortunately,
867
that means granposes can be 'negative' and result in
868
extra being negative */
869
if(extra<0)
870
extra=0;
871
872
if(vb->eofflag){
873
/* trim the end */
874
/* no preceding granulepos; assume we started at zero (we'd
875
have to in a short single-page stream) */
876
/* granulepos could be -1 due to a seek, but that would result
877
in a long count, not short count */
878
879
/* Guard against corrupt/malicious frames that set EOP and
880
a backdated granpos; don't rewind more samples than we
881
actually have */
882
if(extra > (v->pcm_current - v->pcm_returned)<<hs)
883
extra = (v->pcm_current - v->pcm_returned)<<hs;
884
885
v->pcm_current-=extra>>hs;
886
}else{
887
/* trim the beginning */
888
v->pcm_returned+=extra>>hs;
889
if(v->pcm_returned>v->pcm_current)
890
v->pcm_returned=v->pcm_current;
891
}
892
893
}
894
895
}
896
}else{
897
v->granulepos+=ci->blocksizes[v->lW]/4+ci->blocksizes[v->W]/4;
898
if(vb->granulepos!=-1 && v->granulepos!=vb->granulepos){
899
900
if(v->granulepos>vb->granulepos){
901
long extra=v->granulepos-vb->granulepos;
902
903
if(extra)
904
if(vb->eofflag){
905
/* partial last frame. Strip the extra samples off */
906
907
/* Guard against corrupt/malicious frames that set EOP and
908
a backdated granpos; don't rewind more samples than we
909
actually have */
910
if(extra > (v->pcm_current - v->pcm_returned)<<hs)
911
extra = (v->pcm_current - v->pcm_returned)<<hs;
912
913
/* we use ogg_int64_t for granule positions because a
914
uint64 isn't universally available. Unfortunately,
915
that means granposes can be 'negative' and result in
916
extra being negative */
917
if(extra<0)
918
extra=0;
919
920
v->pcm_current-=extra>>hs;
921
} /* else {Shouldn't happen *unless* the bitstream is out of
922
spec. Either way, believe the bitstream } */
923
} /* else {Shouldn't happen *unless* the bitstream is out of
924
spec. Either way, believe the bitstream } */
925
v->granulepos=vb->granulepos;
926
}
927
}
928
929
/* Update, cleanup */
930
931
if(vb->eofflag)v->eofflag=1;
932
return(0);
933
934
}
935
936
/* pcm==NULL indicates we just want the pending samples, no more */
937
int vorbis_synthesis_pcmout(vorbis_dsp_state *v,float ***pcm){
938
vorbis_info *vi=v->vi;
939
940
if(v->pcm_returned>-1 && v->pcm_returned<v->pcm_current){
941
if(pcm){
942
int i;
943
for(i=0;i<vi->channels;i++)
944
v->pcmret[i]=v->pcm[i]+v->pcm_returned;
945
*pcm=v->pcmret;
946
}
947
return(v->pcm_current-v->pcm_returned);
948
}
949
return(0);
950
}
951
952
int vorbis_synthesis_read(vorbis_dsp_state *v,int n){
953
if(n && v->pcm_returned+n>v->pcm_current)return(OV_EINVAL);
954
v->pcm_returned+=n;
955
return(0);
956
}
957
958
/* intended for use with a specific vorbisfile feature; we want access
959
to the [usually synthetic/postextrapolated] buffer and lapping at
960
the end of a decode cycle, specifically, a half-short-block worth.
961
This funtion works like pcmout above, except it will also expose
962
this implicit buffer data not normally decoded. */
963
int vorbis_synthesis_lapout(vorbis_dsp_state *v,float ***pcm){
964
vorbis_info *vi=v->vi;
965
codec_setup_info *ci=vi->codec_setup;
966
int hs=ci->halfrate_flag;
967
968
int n=ci->blocksizes[v->W]>>(hs+1);
969
int n0=ci->blocksizes[0]>>(hs+1);
970
int n1=ci->blocksizes[1]>>(hs+1);
971
int i,j;
972
973
if(v->pcm_returned<0)return 0;
974
975
/* our returned data ends at pcm_returned; because the synthesis pcm
976
buffer is a two-fragment ring, that means our data block may be
977
fragmented by buffering, wrapping or a short block not filling
978
out a buffer. To simplify things, we unfragment if it's at all
979
possibly needed. Otherwise, we'd need to call lapout more than
980
once as well as hold additional dsp state. Opt for
981
simplicity. */
982
983
/* centerW was advanced by blockin; it would be the center of the
984
*next* block */
985
if(v->centerW==n1){
986
/* the data buffer wraps; swap the halves */
987
/* slow, sure, small */
988
for(j=0;j<vi->channels;j++){
989
float *p=v->pcm[j];
990
for(i=0;i<n1;i++){
991
float temp=p[i];
992
p[i]=p[i+n1];
993
p[i+n1]=temp;
994
}
995
}
996
997
v->pcm_current-=n1;
998
v->pcm_returned-=n1;
999
v->centerW=0;
1000
}
1001
1002
/* solidify buffer into contiguous space */
1003
if((v->lW^v->W)==1){
1004
/* long/short or short/long */
1005
for(j=0;j<vi->channels;j++){
1006
float *s=v->pcm[j];
1007
float *d=v->pcm[j]+(n1-n0)/2;
1008
for(i=(n1+n0)/2-1;i>=0;--i)
1009
d[i]=s[i];
1010
}
1011
v->pcm_returned+=(n1-n0)/2;
1012
v->pcm_current+=(n1-n0)/2;
1013
}else{
1014
if(v->lW==0){
1015
/* short/short */
1016
for(j=0;j<vi->channels;j++){
1017
float *s=v->pcm[j];
1018
float *d=v->pcm[j]+n1-n0;
1019
for(i=n0-1;i>=0;--i)
1020
d[i]=s[i];
1021
}
1022
v->pcm_returned+=n1-n0;
1023
v->pcm_current+=n1-n0;
1024
}
1025
}
1026
1027
if(pcm){
1028
int i;
1029
for(i=0;i<vi->channels;i++)
1030
v->pcmret[i]=v->pcm[i]+v->pcm_returned;
1031
*pcm=v->pcmret;
1032
}
1033
1034
return(n1+n-v->pcm_returned);
1035
1036
}
1037
1038
const float *vorbis_window(vorbis_dsp_state *v,int W){
1039
vorbis_info *vi=v->vi;
1040
codec_setup_info *ci=vi->codec_setup;
1041
int hs=ci->halfrate_flag;
1042
private_state *b=v->backend_state;
1043
1044
if(b->window[W]-1<0)return NULL;
1045
return _vorbis_window_get(b->window[W]-hs);
1046
}
1047
1048