📄 mapping0.c
字号:
_vp_tonemask(psy_look, logfft, tone, global_ampmax, local_ampmax[i]);#if 0 if(vi->channels==2){ if(i==0) _analysis_output("toneL",seq,tone,n/2,1,0,0); else _analysis_output("toneR",seq,tone,n/2,1,0,0); }#endif /* third step; we offset the noise vectors, overlay tone masking. We then do a floor1-specific line fit. If we're performing bitrate management, the line fit is performed multiple times for up/down tweakage on demand. */ _vp_offset_and_mix(psy_look, noise, tone, 1, logmask);#if 0 if(vi->channels==2){ if(i==0) _analysis_output("mask1L",seq,logmask,n/2,1,0,0); else _analysis_output("mask1R",seq,logmask,n/2,1,0,0); }#endif /* this algorithm is hardwired to floor 1 for now; abort out if we're *not* floor1. This won't happen unless someone has broken the encode setup lib. Guard it anyway. */ if(ci->floor_type[info->floorsubmap[submap]]!=1)return(-1); floor_posts[i][PACKETBLOBS/2]= floor1_fit(vb,b->flr[info->floorsubmap[submap]], logmdct, logmask); /* are we managing bitrate? If so, perform two more fits for later rate tweaking (fits represent hi/lo) */ if(vorbis_bitrate_managed(vb) && floor_posts[i][PACKETBLOBS/2]){ /* higher rate by way of lower noise curve */ _vp_offset_and_mix(psy_look, noise, tone, 2, logmask);#if 0 if(vi->channels==2){ if(i==0) _analysis_output("mask2L",seq,logmask,n/2,1,0,0); else _analysis_output("mask2R",seq,logmask,n/2,1,0,0); }#endif floor_posts[i][PACKETBLOBS-1]= floor1_fit(vb,b->flr[info->floorsubmap[submap]], logmdct, logmask); /* lower rate by way of higher noise curve */ _vp_offset_and_mix(psy_look, noise, tone, 0, logmask);#if 0 if(vi->channels==2) if(i==0) _analysis_output("mask0L",seq,logmask,n/2,1,0,0); else _analysis_output("mask0R",seq,logmask,n/2,1,0,0);#endif floor_posts[i][0]= floor1_fit(vb,b->flr[info->floorsubmap[submap]], logmdct, logmask); /* we also interpolate a range of intermediate curves for intermediate rates */ for(k=1;k<PACKETBLOBS/2;k++) floor_posts[i][k]= floor1_interpolate_fit(vb,b->flr[info->floorsubmap[submap]], floor_posts[i][0], floor_posts[i][PACKETBLOBS/2], k*65536/(PACKETBLOBS/2)); for(k=PACKETBLOBS/2+1;k<PACKETBLOBS-1;k++) floor_posts[i][k]= floor1_interpolate_fit(vb,b->flr[info->floorsubmap[submap]], floor_posts[i][PACKETBLOBS/2], floor_posts[i][PACKETBLOBS-1], (k-PACKETBLOBS/2)*65536/(PACKETBLOBS/2)); } } } vbi->ampmax=global_ampmax; /* the next phases are performed once for vbr-only and PACKETBLOB times for bitrate managed modes. 1) encode actual mode being used 2) encode the floor for each channel, compute coded mask curve/res 3) normalize and couple. 4) encode residue 5) save packet bytes to the packetblob vector */ /* iterate over the many masking curve fits we've created */ { float **res_bundle=alloca(sizeof(*res_bundle)*vi->channels); float **couple_bundle=alloca(sizeof(*couple_bundle)*vi->channels); int *zerobundle=alloca(sizeof(*zerobundle)*vi->channels); int **sortindex=alloca(sizeof(*sortindex)*vi->channels); float **mag_memo; int **mag_sort; if(info->coupling_steps){ mag_memo=_vp_quantize_couple_memo(vb, &ci->psy_g_param, psy_look, info, gmdct); mag_sort=_vp_quantize_couple_sort(vb, psy_look, info, mag_memo); } memset(sortindex,0,sizeof(*sortindex)*vi->channels); if(psy_look->vi->normal_channel_p){ for(i=0;i<vi->channels;i++){ float *mdct =gmdct[i]; sortindex[i]=alloca(sizeof(**sortindex)*n/2); _vp_noise_normalize_sort(psy_look,mdct,sortindex[i]); } } for(k=(vorbis_bitrate_managed(vb)?0:PACKETBLOBS/2); k<=(vorbis_bitrate_managed(vb)?PACKETBLOBS-1:PACKETBLOBS/2); k++){ /* start out our new packet blob with packet type and mode */ /* Encode the packet type */ oggpack_write(&vb->opb,0,1); /* Encode the modenumber */ /* Encode frame mode, pre,post windowsize, then dispatch */ oggpack_write(&vb->opb,modenumber,b->modebits); if(vb->W){ oggpack_write(&vb->opb,vb->lW,1); oggpack_write(&vb->opb,vb->nW,1); } /* encode floor, compute masking curve, sep out residue */ for(i=0;i<vi->channels;i++){ int submap=info->chmuxlist[i]; float *mdct =gmdct[i]; float *res =vb->pcm[i]; int *ilogmask=ilogmaskch[i]= _vorbis_block_alloc(vb,n/2*sizeof(**gmdct)); nonzero[i]=floor1_encode(vb,b->flr[info->floorsubmap[submap]], floor_posts[i][k], ilogmask);#if 0 { char buf[80]; sprintf(buf,"maskI%c%d",i?'R':'L',k); float work[n/2]; for(j=0;j<n/2;j++) work[j]=FLOOR1_fromdB_LOOKUP[ilogmask[j]]; _analysis_output(buf,seq,work,n/2,1,1,0); }#endif _vp_remove_floor(psy_look, mdct, ilogmask, res, ci->psy_g_param.sliding_lowpass[vb->W][k]); _vp_noise_normalize(psy_look,res,res+n/2,sortindex[i]); #if 0 { char buf[80]; float work[n/2]; for(j=0;j<n/2;j++) work[j]=FLOOR1_fromdB_LOOKUP[ilogmask[j]]*(res+n/2)[j]; sprintf(buf,"resI%c%d",i?'R':'L',k); _analysis_output(buf,seq,work,n/2,1,1,0); }#endif } /* our iteration is now based on masking curve, not prequant and coupling. Only one prequant/coupling step */ /* quantize/couple */ /* incomplete implementation that assumes the tree is all depth one, or no tree at all */ if(info->coupling_steps){ _vp_couple(k, &ci->psy_g_param, psy_look, info, vb->pcm, mag_memo, mag_sort, ilogmaskch, nonzero, ci->psy_g_param.sliding_lowpass[vb->W][k]); } /* classify and encode by submap */ for(i=0;i<info->submaps;i++){ int ch_in_bundle=0; long **classifications; int resnum=info->residuesubmap[i]; for(j=0;j<vi->channels;j++){ if(info->chmuxlist[j]==i){ zerobundle[ch_in_bundle]=0; if(nonzero[j])zerobundle[ch_in_bundle]=1; res_bundle[ch_in_bundle]=vb->pcm[j]; couple_bundle[ch_in_bundle++]=vb->pcm[j]+n/2; } } classifications=_residue_P[ci->residue_type[resnum]]-> class(vb,b->residue[resnum],couple_bundle,zerobundle,ch_in_bundle); _residue_P[ci->residue_type[resnum]]-> forward(vb,b->residue[resnum], couple_bundle,NULL,zerobundle,ch_in_bundle,classifications); } /* ok, done encoding. Mark this protopacket and prepare next. */ oggpack_writealign(&vb->opb); vbi->packetblob_markers[k]=oggpack_bytes(&vb->opb); } }#if 0 seq++; total+=ci->blocksizes[vb->W]/4+ci->blocksizes[vb->nW]/4;#endif return(0);}static int mapping0_inverse(vorbis_block *vb,vorbis_info_mapping *l){ vorbis_dsp_state *vd=vb->vd; vorbis_info *vi=vd->vi; codec_setup_info *ci=vi->codec_setup; private_state *b=vd->backend_state; vorbis_info_mapping0 *info=(vorbis_info_mapping0 *)l; int hs=ci->halfrate_flag; int i,j; long n=vb->pcmend=ci->blocksizes[vb->W]; float **pcmbundle=alloca(sizeof(*pcmbundle)*vi->channels); int *zerobundle=alloca(sizeof(*zerobundle)*vi->channels); int *nonzero =alloca(sizeof(*nonzero)*vi->channels); void **floormemo=alloca(sizeof(*floormemo)*vi->channels); /* recover the spectral envelope; store it in the PCM vector for now */ for(i=0;i<vi->channels;i++){ int submap=info->chmuxlist[i]; floormemo[i]=_floor_P[ci->floor_type[info->floorsubmap[submap]]]-> inverse1(vb,b->flr[info->floorsubmap[submap]]); if(floormemo[i]) nonzero[i]=1; else nonzero[i]=0; memset(vb->pcm[i],0,sizeof(*vb->pcm[i])*n/2); } /* channel coupling can 'dirty' the nonzero listing */ for(i=0;i<info->coupling_steps;i++){ if(nonzero[info->coupling_mag[i]] || nonzero[info->coupling_ang[i]]){ nonzero[info->coupling_mag[i]]=1; nonzero[info->coupling_ang[i]]=1; } } /* recover the residue into our working vectors */ for(i=0;i<info->submaps;i++){ int ch_in_bundle=0; for(j=0;j<vi->channels;j++){ if(info->chmuxlist[j]==i){ if(nonzero[j]) zerobundle[ch_in_bundle]=1; else zerobundle[ch_in_bundle]=0; pcmbundle[ch_in_bundle++]=vb->pcm[j]; } } _residue_P[ci->residue_type[info->residuesubmap[i]]]-> inverse(vb,b->residue[info->residuesubmap[i]], pcmbundle,zerobundle,ch_in_bundle); } /* channel coupling */ for(i=info->coupling_steps-1;i>=0;i--){ float *pcmM=vb->pcm[info->coupling_mag[i]]; float *pcmA=vb->pcm[info->coupling_ang[i]]; for(j=0;j<n/2;j++){ float mag=pcmM[j]; float ang=pcmA[j]; if(mag>0) if(ang>0){ pcmM[j]=mag; pcmA[j]=mag-ang; }else{ pcmA[j]=mag; pcmM[j]=mag+ang; } else if(ang>0){ pcmM[j]=mag; pcmA[j]=mag+ang; }else{ pcmA[j]=mag; pcmM[j]=mag-ang; } } } /* compute and apply spectral envelope */ for(i=0;i<vi->channels;i++){ float *pcm=vb->pcm[i]; int submap=info->chmuxlist[i]; _floor_P[ci->floor_type[info->floorsubmap[submap]]]-> inverse2(vb,b->flr[info->floorsubmap[submap]], floormemo[i],pcm); } /* transform the PCM data; takes PCM vector, vb; modifies PCM vector */ /* only MDCT right now.... */ for(i=0;i<vi->channels;i++){ float *pcm=vb->pcm[i]; mdct_backward(b->transform[vb->W][0],pcm,pcm); } /* all done! */ return(0);}/* export hooks */vorbis_func_mapping mapping0_exportbundle={ &mapping0_pack, &mapping0_unpack, &mapping0_free_info, &mapping0_forward, &mapping0_inverse};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -