⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 res0.c

📁 OGG文件格式音频数解压缩SDK.现在OGG文件格式在一些游戏开发中使用的比较多.
💻 C
📖 第 1 页 / 共 2 页
字号:
  partword[0]=_vorbis_block_alloc(vb,n*ch/samples_per_partition*sizeof(*partword[0]));
  memset(partword[0],0,n*ch/samples_per_partition*sizeof(*partword[0]));

  for(i=0,l=info->begin/ch;i<partvals;i++){
    float magmax=0.f;
    float angmax=0.f;
    for(j=0;j<samples_per_partition;j+=ch){
      if(ogg_fabs(in[0][l])>magmax)magmax=ogg_fabs(in[0][l]);
      for(k=1;k<ch;k++)
	if(ogg_fabs(in[k][l])>angmax)angmax=ogg_fabs(in[k][l]);
      l++;
    }

    for(j=0;j<possible_partitions-1;j++)
      if(magmax<=info->classmetric1[j] &&
	 angmax<=info->classmetric2[j])
	break;

    partword[0][i]=j;

  }  
  
#ifdef TRAIN_RESAUX
  sprintf(buffer,"resaux_%d.vqd",look->train_seq);
  of=fopen(buffer,"a");
  for(i=0;i<partvals;i++)
    fprintf(of,"%ld, ",partword[0][i]);
  fprintf(of,"\n");
  fclose(of);
#endif

  look->frames++;

  return(partword);
}

static int _01forward(vorbis_block *vb,vorbis_look_residue *vl,
		      float **in,int ch,
		      ogg_int32_t **partword,
		      int (*encode)(oggpack_buffer *,float *,int,
				    codebook *,ogg_int32_t *)){
  ogg_int32_t i,j,k,s;
  vorbis_look_residue0 *look=(vorbis_look_residue0 *)vl;
  vorbis_info_residue0 *info=look->info;

  vorbis_dsp_state      *vd=vb->vd;

  /* move all this setup out later */
  int samples_per_partition=info->grouping;
  int possible_partitions=info->partitions;
  int partitions_per_word=look->phrasebook->dim;
  int n=info->end-info->begin;

  int partvals=n/samples_per_partition;
  ogg_int32_t resbits[128];
  ogg_int32_t resvals[128];

#ifdef TRAIN_RES
  for(i=0;i<ch;i++)
    for(j=info->begin;j<info->end;j++){
      if(in[i][j]>look->tmax)look->tmax=in[i][j];
      if(in[i][j]<look->tmin)look->tmin=in[i][j];
    }
#endif

  memset(resbits,0,sizeof(resbits));
  memset(resvals,0,sizeof(resvals));
  
  /* we code the partition words for each channel, then the residual
     words for a partition per channel until we've written all the
     residual words for that partition word.  Then write the next
     partition channel words... */

  for(s=0;s<look->stages;s++){

    for(i=0;i<partvals;){

      /* first we encode a partition codeword for each channel */
      if(s==0){
	for(j=0;j<ch;j++){
	  ogg_int32_t val=partword[j][i];
	  for(k=1;k<partitions_per_word;k++){
	    val*=possible_partitions;
	    if(i+k<partvals)
	      val+=partword[j][i+k];
	  }	

	  /* training hack */
	  if(val<look->phrasebook->entries)
	    look->phrasebits+=vorbis_book_encode(look->phrasebook,val,&vb->opb);
#if 0 /*def TRAIN_RES*/
	  else
	    fprintf(stderr,"!");
#endif
	
	}
      }
      
      /* now we encode interleaved residual values for the partitions */
      for(k=0;k<partitions_per_word && i<partvals;k++,i++){
	ogg_int32_t offset=i*samples_per_partition+info->begin;
	
	for(j=0;j<ch;j++){
	  if(s==0)resvals[partword[j][i]]+=samples_per_partition;
	  if(info->secondstages[partword[j][i]]&(1<<s)){
	    codebook *statebook=look->partbooks[partword[j][i]][s];
	    if(statebook){
	      int ret;
	      ogg_int32_t *accumulator=NULL;

#ifdef TRAIN_RES
	      accumulator=look->training_data[s][partword[j][i]];
	      {
		int l;
		float *samples=in[j]+offset;
		for(l=0;l<samples_per_partition;l++){
		  if(samples[l]<look->training_min[s][partword[j][i]])
		    look->training_min[s][partword[j][i]]=samples[l];
		  if(samples[l]>look->training_max[s][partword[j][i]])
		    look->training_max[s][partword[j][i]]=samples[l];
		}
	      }
#endif
	      
	      ret=encode(&vb->opb,in[j]+offset,samples_per_partition,
			 statebook,accumulator);

	      look->postbits+=ret;
	      resbits[partword[j][i]]+=ret;
	    }
	  }
	}
      }
    }
  }

  /*{
    ogg_int32_t total=0;
    ogg_int32_t totalbits=0;
    fprintf(stderr,"%d :: ",vb->mode);
    for(k=0;k<possible_partitions;k++){
      fprintf(stderr,"%ld/%1.2g, ",resvals[k],(float)resbits[k]/resvals[k]);
      total+=resvals[k];
      totalbits+=resbits[k];
      }
    
    fprintf(stderr,":: %ld:%1.2g\n",total,(double)totalbits/total);
    }*/
  return(0);
}
#endif

/* a truncated packet here just means 'stop working'; it's not an error */
static int _01inverse(vorbis_block *vb,vorbis_look_residue *vl,
		      float **in,int ch,
		      ogg_int32_t (*decodepart)(codebook *, float *, 
					 oggpack_buffer *,int)){

  ogg_int32_t i,j,k,l,s;
  vorbis_look_residue0 *look=(vorbis_look_residue0 *)vl;
  vorbis_info_residue0 *info=look->info;

  /* move all this setup out later */
  int samples_per_partition=info->grouping;
  int partitions_per_word=look->phrasebook->dim;
  int n=info->end-info->begin;
  
  int partvals=n/samples_per_partition;
  int partwords=(partvals+partitions_per_word-1)/partitions_per_word;
  int ***partword=alloca(ch*sizeof(*partword));

  for(j=0;j<ch;j++)
    partword[j]=_vorbis_block_alloc(vb,partwords*sizeof(*partword[j]));

  for(s=0;s<look->stages;s++){

    /* each loop decodes on partition codeword containing 
       partitions_pre_word partitions */
    for(i=0,l=0;i<partvals;l++){
      if(s==0){
	/* fetch the partition word for each channel */
	for(j=0;j<ch;j++){
	  int temp=vorbis_book_decode(look->phrasebook,&vb->opb);
	  if(temp==-1)goto eopbreak;
	  partword[j][l]=look->decodemap[temp];
	  if(partword[j][l]==NULL)goto errout;
	}
      }
      
      /* now we decode residual values for the partitions */
      for(k=0;k<partitions_per_word && i<partvals;k++,i++)
	for(j=0;j<ch;j++){
	  ogg_int32_t offset=info->begin+i*samples_per_partition;
	  if(info->secondstages[partword[j][l][k]]&(1<<s)){
	    codebook *stagebook=look->partbooks[partword[j][l][k]][s];
	    if(stagebook){
	      if(decodepart(stagebook,in[j]+offset,&vb->opb,
			    samples_per_partition)==-1)goto eopbreak;
	    }
	  }
	}
    } 
  }
  
 errout:
 eopbreak:
  return(0);
}

#if 0
/* residue 0 and 1 are just slight variants of one another. 0 is
   interleaved, 1 is not */
ogg_int32_t **res0_class(vorbis_block *vb,vorbis_look_residue *vl,
		  float **in,int *nonzero,int ch){
  /* we encode only the nonzero parts of a bundle */
  int i,used=0;
  for(i=0;i<ch;i++)
    if(nonzero[i])
      in[used++]=in[i];
  if(used)
    /*return(_01class(vb,vl,in,used,_interleaved_testhack));*/
    return(_01class(vb,vl,in,used));
  else
    return(0);
}

int res0_forward(vorbis_block *vb,vorbis_look_residue *vl,
		 float **in,float **out,int *nonzero,int ch,
		 ogg_int32_t **partword){
  /* we encode only the nonzero parts of a bundle */
  int i,j,used=0,n=vb->pcmend/2;
  for(i=0;i<ch;i++)
    if(nonzero[i]){
      if(out)
	for(j=0;j<n;j++)
	  out[i][j]+=in[i][j];
      in[used++]=in[i];
    }
  if(used){
    int ret=_01forward(vb,vl,in,used,partword,
		      _interleaved_encodepart);
    if(out){
      used=0;
      for(i=0;i<ch;i++)
	if(nonzero[i]){
	  for(j=0;j<n;j++)
	    out[i][j]-=in[used][j];
	  used++;
	}
    }
    return(ret);
  }else{
    return(0);
  }
}
#endif

int res0_inverse(vorbis_block *vb,vorbis_look_residue *vl,
		 float **in,int *nonzero,int ch){
  int i,used=0;
  for(i=0;i<ch;i++)
    if(nonzero[i])
      in[used++]=in[i];
  if(used)
    return(_01inverse(vb,vl,in,used,vorbis_book_decodevs_add));
  else
    return(0);
}
#if 0
int res1_forward(vorbis_block *vb,vorbis_look_residue *vl,
		 float **in,float **out,int *nonzero,int ch,
		 ogg_int32_t **partword){
  int i,j,used=0,n=vb->pcmend/2;
  for(i=0;i<ch;i++)
    if(nonzero[i]){
      if(out)
	for(j=0;j<n;j++)
	  out[i][j]+=in[i][j];
      in[used++]=in[i];
    }

  if(used){
    int ret=_01forward(vb,vl,in,used,partword,_encodepart);
    if(out){
      used=0;
      for(i=0;i<ch;i++)
	if(nonzero[i]){
	  for(j=0;j<n;j++)
	    out[i][j]-=in[used][j];
	  used++;
	}
    }
    return(ret);
  }else{
    return(0);
  }
}
#endif
ogg_int32_t **res1_class(vorbis_block *vb,vorbis_look_residue *vl,
		  float **in,int *nonzero,int ch){
  int i,used=0;
  for(i=0;i<ch;i++)
    if(nonzero[i])
      in[used++]=in[i];
  if(used)
    return(_01class(vb,vl,in,used));
  else
    return(0);
}

int res1_inverse(vorbis_block *vb,vorbis_look_residue *vl,
		 float **in,int *nonzero,int ch){
  int i,used=0;
  for(i=0;i<ch;i++)
    if(nonzero[i])
      in[used++]=in[i];
  if(used)
    return(_01inverse(vb,vl,in,used,vorbis_book_decodev_add));
  else
    return(0);
}

#if 0
ogg_int32_t **res2_class(vorbis_block *vb,vorbis_look_residue *vl,
		  float **in,int *nonzero,int ch){
  int i,used=0;
  for(i=0;i<ch;i++)
    if(nonzero[i])used++;
  if(used)
    return(_2class(vb,vl,in,ch));
  else
    return(0);
}

/* res2 is slightly more different; all the channels are interleaved
   into a single vector and encoded. */

int res2_forward(vorbis_block *vb,vorbis_look_residue *vl,
		 float **in,float **out,int *nonzero,int ch,
		 ogg_int32_t **partword){
  ogg_int32_t i,j,k,n=vb->pcmend/2,used=0;

  /* don't duplicate the code; use a working vector hack for now and
     reshape ourselves into a single channel res1 */
  /* ugly; reallocs for each coupling pass :-( */
  float *work=_vorbis_block_alloc(vb,ch*n*sizeof(*work));
  for(i=0;i<ch;i++){
    float *pcm=in[i];
    if(nonzero[i])used++;
    for(j=0,k=i;j<n;j++,k+=ch)
      work[k]=pcm[j];
  }
  
  if(used){
    int ret=_01forward(vb,vl,&work,1,partword,_encodepart);
    /* update the sofar vector */
    if(out){
      for(i=0;i<ch;i++){
	float *pcm=in[i];
	float *sofar=out[i];
	for(j=0,k=i;j<n;j++,k+=ch)
	  sofar[j]+=pcm[j]-work[k];
	
      }
    }
    return(ret);
  }else{
    return(0);
  }
}
#endif
/* duplicate code here as speed is somewhat more important */
int res2_inverse(vorbis_block *vb,vorbis_look_residue *vl,
		 float **in,int *nonzero,int ch){
  ogg_int32_t i,k,l,s;
  vorbis_look_residue0 *look=(vorbis_look_residue0 *)vl;
  vorbis_info_residue0 *info=look->info;

  /* move all this setup out later */
  int samples_per_partition=info->grouping;
  int partitions_per_word=look->phrasebook->dim;
  int n=info->end-info->begin;

  int partvals=n/samples_per_partition;
  int partwords=(partvals+partitions_per_word-1)/partitions_per_word;
  int **partword=_vorbis_block_alloc(vb,partwords*sizeof(*partword));

  for(i=0;i<ch;i++)if(nonzero[i])break;
  if(i==ch)return(0); /* no nonzero vectors */

  for(s=0;s<look->stages;s++){
    for(i=0,l=0;i<partvals;l++){

      if(s==0){
	/* fetch the partition word */
	int temp=vorbis_book_decode(look->phrasebook,&vb->opb);
	if(temp==-1)goto eopbreak;
	partword[l]=look->decodemap[temp];
	if(partword[l]==NULL)goto errout;
      }

      /* now we decode residual values for the partitions */
      for(k=0;k<partitions_per_word && i<partvals;k++,i++)
	if(info->secondstages[partword[l][k]]&(1<<s)){
	  codebook *stagebook=look->partbooks[partword[l][k]][s];
	  
	  if(stagebook){
	    if(vorbis_book_decodevv_add(stagebook,in,
					i*samples_per_partition+info->begin,ch,
					&vb->opb,samples_per_partition)==-1)
	      goto eopbreak;
	  }
	}
    } 
  }
  
 errout:
 eopbreak:
  return(0);
}


vorbis_func_residue residue0_exportbundle={
  NULL,
  &res0_unpack,
  &res0_look,
  &res0_free_info,
  &res0_free_look,
  NULL,
  NULL,
  &res0_inverse
};

vorbis_func_residue residue1_exportbundle={
  NULL, //&res0_pack,
  &res0_unpack,
  &res0_look,
  &res0_free_info,
  &res0_free_look,
  NULL, //&res1_class,
  NULL, //&res1_forward,
  &res1_inverse
};

vorbis_func_residue residue2_exportbundle={
  NULL, //&res0_pack,
  &res0_unpack,
  &res0_look,
  &res0_free_info,
  &res0_free_look,
  NULL, //&res2_class,
  NULL, //&res2_forward,
  &res2_inverse
};

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -