📄 res0.c
字号:
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(fabs(in[0][l])>magmax)magmax=fabs(in[0][l]); for(k=1;k<ch;k++) if(fabs(in[k][l])>angmax)angmax=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, long **partword, int (*encode)(oggpack_buffer *,float *,int, codebook *,long *)){ long 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; long resbits[128]; long 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++){ long 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++){ long 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; long *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; } } } } } } /*{ long total=0; long 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);}/* 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, long (*decodepart)(codebook *, float *, oggpack_buffer *,int)){ long 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++){ long 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 */long **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, long **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); }}#endifint 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);}int res1_forward(vorbis_block *vb,vorbis_look_residue *vl, float **in,float **out,int *nonzero,int ch, long **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); }}long **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);}long **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, long **partword){ long 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); }}/* 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){ long 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={ &res0_pack, &res0_unpack, &res0_look, &res0_free_info, &res0_free_look, &res1_class, &res1_forward, &res1_inverse};vorbis_func_residue residue2_exportbundle={ &res0_pack, &res0_unpack, &res0_look, &res0_free_info, &res0_free_look, &res2_class, &res2_forward, &res2_inverse};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -