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 (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 =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 =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 | |