static void vorbis_encode_residue_setup(vorbis_info *vi,
					int number, int block,
					const vorbis_residue_template *res){

  codec_setup_info *ci=vi->codec_setup;
  int i,n;
  
  vorbis_info_residue0 *r=ci->residue_param[number]=
    _ogg_malloc(sizeof(*r));
  
  memcpy(r,res->res,sizeof(*r));
  if(ci->residues<=number)ci->residues=number+1;

  switch(ci->blocksizes[block]){
  case 64:case 128:case 256:
    r->grouping=16;
    break;
  default:
    r->grouping=32;
    break;
  }
  ci->residue_type[number]=res->res_type;

  /* to be adjusted by lowpass/pointlimit later */
  n=r->end=ci->blocksizes[block]>>1; 
  if(res->res_type==2)
    n=r->end*=vi->channels;
  
  /* fill in all the books */
  {
    int booklist=0,k;
    
    if(ci->hi.managed){
      for(i=0;i<r->partitions;i++)
	for(k=0;k<3;k++)
	  if(res->books_base_managed->books[i][k])
	    r->secondstages[i]|=(1<<k);

      r->groupbook=book_dup_or_new(ci,res->book_aux_managed);
      ci->book_param[r->groupbook]=(static_codebook *)res->book_aux_managed;
    
      for(i=0;i<r->partitions;i++){
	for(k=0;k<3;k++){
	  if(res->books_base_managed->books[i][k]){
	    int bookid=book_dup_or_new(ci,res->books_base_managed->books[i][k]);
	    r->booklist[booklist++]=bookid;
	    ci->book_param[bookid]=(static_codebook *)res->books_base_managed->books[i][k];
	  }
	}
      }

    }else{

      for(i=0;i<r->partitions;i++)
	for(k=0;k<3;k++)
	  if(res->books_base->books[i][k])
	    r->secondstages[i]|=(1<<k);
  
      r->groupbook=book_dup_or_new(ci,res->book_aux);
      ci->book_param[r->groupbook]=(static_codebook *)res->book_aux;
      
      for(i=0;i<r->partitions;i++){
	for(k=0;k<3;k++){
	  if(res->books_base->books[i][k]){
	    int bookid=book_dup_or_new(ci,res->books_base->books[i][k]);
	    r->booklist[booklist++]=bookid;
	    ci->book_param[bookid]=(static_codebook *)res->books_base->books[i][k];
	  }
	}
      }
    }
  }
  
  /* lowpass setup/pointlimit */
  {
    double freq=ci->hi.lowpass_kHz*1000.;
    vorbis_info_floor1 *f=ci->floor_param[block]; /* by convention */
    double nyq=vi->rate/2.;
    long blocksize=ci->blocksizes[block]>>1;

    /* lowpass needs to be set in the floor and the residue. */    
    if(freq>nyq)freq=nyq;
    /* in the floor, the granularity can be very fine; it doesn't alter
       the encoding structure, only the samples used to fit the floor
       approximation */
    f->n=freq/nyq*blocksize; 

    /* this res may by limited by the maximum pointlimit of the mode,
       not the lowpass. the floor is always lowpass limited. */
    if(res->limit_type){
      if(ci->hi.managed)
	freq=ci->psy_g_param.coupling_pkHz[PACKETBLOBS-1]*1000.;
      else
	freq=ci->psy_g_param.coupling_pkHz[PACKETBLOBS/2]*1000.;
      if(freq>nyq)freq=nyq;
    }
    
    /* in the residue, we're constrained, physically, by partition
       boundaries.  We still lowpass 'wherever', but we have to round up
       here to next boundary, or the vorbis spec will round it *down* to
       previous boundary in encode/decode */
    if(ci->residue_type[block]==2){
      r->end=(int)((freq/nyq*blocksize*2)/r->grouping+.9)* /* round up only if we're well past */
	r->grouping;
	  ci->block_lowpassr[block]=r->end/2; /* lowpass (residue) */
    }else{
      r->end=(int)((freq/nyq*blocksize)/r->grouping+.9)* /* round up only if we're well past */
	r->grouping;
	  ci->block_lowpassr[block]=r->end; /* lowpass (residue) */
	}
  }
}
Exemplo n.º 2
0
static void vorbis_encode_residue_setup(vorbis_info *vi,
                                        int number, int block,
                                        const vorbis_residue_template *res){

  codec_setup_info *ci=vi->codec_setup;
  int i;

  vorbis_info_residue0 *r=ci->residue_param[number]=
    _ogg_malloc(sizeof(*r));

  memcpy(r,res->res,sizeof(*r));
  if(ci->residues<=number)ci->residues=number+1;

  r->grouping=res->grouping;
  ci->residue_type[number]=res->res_type;

  /* fill in all the books */
  {
    int booklist=0,k;

    if(ci->hi.managed){
      for(i=0;i<r->partitions;i++)
        for(k=0;k<4;k++)
          if(res->books_base_managed->books[i][k])
            r->secondstages[i]|=(1<<k);

      r->groupbook=book_dup_or_new(ci,res->book_aux_managed);
      ci->book_param[r->groupbook]=(static_codebook *)res->book_aux_managed;

      for(i=0;i<r->partitions;i++){
        for(k=0;k<4;k++){
          if(res->books_base_managed->books[i][k]){
            int bookid=book_dup_or_new(ci,res->books_base_managed->books[i][k]);
            r->booklist[booklist++]=bookid;
            ci->book_param[bookid]=(static_codebook *)res->books_base_managed->books[i][k];
          }
        }
      }

    }else{

      for(i=0;i<r->partitions;i++)
        for(k=0;k<4;k++)
          if(res->books_base->books[i][k])
            r->secondstages[i]|=(1<<k);

      r->groupbook=book_dup_or_new(ci,res->book_aux);
      ci->book_param[r->groupbook]=(static_codebook *)res->book_aux;

      for(i=0;i<r->partitions;i++){
        for(k=0;k<4;k++){
          if(res->books_base->books[i][k]){
            int bookid=book_dup_or_new(ci,res->books_base->books[i][k]);
            r->booklist[booklist++]=bookid;
            ci->book_param[bookid]=(static_codebook *)res->books_base->books[i][k];
          }
        }
      }
    }
  }

  /* lowpass setup/pointlimit */
  {
    double freq=ci->hi.lowpass_kHz*1000.;
    vorbis_info_floor1 *f=ci->floor_param[block]; /* by convention */
    double nyq=vi->rate/2.;
    long blocksize=ci->blocksizes[block]>>1;

    /* lowpass needs to be set in the floor and the residue. */
    if(freq>nyq)freq=nyq;
    /* in the floor, the granularity can be very fine; it doesn't alter
       the encoding structure, only the samples used to fit the floor
       approximation */
    f->n=freq/nyq*blocksize;

    /* this res may by limited by the maximum pointlimit of the mode,
       not the lowpass. the floor is always lowpass limited. */
    switch(res->limit_type){
    case 1: /* point stereo limited */
      if(ci->hi.managed)
        freq=ci->psy_g_param.coupling_pkHz[PACKETBLOBS-1]*1000.;
      else
        freq=ci->psy_g_param.coupling_pkHz[PACKETBLOBS/2]*1000.;
      if(freq>nyq)freq=nyq;
      break;
    case 2: /* LFE channel; lowpass at ~ 250Hz */
      freq=250;
      break;
    default:
      /* already set */
      break;
    }

    /* in the residue, we're constrained, physically, by partition
       boundaries.  We still lowpass 'wherever', but we have to round up
       here to next boundary, or the vorbis spec will round it *down* to
       previous boundary in encode/decode */
    if(ci->residue_type[number]==2){
      /* residue 2 bundles together multiple channels; used by stereo
         and surround.  Count the channels in use */
      /* Multiple maps/submaps can point to the same residue.  In the case
         of residue 2, they all better have the same number of
         channels/samples. */
      int j,k,ch=0;
      for(i=0;i<ci->maps&&ch==0;i++){
        vorbis_info_mapping0 *mi=(vorbis_info_mapping0 *)ci->map_param[i];
        for(j=0;j<mi->submaps && ch==0;j++)
          if(mi->residuesubmap[j]==number) /* we found a submap referencing theis residue backend */
            for(k=0;k<vi->channels;k++)
              if(mi->chmuxlist[k]==j) /* this channel belongs to the submap */
                ch++;
      }

      r->end=(int)((freq/nyq*blocksize*ch)/r->grouping+.9)* /* round up only if we're well past */
        r->grouping;
      /* the blocksize and grouping may disagree at the end */
      if(r->end>blocksize*ch)r->end=blocksize*ch/r->grouping*r->grouping;

    }else{

      r->end=(int)((freq/nyq*blocksize)/r->grouping+.9)* /* round up only if we're well past */
        r->grouping;
      /* the blocksize and grouping may disagree at the end */
      if(r->end>blocksize)r->end=blocksize/r->grouping*r->grouping;

    }

    if(r->end==0)r->end=r->grouping; /* LFE channel */

  }
}