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