Beispiel #1
0
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);
    }

  }
Beispiel #2
0
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);
}