int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb){ vorbis_info *vi=v->vi; codec_setup_info *ci=vi->codec_setup; private_state *b=v->backend_state; int hs=ci->halfrate_flag; int i,j; if(!vb)return(OV_EINVAL); if(v->pcm_current>v->pcm_returned && v->pcm_returned!=-1)return(OV_EINVAL); v->lW=v->W; v->W=vb->W; v->nW=-1; if((v->sequence==-1)|| (v->sequence+1 != vb->sequence)){ v->granulepos=-1; /* out of sequence; lose count */ b->sample_count=-1; } v->sequence=vb->sequence; if(vb->pcm){ /* no pcm to process if vorbis_synthesis_trackonly was called on block */ int n=ci->blocksizes[v->W]>>(hs+1); int n0=ci->blocksizes[0]>>(hs+1); int n1=ci->blocksizes[1]>>(hs+1); int thisCenter; int prevCenter; v->glue_bits+=vb->glue_bits; v->time_bits+=vb->time_bits; v->floor_bits+=vb->floor_bits; v->res_bits+=vb->res_bits; if(v->centerW){ thisCenter=n1; prevCenter=0; }else{ thisCenter=0; prevCenter=n1; } /* v->pcm is now used like a two-stage double buffer. We don't want to have to constantly shift *or* adjust memory usage. Don't accept a new block until the old is shifted out */ for(j=0;j<vi->channels;j++){ /* the overlap/add section */ if(v->lW){ if(v->W){ /* large/large */ float *w=_vorbis_window_get(b->window[1]-hs); float *pcm=v->pcm[j]+prevCenter; float *p=vb->pcm[j]; for(i=0;i<n1;i++) pcm[i]=pcm[i]*w[n1-i-1] + p[i]*w[i]; }else{ /* large/small */ float *w=_vorbis_window_get(b->window[0]-hs); float *pcm=v->pcm[j]+prevCenter+n1/2-n0/2; float *p=vb->pcm[j]; for(i=0;i<n0;i++) pcm[i]=pcm[i]*w[n0-i-1] +p[i]*w[i]; } }else{ if(v->W){ /* small/large */ float *w=_vorbis_window_get(b->window[0]-hs); float *pcm=v->pcm[j]+prevCenter; float *p=vb->pcm[j]+n1/2-n0/2; for(i=0;i<n0;i++) pcm[i]=pcm[i]*w[n0-i-1] +p[i]*w[i]; for(;i<n1/2+n0/2;i++) pcm[i]=p[i]; }else{ /* small/small */ float *w=_vorbis_window_get(b->window[0]-hs); float *pcm=v->pcm[j]+prevCenter; float *p=vb->pcm[j]; for(i=0;i<n0;i++) pcm[i]=pcm[i]*w[n0-i-1] +p[i]*w[i]; } } /* the copy section */ { float *pcm=v->pcm[j]+thisCenter; float *p=vb->pcm[j]+n; for(i=0;i<n;i++) pcm[i]=p[i]; } } if(v->centerW) v->centerW=0; else v->centerW=n1; /* deal with initial packet state; we do this using the explicit pcm_returned==-1 flag otherwise we're sensitive to first block being short or long */ if(v->pcm_returned==-1){ v->pcm_returned=thisCenter; v->pcm_current=thisCenter; }else{ v->pcm_returned=prevCenter; v->pcm_current=prevCenter+ ((ci->blocksizes[v->lW]/4+ ci->blocksizes[v->W]/4)>>hs); } }
static int _vds_shared_init(vorbis_dsp_state *v,vorbis_info *vi) { int i; codec_setup_info *ci=vi->codec_setup; backend_lookup_state *b=NULL; _ogg_memset(v,0,sizeof(*v)); b=v->backend_state=_ogg_calloc(1,sizeof(*b)); if(!b) return -1; v->vi=vi; b->modebits=ilog2(ci->modes); b->transform[0]=oggdec_mdct_init(ci->blocksizes[0]); b->transform[1]=oggdec_mdct_init(ci->blocksizes[1]); if(!b->transform[0] || !b->transform[1]) return -1; b->window[0]=_vorbis_window_get(ci->blocksizes[0]/2); b->window[1]=_vorbis_window_get(ci->blocksizes[1]/2); if(!b->window[0] || !b->window[1]) return -1; if(!ci->fullbooks){ ci->fullbooks=_ogg_calloc(ci->books,sizeof(*ci->fullbooks)); for(i=0;i<ci->books;i++){ if(vorbis_book_init_decode(ci->fullbooks+i,ci->book_param[i])<0) return -1; } for(i=0;i<ci->books;i++){ vorbis_staticbook_destroy(ci->book_param[i]); ci->book_param[i]=NULL; } } v->pcm_storage=ci->blocksizes[1]; v->pcm=_ogg_malloc(vi->channels*sizeof(*v->pcm)); v->pcmret=_ogg_malloc(vi->channels*sizeof(*v->pcmret)); if(!v->pcm || !v->pcmret) return -1; for(i=0;i<vi->channels;i++){ v->pcm[i]=_ogg_malloc(v->pcm_storage*sizeof(*v->pcm[i])); if(!v->pcm[i]) return -1; } b->flr=_ogg_calloc(ci->floors,sizeof(*b->flr)); b->residue=_ogg_calloc(ci->residues,sizeof(*b->residue)); if(!b->flr || !b->residue) return -1; for(i=0;i<ci->floors;i++) b->flr[i]=_floor_P[ci->floor_type[i]]->look(v,ci->floor_param[i]); for(i=0;i<ci->residues;i++) b->residue[i]=_residue_P[ci->residue_type[i]]->look(v,ci->residue_param[i]); return(0); }