- drft_forward(&look->fft_look,additional);
-
- additional[0]*=scale;
- for(j=1;j<n-1;j+=2)
- additional[(j+1)>>1]=scale*FAST_HYPOT(additional[j],additional[j+1]);
-
- /* set up our masking data working vector, and stash unquantized
- data for later */
- /*memcpy(pcm+n/2,pcm,n*sizeof(float)/2);*/
- memcpy(additional+n/2,pcm,n*sizeof(float)/2);
-
- /* begin masking work */
- floor[i]=_vorbis_block_alloc(vb,n*sizeof(float)/2);
-
- //_analysis_output("fft",seq,additional,n/2,0,1);
- //_analysis_output("mdct",seq,additional+n/2,n/2,0,1);
- //_analysis_output("lfft",seq,additional,n/2,0,0);
- //_analysis_output("lmdct",seq,additional+n/2,n/2,0,0);
-
- /* perform psychoacoustics; do masking */
- ret=_vp_compute_mask(look->psy_look+submap,additional,additional+n/2,
- floor[i],NULL,vbi->ampmax);
- if(ret>newmax)newmax=ret;
-
- _analysis_output("prefloor",seq,floor[i],n/2,0,0);
-
- /* perform floor encoding */
- nonzero[i]=look->floor_func[submap]->
- forward(vb,look->floor_look[submap],floor[i]);
-
- _analysis_output("floor",seq,floor[i],n/2,0,1);
-
- /* apply the floor, do optional noise levelling */
- _vp_apply_floor(look->psy_look+submap,pcm,floor[i]);
-
- _analysis_output("res",seq++,pcm,n/2,0,0);
-
-#ifdef TRAIN_RES
- if(nonzero[i]){
- FILE *of;
- char buffer[80];
- int i;
-
- sprintf(buffer,"residue_%d.vqd",vb->mode);
- of=fopen(buffer,"a");
- for(i=0;i<n/2;i++)
- fprintf(of,"%.2f, ",pcm[i]);
- fprintf(of,"\n");
- fclose(of);
+ drft_forward(&b->fft_look[vb->W],pcm);
+ logfft[0]=scale_dB+todB(pcm) + .345; /* + .345 is a hack; the
+ original todB estimation used on
+ IEEE 754 compliant machines had a
+ bug that returned dB values about
+ a third of a decibel too high.
+ The bug was harmless because
+ tunings implicitly took that into
+ account. However, fixing the bug
+ in the estimator requires
+ changing all the tunings as well.
+ For now, it's easier to sync
+ things back up here, and
+ recalibrate the tunings in the
+ next major model upgrade. */
+ local_ampmax[i]=logfft[0];
+ for(j=1;j<n-1;j+=2){
+ float temp=pcm[j]*pcm[j]+pcm[j+1]*pcm[j+1];
+ temp=logfft[(j+1)>>1]=scale_dB+.5f*todB(&temp) + .345; /* +
+ .345 is a hack; the original todB
+ estimation used on IEEE 754
+ compliant machines had a bug that
+ returned dB values about a third
+ of a decibel too high. The bug
+ was harmless because tunings
+ implicitly took that into
+ account. However, fixing the bug
+ in the estimator requires
+ changing all the tunings as well.
+ For now, it's easier to sync
+ things back up here, and
+ recalibrate the tunings in the
+ next major model upgrade. */
+ if(temp>local_ampmax[i])local_ampmax[i]=temp;
+ }
+
+ if(local_ampmax[i]>0.f)local_ampmax[i]=0.f;
+ if(local_ampmax[i]>global_ampmax)global_ampmax=local_ampmax[i];
+
+#if 0
+ if(vi->channels==2){
+ if(i==0){
+ _analysis_output("fftL",seq,logfft,n/2,1,0,0);
+ }else{
+ _analysis_output("fftR",seq,logfft,n/2,1,0,0);
+ }
+ }else{
+ _analysis_output("fft",seq,logfft,n/2,1,0,0);
+ }
+#endif
+
+ }
+
+ {
+ float *noise = _vorbis_block_alloc(vb,n/2*sizeof(*noise));
+ float *tone = _vorbis_block_alloc(vb,n/2*sizeof(*tone));
+
+ for(i=0;i<vi->channels;i++){
+ /* the encoder setup assumes that all the modes used by any
+ specific bitrate tweaking use the same floor */
+
+ int submap=info->chmuxlist[i];
+
+ /* the following makes things clearer to *me* anyway */
+ float *mdct =gmdct[i];
+ float *logfft =vb->pcm[i];
+
+ float *logmdct =logfft+n/2;
+ float *logmask =logfft;
+
+ vb->mode=modenumber;
+
+ floor_posts[i]=_vorbis_block_alloc(vb,PACKETBLOBS*sizeof(**floor_posts));
+ memset(floor_posts[i],0,sizeof(**floor_posts)*PACKETBLOBS);
+
+ for(j=0;j<n/2;j++)
+ logmdct[j]=todB(mdct+j) + .345; /* + .345 is a hack; the original
+ todB estimation used on IEEE 754
+ compliant machines had a bug that
+ returned dB values about a third
+ of a decibel too high. The bug
+ was harmless because tunings
+ implicitly took that into
+ account. However, fixing the bug
+ in the estimator requires
+ changing all the tunings as well.
+ For now, it's easier to sync
+ things back up here, and
+ recalibrate the tunings in the
+ next major model upgrade. */
+
+#if 0
+ if(vi->channels==2){
+ if(i==0)
+ _analysis_output("mdctL",seq,logmdct,n/2,1,0,0);
+ else
+ _analysis_output("mdctR",seq,logmdct,n/2,1,0,0);
+ }else{
+ _analysis_output("mdct",seq,logmdct,n/2,1,0,0);
+ }
+#endif
+
+ /* first step; noise masking. Not only does 'noise masking'
+ give us curves from which we can decide how much resolution
+ to give noise parts of the spectrum, it also implicitly hands
+ us a tonality estimate (the larger the value in the
+ 'noise_depth' vector, the more tonal that area is) */
+
+ _vp_noisemask(psy_look,
+ logmdct,
+ noise); /* noise does not have by-frequency offset
+ bias applied yet */
+#if 0
+ if(vi->channels==2){
+ if(i==0)
+ _analysis_output("noiseL",seq,noise,n/2,1,0,0);
+ else
+ _analysis_output("noiseR",seq,noise,n/2,1,0,0);
+ }else{
+ _analysis_output("noise",seq,noise,n/2,1,0,0);
+ }
+#endif
+
+ /* second step: 'all the other crap'; all the stuff that isn't
+ computed/fit for bitrate management goes in the second psy
+ vector. This includes tone masking, peak limiting and ATH */
+
+ _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);
+ }else{
+ _analysis_output("tone",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. */
+
+#if 0
+ {
+ float aotuv[psy_look->n];
+#endif
+
+ _vp_offset_and_mix(psy_look,
+ noise,
+ tone,
+ 1,
+ logmask,
+ mdct,
+ logmdct);
+
+#if 0
+ if(vi->channels==2){
+ if(i==0)
+ _analysis_output("aotuvM1_L",seq,aotuv,psy_look->n,1,1,0);
+ else
+ _analysis_output("aotuvM1_R",seq,aotuv,psy_look->n,1,1,0);
+ }else{
+ _analysis_output("aotuvM1",seq,aotuv,psy_look->n,1,1,0);
+ }
+ }
+#endif
+
+
+#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);
+ }else{
+ _analysis_output("mask1",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,
+ mdct,
+ logmdct);
+
+#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);
+ }else{
+ _analysis_output("mask2",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,
+ mdct,
+ logmdct);
+
+#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);
+ }else{
+ _analysis_output("mask0",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));
+ }