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