1 : /********************************************************************
2 : * *
3 : * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
4 : * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
5 : * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
6 : * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
7 : * *
8 : * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009 *
9 : * by the Xiph.Org Foundation http://www.xiph.org/ *
10 : * *
11 : ********************************************************************
12 :
13 : function: PCM data vector blocking, windowing and dis/reassembly
14 : last mod: $Id: block.c 17561 2010-10-23 10:34:24Z xiphmont $
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 0 : static int ilog2(unsigned int v){
35 0 : int ret=0;
36 0 : if(v)--v;
37 0 : while(v){
38 0 : ret++;
39 0 : v>>=1;
40 : }
41 0 : 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 0 : int vorbis_block_init(vorbis_dsp_state *v, vorbis_block *vb){
89 : int i;
90 0 : memset(vb,0,sizeof(*vb));
91 0 : vb->vd=v;
92 0 : vb->localalloc=0;
93 0 : vb->localstore=NULL;
94 0 : if(v->analysisp){
95 0 : vorbis_block_internal *vbi=
96 0 : vb->internal=_ogg_calloc(1,sizeof(vorbis_block_internal));
97 0 : vbi->ampmax=-9999;
98 :
99 0 : for(i=0;i<PACKETBLOBS;i++){
100 0 : if(i==PACKETBLOBS/2){
101 0 : vbi->packetblob[i]=&vb->opb;
102 : }else{
103 0 : vbi->packetblob[i]=
104 0 : _ogg_calloc(1,sizeof(oggpack_buffer));
105 : }
106 0 : oggpack_writeinit(vbi->packetblob[i]);
107 : }
108 : }
109 :
110 0 : return(0);
111 : }
112 :
113 0 : void *_vorbis_block_alloc(vorbis_block *vb,long bytes){
114 0 : bytes=(bytes+(WORD_ALIGN-1)) & ~(WORD_ALIGN-1);
115 0 : if(bytes+vb->localtop>vb->localalloc){
116 : /* can't just _ogg_realloc... there are outstanding pointers */
117 0 : if(vb->localstore){
118 0 : struct alloc_chain *link=_ogg_malloc(sizeof(*link));
119 0 : vb->totaluse+=vb->localtop;
120 0 : link->next=vb->reap;
121 0 : link->ptr=vb->localstore;
122 0 : vb->reap=link;
123 : }
124 : /* highly conservative */
125 0 : vb->localalloc=bytes;
126 0 : vb->localstore=_ogg_malloc(vb->localalloc);
127 0 : vb->localtop=0;
128 : }
129 : {
130 0 : void *ret=(void *)(((char *)vb->localstore)+vb->localtop);
131 0 : vb->localtop+=bytes;
132 0 : return ret;
133 : }
134 : }
135 :
136 : /* reap the chain, pull the ripcord */
137 0 : void _vorbis_block_ripcord(vorbis_block *vb){
138 : /* reap the chain */
139 0 : struct alloc_chain *reap=vb->reap;
140 0 : while(reap){
141 0 : struct alloc_chain *next=reap->next;
142 0 : _ogg_free(reap->ptr);
143 0 : memset(reap,0,sizeof(*reap));
144 0 : _ogg_free(reap);
145 0 : reap=next;
146 : }
147 : /* consolidate storage */
148 0 : if(vb->totaluse){
149 0 : vb->localstore=_ogg_realloc(vb->localstore,vb->totaluse+vb->localalloc);
150 0 : vb->localalloc+=vb->totaluse;
151 0 : vb->totaluse=0;
152 : }
153 :
154 : /* pull the ripcord */
155 0 : vb->localtop=0;
156 0 : vb->reap=NULL;
157 0 : }
158 :
159 0 : int vorbis_block_clear(vorbis_block *vb){
160 : int i;
161 0 : vorbis_block_internal *vbi=vb->internal;
162 :
163 0 : _vorbis_block_ripcord(vb);
164 0 : if(vb->localstore)_ogg_free(vb->localstore);
165 :
166 0 : if(vbi){
167 0 : for(i=0;i<PACKETBLOBS;i++){
168 0 : oggpack_writeclear(vbi->packetblob[i]);
169 0 : if(i!=PACKETBLOBS/2)_ogg_free(vbi->packetblob[i]);
170 : }
171 0 : _ogg_free(vbi);
172 : }
173 0 : memset(vb,0,sizeof(*vb));
174 0 : return(0);
175 : }
176 :
177 : /* Analysis side code, but directly related to blocking. Thus it's
178 : here and not in analysis.c (which is for analysis transforms only).
179 : The init is here because some of it is shared */
180 :
181 0 : static int _vds_shared_init(vorbis_dsp_state *v,vorbis_info *vi,int encp){
182 : int i;
183 0 : codec_setup_info *ci=vi->codec_setup;
184 0 : private_state *b=NULL;
185 : int hs;
186 :
187 0 : if(ci==NULL) return 1;
188 0 : hs=ci->halfrate_flag;
189 :
190 0 : memset(v,0,sizeof(*v));
191 0 : b=v->backend_state=_ogg_calloc(1,sizeof(*b));
192 :
193 0 : v->vi=vi;
194 0 : b->modebits=ilog2(ci->modes);
195 :
196 0 : b->transform[0]=_ogg_calloc(VI_TRANSFORMB,sizeof(*b->transform[0]));
197 0 : b->transform[1]=_ogg_calloc(VI_TRANSFORMB,sizeof(*b->transform[1]));
198 :
199 : /* MDCT is tranform 0 */
200 :
201 0 : b->transform[0][0]=_ogg_calloc(1,sizeof(mdct_lookup));
202 0 : b->transform[1][0]=_ogg_calloc(1,sizeof(mdct_lookup));
203 0 : mdct_init(b->transform[0][0],ci->blocksizes[0]>>hs);
204 0 : mdct_init(b->transform[1][0],ci->blocksizes[1]>>hs);
205 :
206 : /* Vorbis I uses only window type 0 */
207 0 : b->window[0]=ilog2(ci->blocksizes[0])-6;
208 0 : b->window[1]=ilog2(ci->blocksizes[1])-6;
209 :
210 0 : if(encp){ /* encode/decode differ here */
211 :
212 : /* analysis always needs an fft */
213 0 : drft_init(&b->fft_look[0],ci->blocksizes[0]);
214 0 : drft_init(&b->fft_look[1],ci->blocksizes[1]);
215 :
216 : /* finish the codebooks */
217 0 : if(!ci->fullbooks){
218 0 : ci->fullbooks=_ogg_calloc(ci->books,sizeof(*ci->fullbooks));
219 0 : for(i=0;i<ci->books;i++)
220 0 : vorbis_book_init_encode(ci->fullbooks+i,ci->book_param[i]);
221 : }
222 :
223 0 : b->psy=_ogg_calloc(ci->psys,sizeof(*b->psy));
224 0 : for(i=0;i<ci->psys;i++){
225 0 : _vp_psy_init(b->psy+i,
226 : ci->psy_param[i],
227 : &ci->psy_g_param,
228 0 : ci->blocksizes[ci->psy_param[i]->blockflag]/2,
229 : vi->rate);
230 : }
231 :
232 0 : v->analysisp=1;
233 : }else{
234 : /* finish the codebooks */
235 0 : if(!ci->fullbooks){
236 0 : ci->fullbooks=_ogg_calloc(ci->books,sizeof(*ci->fullbooks));
237 0 : for(i=0;i<ci->books;i++){
238 0 : if(ci->book_param[i]==NULL)
239 0 : goto abort_books;
240 0 : if(vorbis_book_init_decode(ci->fullbooks+i,ci->book_param[i]))
241 0 : goto abort_books;
242 : /* decode codebooks are now standalone after init */
243 0 : vorbis_staticbook_destroy(ci->book_param[i]);
244 0 : 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 0 : v->pcm_storage=ci->blocksizes[1];
252 0 : v->pcm=_ogg_malloc(vi->channels*sizeof(*v->pcm));
253 0 : v->pcmret=_ogg_malloc(vi->channels*sizeof(*v->pcmret));
254 : {
255 : int i;
256 0 : for(i=0;i<vi->channels;i++)
257 0 : 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 0 : v->lW=0; /* previous window size */
263 0 : v->W=0; /* current window size */
264 :
265 : /* all vector indexes */
266 0 : v->centerW=ci->blocksizes[1]/2;
267 :
268 0 : v->pcm_current=v->centerW;
269 :
270 : /* initialize all the backend lookups */
271 0 : b->flr=_ogg_calloc(ci->floors,sizeof(*b->flr));
272 0 : b->residue=_ogg_calloc(ci->residues,sizeof(*b->residue));
273 :
274 0 : for(i=0;i<ci->floors;i++)
275 0 : b->flr[i]=_floor_P[ci->floor_type[i]]->
276 0 : look(v,ci->floor_param[i]);
277 :
278 0 : for(i=0;i<ci->residues;i++)
279 0 : b->residue[i]=_residue_P[ci->residue_type[i]]->
280 0 : look(v,ci->residue_param[i]);
281 :
282 0 : return 0;
283 : abort_books:
284 0 : for(i=0;i<ci->books;i++){
285 0 : if(ci->book_param[i]!=NULL){
286 0 : vorbis_staticbook_destroy(ci->book_param[i]);
287 0 : ci->book_param[i]=NULL;
288 : }
289 : }
290 0 : vorbis_dsp_clear(v);
291 0 : return -1;
292 : }
293 :
294 : /* arbitrary settings and spec-mandated numbers get filled in here */
295 0 : int vorbis_analysis_init(vorbis_dsp_state *v,vorbis_info *vi){
296 0 : private_state *b=NULL;
297 :
298 0 : if(_vds_shared_init(v,vi,1))return 1;
299 0 : b=v->backend_state;
300 0 : b->psy_g_look=_vp_global_look(vi);
301 :
302 : /* Initialize the envelope state storage */
303 0 : b->ve=_ogg_calloc(1,sizeof(*b->ve));
304 0 : _ve_envelope_init(b->ve,vi);
305 :
306 0 : vorbis_bitrate_init(vi,&b->bms);
307 :
308 : /* compressed audio packets start after the headers
309 : with sequence number 3 */
310 0 : v->sequence=3;
311 :
312 0 : return(0);
313 : }
314 :
315 0 : void vorbis_dsp_clear(vorbis_dsp_state *v){
316 : int i;
317 0 : if(v){
318 0 : vorbis_info *vi=v->vi;
319 0 : codec_setup_info *ci=(vi?vi->codec_setup:NULL);
320 0 : private_state *b=v->backend_state;
321 :
322 0 : if(b){
323 :
324 0 : if(b->ve){
325 0 : _ve_envelope_clear(b->ve);
326 0 : _ogg_free(b->ve);
327 : }
328 :
329 0 : if(b->transform[0]){
330 0 : mdct_clear(b->transform[0][0]);
331 0 : _ogg_free(b->transform[0][0]);
332 0 : _ogg_free(b->transform[0]);
333 : }
334 0 : if(b->transform[1]){
335 0 : mdct_clear(b->transform[1][0]);
336 0 : _ogg_free(b->transform[1][0]);
337 0 : _ogg_free(b->transform[1]);
338 : }
339 :
340 0 : if(b->flr){
341 0 : if(ci)
342 0 : for(i=0;i<ci->floors;i++)
343 0 : _floor_P[ci->floor_type[i]]->
344 0 : free_look(b->flr[i]);
345 0 : _ogg_free(b->flr);
346 : }
347 0 : if(b->residue){
348 0 : if(ci)
349 0 : for(i=0;i<ci->residues;i++)
350 0 : _residue_P[ci->residue_type[i]]->
351 0 : free_look(b->residue[i]);
352 0 : _ogg_free(b->residue);
353 : }
354 0 : if(b->psy){
355 0 : if(ci)
356 0 : for(i=0;i<ci->psys;i++)
357 0 : _vp_psy_clear(b->psy+i);
358 0 : _ogg_free(b->psy);
359 : }
360 :
361 0 : if(b->psy_g_look)_vp_global_free(b->psy_g_look);
362 0 : vorbis_bitrate_clear(&b->bms);
363 :
364 0 : drft_clear(&b->fft_look[0]);
365 0 : drft_clear(&b->fft_look[1]);
366 :
367 : }
368 :
369 0 : if(v->pcm){
370 0 : if(vi)
371 0 : for(i=0;i<vi->channels;i++)
372 0 : if(v->pcm[i])_ogg_free(v->pcm[i]);
373 0 : _ogg_free(v->pcm);
374 0 : if(v->pcmret)_ogg_free(v->pcmret);
375 : }
376 :
377 0 : if(b){
378 : /* free header, header1, header2 */
379 0 : if(b->header)_ogg_free(b->header);
380 0 : if(b->header1)_ogg_free(b->header1);
381 0 : if(b->header2)_ogg_free(b->header2);
382 0 : _ogg_free(b);
383 : }
384 :
385 0 : memset(v,0,sizeof(*v));
386 : }
387 0 : }
388 :
389 0 : float **vorbis_analysis_buffer(vorbis_dsp_state *v, int vals){
390 : int i;
391 0 : vorbis_info *vi=v->vi;
392 0 : private_state *b=v->backend_state;
393 :
394 : /* free header, header1, header2 */
395 0 : if(b->header)_ogg_free(b->header);b->header=NULL;
396 0 : if(b->header1)_ogg_free(b->header1);b->header1=NULL;
397 0 : 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 0 : if(v->pcm_current+vals>=v->pcm_storage){
403 0 : v->pcm_storage=v->pcm_current+vals*2;
404 :
405 0 : for(i=0;i<vi->channels;i++){
406 0 : v->pcm[i]=_ogg_realloc(v->pcm[i],v->pcm_storage*sizeof(*v->pcm[i]));
407 : }
408 : }
409 :
410 0 : for(i=0;i<vi->channels;i++)
411 0 : v->pcmret[i]=v->pcm[i]+v->pcm_current;
412 :
413 0 : return(v->pcmret);
414 : }
415 :
416 0 : static void _preextrapolate_helper(vorbis_dsp_state *v){
417 : int i;
418 0 : int order=16;
419 0 : float *lpc=alloca(order*sizeof(*lpc));
420 0 : float *work=alloca(v->pcm_current*sizeof(*work));
421 : long j;
422 0 : v->preextrapolate=1;
423 :
424 0 : if(v->pcm_current-v->centerW>order*2){ /* safety */
425 0 : for(i=0;i<v->vi->channels;i++){
426 : /* need to run the extrapolation in reverse! */
427 0 : for(j=0;j<v->pcm_current;j++)
428 0 : work[j]=v->pcm[i][v->pcm_current-j-1];
429 :
430 : /* prime as above */
431 0 : 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 0 : vorbis_lpc_predict(lpc,work+v->pcm_current-v->centerW-order,
446 : order,
447 0 : work+v->pcm_current-v->centerW,
448 : v->centerW);
449 :
450 0 : for(j=0;j<v->pcm_current;j++)
451 0 : v->pcm[i][v->pcm_current-j-1]=work[j];
452 :
453 : }
454 : }
455 0 : }
456 :
457 :
458 : /* call with val<=0 to set eof */
459 :
460 0 : int vorbis_analysis_wrote(vorbis_dsp_state *v, int vals){
461 0 : vorbis_info *vi=v->vi;
462 0 : codec_setup_info *ci=vi->codec_setup;
463 :
464 0 : if(vals<=0){
465 0 : int order=32;
466 : int i;
467 0 : float *lpc=alloca(order*sizeof(*lpc));
468 :
469 : /* if it wasn't done earlier (very short sample) */
470 0 : if(!v->preextrapolate)
471 0 : _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 0 : vorbis_analysis_buffer(v,ci->blocksizes[1]*3);
480 0 : v->eofflag=v->pcm_current;
481 0 : v->pcm_current+=ci->blocksizes[1]*3;
482 :
483 0 : for(i=0;i<vi->channels;i++){
484 0 : if(v->eofflag>order*2){
485 : /* extrapolate with LPC to fill in */
486 : long n;
487 :
488 : /* make a predictor filter */
489 0 : n=v->eofflag;
490 0 : if(n>ci->blocksizes[1])n=ci->blocksizes[1];
491 0 : vorbis_lpc_from_data(v->pcm[i]+v->eofflag-n,lpc,n,order);
492 :
493 : /* run the predictor filter */
494 0 : vorbis_lpc_predict(lpc,v->pcm[i]+v->eofflag-order,order,
495 0 : 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 0 : memset(v->pcm[i]+v->eofflag,0,
501 0 : (v->pcm_current-v->eofflag)*sizeof(*v->pcm[i]));
502 :
503 : }
504 : }
505 : }else{
506 :
507 0 : if(v->pcm_current+vals>v->pcm_storage)
508 0 : return(OV_EINVAL);
509 :
510 0 : 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 0 : if(!v->preextrapolate && v->pcm_current-v->centerW>ci->blocksizes[1])
516 0 : _preextrapolate_helper(v);
517 :
518 : }
519 0 : 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 0 : int vorbis_analysis_blockout(vorbis_dsp_state *v,vorbis_block *vb){
525 : int i;
526 0 : vorbis_info *vi=v->vi;
527 0 : codec_setup_info *ci=vi->codec_setup;
528 0 : private_state *b=v->backend_state;
529 0 : vorbis_look_psy_global *g=b->psy_g_look;
530 0 : long beginW=v->centerW-ci->blocksizes[v->W]/2,centerNext;
531 0 : vorbis_block_internal *vbi=(vorbis_block_internal *)vb->internal;
532 :
533 : /* check to see if we're started... */
534 0 : if(!v->preextrapolate)return(0);
535 :
536 : /* check to see if we're done... */
537 0 : 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 0 : long bp=_ve_envelope_search(v);
548 0 : if(bp==-1){
549 :
550 0 : if(v->eofflag==0)return(0); /* not enough data currently to search for a
551 : full long block */
552 0 : v->nW=0;
553 : }else{
554 :
555 0 : if(ci->blocksizes[0]==ci->blocksizes[1])
556 0 : v->nW=0;
557 : else
558 0 : v->nW=bp;
559 : }
560 : }
561 :
562 0 : 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 0 : long blockbound=centerNext+ci->blocksizes[v->nW]/2;
568 0 : 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 0 : _vorbis_block_ripcord(vb);
583 0 : vb->lW=v->lW;
584 0 : vb->W=v->W;
585 0 : vb->nW=v->nW;
586 :
587 0 : if(v->W){
588 0 : if(!v->lW || !v->nW){
589 0 : vbi->blocktype=BLOCKTYPE_TRANSITION;
590 : /*fprintf(stderr,"-");*/
591 : }else{
592 0 : vbi->blocktype=BLOCKTYPE_LONG;
593 : /*fprintf(stderr,"_");*/
594 : }
595 : }else{
596 0 : if(_ve_envelope_mark(v)){
597 0 : vbi->blocktype=BLOCKTYPE_IMPULSE;
598 : /*fprintf(stderr,"|");*/
599 :
600 : }else{
601 0 : vbi->blocktype=BLOCKTYPE_PADDING;
602 : /*fprintf(stderr,".");*/
603 :
604 : }
605 : }
606 :
607 0 : vb->vd=v;
608 0 : vb->sequence=v->sequence++;
609 0 : vb->granulepos=v->granulepos;
610 0 : 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 0 : if(vbi->ampmax>g->ampmax)g->ampmax=vbi->ampmax;
617 0 : g->ampmax=_vp_ampmax_decay(g->ampmax,v);
618 0 : vbi->ampmax=g->ampmax;
619 :
620 0 : vb->pcm=_vorbis_block_alloc(vb,sizeof(*vb->pcm)*vi->channels);
621 0 : vbi->pcmdelay=_vorbis_block_alloc(vb,sizeof(*vbi->pcmdelay)*vi->channels);
622 0 : for(i=0;i<vi->channels;i++){
623 0 : vbi->pcmdelay[i]=
624 0 : _vorbis_block_alloc(vb,(vb->pcmend+beginW)*sizeof(*vbi->pcmdelay[i]));
625 0 : memcpy(vbi->pcmdelay[i],v->pcm[i],(vb->pcmend+beginW)*sizeof(*vbi->pcmdelay[i]));
626 0 : 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 0 : if(v->eofflag){
640 0 : if(v->centerW>=v->eofflag){
641 0 : v->eofflag=-1;
642 0 : vb->eofflag=1;
643 0 : return(1);
644 : }
645 : }
646 :
647 : /* advance storage vectors and clean up */
648 : {
649 0 : int new_centerNext=ci->blocksizes[1]/2;
650 0 : int movementW=centerNext-new_centerNext;
651 :
652 0 : if(movementW>0){
653 :
654 0 : _ve_envelope_shift(b->ve,movementW);
655 0 : v->pcm_current-=movementW;
656 :
657 0 : for(i=0;i<vi->channels;i++)
658 0 : memmove(v->pcm[i],v->pcm[i]+movementW,
659 0 : v->pcm_current*sizeof(*v->pcm[i]));
660 :
661 :
662 0 : v->lW=v->W;
663 0 : v->W=v->nW;
664 0 : v->centerW=new_centerNext;
665 :
666 0 : if(v->eofflag){
667 0 : v->eofflag-=movementW;
668 0 : if(v->eofflag<=0)v->eofflag=-1;
669 : /* do not add padding to end of stream! */
670 0 : if(v->centerW>=v->eofflag){
671 0 : v->granulepos+=movementW-(v->centerW-v->eofflag);
672 : }else{
673 0 : v->granulepos+=movementW;
674 : }
675 : }else{
676 0 : v->granulepos+=movementW;
677 : }
678 : }
679 : }
680 :
681 : /* done */
682 0 : return(1);
683 : }
684 :
685 0 : int vorbis_synthesis_restart(vorbis_dsp_state *v){
686 0 : vorbis_info *vi=v->vi;
687 : codec_setup_info *ci;
688 : int hs;
689 :
690 0 : if(!v->backend_state)return -1;
691 0 : if(!vi)return -1;
692 0 : ci=vi->codec_setup;
693 0 : if(!ci)return -1;
694 0 : hs=ci->halfrate_flag;
695 :
696 0 : v->centerW=ci->blocksizes[1]>>(hs+1);
697 0 : v->pcm_current=v->centerW>>hs;
698 :
699 0 : v->pcm_returned=-1;
700 0 : v->granulepos=-1;
701 0 : v->sequence=-1;
702 0 : v->eofflag=0;
703 0 : ((private_state *)(v->backend_state))->sample_count=-1;
704 :
705 0 : return(0);
706 : }
707 :
708 0 : int vorbis_synthesis_init(vorbis_dsp_state *v,vorbis_info *vi){
709 0 : if(_vds_shared_init(v,vi,0)){
710 0 : vorbis_dsp_clear(v);
711 0 : return 1;
712 : }
713 0 : vorbis_synthesis_restart(v);
714 0 : 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 0 : int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb){
722 0 : vorbis_info *vi=v->vi;
723 0 : codec_setup_info *ci=vi->codec_setup;
724 0 : private_state *b=v->backend_state;
725 0 : int hs=ci->halfrate_flag;
726 : int i,j;
727 :
728 0 : if(!vb)return(OV_EINVAL);
729 0 : if(v->pcm_current>v->pcm_returned && v->pcm_returned!=-1)return(OV_EINVAL);
730 :
731 0 : v->lW=v->W;
732 0 : v->W=vb->W;
733 0 : v->nW=-1;
734 :
735 0 : if((v->sequence==-1)||
736 0 : (v->sequence+1 != vb->sequence)){
737 0 : v->granulepos=-1; /* out of sequence; lose count */
738 0 : b->sample_count=-1;
739 : }
740 :
741 0 : v->sequence=vb->sequence;
742 :
743 0 : if(vb->pcm){ /* no pcm to process if vorbis_synthesis_trackonly
744 : was called on block */
745 0 : int n=ci->blocksizes[v->W]>>(hs+1);
746 0 : int n0=ci->blocksizes[0]>>(hs+1);
747 0 : int n1=ci->blocksizes[1]>>(hs+1);
748 :
749 : int thisCenter;
750 : int prevCenter;
751 :
752 0 : v->glue_bits+=vb->glue_bits;
753 0 : v->time_bits+=vb->time_bits;
754 0 : v->floor_bits+=vb->floor_bits;
755 0 : v->res_bits+=vb->res_bits;
756 :
757 0 : if(v->centerW){
758 0 : thisCenter=n1;
759 0 : prevCenter=0;
760 : }else{
761 0 : thisCenter=0;
762 0 : 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 0 : for(j=0;j<vi->channels;j++){
770 : /* the overlap/add section */
771 0 : if(v->lW){
772 0 : if(v->W){
773 : /* large/large */
774 0 : float *w=_vorbis_window_get(b->window[1]-hs);
775 0 : float *pcm=v->pcm[j]+prevCenter;
776 0 : float *p=vb->pcm[j];
777 0 : for(i=0;i<n1;i++)
778 0 : pcm[i]=pcm[i]*w[n1-i-1] + p[i]*w[i];
779 : }else{
780 : /* large/small */
781 0 : float *w=_vorbis_window_get(b->window[0]-hs);
782 0 : float *pcm=v->pcm[j]+prevCenter+n1/2-n0/2;
783 0 : float *p=vb->pcm[j];
784 0 : for(i=0;i<n0;i++)
785 0 : pcm[i]=pcm[i]*w[n0-i-1] +p[i]*w[i];
786 : }
787 : }else{
788 0 : if(v->W){
789 : /* small/large */
790 0 : float *w=_vorbis_window_get(b->window[0]-hs);
791 0 : float *pcm=v->pcm[j]+prevCenter;
792 0 : float *p=vb->pcm[j]+n1/2-n0/2;
793 0 : for(i=0;i<n0;i++)
794 0 : pcm[i]=pcm[i]*w[n0-i-1] +p[i]*w[i];
795 0 : for(;i<n1/2+n0/2;i++)
796 0 : pcm[i]=p[i];
797 : }else{
798 : /* small/small */
799 0 : float *w=_vorbis_window_get(b->window[0]-hs);
800 0 : float *pcm=v->pcm[j]+prevCenter;
801 0 : float *p=vb->pcm[j];
802 0 : for(i=0;i<n0;i++)
803 0 : pcm[i]=pcm[i]*w[n0-i-1] +p[i]*w[i];
804 : }
805 : }
806 :
807 : /* the copy section */
808 : {
809 0 : float *pcm=v->pcm[j]+thisCenter;
810 0 : float *p=vb->pcm[j]+n;
811 0 : for(i=0;i<n;i++)
812 0 : pcm[i]=p[i];
813 : }
814 : }
815 :
816 0 : if(v->centerW)
817 0 : v->centerW=0;
818 : else
819 0 : 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 0 : if(v->pcm_returned==-1){
826 0 : v->pcm_returned=thisCenter;
827 0 : v->pcm_current=thisCenter;
828 : }else{
829 0 : v->pcm_returned=prevCenter;
830 0 : v->pcm_current=prevCenter+
831 0 : ((ci->blocksizes[v->lW]/4+
832 0 : 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 0 : if(b->sample_count==-1){
849 0 : b->sample_count=0;
850 : }else{
851 0 : b->sample_count+=ci->blocksizes[v->lW]/4+ci->blocksizes[v->W]/4;
852 : }
853 :
854 0 : if(v->granulepos==-1){
855 0 : if(vb->granulepos!=-1){ /* only set if we have a position to set to */
856 :
857 0 : v->granulepos=vb->granulepos;
858 :
859 : /* is this a short page? */
860 0 : 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 0 : 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 0 : if(extra<0)
870 0 : extra=0;
871 :
872 0 : 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 0 : if(extra > (v->pcm_current - v->pcm_returned)<<hs)
883 0 : extra = (v->pcm_current - v->pcm_returned)<<hs;
884 :
885 0 : v->pcm_current-=extra>>hs;
886 : }else{
887 : /* trim the beginning */
888 0 : v->pcm_returned+=extra>>hs;
889 0 : if(v->pcm_returned>v->pcm_current)
890 0 : v->pcm_returned=v->pcm_current;
891 : }
892 :
893 : }
894 :
895 : }
896 : }else{
897 0 : v->granulepos+=ci->blocksizes[v->lW]/4+ci->blocksizes[v->W]/4;
898 0 : if(vb->granulepos!=-1 && v->granulepos!=vb->granulepos){
899 :
900 0 : if(v->granulepos>vb->granulepos){
901 0 : long extra=v->granulepos-vb->granulepos;
902 :
903 0 : if(extra)
904 0 : 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 0 : if(extra > (v->pcm_current - v->pcm_returned)<<hs)
911 0 : 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 0 : if(extra<0)
918 0 : extra=0;
919 :
920 0 : 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 0 : v->granulepos=vb->granulepos;
926 : }
927 : }
928 :
929 : /* Update, cleanup */
930 :
931 0 : if(vb->eofflag)v->eofflag=1;
932 0 : return(0);
933 :
934 : }
935 :
936 : /* pcm==NULL indicates we just want the pending samples, no more */
937 0 : int vorbis_synthesis_pcmout(vorbis_dsp_state *v,float ***pcm){
938 0 : vorbis_info *vi=v->vi;
939 :
940 0 : if(v->pcm_returned>-1 && v->pcm_returned<v->pcm_current){
941 0 : if(pcm){
942 : int i;
943 0 : for(i=0;i<vi->channels;i++)
944 0 : v->pcmret[i]=v->pcm[i]+v->pcm_returned;
945 0 : *pcm=v->pcmret;
946 : }
947 0 : return(v->pcm_current-v->pcm_returned);
948 : }
949 0 : return(0);
950 : }
951 :
952 0 : int vorbis_synthesis_read(vorbis_dsp_state *v,int n){
953 0 : if(n && v->pcm_returned+n>v->pcm_current)return(OV_EINVAL);
954 0 : v->pcm_returned+=n;
955 0 : 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 0 : int vorbis_synthesis_lapout(vorbis_dsp_state *v,float ***pcm){
964 0 : vorbis_info *vi=v->vi;
965 0 : codec_setup_info *ci=vi->codec_setup;
966 0 : int hs=ci->halfrate_flag;
967 :
968 0 : int n=ci->blocksizes[v->W]>>(hs+1);
969 0 : int n0=ci->blocksizes[0]>>(hs+1);
970 0 : int n1=ci->blocksizes[1]>>(hs+1);
971 : int i,j;
972 :
973 0 : 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 0 : if(v->centerW==n1){
986 : /* the data buffer wraps; swap the halves */
987 : /* slow, sure, small */
988 0 : for(j=0;j<vi->channels;j++){
989 0 : float *p=v->pcm[j];
990 0 : for(i=0;i<n1;i++){
991 0 : float temp=p[i];
992 0 : p[i]=p[i+n1];
993 0 : p[i+n1]=temp;
994 : }
995 : }
996 :
997 0 : v->pcm_current-=n1;
998 0 : v->pcm_returned-=n1;
999 0 : v->centerW=0;
1000 : }
1001 :
1002 : /* solidify buffer into contiguous space */
1003 0 : if((v->lW^v->W)==1){
1004 : /* long/short or short/long */
1005 0 : for(j=0;j<vi->channels;j++){
1006 0 : float *s=v->pcm[j];
1007 0 : float *d=v->pcm[j]+(n1-n0)/2;
1008 0 : for(i=(n1+n0)/2-1;i>=0;--i)
1009 0 : d[i]=s[i];
1010 : }
1011 0 : v->pcm_returned+=(n1-n0)/2;
1012 0 : v->pcm_current+=(n1-n0)/2;
1013 : }else{
1014 0 : if(v->lW==0){
1015 : /* short/short */
1016 0 : for(j=0;j<vi->channels;j++){
1017 0 : float *s=v->pcm[j];
1018 0 : float *d=v->pcm[j]+n1-n0;
1019 0 : for(i=n0-1;i>=0;--i)
1020 0 : d[i]=s[i];
1021 : }
1022 0 : v->pcm_returned+=n1-n0;
1023 0 : v->pcm_current+=n1-n0;
1024 : }
1025 : }
1026 :
1027 0 : if(pcm){
1028 : int i;
1029 0 : for(i=0;i<vi->channels;i++)
1030 0 : v->pcmret[i]=v->pcm[i]+v->pcm_returned;
1031 0 : *pcm=v->pcmret;
1032 : }
1033 :
1034 0 : return(n1+n-v->pcm_returned);
1035 :
1036 : }
1037 :
1038 0 : float *vorbis_window(vorbis_dsp_state *v,int W){
1039 0 : vorbis_info *vi=v->vi;
1040 0 : codec_setup_info *ci=vi->codec_setup;
1041 0 : int hs=ci->halfrate_flag;
1042 0 : private_state *b=v->backend_state;
1043 :
1044 0 : if(b->window[W]-1<0)return NULL;
1045 0 : return _vorbis_window_get(b->window[W]-hs);
1046 : }
|