VirtualBox

source: vbox/trunk/src/libs/libvorbis-1.3.7/lib/block.c@ 106199

Last change on this file since 106199 was 96468, checked in by vboxsync, 2 years ago

libs/libvorbis-1.3.7: Re-exporting, hopefully this time everything is there. bugref:10275

File size: 29.9 KB
Line 
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
77int 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
102void *_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 */
126void _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
148int 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
170static 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 for(i=0;i<vi->channels;i++)
256 v->pcm[i]=_ogg_calloc(v->pcm_storage,sizeof(*v->pcm[i]));
257 }
258
259 /* all 1 (large block) or 0 (small block) */
260 /* explicitly set for the sake of clarity */
261 v->lW=0; /* previous window size */
262 v->W=0; /* current window size */
263
264 /* all vector indexes */
265 v->centerW=ci->blocksizes[1]/2;
266
267 v->pcm_current=v->centerW;
268
269 /* initialize all the backend lookups */
270 b->flr=_ogg_calloc(ci->floors,sizeof(*b->flr));
271 b->residue=_ogg_calloc(ci->residues,sizeof(*b->residue));
272
273 for(i=0;i<ci->floors;i++)
274 b->flr[i]=_floor_P[ci->floor_type[i]]->
275 look(v,ci->floor_param[i]);
276
277 for(i=0;i<ci->residues;i++)
278 b->residue[i]=_residue_P[ci->residue_type[i]]->
279 look(v,ci->residue_param[i]);
280
281 return 0;
282 abort_books:
283 for(i=0;i<ci->books;i++){
284 if(ci->book_param[i]!=NULL){
285 vorbis_staticbook_destroy(ci->book_param[i]);
286 ci->book_param[i]=NULL;
287 }
288 }
289 vorbis_dsp_clear(v);
290 return -1;
291}
292
293/* arbitrary settings and spec-mandated numbers get filled in here */
294int vorbis_analysis_init(vorbis_dsp_state *v,vorbis_info *vi){
295 private_state *b=NULL;
296
297 if(_vds_shared_init(v,vi,1))return 1;
298 b=v->backend_state;
299 b->psy_g_look=_vp_global_look(vi);
300
301 /* Initialize the envelope state storage */
302 b->ve=_ogg_calloc(1,sizeof(*b->ve));
303 _ve_envelope_init(b->ve,vi);
304
305 vorbis_bitrate_init(vi,&b->bms);
306
307 /* compressed audio packets start after the headers
308 with sequence number 3 */
309 v->sequence=3;
310
311 return(0);
312}
313
314void vorbis_dsp_clear(vorbis_dsp_state *v){
315 int i;
316 if(v){
317 vorbis_info *vi=v->vi;
318 codec_setup_info *ci=(vi?vi->codec_setup:NULL);
319 private_state *b=v->backend_state;
320
321 if(b){
322
323 if(b->ve){
324 _ve_envelope_clear(b->ve);
325 _ogg_free(b->ve);
326 }
327
328 if(b->transform[0]){
329 mdct_clear(b->transform[0][0]);
330 _ogg_free(b->transform[0][0]);
331 _ogg_free(b->transform[0]);
332 }
333 if(b->transform[1]){
334 mdct_clear(b->transform[1][0]);
335 _ogg_free(b->transform[1][0]);
336 _ogg_free(b->transform[1]);
337 }
338
339 if(b->flr){
340 if(ci)
341 for(i=0;i<ci->floors;i++)
342 _floor_P[ci->floor_type[i]]->
343 free_look(b->flr[i]);
344 _ogg_free(b->flr);
345 }
346 if(b->residue){
347 if(ci)
348 for(i=0;i<ci->residues;i++)
349 _residue_P[ci->residue_type[i]]->
350 free_look(b->residue[i]);
351 _ogg_free(b->residue);
352 }
353 if(b->psy){
354 if(ci)
355 for(i=0;i<ci->psys;i++)
356 _vp_psy_clear(b->psy+i);
357 _ogg_free(b->psy);
358 }
359
360 if(b->psy_g_look)_vp_global_free(b->psy_g_look);
361 vorbis_bitrate_clear(&b->bms);
362
363 drft_clear(&b->fft_look[0]);
364 drft_clear(&b->fft_look[1]);
365
366 }
367
368 if(v->pcm){
369 if(vi)
370 for(i=0;i<vi->channels;i++)
371 if(v->pcm[i])_ogg_free(v->pcm[i]);
372 _ogg_free(v->pcm);
373 if(v->pcmret)_ogg_free(v->pcmret);
374 }
375
376 if(b){
377 /* free header, header1, header2 */
378 if(b->header)_ogg_free(b->header);
379 if(b->header1)_ogg_free(b->header1);
380 if(b->header2)_ogg_free(b->header2);
381 _ogg_free(b);
382 }
383
384 memset(v,0,sizeof(*v));
385 }
386}
387
388float **vorbis_analysis_buffer(vorbis_dsp_state *v, int vals){
389 int i;
390 vorbis_info *vi=v->vi;
391 private_state *b=v->backend_state;
392
393 /* free header, header1, header2 */
394 if(b->header)_ogg_free(b->header);b->header=NULL;
395 if(b->header1)_ogg_free(b->header1);b->header1=NULL;
396 if(b->header2)_ogg_free(b->header2);b->header2=NULL;
397
398 /* Do we have enough storage space for the requested buffer? If not,
399 expand the PCM (and envelope) storage */
400
401 if(v->pcm_current+vals>=v->pcm_storage){
402 v->pcm_storage=v->pcm_current+vals*2;
403
404 for(i=0;i<vi->channels;i++){
405 v->pcm[i]=_ogg_realloc(v->pcm[i],v->pcm_storage*sizeof(*v->pcm[i]));
406 }
407 }
408
409 for(i=0;i<vi->channels;i++)
410 v->pcmret[i]=v->pcm[i]+v->pcm_current;
411
412 return(v->pcmret);
413}
414
415static void _preextrapolate_helper(vorbis_dsp_state *v){
416 int i;
417 int order=16;
418 float *lpc=alloca(order*sizeof(*lpc));
419 float *work=alloca(v->pcm_current*sizeof(*work));
420 long j;
421 v->preextrapolate=1;
422
423 if(v->pcm_current-v->centerW>order*2){ /* safety */
424 for(i=0;i<v->vi->channels;i++){
425 /* need to run the extrapolation in reverse! */
426 for(j=0;j<v->pcm_current;j++)
427 work[j]=v->pcm[i][v->pcm_current-j-1];
428
429 /* prime as above */
430 vorbis_lpc_from_data(work,lpc,v->pcm_current-v->centerW,order);
431
432#if 0
433 if(v->vi->channels==2){
434 if(i==0)
435 _analysis_output("predataL",0,work,v->pcm_current-v->centerW,0,0,0);
436 else
437 _analysis_output("predataR",0,work,v->pcm_current-v->centerW,0,0,0);
438 }else{
439 _analysis_output("predata",0,work,v->pcm_current-v->centerW,0,0,0);
440 }
441#endif
442
443 /* run the predictor filter */
444 vorbis_lpc_predict(lpc,work+v->pcm_current-v->centerW-order,
445 order,
446 work+v->pcm_current-v->centerW,
447 v->centerW);
448
449 for(j=0;j<v->pcm_current;j++)
450 v->pcm[i][v->pcm_current-j-1]=work[j];
451
452 }
453 }
454}
455
456
457/* call with val<=0 to set eof */
458
459int vorbis_analysis_wrote(vorbis_dsp_state *v, int vals){
460 vorbis_info *vi=v->vi;
461 codec_setup_info *ci=vi->codec_setup;
462
463 if(vals<=0){
464 int order=32;
465 int i;
466 float *lpc=alloca(order*sizeof(*lpc));
467
468 /* if it wasn't done earlier (very short sample) */
469 if(!v->preextrapolate)
470 _preextrapolate_helper(v);
471
472 /* We're encoding the end of the stream. Just make sure we have
473 [at least] a few full blocks of zeroes at the end. */
474 /* actually, we don't want zeroes; that could drop a large
475 amplitude off a cliff, creating spread spectrum noise that will
476 suck to encode. Extrapolate for the sake of cleanliness. */
477
478 vorbis_analysis_buffer(v,ci->blocksizes[1]*3);
479 v->eofflag=v->pcm_current;
480 v->pcm_current+=ci->blocksizes[1]*3;
481
482 for(i=0;i<vi->channels;i++){
483 if(v->eofflag>order*2){
484 /* extrapolate with LPC to fill in */
485 long n;
486
487 /* make a predictor filter */
488 n=v->eofflag;
489 if(n>ci->blocksizes[1])n=ci->blocksizes[1];
490 vorbis_lpc_from_data(v->pcm[i]+v->eofflag-n,lpc,n,order);
491
492 /* run the predictor filter */
493 vorbis_lpc_predict(lpc,v->pcm[i]+v->eofflag-order,order,
494 v->pcm[i]+v->eofflag,v->pcm_current-v->eofflag);
495 }else{
496 /* not enough data to extrapolate (unlikely to happen due to
497 guarding the overlap, but bulletproof in case that
498 assumtion goes away). zeroes will do. */
499 memset(v->pcm[i]+v->eofflag,0,
500 (v->pcm_current-v->eofflag)*sizeof(*v->pcm[i]));
501
502 }
503 }
504 }else{
505
506 if(v->pcm_current+vals>v->pcm_storage)
507 return(OV_EINVAL);
508
509 v->pcm_current+=vals;
510
511 /* we may want to reverse extrapolate the beginning of a stream
512 too... in case we're beginning on a cliff! */
513 /* clumsy, but simple. It only runs once, so simple is good. */
514 if(!v->preextrapolate && v->pcm_current-v->centerW>ci->blocksizes[1])
515 _preextrapolate_helper(v);
516
517 }
518 return(0);
519}
520
521/* do the deltas, envelope shaping, pre-echo and determine the size of
522 the next block on which to continue analysis */
523int vorbis_analysis_blockout(vorbis_dsp_state *v,vorbis_block *vb){
524 int i;
525 vorbis_info *vi=v->vi;
526 codec_setup_info *ci=vi->codec_setup;
527 private_state *b=v->backend_state;
528 vorbis_look_psy_global *g=b->psy_g_look;
529 long beginW=v->centerW-ci->blocksizes[v->W]/2,centerNext;
530 vorbis_block_internal *vbi=(vorbis_block_internal *)vb->internal;
531
532 /* check to see if we're started... */
533 if(!v->preextrapolate)return(0);
534
535 /* check to see if we're done... */
536 if(v->eofflag==-1)return(0);
537
538 /* By our invariant, we have lW, W and centerW set. Search for
539 the next boundary so we can determine nW (the next window size)
540 which lets us compute the shape of the current block's window */
541
542 /* we do an envelope search even on a single blocksize; we may still
543 be throwing more bits at impulses, and envelope search handles
544 marking impulses too. */
545 {
546 long bp=_ve_envelope_search(v);
547 if(bp==-1){
548
549 if(v->eofflag==0)return(0); /* not enough data currently to search for a
550 full long block */
551 v->nW=0;
552 }else{
553
554 if(ci->blocksizes[0]==ci->blocksizes[1])
555 v->nW=0;
556 else
557 v->nW=bp;
558 }
559 }
560
561 centerNext=v->centerW+ci->blocksizes[v->W]/4+ci->blocksizes[v->nW]/4;
562
563 {
564 /* center of next block + next block maximum right side. */
565
566 long blockbound=centerNext+ci->blocksizes[v->nW]/2;
567 if(v->pcm_current<blockbound)return(0); /* not enough data yet;
568 although this check is
569 less strict that the
570 _ve_envelope_search,
571 the search is not run
572 if we only use one
573 block size */
574
575
576 }
577
578 /* fill in the block. Note that for a short window, lW and nW are *short*
579 regardless of actual settings in the stream */
580
581 _vorbis_block_ripcord(vb);
582 vb->lW=v->lW;
583 vb->W=v->W;
584 vb->nW=v->nW;
585
586 if(v->W){
587 if(!v->lW || !v->nW){
588 vbi->blocktype=BLOCKTYPE_TRANSITION;
589 /*fprintf(stderr,"-");*/
590 }else{
591 vbi->blocktype=BLOCKTYPE_LONG;
592 /*fprintf(stderr,"_");*/
593 }
594 }else{
595 if(_ve_envelope_mark(v)){
596 vbi->blocktype=BLOCKTYPE_IMPULSE;
597 /*fprintf(stderr,"|");*/
598
599 }else{
600 vbi->blocktype=BLOCKTYPE_PADDING;
601 /*fprintf(stderr,".");*/
602
603 }
604 }
605
606 vb->vd=v;
607 vb->sequence=v->sequence++;
608 vb->granulepos=v->granulepos;
609 vb->pcmend=ci->blocksizes[v->W];
610
611 /* copy the vectors; this uses the local storage in vb */
612
613 /* this tracks 'strongest peak' for later psychoacoustics */
614 /* moved to the global psy state; clean this mess up */
615 if(vbi->ampmax>g->ampmax)g->ampmax=vbi->ampmax;
616 g->ampmax=_vp_ampmax_decay(g->ampmax,v);
617 vbi->ampmax=g->ampmax;
618
619 vb->pcm=_vorbis_block_alloc(vb,sizeof(*vb->pcm)*vi->channels);
620 vbi->pcmdelay=_vorbis_block_alloc(vb,sizeof(*vbi->pcmdelay)*vi->channels);
621 for(i=0;i<vi->channels;i++){
622 vbi->pcmdelay[i]=
623 _vorbis_block_alloc(vb,(vb->pcmend+beginW)*sizeof(*vbi->pcmdelay[i]));
624 memcpy(vbi->pcmdelay[i],v->pcm[i],(vb->pcmend+beginW)*sizeof(*vbi->pcmdelay[i]));
625 vb->pcm[i]=vbi->pcmdelay[i]+beginW;
626
627 /* before we added the delay
628 vb->pcm[i]=_vorbis_block_alloc(vb,vb->pcmend*sizeof(*vb->pcm[i]));
629 memcpy(vb->pcm[i],v->pcm[i]+beginW,ci->blocksizes[v->W]*sizeof(*vb->pcm[i]));
630 */
631
632 }
633
634 /* handle eof detection: eof==0 means that we've not yet received EOF
635 eof>0 marks the last 'real' sample in pcm[]
636 eof<0 'no more to do'; doesn't get here */
637
638 if(v->eofflag){
639 if(v->centerW>=v->eofflag){
640 v->eofflag=-1;
641 vb->eofflag=1;
642 return(1);
643 }
644 }
645
646 /* advance storage vectors and clean up */
647 {
648 int new_centerNext=ci->blocksizes[1]/2;
649 int movementW=centerNext-new_centerNext;
650
651 if(movementW>0){
652
653 _ve_envelope_shift(b->ve,movementW);
654 v->pcm_current-=movementW;
655
656 for(i=0;i<vi->channels;i++)
657 memmove(v->pcm[i],v->pcm[i]+movementW,
658 v->pcm_current*sizeof(*v->pcm[i]));
659
660
661 v->lW=v->W;
662 v->W=v->nW;
663 v->centerW=new_centerNext;
664
665 if(v->eofflag){
666 v->eofflag-=movementW;
667 if(v->eofflag<=0)v->eofflag=-1;
668 /* do not add padding to end of stream! */
669 if(v->centerW>=v->eofflag){
670 v->granulepos+=movementW-(v->centerW-v->eofflag);
671 }else{
672 v->granulepos+=movementW;
673 }
674 }else{
675 v->granulepos+=movementW;
676 }
677 }
678 }
679
680 /* done */
681 return(1);
682}
683
684int vorbis_synthesis_restart(vorbis_dsp_state *v){
685 vorbis_info *vi=v->vi;
686 codec_setup_info *ci;
687 int hs;
688
689 if(!v->backend_state)return -1;
690 if(!vi)return -1;
691 ci=vi->codec_setup;
692 if(!ci)return -1;
693 hs=ci->halfrate_flag;
694
695 v->centerW=ci->blocksizes[1]>>(hs+1);
696 v->pcm_current=v->centerW>>hs;
697
698 v->pcm_returned=-1;
699 v->granulepos=-1;
700 v->sequence=-1;
701 v->eofflag=0;
702 ((private_state *)(v->backend_state))->sample_count=-1;
703
704 return(0);
705}
706
707int vorbis_synthesis_init(vorbis_dsp_state *v,vorbis_info *vi){
708 if(_vds_shared_init(v,vi,0)){
709 vorbis_dsp_clear(v);
710 return 1;
711 }
712 vorbis_synthesis_restart(v);
713 return 0;
714}
715
716/* Unlike in analysis, the window is only partially applied for each
717 block. The time domain envelope is not yet handled at the point of
718 calling (as it relies on the previous block). */
719
720int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb){
721 vorbis_info *vi=v->vi;
722 codec_setup_info *ci=vi->codec_setup;
723 private_state *b=v->backend_state;
724 int hs=ci->halfrate_flag;
725 int i,j;
726
727 if(!vb)return(OV_EINVAL);
728 if(v->pcm_current>v->pcm_returned && v->pcm_returned!=-1)return(OV_EINVAL);
729
730 v->lW=v->W;
731 v->W=vb->W;
732 v->nW=-1;
733
734 if((v->sequence==-1)||
735 (v->sequence+1 != vb->sequence)){
736 v->granulepos=-1; /* out of sequence; lose count */
737 b->sample_count=-1;
738 }
739
740 v->sequence=vb->sequence;
741
742 if(vb->pcm){ /* no pcm to process if vorbis_synthesis_trackonly
743 was called on block */
744 int n=ci->blocksizes[v->W]>>(hs+1);
745 int n0=ci->blocksizes[0]>>(hs+1);
746 int n1=ci->blocksizes[1]>>(hs+1);
747
748 int thisCenter;
749 int prevCenter;
750
751 v->glue_bits+=vb->glue_bits;
752 v->time_bits+=vb->time_bits;
753 v->floor_bits+=vb->floor_bits;
754 v->res_bits+=vb->res_bits;
755
756 if(v->centerW){
757 thisCenter=n1;
758 prevCenter=0;
759 }else{
760 thisCenter=0;
761 prevCenter=n1;
762 }
763
764 /* v->pcm is now used like a two-stage double buffer. We don't want
765 to have to constantly shift *or* adjust memory usage. Don't
766 accept a new block until the old is shifted out */
767
768 for(j=0;j<vi->channels;j++){
769 /* the overlap/add section */
770 if(v->lW){
771 if(v->W){
772 /* large/large */
773 const float *w=_vorbis_window_get(b->window[1]-hs);
774 float *pcm=v->pcm[j]+prevCenter;
775 float *p=vb->pcm[j];
776 for(i=0;i<n1;i++)
777 pcm[i]=pcm[i]*w[n1-i-1] + p[i]*w[i];
778 }else{
779 /* large/small */
780 const float *w=_vorbis_window_get(b->window[0]-hs);
781 float *pcm=v->pcm[j]+prevCenter+n1/2-n0/2;
782 float *p=vb->pcm[j];
783 for(i=0;i<n0;i++)
784 pcm[i]=pcm[i]*w[n0-i-1] +p[i]*w[i];
785 }
786 }else{
787 if(v->W){
788 /* small/large */
789 const float *w=_vorbis_window_get(b->window[0]-hs);
790 float *pcm=v->pcm[j]+prevCenter;
791 float *p=vb->pcm[j]+n1/2-n0/2;
792 for(i=0;i<n0;i++)
793 pcm[i]=pcm[i]*w[n0-i-1] +p[i]*w[i];
794 for(;i<n1/2+n0/2;i++)
795 pcm[i]=p[i];
796 }else{
797 /* small/small */
798 const float *w=_vorbis_window_get(b->window[0]-hs);
799 float *pcm=v->pcm[j]+prevCenter;
800 float *p=vb->pcm[j];
801 for(i=0;i<n0;i++)
802 pcm[i]=pcm[i]*w[n0-i-1] +p[i]*w[i];
803 }
804 }
805
806 /* the copy section */
807 {
808 float *pcm=v->pcm[j]+thisCenter;
809 float *p=vb->pcm[j]+n;
810 for(i=0;i<n;i++)
811 pcm[i]=p[i];
812 }
813 }
814
815 if(v->centerW)
816 v->centerW=0;
817 else
818 v->centerW=n1;
819
820 /* deal with initial packet state; we do this using the explicit
821 pcm_returned==-1 flag otherwise we're sensitive to first block
822 being short or long */
823
824 if(v->pcm_returned==-1){
825 v->pcm_returned=thisCenter;
826 v->pcm_current=thisCenter;
827 }else{
828 v->pcm_returned=prevCenter;
829 v->pcm_current=prevCenter+
830 ((ci->blocksizes[v->lW]/4+
831 ci->blocksizes[v->W]/4)>>hs);
832 }
833
834 }
835
836 /* track the frame number... This is for convenience, but also
837 making sure our last packet doesn't end with added padding. If
838 the last packet is partial, the number of samples we'll have to
839 return will be past the vb->granulepos.
840
841 This is not foolproof! It will be confused if we begin
842 decoding at the last page after a seek or hole. In that case,
843 we don't have a starting point to judge where the last frame
844 is. For this reason, vorbisfile will always try to make sure
845 it reads the last two marked pages in proper sequence */
846
847 if(b->sample_count==-1){
848 b->sample_count=0;
849 }else{
850 b->sample_count+=ci->blocksizes[v->lW]/4+ci->blocksizes[v->W]/4;
851 }
852
853 if(v->granulepos==-1){
854 if(vb->granulepos!=-1){ /* only set if we have a position to set to */
855
856 v->granulepos=vb->granulepos;
857
858 /* is this a short page? */
859 if(b->sample_count>v->granulepos){
860 /* corner case; if this is both the first and last audio page,
861 then spec says the end is cut, not beginning */
862 long extra=b->sample_count-vb->granulepos;
863
864 /* we use ogg_int64_t for granule positions because a
865 uint64 isn't universally available. Unfortunately,
866 that means granposes can be 'negative' and result in
867 extra being negative */
868 if(extra<0)
869 extra=0;
870
871 if(vb->eofflag){
872 /* trim the end */
873 /* no preceding granulepos; assume we started at zero (we'd
874 have to in a short single-page stream) */
875 /* granulepos could be -1 due to a seek, but that would result
876 in a long count, not short count */
877
878 /* Guard against corrupt/malicious frames that set EOP and
879 a backdated granpos; don't rewind more samples than we
880 actually have */
881 if(extra > (v->pcm_current - v->pcm_returned)<<hs)
882 extra = (v->pcm_current - v->pcm_returned)<<hs;
883
884 v->pcm_current-=extra>>hs;
885 }else{
886 /* trim the beginning */
887 v->pcm_returned+=extra>>hs;
888 if(v->pcm_returned>v->pcm_current)
889 v->pcm_returned=v->pcm_current;
890 }
891
892 }
893
894 }
895 }else{
896 v->granulepos+=ci->blocksizes[v->lW]/4+ci->blocksizes[v->W]/4;
897 if(vb->granulepos!=-1 && v->granulepos!=vb->granulepos){
898
899 if(v->granulepos>vb->granulepos){
900 long extra=v->granulepos-vb->granulepos;
901
902 if(extra)
903 if(vb->eofflag){
904 /* partial last frame. Strip the extra samples off */
905
906 /* Guard against corrupt/malicious frames that set EOP and
907 a backdated granpos; don't rewind more samples than we
908 actually have */
909 if(extra > (v->pcm_current - v->pcm_returned)<<hs)
910 extra = (v->pcm_current - v->pcm_returned)<<hs;
911
912 /* we use ogg_int64_t for granule positions because a
913 uint64 isn't universally available. Unfortunately,
914 that means granposes can be 'negative' and result in
915 extra being negative */
916 if(extra<0)
917 extra=0;
918
919 v->pcm_current-=extra>>hs;
920 } /* else {Shouldn't happen *unless* the bitstream is out of
921 spec. Either way, believe the bitstream } */
922 } /* else {Shouldn't happen *unless* the bitstream is out of
923 spec. Either way, believe the bitstream } */
924 v->granulepos=vb->granulepos;
925 }
926 }
927
928 /* Update, cleanup */
929
930 if(vb->eofflag)v->eofflag=1;
931 return(0);
932
933}
934
935/* pcm==NULL indicates we just want the pending samples, no more */
936int vorbis_synthesis_pcmout(vorbis_dsp_state *v,float ***pcm){
937 vorbis_info *vi=v->vi;
938
939 if(v->pcm_returned>-1 && v->pcm_returned<v->pcm_current){
940 if(pcm){
941 int i;
942 for(i=0;i<vi->channels;i++)
943 v->pcmret[i]=v->pcm[i]+v->pcm_returned;
944 *pcm=v->pcmret;
945 }
946 return(v->pcm_current-v->pcm_returned);
947 }
948 return(0);
949}
950
951int vorbis_synthesis_read(vorbis_dsp_state *v,int n){
952 if(n && v->pcm_returned+n>v->pcm_current)return(OV_EINVAL);
953 v->pcm_returned+=n;
954 return(0);
955}
956
957/* intended for use with a specific vorbisfile feature; we want access
958 to the [usually synthetic/postextrapolated] buffer and lapping at
959 the end of a decode cycle, specifically, a half-short-block worth.
960 This funtion works like pcmout above, except it will also expose
961 this implicit buffer data not normally decoded. */
962int vorbis_synthesis_lapout(vorbis_dsp_state *v,float ***pcm){
963 vorbis_info *vi=v->vi;
964 codec_setup_info *ci=vi->codec_setup;
965 int hs=ci->halfrate_flag;
966
967 int n=ci->blocksizes[v->W]>>(hs+1);
968 int n0=ci->blocksizes[0]>>(hs+1);
969 int n1=ci->blocksizes[1]>>(hs+1);
970 int i,j;
971
972 if(v->pcm_returned<0)return 0;
973
974 /* our returned data ends at pcm_returned; because the synthesis pcm
975 buffer is a two-fragment ring, that means our data block may be
976 fragmented by buffering, wrapping or a short block not filling
977 out a buffer. To simplify things, we unfragment if it's at all
978 possibly needed. Otherwise, we'd need to call lapout more than
979 once as well as hold additional dsp state. Opt for
980 simplicity. */
981
982 /* centerW was advanced by blockin; it would be the center of the
983 *next* block */
984 if(v->centerW==n1){
985 /* the data buffer wraps; swap the halves */
986 /* slow, sure, small */
987 for(j=0;j<vi->channels;j++){
988 float *p=v->pcm[j];
989 for(i=0;i<n1;i++){
990 float temp=p[i];
991 p[i]=p[i+n1];
992 p[i+n1]=temp;
993 }
994 }
995
996 v->pcm_current-=n1;
997 v->pcm_returned-=n1;
998 v->centerW=0;
999 }
1000
1001 /* solidify buffer into contiguous space */
1002 if((v->lW^v->W)==1){
1003 /* long/short or short/long */
1004 for(j=0;j<vi->channels;j++){
1005 float *s=v->pcm[j];
1006 float *d=v->pcm[j]+(n1-n0)/2;
1007 for(i=(n1+n0)/2-1;i>=0;--i)
1008 d[i]=s[i];
1009 }
1010 v->pcm_returned+=(n1-n0)/2;
1011 v->pcm_current+=(n1-n0)/2;
1012 }else{
1013 if(v->lW==0){
1014 /* short/short */
1015 for(j=0;j<vi->channels;j++){
1016 float *s=v->pcm[j];
1017 float *d=v->pcm[j]+n1-n0;
1018 for(i=n0-1;i>=0;--i)
1019 d[i]=s[i];
1020 }
1021 v->pcm_returned+=n1-n0;
1022 v->pcm_current+=n1-n0;
1023 }
1024 }
1025
1026 if(pcm){
1027 for(i=0;i<vi->channels;i++)
1028 v->pcmret[i]=v->pcm[i]+v->pcm_returned;
1029 *pcm=v->pcmret;
1030 }
1031
1032 return(n1+n-v->pcm_returned);
1033
1034}
1035
1036const float *vorbis_window(vorbis_dsp_state *v,int W){
1037 vorbis_info *vi=v->vi;
1038 codec_setup_info *ci=vi->codec_setup;
1039 int hs=ci->halfrate_flag;
1040 private_state *b=v->backend_state;
1041
1042 if(b->window[W]-1<0)return NULL;
1043 return _vorbis_window_get(b->window[W]-hs);
1044}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette