Home | History | Annotate | Download | only in lib
      1 /********************************************************************
      2  *                                                                  *
      3  * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
      4  * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
      5  * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
      6  * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
      7  *                                                                  *
      8  * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2010             *
      9  * by the Xiph.Org Foundation http://www.xiph.org/                  *
     10  *                                                                  *
     11  ********************************************************************
     12 
     13  function: psychoacoustics not including preecho
     14  last mod: $Id: psy.c 17077 2010-03-26 06:22:19Z xiphmont $
     15 
     16  ********************************************************************/
     17 
     18 #include <stdlib.h>
     19 #include <math.h>
     20 #include <string.h>
     21 #include "vorbis/codec.h"
     22 #include "codec_internal.h"
     23 
     24 #include "masking.h"
     25 #include "psy.h"
     26 #include "os.h"
     27 #include "lpc.h"
     28 #include "smallft.h"
     29 #include "scales.h"
     30 #include "misc.h"
     31 
     32 #define NEGINF -9999.f
     33 static const double stereo_threshholds[]={0.0, .5, 1.0, 1.5, 2.5, 4.5, 8.5, 16.5, 9e10};
     34 static const double stereo_threshholds_limited[]={0.0, .5, 1.0, 1.5, 2.0, 2.5, 4.5, 8.5, 9e10};
     35 
     36 vorbis_look_psy_global *_vp_global_look(vorbis_info *vi){
     37   codec_setup_info *ci=vi->codec_setup;
     38   vorbis_info_psy_global *gi=&ci->psy_g_param;
     39   vorbis_look_psy_global *look=_ogg_calloc(1,sizeof(*look));
     40 
     41   look->channels=vi->channels;
     42 
     43   look->ampmax=-9999.;
     44   look->gi=gi;
     45   return(look);
     46 }
     47 
     48 void _vp_global_free(vorbis_look_psy_global *look){
     49   if(look){
     50     memset(look,0,sizeof(*look));
     51     _ogg_free(look);
     52   }
     53 }
     54 
     55 void _vi_gpsy_free(vorbis_info_psy_global *i){
     56   if(i){
     57     memset(i,0,sizeof(*i));
     58     _ogg_free(i);
     59   }
     60 }
     61 
     62 void _vi_psy_free(vorbis_info_psy *i){
     63   if(i){
     64     memset(i,0,sizeof(*i));
     65     _ogg_free(i);
     66   }
     67 }
     68 
     69 static void min_curve(float *c,
     70                        float *c2){
     71   int i;
     72   for(i=0;i<EHMER_MAX;i++)if(c2[i]<c[i])c[i]=c2[i];
     73 }
     74 static void max_curve(float *c,
     75                        float *c2){
     76   int i;
     77   for(i=0;i<EHMER_MAX;i++)if(c2[i]>c[i])c[i]=c2[i];
     78 }
     79 
     80 static void attenuate_curve(float *c,float att){
     81   int i;
     82   for(i=0;i<EHMER_MAX;i++)
     83     c[i]+=att;
     84 }
     85 
     86 static float ***setup_tone_curves(float curveatt_dB[P_BANDS],float binHz,int n,
     87                                   float center_boost, float center_decay_rate){
     88   int i,j,k,m;
     89   float ath[EHMER_MAX];
     90   float workc[P_BANDS][P_LEVELS][EHMER_MAX];
     91   float athc[P_LEVELS][EHMER_MAX];
     92   float *brute_buffer=alloca(n*sizeof(*brute_buffer));
     93 
     94   float ***ret=_ogg_malloc(sizeof(*ret)*P_BANDS);
     95 
     96   memset(workc,0,sizeof(workc));
     97 
     98   for(i=0;i<P_BANDS;i++){
     99     /* we add back in the ATH to avoid low level curves falling off to
    100        -infinity and unnecessarily cutting off high level curves in the
    101        curve limiting (last step). */
    102 
    103     /* A half-band's settings must be valid over the whole band, and
    104        it's better to mask too little than too much */
    105     int ath_offset=i*4;
    106     for(j=0;j<EHMER_MAX;j++){
    107       float min=999.;
    108       for(k=0;k<4;k++)
    109         if(j+k+ath_offset<MAX_ATH){
    110           if(min>ATH[j+k+ath_offset])min=ATH[j+k+ath_offset];
    111         }else{
    112           if(min>ATH[MAX_ATH-1])min=ATH[MAX_ATH-1];
    113         }
    114       ath[j]=min;
    115     }
    116 
    117     /* copy curves into working space, replicate the 50dB curve to 30
    118        and 40, replicate the 100dB curve to 110 */
    119     for(j=0;j<6;j++)
    120       memcpy(workc[i][j+2],tonemasks[i][j],EHMER_MAX*sizeof(*tonemasks[i][j]));
    121     memcpy(workc[i][0],tonemasks[i][0],EHMER_MAX*sizeof(*tonemasks[i][0]));
    122     memcpy(workc[i][1],tonemasks[i][0],EHMER_MAX*sizeof(*tonemasks[i][0]));
    123 
    124     /* apply centered curve boost/decay */
    125     for(j=0;j<P_LEVELS;j++){
    126       for(k=0;k<EHMER_MAX;k++){
    127         float adj=center_boost+abs(EHMER_OFFSET-k)*center_decay_rate;
    128         if(adj<0. && center_boost>0)adj=0.;
    129         if(adj>0. && center_boost<0)adj=0.;
    130         workc[i][j][k]+=adj;
    131       }
    132     }
    133 
    134     /* normalize curves so the driving amplitude is 0dB */
    135     /* make temp curves with the ATH overlayed */
    136     for(j=0;j<P_LEVELS;j++){
    137       attenuate_curve(workc[i][j],curveatt_dB[i]+100.-(j<2?2:j)*10.-P_LEVEL_0);
    138       memcpy(athc[j],ath,EHMER_MAX*sizeof(**athc));
    139       attenuate_curve(athc[j],+100.-j*10.f-P_LEVEL_0);
    140       max_curve(athc[j],workc[i][j]);
    141     }
    142 
    143     /* Now limit the louder curves.
    144 
    145        the idea is this: We don't know what the playback attenuation
    146        will be; 0dB SL moves every time the user twiddles the volume
    147        knob. So that means we have to use a single 'most pessimal' curve
    148        for all masking amplitudes, right?  Wrong.  The *loudest* sound
    149        can be in (we assume) a range of ...+100dB] SL.  However, sounds
    150        20dB down will be in a range ...+80], 40dB down is from ...+60],
    151        etc... */
    152 
    153     for(j=1;j<P_LEVELS;j++){
    154       min_curve(athc[j],athc[j-1]);
    155       min_curve(workc[i][j],athc[j]);
    156     }
    157   }
    158 
    159   for(i=0;i<P_BANDS;i++){
    160     int hi_curve,lo_curve,bin;
    161     ret[i]=_ogg_malloc(sizeof(**ret)*P_LEVELS);
    162 
    163     /* low frequency curves are measured with greater resolution than
    164        the MDCT/FFT will actually give us; we want the curve applied
    165        to the tone data to be pessimistic and thus apply the minimum
    166        masking possible for a given bin.  That means that a single bin
    167        could span more than one octave and that the curve will be a
    168        composite of multiple octaves.  It also may mean that a single
    169        bin may span > an eighth of an octave and that the eighth
    170        octave values may also be composited. */
    171 
    172     /* which octave curves will we be compositing? */
    173     bin=floor(fromOC(i*.5)/binHz);
    174     lo_curve=  ceil(toOC(bin*binHz+1)*2);
    175     hi_curve=  floor(toOC((bin+1)*binHz)*2);
    176     if(lo_curve>i)lo_curve=i;
    177     if(lo_curve<0)lo_curve=0;
    178     if(hi_curve>=P_BANDS)hi_curve=P_BANDS-1;
    179 
    180     for(m=0;m<P_LEVELS;m++){
    181       ret[i][m]=_ogg_malloc(sizeof(***ret)*(EHMER_MAX+2));
    182 
    183       for(j=0;j<n;j++)brute_buffer[j]=999.;
    184 
    185       /* render the curve into bins, then pull values back into curve.
    186          The point is that any inherent subsampling aliasing results in
    187          a safe minimum */
    188       for(k=lo_curve;k<=hi_curve;k++){
    189         int l=0;
    190 
    191         for(j=0;j<EHMER_MAX;j++){
    192           int lo_bin= fromOC(j*.125+k*.5-2.0625)/binHz;
    193           int hi_bin= fromOC(j*.125+k*.5-1.9375)/binHz+1;
    194 
    195           if(lo_bin<0)lo_bin=0;
    196           if(lo_bin>n)lo_bin=n;
    197           if(lo_bin<l)l=lo_bin;
    198           if(hi_bin<0)hi_bin=0;
    199           if(hi_bin>n)hi_bin=n;
    200 
    201           for(;l<hi_bin && l<n;l++)
    202             if(brute_buffer[l]>workc[k][m][j])
    203               brute_buffer[l]=workc[k][m][j];
    204         }
    205 
    206         for(;l<n;l++)
    207           if(brute_buffer[l]>workc[k][m][EHMER_MAX-1])
    208             brute_buffer[l]=workc[k][m][EHMER_MAX-1];
    209 
    210       }
    211 
    212       /* be equally paranoid about being valid up to next half ocatve */
    213       if(i+1<P_BANDS){
    214         int l=0;
    215         k=i+1;
    216         for(j=0;j<EHMER_MAX;j++){
    217           int lo_bin= fromOC(j*.125+i*.5-2.0625)/binHz;
    218           int hi_bin= fromOC(j*.125+i*.5-1.9375)/binHz+1;
    219 
    220           if(lo_bin<0)lo_bin=0;
    221           if(lo_bin>n)lo_bin=n;
    222           if(lo_bin<l)l=lo_bin;
    223           if(hi_bin<0)hi_bin=0;
    224           if(hi_bin>n)hi_bin=n;
    225 
    226           for(;l<hi_bin && l<n;l++)
    227             if(brute_buffer[l]>workc[k][m][j])
    228               brute_buffer[l]=workc[k][m][j];
    229         }
    230 
    231         for(;l<n;l++)
    232           if(brute_buffer[l]>workc[k][m][EHMER_MAX-1])
    233             brute_buffer[l]=workc[k][m][EHMER_MAX-1];
    234 
    235       }
    236 
    237 
    238       for(j=0;j<EHMER_MAX;j++){
    239         int bin=fromOC(j*.125+i*.5-2.)/binHz;
    240         if(bin<0){
    241           ret[i][m][j+2]=-999.;
    242         }else{
    243           if(bin>=n){
    244             ret[i][m][j+2]=-999.;
    245           }else{
    246             ret[i][m][j+2]=brute_buffer[bin];
    247           }
    248         }
    249       }
    250 
    251       /* add fenceposts */
    252       for(j=0;j<EHMER_OFFSET;j++)
    253         if(ret[i][m][j+2]>-200.f)break;
    254       ret[i][m][0]=j;
    255 
    256       for(j=EHMER_MAX-1;j>EHMER_OFFSET+1;j--)
    257         if(ret[i][m][j+2]>-200.f)
    258           break;
    259       ret[i][m][1]=j;
    260 
    261     }
    262   }
    263 
    264   return(ret);
    265 }
    266 
    267 void _vp_psy_init(vorbis_look_psy *p,vorbis_info_psy *vi,
    268                   vorbis_info_psy_global *gi,int n,long rate){
    269   long i,j,lo=-99,hi=1;
    270   long maxoc;
    271   memset(p,0,sizeof(*p));
    272 
    273   p->eighth_octave_lines=gi->eighth_octave_lines;
    274   p->shiftoc=rint(log(gi->eighth_octave_lines*8.f)/log(2.f))-1;
    275 
    276   p->firstoc=toOC(.25f*rate*.5/n)*(1<<(p->shiftoc+1))-gi->eighth_octave_lines;
    277   maxoc=toOC((n+.25f)*rate*.5/n)*(1<<(p->shiftoc+1))+.5f;
    278   p->total_octave_lines=maxoc-p->firstoc+1;
    279   p->ath=_ogg_malloc(n*sizeof(*p->ath));
    280 
    281   p->octave=_ogg_malloc(n*sizeof(*p->octave));
    282   p->bark=_ogg_malloc(n*sizeof(*p->bark));
    283   p->vi=vi;
    284   p->n=n;
    285   p->rate=rate;
    286 
    287   /* AoTuV HF weighting */
    288   p->m_val = 1.;
    289   if(rate < 26000) p->m_val = 0;
    290   else if(rate < 38000) p->m_val = .94;   /* 32kHz */
    291   else if(rate > 46000) p->m_val = 1.275; /* 48kHz */
    292 
    293   /* set up the lookups for a given blocksize and sample rate */
    294 
    295   for(i=0,j=0;i<MAX_ATH-1;i++){
    296     int endpos=rint(fromOC((i+1)*.125-2.)*2*n/rate);
    297     float base=ATH[i];
    298     if(j<endpos){
    299       float delta=(ATH[i+1]-base)/(endpos-j);
    300       for(;j<endpos && j<n;j++){
    301         p->ath[j]=base+100.;
    302         base+=delta;
    303       }
    304     }
    305   }
    306 
    307   for(;j<n;j++){
    308     p->ath[j]=p->ath[j-1];
    309   }
    310 
    311   for(i=0;i<n;i++){
    312     float bark=toBARK(rate/(2*n)*i);
    313 
    314     for(;lo+vi->noisewindowlomin<i &&
    315           toBARK(rate/(2*n)*lo)<(bark-vi->noisewindowlo);lo++);
    316 
    317     for(;hi<=n && (hi<i+vi->noisewindowhimin ||
    318           toBARK(rate/(2*n)*hi)<(bark+vi->noisewindowhi));hi++);
    319 
    320     p->bark[i]=((lo-1)<<16)+(hi-1);
    321 
    322   }
    323 
    324   for(i=0;i<n;i++)
    325     p->octave[i]=toOC((i+.25f)*.5*rate/n)*(1<<(p->shiftoc+1))+.5f;
    326 
    327   p->tonecurves=setup_tone_curves(vi->toneatt,rate*.5/n,n,
    328                                   vi->tone_centerboost,vi->tone_decay);
    329 
    330   /* set up rolling noise median */
    331   p->noiseoffset=_ogg_malloc(P_NOISECURVES*sizeof(*p->noiseoffset));
    332   for(i=0;i<P_NOISECURVES;i++)
    333     p->noiseoffset[i]=_ogg_malloc(n*sizeof(**p->noiseoffset));
    334 
    335   for(i=0;i<n;i++){
    336     float halfoc=toOC((i+.5)*rate/(2.*n))*2.;
    337     int inthalfoc;
    338     float del;
    339 
    340     if(halfoc<0)halfoc=0;
    341     if(halfoc>=P_BANDS-1)halfoc=P_BANDS-1;
    342     inthalfoc=(int)halfoc;
    343     del=halfoc-inthalfoc;
    344 
    345     for(j=0;j<P_NOISECURVES;j++)
    346       p->noiseoffset[j][i]=
    347         p->vi->noiseoff[j][inthalfoc]*(1.-del) +
    348         p->vi->noiseoff[j][inthalfoc+1]*del;
    349 
    350   }
    351 #if 0
    352   {
    353     static int ls=0;
    354     _analysis_output_always("noiseoff0",ls,p->noiseoffset[0],n,1,0,0);
    355     _analysis_output_always("noiseoff1",ls,p->noiseoffset[1],n,1,0,0);
    356     _analysis_output_always("noiseoff2",ls++,p->noiseoffset[2],n,1,0,0);
    357   }
    358 #endif
    359 }
    360 
    361 void _vp_psy_clear(vorbis_look_psy *p){
    362   int i,j;
    363   if(p){
    364     if(p->ath)_ogg_free(p->ath);
    365     if(p->octave)_ogg_free(p->octave);
    366     if(p->bark)_ogg_free(p->bark);
    367     if(p->tonecurves){
    368       for(i=0;i<P_BANDS;i++){
    369         for(j=0;j<P_LEVELS;j++){
    370           _ogg_free(p->tonecurves[i][j]);
    371         }
    372         _ogg_free(p->tonecurves[i]);
    373       }
    374       _ogg_free(p->tonecurves);
    375     }
    376     if(p->noiseoffset){
    377       for(i=0;i<P_NOISECURVES;i++){
    378         _ogg_free(p->noiseoffset[i]);
    379       }
    380       _ogg_free(p->noiseoffset);
    381     }
    382     memset(p,0,sizeof(*p));
    383   }
    384 }
    385 
    386 /* octave/(8*eighth_octave_lines) x scale and dB y scale */
    387 static void seed_curve(float *seed,
    388                        const float **curves,
    389                        float amp,
    390                        int oc, int n,
    391                        int linesper,float dBoffset){
    392   int i,post1;
    393   int seedptr;
    394   const float *posts,*curve;
    395 
    396   int choice=(int)((amp+dBoffset-P_LEVEL_0)*.1f);
    397   choice=max(choice,0);
    398   choice=min(choice,P_LEVELS-1);
    399   posts=curves[choice];
    400   curve=posts+2;
    401   post1=(int)posts[1];
    402   seedptr=oc+(posts[0]-EHMER_OFFSET)*linesper-(linesper>>1);
    403 
    404   for(i=posts[0];i<post1;i++){
    405     if(seedptr>0){
    406       float lin=amp+curve[i];
    407       if(seed[seedptr]<lin)seed[seedptr]=lin;
    408     }
    409     seedptr+=linesper;
    410     if(seedptr>=n)break;
    411   }
    412 }
    413 
    414 static void seed_loop(vorbis_look_psy *p,
    415                       const float ***curves,
    416                       const float *f,
    417                       const float *flr,
    418                       float *seed,
    419                       float specmax){
    420   vorbis_info_psy *vi=p->vi;
    421   long n=p->n,i;
    422   float dBoffset=vi->max_curve_dB-specmax;
    423 
    424   /* prime the working vector with peak values */
    425 
    426   for(i=0;i<n;i++){
    427     float max=f[i];
    428     long oc=p->octave[i];
    429     while(i+1<n && p->octave[i+1]==oc){
    430       i++;
    431       if(f[i]>max)max=f[i];
    432     }
    433 
    434     if(max+6.f>flr[i]){
    435       oc=oc>>p->shiftoc;
    436 
    437       if(oc>=P_BANDS)oc=P_BANDS-1;
    438       if(oc<0)oc=0;
    439 
    440       seed_curve(seed,
    441                  curves[oc],
    442                  max,
    443                  p->octave[i]-p->firstoc,
    444                  p->total_octave_lines,
    445                  p->eighth_octave_lines,
    446                  dBoffset);
    447     }
    448   }
    449 }
    450 
    451 static void seed_chase(float *seeds, int linesper, long n){
    452   long  *posstack=alloca(n*sizeof(*posstack));
    453   float *ampstack=alloca(n*sizeof(*ampstack));
    454   long   stack=0;
    455   long   pos=0;
    456   long   i;
    457 
    458   for(i=0;i<n;i++){
    459     if(stack<2){
    460       posstack[stack]=i;
    461       ampstack[stack++]=seeds[i];
    462     }else{
    463       while(1){
    464         if(seeds[i]<ampstack[stack-1]){
    465           posstack[stack]=i;
    466           ampstack[stack++]=seeds[i];
    467           break;
    468         }else{
    469           if(i<posstack[stack-1]+linesper){
    470             if(stack>1 && ampstack[stack-1]<=ampstack[stack-2] &&
    471                i<posstack[stack-2]+linesper){
    472               /* we completely overlap, making stack-1 irrelevant.  pop it */
    473               stack--;
    474               continue;
    475             }
    476           }
    477           posstack[stack]=i;
    478           ampstack[stack++]=seeds[i];
    479           break;
    480 
    481         }
    482       }
    483     }
    484   }
    485 
    486   /* the stack now contains only the positions that are relevant. Scan
    487      'em straight through */
    488 
    489   for(i=0;i<stack;i++){
    490     long endpos;
    491     if(i<stack-1 && ampstack[i+1]>ampstack[i]){
    492       endpos=posstack[i+1];
    493     }else{
    494       endpos=posstack[i]+linesper+1; /* +1 is important, else bin 0 is
    495                                         discarded in short frames */
    496     }
    497     if(endpos>n)endpos=n;
    498     for(;pos<endpos;pos++)
    499       seeds[pos]=ampstack[i];
    500   }
    501 
    502   /* there.  Linear time.  I now remember this was on a problem set I
    503      had in Grad Skool... I didn't solve it at the time ;-) */
    504 
    505 }
    506 
    507 /* bleaugh, this is more complicated than it needs to be */
    508 #include<stdio.h>
    509 static void max_seeds(vorbis_look_psy *p,
    510                       float *seed,
    511                       float *flr){
    512   long   n=p->total_octave_lines;
    513   int    linesper=p->eighth_octave_lines;
    514   long   linpos=0;
    515   long   pos;
    516 
    517   seed_chase(seed,linesper,n); /* for masking */
    518 
    519   pos=p->octave[0]-p->firstoc-(linesper>>1);
    520 
    521   while(linpos+1<p->n){
    522     float minV=seed[pos];
    523     long end=((p->octave[linpos]+p->octave[linpos+1])>>1)-p->firstoc;
    524     if(minV>p->vi->tone_abs_limit)minV=p->vi->tone_abs_limit;
    525     while(pos+1<=end){
    526       pos++;
    527       if((seed[pos]>NEGINF && seed[pos]<minV) || minV==NEGINF)
    528         minV=seed[pos];
    529     }
    530 
    531     end=pos+p->firstoc;
    532     for(;linpos<p->n && p->octave[linpos]<=end;linpos++)
    533       if(flr[linpos]<minV)flr[linpos]=minV;
    534   }
    535 
    536   {
    537     float minV=seed[p->total_octave_lines-1];
    538     for(;linpos<p->n;linpos++)
    539       if(flr[linpos]<minV)flr[linpos]=minV;
    540   }
    541 
    542 }
    543 
    544 static void bark_noise_hybridmp(int n,const long *b,
    545                                 const float *f,
    546                                 float *noise,
    547                                 const float offset,
    548                                 const int fixed){
    549 
    550   float *N=alloca(n*sizeof(*N));
    551   float *X=alloca(n*sizeof(*N));
    552   float *XX=alloca(n*sizeof(*N));
    553   float *Y=alloca(n*sizeof(*N));
    554   float *XY=alloca(n*sizeof(*N));
    555 
    556   float tN, tX, tXX, tY, tXY;
    557   int i;
    558 
    559   int lo, hi;
    560   float R=0.f;
    561   float A=0.f;
    562   float B=0.f;
    563   float D=1.f;
    564   float w, x, y;
    565 
    566   tN = tX = tXX = tY = tXY = 0.f;
    567 
    568   y = f[0] + offset;
    569   if (y < 1.f) y = 1.f;
    570 
    571   w = y * y * .5;
    572 
    573   tN += w;
    574   tX += w;
    575   tY += w * y;
    576 
    577   N[0] = tN;
    578   X[0] = tX;
    579   XX[0] = tXX;
    580   Y[0] = tY;
    581   XY[0] = tXY;
    582 
    583   for (i = 1, x = 1.f; i < n; i++, x += 1.f) {
    584 
    585     y = f[i] + offset;
    586     if (y < 1.f) y = 1.f;
    587 
    588     w = y * y;
    589 
    590     tN += w;
    591     tX += w * x;
    592     tXX += w * x * x;
    593     tY += w * y;
    594     tXY += w * x * y;
    595 
    596     N[i] = tN;
    597     X[i] = tX;
    598     XX[i] = tXX;
    599     Y[i] = tY;
    600     XY[i] = tXY;
    601   }
    602 
    603   for (i = 0, x = 0.f;; i++, x += 1.f) {
    604 
    605     lo = b[i] >> 16;
    606     if( lo>=0 ) break;
    607     hi = b[i] & 0xffff;
    608 
    609     tN = N[hi] + N[-lo];
    610     tX = X[hi] - X[-lo];
    611     tXX = XX[hi] + XX[-lo];
    612     tY = Y[hi] + Y[-lo];
    613     tXY = XY[hi] - XY[-lo];
    614 
    615     A = tY * tXX - tX * tXY;
    616     B = tN * tXY - tX * tY;
    617     D = tN * tXX - tX * tX;
    618     R = (A + x * B) / D;
    619     if (R < 0.f)
    620       R = 0.f;
    621 
    622     noise[i] = R - offset;
    623   }
    624 
    625   for ( ;; i++, x += 1.f) {
    626 
    627     lo = b[i] >> 16;
    628     hi = b[i] & 0xffff;
    629     if(hi>=n)break;
    630 
    631     tN = N[hi] - N[lo];
    632     tX = X[hi] - X[lo];
    633     tXX = XX[hi] - XX[lo];
    634     tY = Y[hi] - Y[lo];
    635     tXY = XY[hi] - XY[lo];
    636 
    637     A = tY * tXX - tX * tXY;
    638     B = tN * tXY - tX * tY;
    639     D = tN * tXX - tX * tX;
    640     R = (A + x * B) / D;
    641     if (R < 0.f) R = 0.f;
    642 
    643     noise[i] = R - offset;
    644   }
    645   for ( ; i < n; i++, x += 1.f) {
    646 
    647     R = (A + x * B) / D;
    648     if (R < 0.f) R = 0.f;
    649 
    650     noise[i] = R - offset;
    651   }
    652 
    653   if (fixed <= 0) return;
    654 
    655   for (i = 0, x = 0.f;; i++, x += 1.f) {
    656     hi = i + fixed / 2;
    657     lo = hi - fixed;
    658     if(lo>=0)break;
    659 
    660     tN = N[hi] + N[-lo];
    661     tX = X[hi] - X[-lo];
    662     tXX = XX[hi] + XX[-lo];
    663     tY = Y[hi] + Y[-lo];
    664     tXY = XY[hi] - XY[-lo];
    665 
    666 
    667     A = tY * tXX - tX * tXY;
    668     B = tN * tXY - tX * tY;
    669     D = tN * tXX - tX * tX;
    670     R = (A + x * B) / D;
    671 
    672     if (R - offset < noise[i]) noise[i] = R - offset;
    673   }
    674   for ( ;; i++, x += 1.f) {
    675 
    676     hi = i + fixed / 2;
    677     lo = hi - fixed;
    678     if(hi>=n)break;
    679 
    680     tN = N[hi] - N[lo];
    681     tX = X[hi] - X[lo];
    682     tXX = XX[hi] - XX[lo];
    683     tY = Y[hi] - Y[lo];
    684     tXY = XY[hi] - XY[lo];
    685 
    686     A = tY * tXX - tX * tXY;
    687     B = tN * tXY - tX * tY;
    688     D = tN * tXX - tX * tX;
    689     R = (A + x * B) / D;
    690 
    691     if (R - offset < noise[i]) noise[i] = R - offset;
    692   }
    693   for ( ; i < n; i++, x += 1.f) {
    694     R = (A + x * B) / D;
    695     if (R - offset < noise[i]) noise[i] = R - offset;
    696   }
    697 }
    698 
    699 void _vp_noisemask(vorbis_look_psy *p,
    700                    float *logmdct,
    701                    float *logmask){
    702 
    703   int i,n=p->n;
    704   float *work=alloca(n*sizeof(*work));
    705 
    706   bark_noise_hybridmp(n,p->bark,logmdct,logmask,
    707                       140.,-1);
    708 
    709   for(i=0;i<n;i++)work[i]=logmdct[i]-logmask[i];
    710 
    711   bark_noise_hybridmp(n,p->bark,work,logmask,0.,
    712                       p->vi->noisewindowfixed);
    713 
    714   for(i=0;i<n;i++)work[i]=logmdct[i]-work[i];
    715 
    716 #if 0
    717   {
    718     static int seq=0;
    719 
    720     float work2[n];
    721     for(i=0;i<n;i++){
    722       work2[i]=logmask[i]+work[i];
    723     }
    724 
    725     if(seq&1)
    726       _analysis_output("median2R",seq/2,work,n,1,0,0);
    727     else
    728       _analysis_output("median2L",seq/2,work,n,1,0,0);
    729 
    730     if(seq&1)
    731       _analysis_output("envelope2R",seq/2,work2,n,1,0,0);
    732     else
    733       _analysis_output("envelope2L",seq/2,work2,n,1,0,0);
    734     seq++;
    735   }
    736 #endif
    737 
    738   for(i=0;i<n;i++){
    739     int dB=logmask[i]+.5;
    740     if(dB>=NOISE_COMPAND_LEVELS)dB=NOISE_COMPAND_LEVELS-1;
    741     if(dB<0)dB=0;
    742     logmask[i]= work[i]+p->vi->noisecompand[dB];
    743   }
    744 
    745 }
    746 
    747 void _vp_tonemask(vorbis_look_psy *p,
    748                   float *logfft,
    749                   float *logmask,
    750                   float global_specmax,
    751                   float local_specmax){
    752 
    753   int i,n=p->n;
    754 
    755   float *seed=alloca(sizeof(*seed)*p->total_octave_lines);
    756   float att=local_specmax+p->vi->ath_adjatt;
    757   for(i=0;i<p->total_octave_lines;i++)seed[i]=NEGINF;
    758 
    759   /* set the ATH (floating below localmax, not global max by a
    760      specified att) */
    761   if(att<p->vi->ath_maxatt)att=p->vi->ath_maxatt;
    762 
    763   for(i=0;i<n;i++)
    764     logmask[i]=p->ath[i]+att;
    765 
    766   /* tone masking */
    767   seed_loop(p,(const float ***)p->tonecurves,logfft,logmask,seed,global_specmax);
    768   max_seeds(p,seed,logmask);
    769 
    770 }
    771 
    772 void _vp_offset_and_mix(vorbis_look_psy *p,
    773                         float *noise,
    774                         float *tone,
    775                         int offset_select,
    776                         float *logmask,
    777                         float *mdct,
    778                         float *logmdct){
    779   int i,n=p->n;
    780   float de, coeffi, cx;/* AoTuV */
    781   float toneatt=p->vi->tone_masteratt[offset_select];
    782 
    783   cx = p->m_val;
    784 
    785   for(i=0;i<n;i++){
    786     float val= noise[i]+p->noiseoffset[offset_select][i];
    787     if(val>p->vi->noisemaxsupp)val=p->vi->noisemaxsupp;
    788     logmask[i]=max(val,tone[i]+toneatt);
    789 
    790 
    791     /* AoTuV */
    792     /** @ M1 **
    793         The following codes improve a noise problem.
    794         A fundamental idea uses the value of masking and carries out
    795         the relative compensation of the MDCT.
    796         However, this code is not perfect and all noise problems cannot be solved.
    797         by Aoyumi @ 2004/04/18
    798     */
    799 
    800     if(offset_select == 1) {
    801       coeffi = -17.2;       /* coeffi is a -17.2dB threshold */
    802       val = val - logmdct[i];  /* val == mdct line value relative to floor in dB */
    803 
    804       if(val > coeffi){
    805         /* mdct value is > -17.2 dB below floor */
    806 
    807         de = 1.0-((val-coeffi)*0.005*cx);
    808         /* pro-rated attenuation:
    809            -0.00 dB boost if mdct value is -17.2dB (relative to floor)
    810            -0.77 dB boost if mdct value is 0dB (relative to floor)
    811            -1.64 dB boost if mdct value is +17.2dB (relative to floor)
    812            etc... */
    813 
    814         if(de < 0) de = 0.0001;
    815       }else
    816         /* mdct value is <= -17.2 dB below floor */
    817 
    818         de = 1.0-((val-coeffi)*0.0003*cx);
    819       /* pro-rated attenuation:
    820          +0.00 dB atten if mdct value is -17.2dB (relative to floor)
    821          +0.45 dB atten if mdct value is -34.4dB (relative to floor)
    822          etc... */
    823 
    824       mdct[i] *= de;
    825 
    826     }
    827   }
    828 }
    829 
    830 float _vp_ampmax_decay(float amp,vorbis_dsp_state *vd){
    831   vorbis_info *vi=vd->vi;
    832   codec_setup_info *ci=vi->codec_setup;
    833   vorbis_info_psy_global *gi=&ci->psy_g_param;
    834 
    835   int n=ci->blocksizes[vd->W]/2;
    836   float secs=(float)n/vi->rate;
    837 
    838   amp+=secs*gi->ampmax_att_per_sec;
    839   if(amp<-9999)amp=-9999;
    840   return(amp);
    841 }
    842 
    843 static float FLOOR1_fromdB_LOOKUP[256]={
    844   1.0649863e-07F, 1.1341951e-07F, 1.2079015e-07F, 1.2863978e-07F,
    845   1.3699951e-07F, 1.4590251e-07F, 1.5538408e-07F, 1.6548181e-07F,
    846   1.7623575e-07F, 1.8768855e-07F, 1.9988561e-07F, 2.128753e-07F,
    847   2.2670913e-07F, 2.4144197e-07F, 2.5713223e-07F, 2.7384213e-07F,
    848   2.9163793e-07F, 3.1059021e-07F, 3.3077411e-07F, 3.5226968e-07F,
    849   3.7516214e-07F, 3.9954229e-07F, 4.2550680e-07F, 4.5315863e-07F,
    850   4.8260743e-07F, 5.1396998e-07F, 5.4737065e-07F, 5.8294187e-07F,
    851   6.2082472e-07F, 6.6116941e-07F, 7.0413592e-07F, 7.4989464e-07F,
    852   7.9862701e-07F, 8.5052630e-07F, 9.0579828e-07F, 9.6466216e-07F,
    853   1.0273513e-06F, 1.0941144e-06F, 1.1652161e-06F, 1.2409384e-06F,
    854   1.3215816e-06F, 1.4074654e-06F, 1.4989305e-06F, 1.5963394e-06F,
    855   1.7000785e-06F, 1.8105592e-06F, 1.9282195e-06F, 2.0535261e-06F,
    856   2.1869758e-06F, 2.3290978e-06F, 2.4804557e-06F, 2.6416497e-06F,
    857   2.8133190e-06F, 2.9961443e-06F, 3.1908506e-06F, 3.3982101e-06F,
    858   3.6190449e-06F, 3.8542308e-06F, 4.1047004e-06F, 4.3714470e-06F,
    859   4.6555282e-06F, 4.9580707e-06F, 5.2802740e-06F, 5.6234160e-06F,
    860   5.9888572e-06F, 6.3780469e-06F, 6.7925283e-06F, 7.2339451e-06F,
    861   7.7040476e-06F, 8.2047000e-06F, 8.7378876e-06F, 9.3057248e-06F,
    862   9.9104632e-06F, 1.0554501e-05F, 1.1240392e-05F, 1.1970856e-05F,
    863   1.2748789e-05F, 1.3577278e-05F, 1.4459606e-05F, 1.5399272e-05F,
    864   1.6400004e-05F, 1.7465768e-05F, 1.8600792e-05F, 1.9809576e-05F,
    865   2.1096914e-05F, 2.2467911e-05F, 2.3928002e-05F, 2.5482978e-05F,
    866   2.7139006e-05F, 2.8902651e-05F, 3.0780908e-05F, 3.2781225e-05F,
    867   3.4911534e-05F, 3.7180282e-05F, 3.9596466e-05F, 4.2169667e-05F,
    868   4.4910090e-05F, 4.7828601e-05F, 5.0936773e-05F, 5.4246931e-05F,
    869   5.7772202e-05F, 6.1526565e-05F, 6.5524908e-05F, 6.9783085e-05F,
    870   7.4317983e-05F, 7.9147585e-05F, 8.4291040e-05F, 8.9768747e-05F,
    871   9.5602426e-05F, 0.00010181521F, 0.00010843174F, 0.00011547824F,
    872   0.00012298267F, 0.00013097477F, 0.00013948625F, 0.00014855085F,
    873   0.00015820453F, 0.00016848555F, 0.00017943469F, 0.00019109536F,
    874   0.00020351382F, 0.00021673929F, 0.00023082423F, 0.00024582449F,
    875   0.00026179955F, 0.00027881276F, 0.00029693158F, 0.00031622787F,
    876   0.00033677814F, 0.00035866388F, 0.00038197188F, 0.00040679456F,
    877   0.00043323036F, 0.00046138411F, 0.00049136745F, 0.00052329927F,
    878   0.00055730621F, 0.00059352311F, 0.00063209358F, 0.00067317058F,
    879   0.00071691700F, 0.00076350630F, 0.00081312324F, 0.00086596457F,
    880   0.00092223983F, 0.00098217216F, 0.0010459992F, 0.0011139742F,
    881   0.0011863665F, 0.0012634633F, 0.0013455702F, 0.0014330129F,
    882   0.0015261382F, 0.0016253153F, 0.0017309374F, 0.0018434235F,
    883   0.0019632195F, 0.0020908006F, 0.0022266726F, 0.0023713743F,
    884   0.0025254795F, 0.0026895994F, 0.0028643847F, 0.0030505286F,
    885   0.0032487691F, 0.0034598925F, 0.0036847358F, 0.0039241906F,
    886   0.0041792066F, 0.0044507950F, 0.0047400328F, 0.0050480668F,
    887   0.0053761186F, 0.0057254891F, 0.0060975636F, 0.0064938176F,
    888   0.0069158225F, 0.0073652516F, 0.0078438871F, 0.0083536271F,
    889   0.0088964928F, 0.009474637F, 0.010090352F, 0.010746080F,
    890   0.011444421F, 0.012188144F, 0.012980198F, 0.013823725F,
    891   0.014722068F, 0.015678791F, 0.016697687F, 0.017782797F,
    892   0.018938423F, 0.020169149F, 0.021479854F, 0.022875735F,
    893   0.024362330F, 0.025945531F, 0.027631618F, 0.029427276F,
    894   0.031339626F, 0.033376252F, 0.035545228F, 0.037855157F,
    895   0.040315199F, 0.042935108F, 0.045725273F, 0.048696758F,
    896   0.051861348F, 0.055231591F, 0.058820850F, 0.062643361F,
    897   0.066714279F, 0.071049749F, 0.075666962F, 0.080584227F,
    898   0.085821044F, 0.091398179F, 0.097337747F, 0.10366330F,
    899   0.11039993F, 0.11757434F, 0.12521498F, 0.13335215F,
    900   0.14201813F, 0.15124727F, 0.16107617F, 0.17154380F,
    901   0.18269168F, 0.19456402F, 0.20720788F, 0.22067342F,
    902   0.23501402F, 0.25028656F, 0.26655159F, 0.28387361F,
    903   0.30232132F, 0.32196786F, 0.34289114F, 0.36517414F,
    904   0.38890521F, 0.41417847F, 0.44109412F, 0.46975890F,
    905   0.50028648F, 0.53279791F, 0.56742212F, 0.60429640F,
    906   0.64356699F, 0.68538959F, 0.72993007F, 0.77736504F,
    907   0.82788260F, 0.88168307F, 0.9389798F, 1.F,
    908 };
    909 
    910 /* this is for per-channel noise normalization */
    911 static int apsort(const void *a, const void *b){
    912   float f1=**(float**)a;
    913   float f2=**(float**)b;
    914   return (f1<f2)-(f1>f2);
    915 }
    916 
    917 static void flag_lossless(int limit, float prepoint, float postpoint, float *mdct,
    918                          float *floor, int *flag, int i, int jn){
    919   int j;
    920   for(j=0;j<jn;j++){
    921     float point = j>=limit-i ? postpoint : prepoint;
    922     float r = fabs(mdct[j])/floor[j];
    923     if(r<point)
    924       flag[j]=0;
    925     else
    926       flag[j]=1;
    927   }
    928 }
    929 
    930 /* Overload/Side effect: On input, the *q vector holds either the
    931    quantized energy (for elements with the flag set) or the absolute
    932    values of the *r vector (for elements with flag unset).  On output,
    933    *q holds the quantized energy for all elements */
    934 static float noise_normalize(vorbis_look_psy *p, int limit, float *r, float *q, float *f, int *flags, float acc, int i, int n, int *out){
    935 
    936   vorbis_info_psy *vi=p->vi;
    937   float **sort = alloca(n*sizeof(*sort));
    938   int j,count=0;
    939   int start = (vi->normal_p ? vi->normal_start-i : n);
    940   if(start>n)start=n;
    941 
    942   /* force classic behavior where only energy in the current band is considered */
    943   acc=0.f;
    944 
    945   /* still responsible for populating *out where noise norm not in
    946      effect.  There's no need to [re]populate *q in these areas */
    947   for(j=0;j<start;j++){
    948     if(!flags || !flags[j]){ /* lossless coupling already quantized.
    949                                 Don't touch; requantizing based on
    950                                 energy would be incorrect. */
    951       float ve = q[j]/f[j];
    952       if(r[j]<0)
    953         out[j] = -rint(sqrt(ve));
    954       else
    955         out[j] = rint(sqrt(ve));
    956     }
    957   }
    958 
    959   /* sort magnitudes for noise norm portion of partition */
    960   for(;j<n;j++){
    961     if(!flags || !flags[j]){ /* can't noise norm elements that have
    962                                 already been loslessly coupled; we can
    963                                 only account for their energy error */
    964       float ve = q[j]/f[j];
    965       /* Despite all the new, more capable coupling code, for now we
    966          implement noise norm as it has been up to this point. Only
    967          consider promotions to unit magnitude from 0.  In addition
    968          the only energy error counted is quantizations to zero. */
    969       /* also-- the original point code only applied noise norm at > pointlimit */
    970       if(ve<.25f && (!flags || j>=limit-i)){
    971         acc += ve;
    972         sort[count++]=q+j; /* q is fabs(r) for unflagged element */
    973       }else{
    974         /* For now: no acc adjustment for nonzero quantization.  populate *out and q as this value is final. */
    975         if(r[j]<0)
    976           out[j] = -rint(sqrt(ve));
    977         else
    978           out[j] = rint(sqrt(ve));
    979         q[j] = out[j]*out[j]*f[j];
    980       }
    981     }/* else{
    982         again, no energy adjustment for error in nonzero quant-- for now
    983         }*/
    984   }
    985 
    986   if(count){
    987     /* noise norm to do */
    988     qsort(sort,count,sizeof(*sort),apsort);
    989     for(j=0;j<count;j++){
    990       int k=sort[j]-q;
    991       if(acc>=vi->normal_thresh){
    992         out[k]=unitnorm(r[k]);
    993         acc-=1.f;
    994         q[k]=f[k];
    995       }else{
    996         out[k]=0;
    997         q[k]=0.f;
    998       }
    999     }
   1000   }
   1001 
   1002   return acc;
   1003 }
   1004 
   1005 /* Noise normalization, quantization and coupling are not wholly
   1006    seperable processes in depth>1 coupling. */
   1007 void _vp_couple_quantize_normalize(int blobno,
   1008                                    vorbis_info_psy_global *g,
   1009                                    vorbis_look_psy *p,
   1010                                    vorbis_info_mapping0 *vi,
   1011                                    float **mdct,
   1012                                    int   **iwork,
   1013                                    int    *nonzero,
   1014                                    int     sliding_lowpass,
   1015                                    int     ch){
   1016 
   1017   int i;
   1018   int n = p->n;
   1019   int partition=(p->vi->normal_p ? p->vi->normal_partition : 16);
   1020   int limit = g->coupling_pointlimit[p->vi->blockflag][blobno];
   1021   float prepoint=stereo_threshholds[g->coupling_prepointamp[blobno]];
   1022   float postpoint=stereo_threshholds[g->coupling_postpointamp[blobno]];
   1023   float de=0.1*p->m_val; /* a blend of the AoTuV M2 and M3 code here and below */
   1024 
   1025   /* mdct is our raw mdct output, floor not removed. */
   1026   /* inout passes in the ifloor, passes back quantized result */
   1027 
   1028   /* unquantized energy (negative indicates amplitude has negative sign) */
   1029   float **raw = alloca(ch*sizeof(*raw));
   1030 
   1031   /* dual pupose; quantized energy (if flag set), othersize fabs(raw) */
   1032   float **quant = alloca(ch*sizeof(*quant));
   1033 
   1034   /* floor energy */
   1035   float **floor = alloca(ch*sizeof(*floor));
   1036 
   1037   /* flags indicating raw/quantized status of elements in raw vector */
   1038   int   **flag  = alloca(ch*sizeof(*flag));
   1039 
   1040   /* non-zero flag working vector */
   1041   int    *nz    = alloca(ch*sizeof(*nz));
   1042 
   1043   /* energy surplus/defecit tracking */
   1044   float  *acc   = alloca((ch+vi->coupling_steps)*sizeof(*acc));
   1045 
   1046   /* The threshold of a stereo is changed with the size of n */
   1047   if(n > 1000)
   1048     postpoint=stereo_threshholds_limited[g->coupling_postpointamp[blobno]];
   1049 
   1050   raw[0]   = alloca(ch*partition*sizeof(**raw));
   1051   quant[0] = alloca(ch*partition*sizeof(**quant));
   1052   floor[0] = alloca(ch*partition*sizeof(**floor));
   1053   flag[0]  = alloca(ch*partition*sizeof(**flag));
   1054 
   1055   for(i=1;i<ch;i++){
   1056     raw[i]   = &raw[0][partition*i];
   1057     quant[i] = &quant[0][partition*i];
   1058     floor[i] = &floor[0][partition*i];
   1059     flag[i]  = &flag[0][partition*i];
   1060   }
   1061   for(i=0;i<ch+vi->coupling_steps;i++)
   1062     acc[i]=0.f;
   1063 
   1064   for(i=0;i<n;i+=partition){
   1065     int k,j,jn = partition > n-i ? n-i : partition;
   1066     int step,track = 0;
   1067 
   1068     memcpy(nz,nonzero,sizeof(*nz)*ch);
   1069 
   1070     /* prefill */
   1071     memset(flag[0],0,ch*partition*sizeof(**flag));
   1072     for(k=0;k<ch;k++){
   1073       int *iout = &iwork[k][i];
   1074       if(nz[k]){
   1075 
   1076         for(j=0;j<jn;j++)
   1077           floor[k][j] = FLOOR1_fromdB_LOOKUP[iout[j]];
   1078 
   1079         flag_lossless(limit,prepoint,postpoint,&mdct[k][i],floor[k],flag[k],i,jn);
   1080 
   1081         for(j=0;j<jn;j++){
   1082           quant[k][j] = raw[k][j] = mdct[k][i+j]*mdct[k][i+j];
   1083           if(mdct[k][i+j]<0.f) raw[k][j]*=-1.f;
   1084           floor[k][j]*=floor[k][j];
   1085         }
   1086 
   1087         acc[track]=noise_normalize(p,limit,raw[k],quant[k],floor[k],NULL,acc[track],i,jn,iout);
   1088 
   1089       }else{
   1090         for(j=0;j<jn;j++){
   1091           floor[k][j] = 1e-10f;
   1092           raw[k][j] = 0.f;
   1093           quant[k][j] = 0.f;
   1094           flag[k][j] = 0;
   1095           iout[j]=0;
   1096         }
   1097         acc[track]=0.f;
   1098       }
   1099       track++;
   1100     }
   1101 
   1102     /* coupling */
   1103     for(step=0;step<vi->coupling_steps;step++){
   1104       int Mi = vi->coupling_mag[step];
   1105       int Ai = vi->coupling_ang[step];
   1106       int *iM = &iwork[Mi][i];
   1107       int *iA = &iwork[Ai][i];
   1108       float *reM = raw[Mi];
   1109       float *reA = raw[Ai];
   1110       float *qeM = quant[Mi];
   1111       float *qeA = quant[Ai];
   1112       float *floorM = floor[Mi];
   1113       float *floorA = floor[Ai];
   1114       int *fM = flag[Mi];
   1115       int *fA = flag[Ai];
   1116 
   1117       if(nz[Mi] || nz[Ai]){
   1118         nz[Mi] = nz[Ai] = 1;
   1119 
   1120         for(j=0;j<jn;j++){
   1121 
   1122           if(j<sliding_lowpass-i){
   1123             if(fM[j] || fA[j]){
   1124               /* lossless coupling */
   1125 
   1126               reM[j] = fabs(reM[j])+fabs(reA[j]);
   1127               qeM[j] = qeM[j]+qeA[j];
   1128               fM[j]=fA[j]=1;
   1129 
   1130               /* couple iM/iA */
   1131               {
   1132                 int A = iM[j];
   1133                 int B = iA[j];
   1134 
   1135                 if(abs(A)>abs(B)){
   1136                   iA[j]=(A>0?A-B:B-A);
   1137                 }else{
   1138                   iA[j]=(B>0?A-B:B-A);
   1139                   iM[j]=B;
   1140                 }
   1141 
   1142                 /* collapse two equivalent tuples to one */
   1143                 if(iA[j]>=abs(iM[j])*2){
   1144                   iA[j]= -iA[j];
   1145                   iM[j]= -iM[j];
   1146                 }
   1147 
   1148               }
   1149 
   1150             }else{
   1151               /* lossy (point) coupling */
   1152               if(j<limit-i){
   1153                 /* dipole */
   1154                 reM[j] += reA[j];
   1155                 qeM[j] = fabs(reM[j]);
   1156               }else{
   1157                 /* AoTuV */
   1158                 /** @ M2 **
   1159                     The boost problem by the combination of noise normalization and point stereo is eased.
   1160                     However, this is a temporary patch.
   1161                     by Aoyumi @ 2004/04/18
   1162                 */
   1163                 float derate = (1.0 - de*((float)(j-limit+i) / (float)(n-limit)));
   1164 
   1165                 /* elliptical */
   1166                 if(reM[j]+reA[j]<0){
   1167                   reM[j] = - (qeM[j] = (fabs(reM[j])+fabs(reA[j]))*derate*derate);
   1168                 }else{
   1169                   reM[j] =   (qeM[j] = (fabs(reM[j])+fabs(reA[j]))*derate*derate);
   1170                 }
   1171               }
   1172               reA[j]=qeA[j]=0.f;
   1173               fA[j]=1;
   1174               iA[j]=0;
   1175             }
   1176           }
   1177           floorM[j]=floorA[j]=floorM[j]+floorA[j];
   1178         }
   1179         /* normalize the resulting mag vector */
   1180         acc[track]=noise_normalize(p,limit,raw[Mi],quant[Mi],floor[Mi],flag[Mi],acc[track],i,jn,iM);
   1181         track++;
   1182       }
   1183     }
   1184   }
   1185 
   1186   for(i=0;i<vi->coupling_steps;i++){
   1187     /* make sure coupling a zero and a nonzero channel results in two
   1188        nonzero channels. */
   1189     if(nonzero[vi->coupling_mag[i]] ||
   1190        nonzero[vi->coupling_ang[i]]){
   1191       nonzero[vi->coupling_mag[i]]=1;
   1192       nonzero[vi->coupling_ang[i]]=1;
   1193     }
   1194   }
   1195 }
   1196