LCOV - code coverage report
Current view: top level - media/libvorbis/lib - vorbis_psy.c (source / functions) Hit Total Coverage
Test: output.info Lines: 0 573 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 23 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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$
      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           0 : vorbis_look_psy_global *_vp_global_look(vorbis_info *vi){
      37           0 :   codec_setup_info *ci=vi->codec_setup;
      38           0 :   vorbis_info_psy_global *gi=&ci->psy_g_param;
      39           0 :   vorbis_look_psy_global *look=_ogg_calloc(1,sizeof(*look));
      40             : 
      41           0 :   look->channels=vi->channels;
      42             : 
      43           0 :   look->ampmax=-9999.;
      44           0 :   look->gi=gi;
      45           0 :   return(look);
      46             : }
      47             : 
      48           0 : void _vp_global_free(vorbis_look_psy_global *look){
      49           0 :   if(look){
      50           0 :     memset(look,0,sizeof(*look));
      51           0 :     _ogg_free(look);
      52             :   }
      53           0 : }
      54             : 
      55           0 : void _vi_gpsy_free(vorbis_info_psy_global *i){
      56           0 :   if(i){
      57           0 :     memset(i,0,sizeof(*i));
      58           0 :     _ogg_free(i);
      59             :   }
      60           0 : }
      61             : 
      62           0 : void _vi_psy_free(vorbis_info_psy *i){
      63           0 :   if(i){
      64           0 :     memset(i,0,sizeof(*i));
      65           0 :     _ogg_free(i);
      66             :   }
      67           0 : }
      68             : 
      69           0 : static void min_curve(float *c,
      70             :                        float *c2){
      71             :   int i;
      72           0 :   for(i=0;i<EHMER_MAX;i++)if(c2[i]<c[i])c[i]=c2[i];
      73           0 : }
      74           0 : static void max_curve(float *c,
      75             :                        float *c2){
      76             :   int i;
      77           0 :   for(i=0;i<EHMER_MAX;i++)if(c2[i]>c[i])c[i]=c2[i];
      78           0 : }
      79             : 
      80           0 : static void attenuate_curve(float *c,float att){
      81             :   int i;
      82           0 :   for(i=0;i<EHMER_MAX;i++)
      83           0 :     c[i]+=att;
      84           0 : }
      85             : 
      86           0 : 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           0 :   float *brute_buffer=alloca(n*sizeof(*brute_buffer));
      93             : 
      94           0 :   float ***ret=_ogg_malloc(sizeof(*ret)*P_BANDS);
      95             : 
      96           0 :   memset(workc,0,sizeof(workc));
      97             : 
      98           0 :   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           0 :     int ath_offset=i*4;
     106           0 :     for(j=0;j<EHMER_MAX;j++){
     107           0 :       float min=999.;
     108           0 :       for(k=0;k<4;k++)
     109           0 :         if(j+k+ath_offset<MAX_ATH){
     110           0 :           if(min>ATH[j+k+ath_offset])min=ATH[j+k+ath_offset];
     111             :         }else{
     112           0 :           if(min>ATH[MAX_ATH-1])min=ATH[MAX_ATH-1];
     113             :         }
     114           0 :       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           0 :     for(j=0;j<6;j++)
     120           0 :       memcpy(workc[i][j+2],tonemasks[i][j],EHMER_MAX*sizeof(*tonemasks[i][j]));
     121           0 :     memcpy(workc[i][0],tonemasks[i][0],EHMER_MAX*sizeof(*tonemasks[i][0]));
     122           0 :     memcpy(workc[i][1],tonemasks[i][0],EHMER_MAX*sizeof(*tonemasks[i][0]));
     123             : 
     124             :     /* apply centered curve boost/decay */
     125           0 :     for(j=0;j<P_LEVELS;j++){
     126           0 :       for(k=0;k<EHMER_MAX;k++){
     127           0 :         float adj=center_boost+abs(EHMER_OFFSET-k)*center_decay_rate;
     128           0 :         if(adj<0. && center_boost>0)adj=0.;
     129           0 :         if(adj>0. && center_boost<0)adj=0.;
     130           0 :         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           0 :     for(j=0;j<P_LEVELS;j++){
     137           0 :       attenuate_curve(workc[i][j],curveatt_dB[i]+100.-(j<2?2:j)*10.-P_LEVEL_0);
     138           0 :       memcpy(athc[j],ath,EHMER_MAX*sizeof(**athc));
     139           0 :       attenuate_curve(athc[j],+100.-j*10.f-P_LEVEL_0);
     140           0 :       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           0 :     for(j=1;j<P_LEVELS;j++){
     154           0 :       min_curve(athc[j],athc[j-1]);
     155           0 :       min_curve(workc[i][j],athc[j]);
     156             :     }
     157             :   }
     158             : 
     159           0 :   for(i=0;i<P_BANDS;i++){
     160             :     int hi_curve,lo_curve,bin;
     161           0 :     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           0 :     bin=floor(fromOC(i*.5)/binHz);
     174           0 :     lo_curve=  ceil(toOC(bin*binHz+1)*2);
     175           0 :     hi_curve=  floor(toOC((bin+1)*binHz)*2);
     176           0 :     if(lo_curve>i)lo_curve=i;
     177           0 :     if(lo_curve<0)lo_curve=0;
     178           0 :     if(hi_curve>=P_BANDS)hi_curve=P_BANDS-1;
     179             : 
     180           0 :     for(m=0;m<P_LEVELS;m++){
     181           0 :       ret[i][m]=_ogg_malloc(sizeof(***ret)*(EHMER_MAX+2));
     182             : 
     183           0 :       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           0 :       for(k=lo_curve;k<=hi_curve;k++){
     189           0 :         int l=0;
     190             : 
     191           0 :         for(j=0;j<EHMER_MAX;j++){
     192           0 :           int lo_bin= fromOC(j*.125+k*.5-2.0625)/binHz;
     193           0 :           int hi_bin= fromOC(j*.125+k*.5-1.9375)/binHz+1;
     194             : 
     195           0 :           if(lo_bin<0)lo_bin=0;
     196           0 :           if(lo_bin>n)lo_bin=n;
     197           0 :           if(lo_bin<l)l=lo_bin;
     198           0 :           if(hi_bin<0)hi_bin=0;
     199           0 :           if(hi_bin>n)hi_bin=n;
     200             : 
     201           0 :           for(;l<hi_bin && l<n;l++)
     202           0 :             if(brute_buffer[l]>workc[k][m][j])
     203           0 :               brute_buffer[l]=workc[k][m][j];
     204             :         }
     205             : 
     206           0 :         for(;l<n;l++)
     207           0 :           if(brute_buffer[l]>workc[k][m][EHMER_MAX-1])
     208           0 :             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           0 :       if(i+1<P_BANDS){
     214           0 :         int l=0;
     215           0 :         k=i+1;
     216           0 :         for(j=0;j<EHMER_MAX;j++){
     217           0 :           int lo_bin= fromOC(j*.125+i*.5-2.0625)/binHz;
     218           0 :           int hi_bin= fromOC(j*.125+i*.5-1.9375)/binHz+1;
     219             : 
     220           0 :           if(lo_bin<0)lo_bin=0;
     221           0 :           if(lo_bin>n)lo_bin=n;
     222           0 :           if(lo_bin<l)l=lo_bin;
     223           0 :           if(hi_bin<0)hi_bin=0;
     224           0 :           if(hi_bin>n)hi_bin=n;
     225             : 
     226           0 :           for(;l<hi_bin && l<n;l++)
     227           0 :             if(brute_buffer[l]>workc[k][m][j])
     228           0 :               brute_buffer[l]=workc[k][m][j];
     229             :         }
     230             : 
     231           0 :         for(;l<n;l++)
     232           0 :           if(brute_buffer[l]>workc[k][m][EHMER_MAX-1])
     233           0 :             brute_buffer[l]=workc[k][m][EHMER_MAX-1];
     234             : 
     235             :       }
     236             : 
     237             : 
     238           0 :       for(j=0;j<EHMER_MAX;j++){
     239           0 :         int bin=fromOC(j*.125+i*.5-2.)/binHz;
     240           0 :         if(bin<0){
     241           0 :           ret[i][m][j+2]=-999.;
     242             :         }else{
     243           0 :           if(bin>=n){
     244           0 :             ret[i][m][j+2]=-999.;
     245             :           }else{
     246           0 :             ret[i][m][j+2]=brute_buffer[bin];
     247             :           }
     248             :         }
     249             :       }
     250             : 
     251             :       /* add fenceposts */
     252           0 :       for(j=0;j<EHMER_OFFSET;j++)
     253           0 :         if(ret[i][m][j+2]>-200.f)break;
     254           0 :       ret[i][m][0]=j;
     255             : 
     256           0 :       for(j=EHMER_MAX-1;j>EHMER_OFFSET+1;j--)
     257           0 :         if(ret[i][m][j+2]>-200.f)
     258           0 :           break;
     259           0 :       ret[i][m][1]=j;
     260             : 
     261             :     }
     262             :   }
     263             : 
     264           0 :   return(ret);
     265             : }
     266             : 
     267           0 : void _vp_psy_init(vorbis_look_psy *p,vorbis_info_psy *vi,
     268             :                   vorbis_info_psy_global *gi,int n,long rate){
     269           0 :   long i,j,lo=-99,hi=1;
     270             :   long maxoc;
     271           0 :   memset(p,0,sizeof(*p));
     272             : 
     273           0 :   p->eighth_octave_lines=gi->eighth_octave_lines;
     274           0 :   p->shiftoc=rint(log(gi->eighth_octave_lines*8.f)/log(2.f))-1;
     275             : 
     276           0 :   p->firstoc=toOC(.25f*rate*.5/n)*(1<<(p->shiftoc+1))-gi->eighth_octave_lines;
     277           0 :   maxoc=toOC((n+.25f)*rate*.5/n)*(1<<(p->shiftoc+1))+.5f;
     278           0 :   p->total_octave_lines=maxoc-p->firstoc+1;
     279           0 :   p->ath=_ogg_malloc(n*sizeof(*p->ath));
     280             : 
     281           0 :   p->octave=_ogg_malloc(n*sizeof(*p->octave));
     282           0 :   p->bark=_ogg_malloc(n*sizeof(*p->bark));
     283           0 :   p->vi=vi;
     284           0 :   p->n=n;
     285           0 :   p->rate=rate;
     286             : 
     287             :   /* AoTuV HF weighting */
     288           0 :   p->m_val = 1.;
     289           0 :   if(rate < 26000) p->m_val = 0;
     290           0 :   else if(rate < 38000) p->m_val = .94;   /* 32kHz */
     291           0 :   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           0 :   for(i=0,j=0;i<MAX_ATH-1;i++){
     296           0 :     int endpos=rint(fromOC((i+1)*.125-2.)*2*n/rate);
     297           0 :     float base=ATH[i];
     298           0 :     if(j<endpos){
     299           0 :       float delta=(ATH[i+1]-base)/(endpos-j);
     300           0 :       for(;j<endpos && j<n;j++){
     301           0 :         p->ath[j]=base+100.;
     302           0 :         base+=delta;
     303             :       }
     304             :     }
     305             :   }
     306             : 
     307           0 :   for(;j<n;j++){
     308           0 :     p->ath[j]=p->ath[j-1];
     309             :   }
     310             : 
     311           0 :   for(i=0;i<n;i++){
     312           0 :     float bark=toBARK(rate/(2*n)*i);
     313             : 
     314           0 :     for(;lo+vi->noisewindowlomin<i &&
     315           0 :           toBARK(rate/(2*n)*lo)<(bark-vi->noisewindowlo);lo++);
     316             : 
     317           0 :     for(;hi<=n && (hi<i+vi->noisewindowhimin ||
     318           0 :           toBARK(rate/(2*n)*hi)<(bark+vi->noisewindowhi));hi++);
     319             : 
     320           0 :     p->bark[i]=((lo-1)<<16)+(hi-1);
     321             : 
     322             :   }
     323             : 
     324           0 :   for(i=0;i<n;i++)
     325           0 :     p->octave[i]=toOC((i+.25f)*.5*rate/n)*(1<<(p->shiftoc+1))+.5f;
     326             : 
     327           0 :   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           0 :   p->noiseoffset=_ogg_malloc(P_NOISECURVES*sizeof(*p->noiseoffset));
     332           0 :   for(i=0;i<P_NOISECURVES;i++)
     333           0 :     p->noiseoffset[i]=_ogg_malloc(n*sizeof(**p->noiseoffset));
     334             : 
     335           0 :   for(i=0;i<n;i++){
     336           0 :     float halfoc=toOC((i+.5)*rate/(2.*n))*2.;
     337             :     int inthalfoc;
     338             :     float del;
     339             : 
     340           0 :     if(halfoc<0)halfoc=0;
     341           0 :     if(halfoc>=P_BANDS-1)halfoc=P_BANDS-1;
     342           0 :     inthalfoc=(int)halfoc;
     343           0 :     del=halfoc-inthalfoc;
     344             : 
     345           0 :     for(j=0;j<P_NOISECURVES;j++)
     346           0 :       p->noiseoffset[j][i]=
     347           0 :         p->vi->noiseoff[j][inthalfoc]*(1.-del) +
     348           0 :         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           0 : }
     360             : 
     361           0 : void _vp_psy_clear(vorbis_look_psy *p){
     362             :   int i,j;
     363           0 :   if(p){
     364           0 :     if(p->ath)_ogg_free(p->ath);
     365           0 :     if(p->octave)_ogg_free(p->octave);
     366           0 :     if(p->bark)_ogg_free(p->bark);
     367           0 :     if(p->tonecurves){
     368           0 :       for(i=0;i<P_BANDS;i++){
     369           0 :         for(j=0;j<P_LEVELS;j++){
     370           0 :           _ogg_free(p->tonecurves[i][j]);
     371             :         }
     372           0 :         _ogg_free(p->tonecurves[i]);
     373             :       }
     374           0 :       _ogg_free(p->tonecurves);
     375             :     }
     376           0 :     if(p->noiseoffset){
     377           0 :       for(i=0;i<P_NOISECURVES;i++){
     378           0 :         _ogg_free(p->noiseoffset[i]);
     379             :       }
     380           0 :       _ogg_free(p->noiseoffset);
     381             :     }
     382           0 :     memset(p,0,sizeof(*p));
     383             :   }
     384           0 : }
     385             : 
     386             : /* octave/(8*eighth_octave_lines) x scale and dB y scale */
     387           0 : 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           0 :   int choice=(int)((amp+dBoffset-P_LEVEL_0)*.1f);
     397           0 :   choice=max(choice,0);
     398           0 :   choice=min(choice,P_LEVELS-1);
     399           0 :   posts=curves[choice];
     400           0 :   curve=posts+2;
     401           0 :   post1=(int)posts[1];
     402           0 :   seedptr=oc+(posts[0]-EHMER_OFFSET)*linesper-(linesper>>1);
     403             : 
     404           0 :   for(i=posts[0];i<post1;i++){
     405           0 :     if(seedptr>0){
     406           0 :       float lin=amp+curve[i];
     407           0 :       if(seed[seedptr]<lin)seed[seedptr]=lin;
     408             :     }
     409           0 :     seedptr+=linesper;
     410           0 :     if(seedptr>=n)break;
     411             :   }
     412           0 : }
     413             : 
     414           0 : 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           0 :   vorbis_info_psy *vi=p->vi;
     421           0 :   long n=p->n,i;
     422           0 :   float dBoffset=vi->max_curve_dB-specmax;
     423             : 
     424             :   /* prime the working vector with peak values */
     425             : 
     426           0 :   for(i=0;i<n;i++){
     427           0 :     float max=f[i];
     428           0 :     long oc=p->octave[i];
     429           0 :     while(i+1<n && p->octave[i+1]==oc){
     430           0 :       i++;
     431           0 :       if(f[i]>max)max=f[i];
     432             :     }
     433             : 
     434           0 :     if(max+6.f>flr[i]){
     435           0 :       oc=oc>>p->shiftoc;
     436             : 
     437           0 :       if(oc>=P_BANDS)oc=P_BANDS-1;
     438           0 :       if(oc<0)oc=0;
     439             : 
     440           0 :       seed_curve(seed,
     441           0 :                  curves[oc],
     442             :                  max,
     443           0 :                  p->octave[i]-p->firstoc,
     444             :                  p->total_octave_lines,
     445             :                  p->eighth_octave_lines,
     446             :                  dBoffset);
     447             :     }
     448             :   }
     449           0 : }
     450             : 
     451           0 : static void seed_chase(float *seeds, int linesper, long n){
     452           0 :   long  *posstack=alloca(n*sizeof(*posstack));
     453           0 :   float *ampstack=alloca(n*sizeof(*ampstack));
     454           0 :   long   stack=0;
     455           0 :   long   pos=0;
     456             :   long   i;
     457             : 
     458           0 :   for(i=0;i<n;i++){
     459           0 :     if(stack<2){
     460           0 :       posstack[stack]=i;
     461           0 :       ampstack[stack++]=seeds[i];
     462             :     }else{
     463             :       while(1){
     464           0 :         if(seeds[i]<ampstack[stack-1]){
     465           0 :           posstack[stack]=i;
     466           0 :           ampstack[stack++]=seeds[i];
     467           0 :           break;
     468             :         }else{
     469           0 :           if(i<posstack[stack-1]+linesper){
     470           0 :             if(stack>1 && ampstack[stack-1]<=ampstack[stack-2] &&
     471           0 :                i<posstack[stack-2]+linesper){
     472             :               /* we completely overlap, making stack-1 irrelevant.  pop it */
     473           0 :               stack--;
     474           0 :               continue;
     475             :             }
     476             :           }
     477           0 :           posstack[stack]=i;
     478           0 :           ampstack[stack++]=seeds[i];
     479           0 :           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           0 :   for(i=0;i<stack;i++){
     490             :     long endpos;
     491           0 :     if(i<stack-1 && ampstack[i+1]>ampstack[i]){
     492           0 :       endpos=posstack[i+1];
     493             :     }else{
     494           0 :       endpos=posstack[i]+linesper+1; /* +1 is important, else bin 0 is
     495             :                                         discarded in short frames */
     496             :     }
     497           0 :     if(endpos>n)endpos=n;
     498           0 :     for(;pos<endpos;pos++)
     499           0 :       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           0 : }
     506             : 
     507             : /* bleaugh, this is more complicated than it needs to be */
     508             : #include<stdio.h>
     509           0 : static void max_seeds(vorbis_look_psy *p,
     510             :                       float *seed,
     511             :                       float *flr){
     512           0 :   long   n=p->total_octave_lines;
     513           0 :   int    linesper=p->eighth_octave_lines;
     514           0 :   long   linpos=0;
     515             :   long   pos;
     516             : 
     517           0 :   seed_chase(seed,linesper,n); /* for masking */
     518             : 
     519           0 :   pos=p->octave[0]-p->firstoc-(linesper>>1);
     520             : 
     521           0 :   while(linpos+1<p->n){
     522           0 :     float minV=seed[pos];
     523           0 :     long end=((p->octave[linpos]+p->octave[linpos+1])>>1)-p->firstoc;
     524           0 :     if(minV>p->vi->tone_abs_limit)minV=p->vi->tone_abs_limit;
     525           0 :     while(pos+1<=end){
     526           0 :       pos++;
     527           0 :       if((seed[pos]>NEGINF && seed[pos]<minV) || minV==NEGINF)
     528           0 :         minV=seed[pos];
     529             :     }
     530             : 
     531           0 :     end=pos+p->firstoc;
     532           0 :     for(;linpos<p->n && p->octave[linpos]<=end;linpos++)
     533           0 :       if(flr[linpos]<minV)flr[linpos]=minV;
     534             :   }
     535             : 
     536             :   {
     537           0 :     float minV=seed[p->total_octave_lines-1];
     538           0 :     for(;linpos<p->n;linpos++)
     539           0 :       if(flr[linpos]<minV)flr[linpos]=minV;
     540             :   }
     541             : 
     542           0 : }
     543             : 
     544           0 : 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           0 :   float *N=alloca(n*sizeof(*N));
     551           0 :   float *X=alloca(n*sizeof(*N));
     552           0 :   float *XX=alloca(n*sizeof(*N));
     553           0 :   float *Y=alloca(n*sizeof(*N));
     554           0 :   float *XY=alloca(n*sizeof(*N));
     555             : 
     556             :   float tN, tX, tXX, tY, tXY;
     557             :   int i;
     558             : 
     559             :   int lo, hi;
     560           0 :   float R=0.f;
     561           0 :   float A=0.f;
     562           0 :   float B=0.f;
     563           0 :   float D=1.f;
     564             :   float w, x, y;
     565             : 
     566           0 :   tN = tX = tXX = tY = tXY = 0.f;
     567             : 
     568           0 :   y = f[0] + offset;
     569           0 :   if (y < 1.f) y = 1.f;
     570             : 
     571           0 :   w = y * y * .5;
     572             : 
     573           0 :   tN += w;
     574           0 :   tX += w;
     575           0 :   tY += w * y;
     576             : 
     577           0 :   N[0] = tN;
     578           0 :   X[0] = tX;
     579           0 :   XX[0] = tXX;
     580           0 :   Y[0] = tY;
     581           0 :   XY[0] = tXY;
     582             : 
     583           0 :   for (i = 1, x = 1.f; i < n; i++, x += 1.f) {
     584             : 
     585           0 :     y = f[i] + offset;
     586           0 :     if (y < 1.f) y = 1.f;
     587             : 
     588           0 :     w = y * y;
     589             : 
     590           0 :     tN += w;
     591           0 :     tX += w * x;
     592           0 :     tXX += w * x * x;
     593           0 :     tY += w * y;
     594           0 :     tXY += w * x * y;
     595             : 
     596           0 :     N[i] = tN;
     597           0 :     X[i] = tX;
     598           0 :     XX[i] = tXX;
     599           0 :     Y[i] = tY;
     600           0 :     XY[i] = tXY;
     601             :   }
     602             : 
     603           0 :   for (i = 0, x = 0.f;; i++, x += 1.f) {
     604             : 
     605           0 :     lo = b[i] >> 16;
     606           0 :     if( lo>=0 ) break;
     607           0 :     hi = b[i] & 0xffff;
     608             : 
     609           0 :     tN = N[hi] + N[-lo];
     610           0 :     tX = X[hi] - X[-lo];
     611           0 :     tXX = XX[hi] + XX[-lo];
     612           0 :     tY = Y[hi] + Y[-lo];
     613           0 :     tXY = XY[hi] - XY[-lo];
     614             : 
     615           0 :     A = tY * tXX - tX * tXY;
     616           0 :     B = tN * tXY - tX * tY;
     617           0 :     D = tN * tXX - tX * tX;
     618           0 :     R = (A + x * B) / D;
     619           0 :     if (R < 0.f)
     620           0 :       R = 0.f;
     621             : 
     622           0 :     noise[i] = R - offset;
     623             :   }
     624             : 
     625           0 :   for ( ;; i++, x += 1.f) {
     626             : 
     627           0 :     lo = b[i] >> 16;
     628           0 :     hi = b[i] & 0xffff;
     629           0 :     if(hi>=n)break;
     630             : 
     631           0 :     tN = N[hi] - N[lo];
     632           0 :     tX = X[hi] - X[lo];
     633           0 :     tXX = XX[hi] - XX[lo];
     634           0 :     tY = Y[hi] - Y[lo];
     635           0 :     tXY = XY[hi] - XY[lo];
     636             : 
     637           0 :     A = tY * tXX - tX * tXY;
     638           0 :     B = tN * tXY - tX * tY;
     639           0 :     D = tN * tXX - tX * tX;
     640           0 :     R = (A + x * B) / D;
     641           0 :     if (R < 0.f) R = 0.f;
     642             : 
     643           0 :     noise[i] = R - offset;
     644             :   }
     645           0 :   for ( ; i < n; i++, x += 1.f) {
     646             : 
     647           0 :     R = (A + x * B) / D;
     648           0 :     if (R < 0.f) R = 0.f;
     649             : 
     650           0 :     noise[i] = R - offset;
     651             :   }
     652             : 
     653           0 :   if (fixed <= 0) return;
     654             : 
     655           0 :   for (i = 0, x = 0.f;; i++, x += 1.f) {
     656           0 :     hi = i + fixed / 2;
     657           0 :     lo = hi - fixed;
     658           0 :     if(lo>=0)break;
     659             : 
     660           0 :     tN = N[hi] + N[-lo];
     661           0 :     tX = X[hi] - X[-lo];
     662           0 :     tXX = XX[hi] + XX[-lo];
     663           0 :     tY = Y[hi] + Y[-lo];
     664           0 :     tXY = XY[hi] - XY[-lo];
     665             : 
     666             : 
     667           0 :     A = tY * tXX - tX * tXY;
     668           0 :     B = tN * tXY - tX * tY;
     669           0 :     D = tN * tXX - tX * tX;
     670           0 :     R = (A + x * B) / D;
     671             : 
     672           0 :     if (R - offset < noise[i]) noise[i] = R - offset;
     673             :   }
     674           0 :   for ( ;; i++, x += 1.f) {
     675             : 
     676           0 :     hi = i + fixed / 2;
     677           0 :     lo = hi - fixed;
     678           0 :     if(hi>=n)break;
     679             : 
     680           0 :     tN = N[hi] - N[lo];
     681           0 :     tX = X[hi] - X[lo];
     682           0 :     tXX = XX[hi] - XX[lo];
     683           0 :     tY = Y[hi] - Y[lo];
     684           0 :     tXY = XY[hi] - XY[lo];
     685             : 
     686           0 :     A = tY * tXX - tX * tXY;
     687           0 :     B = tN * tXY - tX * tY;
     688           0 :     D = tN * tXX - tX * tX;
     689           0 :     R = (A + x * B) / D;
     690             : 
     691           0 :     if (R - offset < noise[i]) noise[i] = R - offset;
     692             :   }
     693           0 :   for ( ; i < n; i++, x += 1.f) {
     694           0 :     R = (A + x * B) / D;
     695           0 :     if (R - offset < noise[i]) noise[i] = R - offset;
     696             :   }
     697             : }
     698             : 
     699           0 : void _vp_noisemask(vorbis_look_psy *p,
     700             :                    float *logmdct,
     701             :                    float *logmask){
     702             : 
     703           0 :   int i,n=p->n;
     704           0 :   float *work=alloca(n*sizeof(*work));
     705             : 
     706           0 :   bark_noise_hybridmp(n,p->bark,logmdct,logmask,
     707             :                       140.,-1);
     708             : 
     709           0 :   for(i=0;i<n;i++)work[i]=logmdct[i]-logmask[i];
     710             : 
     711           0 :   bark_noise_hybridmp(n,p->bark,work,logmask,0.,
     712           0 :                       p->vi->noisewindowfixed);
     713             : 
     714           0 :   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           0 :   for(i=0;i<n;i++){
     739           0 :     int dB=logmask[i]+.5;
     740           0 :     if(dB>=NOISE_COMPAND_LEVELS)dB=NOISE_COMPAND_LEVELS-1;
     741           0 :     if(dB<0)dB=0;
     742           0 :     logmask[i]= work[i]+p->vi->noisecompand[dB];
     743             :   }
     744             : 
     745           0 : }
     746             : 
     747           0 : void _vp_tonemask(vorbis_look_psy *p,
     748             :                   float *logfft,
     749             :                   float *logmask,
     750             :                   float global_specmax,
     751             :                   float local_specmax){
     752             : 
     753           0 :   int i,n=p->n;
     754             : 
     755           0 :   float *seed=alloca(sizeof(*seed)*p->total_octave_lines);
     756           0 :   float att=local_specmax+p->vi->ath_adjatt;
     757           0 :   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           0 :   if(att<p->vi->ath_maxatt)att=p->vi->ath_maxatt;
     762             : 
     763           0 :   for(i=0;i<n;i++)
     764           0 :     logmask[i]=p->ath[i]+att;
     765             : 
     766             :   /* tone masking */
     767           0 :   seed_loop(p,(const float ***)p->tonecurves,logfft,logmask,seed,global_specmax);
     768           0 :   max_seeds(p,seed,logmask);
     769             : 
     770           0 : }
     771             : 
     772           0 : 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           0 :   int i,n=p->n;
     780             :   float de, coeffi, cx;/* AoTuV */
     781           0 :   float toneatt=p->vi->tone_masteratt[offset_select];
     782             : 
     783           0 :   cx = p->m_val;
     784             : 
     785           0 :   for(i=0;i<n;i++){
     786           0 :     float val= noise[i]+p->noiseoffset[offset_select][i];
     787           0 :     if(val>p->vi->noisemaxsupp)val=p->vi->noisemaxsupp;
     788           0 :     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           0 :     if(offset_select == 1) {
     801           0 :       coeffi = -17.2;       /* coeffi is a -17.2dB threshold */
     802           0 :       val = val - logmdct[i];  /* val == mdct line value relative to floor in dB */
     803             : 
     804           0 :       if(val > coeffi){
     805             :         /* mdct value is > -17.2 dB below floor */
     806             : 
     807           0 :         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           0 :         if(de < 0) de = 0.0001;
     815             :       }else
     816             :         /* mdct value is <= -17.2 dB below floor */
     817             : 
     818           0 :         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           0 :       mdct[i] *= de;
     825             : 
     826             :     }
     827             :   }
     828           0 : }
     829             : 
     830           0 : float _vp_ampmax_decay(float amp,vorbis_dsp_state *vd){
     831           0 :   vorbis_info *vi=vd->vi;
     832           0 :   codec_setup_info *ci=vi->codec_setup;
     833           0 :   vorbis_info_psy_global *gi=&ci->psy_g_param;
     834             : 
     835           0 :   int n=ci->blocksizes[vd->W]/2;
     836           0 :   float secs=(float)n/vi->rate;
     837             : 
     838           0 :   amp+=secs*gi->ampmax_att_per_sec;
     839           0 :   if(amp<-9999)amp=-9999;
     840           0 :   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           0 : static int apsort(const void *a, const void *b){
     912           0 :   float f1=**(float**)a;
     913           0 :   float f2=**(float**)b;
     914           0 :   return (f1<f2)-(f1>f2);
     915             : }
     916             : 
     917           0 : 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           0 :   for(j=0;j<jn;j++){
     921           0 :     float point = j>=limit-i ? postpoint : prepoint;
     922           0 :     float r = fabs(mdct[j])/floor[j];
     923           0 :     if(r<point)
     924           0 :       flag[j]=0;
     925             :     else
     926           0 :       flag[j]=1;
     927             :   }
     928           0 : }
     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           0 : 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           0 :   vorbis_info_psy *vi=p->vi;
     937           0 :   float **sort = alloca(n*sizeof(*sort));
     938           0 :   int j,count=0;
     939           0 :   int start = (vi->normal_p ? vi->normal_start-i : n);
     940           0 :   if(start>n)start=n;
     941             : 
     942             :   /* force classic behavior where only energy in the current band is considered */
     943           0 :   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           0 :   for(j=0;j<start;j++){
     948           0 :     if(!flags || !flags[j]){ /* lossless coupling already quantized.
     949             :                                 Don't touch; requantizing based on
     950             :                                 energy would be incorrect. */
     951           0 :       float ve = q[j]/f[j];
     952           0 :       if(r[j]<0)
     953           0 :         out[j] = -rint(sqrt(ve));
     954             :       else
     955           0 :         out[j] = rint(sqrt(ve));
     956             :     }
     957             :   }
     958             : 
     959             :   /* sort magnitudes for noise norm portion of partition */
     960           0 :   for(;j<n;j++){
     961           0 :     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           0 :       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           0 :       if(ve<.25f && (!flags || j>=limit-i)){
     971           0 :         acc += ve;
     972           0 :         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           0 :         if(r[j]<0)
     976           0 :           out[j] = -rint(sqrt(ve));
     977             :         else
     978           0 :           out[j] = rint(sqrt(ve));
     979           0 :         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           0 :   if(count){
     987             :     /* noise norm to do */
     988           0 :     qsort(sort,count,sizeof(*sort),apsort);
     989           0 :     for(j=0;j<count;j++){
     990           0 :       int k=sort[j]-q;
     991           0 :       if(acc>=vi->normal_thresh){
     992           0 :         out[k]=unitnorm(r[k]);
     993           0 :         acc-=1.f;
     994           0 :         q[k]=f[k];
     995             :       }else{
     996           0 :         out[k]=0;
     997           0 :         q[k]=0.f;
     998             :       }
     999             :     }
    1000             :   }
    1001             : 
    1002           0 :   return acc;
    1003             : }
    1004             : 
    1005             : /* Noise normalization, quantization and coupling are not wholly
    1006             :    seperable processes in depth>1 coupling. */
    1007           0 : 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           0 :   int n = p->n;
    1019           0 :   int partition=(p->vi->normal_p ? p->vi->normal_partition : 16);
    1020           0 :   int limit = g->coupling_pointlimit[p->vi->blockflag][blobno];
    1021           0 :   float prepoint=stereo_threshholds[g->coupling_prepointamp[blobno]];
    1022           0 :   float postpoint=stereo_threshholds[g->coupling_postpointamp[blobno]];
    1023             : #if 0
    1024             :   float de=0.1*p->m_val; /* a blend of the AoTuV M2 and M3 code here and below */
    1025             : #endif
    1026             : 
    1027             :   /* mdct is our raw mdct output, floor not removed. */
    1028             :   /* inout passes in the ifloor, passes back quantized result */
    1029             : 
    1030             :   /* unquantized energy (negative indicates amplitude has negative sign) */
    1031           0 :   float **raw = alloca(ch*sizeof(*raw));
    1032             : 
    1033             :   /* dual pupose; quantized energy (if flag set), othersize fabs(raw) */
    1034           0 :   float **quant = alloca(ch*sizeof(*quant));
    1035             : 
    1036             :   /* floor energy */
    1037           0 :   float **floor = alloca(ch*sizeof(*floor));
    1038             : 
    1039             :   /* flags indicating raw/quantized status of elements in raw vector */
    1040           0 :   int   **flag  = alloca(ch*sizeof(*flag));
    1041             : 
    1042             :   /* non-zero flag working vector */
    1043           0 :   int    *nz    = alloca(ch*sizeof(*nz));
    1044             : 
    1045             :   /* energy surplus/defecit tracking */
    1046           0 :   float  *acc   = alloca((ch+vi->coupling_steps)*sizeof(*acc));
    1047             : 
    1048             :   /* The threshold of a stereo is changed with the size of n */
    1049           0 :   if(n > 1000)
    1050           0 :     postpoint=stereo_threshholds_limited[g->coupling_postpointamp[blobno]];
    1051             : 
    1052           0 :   raw[0]   = alloca(ch*partition*sizeof(**raw));
    1053           0 :   quant[0] = alloca(ch*partition*sizeof(**quant));
    1054           0 :   floor[0] = alloca(ch*partition*sizeof(**floor));
    1055           0 :   flag[0]  = alloca(ch*partition*sizeof(**flag));
    1056             : 
    1057           0 :   for(i=1;i<ch;i++){
    1058           0 :     raw[i]   = &raw[0][partition*i];
    1059           0 :     quant[i] = &quant[0][partition*i];
    1060           0 :     floor[i] = &floor[0][partition*i];
    1061           0 :     flag[i]  = &flag[0][partition*i];
    1062             :   }
    1063           0 :   for(i=0;i<ch+vi->coupling_steps;i++)
    1064           0 :     acc[i]=0.f;
    1065             : 
    1066           0 :   for(i=0;i<n;i+=partition){
    1067           0 :     int k,j,jn = partition > n-i ? n-i : partition;
    1068           0 :     int step,track = 0;
    1069             : 
    1070           0 :     memcpy(nz,nonzero,sizeof(*nz)*ch);
    1071             : 
    1072             :     /* prefill */
    1073           0 :     memset(flag[0],0,ch*partition*sizeof(**flag));
    1074           0 :     for(k=0;k<ch;k++){
    1075           0 :       int *iout = &iwork[k][i];
    1076           0 :       if(nz[k]){
    1077             : 
    1078           0 :         for(j=0;j<jn;j++)
    1079           0 :           floor[k][j] = FLOOR1_fromdB_LOOKUP[iout[j]];
    1080             : 
    1081           0 :         flag_lossless(limit,prepoint,postpoint,&mdct[k][i],floor[k],flag[k],i,jn);
    1082             : 
    1083           0 :         for(j=0;j<jn;j++){
    1084           0 :           quant[k][j] = raw[k][j] = mdct[k][i+j]*mdct[k][i+j];
    1085           0 :           if(mdct[k][i+j]<0.f) raw[k][j]*=-1.f;
    1086           0 :           floor[k][j]*=floor[k][j];
    1087             :         }
    1088             : 
    1089           0 :         acc[track]=noise_normalize(p,limit,raw[k],quant[k],floor[k],NULL,acc[track],i,jn,iout);
    1090             : 
    1091             :       }else{
    1092           0 :         for(j=0;j<jn;j++){
    1093           0 :           floor[k][j] = 1e-10f;
    1094           0 :           raw[k][j] = 0.f;
    1095           0 :           quant[k][j] = 0.f;
    1096           0 :           flag[k][j] = 0;
    1097           0 :           iout[j]=0;
    1098             :         }
    1099           0 :         acc[track]=0.f;
    1100             :       }
    1101           0 :       track++;
    1102             :     }
    1103             : 
    1104             :     /* coupling */
    1105           0 :     for(step=0;step<vi->coupling_steps;step++){
    1106           0 :       int Mi = vi->coupling_mag[step];
    1107           0 :       int Ai = vi->coupling_ang[step];
    1108           0 :       int *iM = &iwork[Mi][i];
    1109           0 :       int *iA = &iwork[Ai][i];
    1110           0 :       float *reM = raw[Mi];
    1111           0 :       float *reA = raw[Ai];
    1112           0 :       float *qeM = quant[Mi];
    1113           0 :       float *qeA = quant[Ai];
    1114           0 :       float *floorM = floor[Mi];
    1115           0 :       float *floorA = floor[Ai];
    1116           0 :       int *fM = flag[Mi];
    1117           0 :       int *fA = flag[Ai];
    1118             : 
    1119           0 :       if(nz[Mi] || nz[Ai]){
    1120           0 :         nz[Mi] = nz[Ai] = 1;
    1121             : 
    1122           0 :         for(j=0;j<jn;j++){
    1123             : 
    1124           0 :           if(j<sliding_lowpass-i){
    1125           0 :             if(fM[j] || fA[j]){
    1126             :               /* lossless coupling */
    1127             : 
    1128           0 :               reM[j] = fabs(reM[j])+fabs(reA[j]);
    1129           0 :               qeM[j] = qeM[j]+qeA[j];
    1130           0 :               fM[j]=fA[j]=1;
    1131             : 
    1132             :               /* couple iM/iA */
    1133           0 :               {
    1134           0 :                 int A = iM[j];
    1135           0 :                 int B = iA[j];
    1136             : 
    1137           0 :                 if(abs(A)>abs(B)){
    1138           0 :                   iA[j]=(A>0?A-B:B-A);
    1139             :                 }else{
    1140           0 :                   iA[j]=(B>0?A-B:B-A);
    1141           0 :                   iM[j]=B;
    1142             :                 }
    1143             : 
    1144             :                 /* collapse two equivalent tuples to one */
    1145           0 :                 if(iA[j]>=abs(iM[j])*2){
    1146           0 :                   iA[j]= -iA[j];
    1147           0 :                   iM[j]= -iM[j];
    1148             :                 }
    1149             : 
    1150             :               }
    1151             : 
    1152             :             }else{
    1153             :               /* lossy (point) coupling */
    1154           0 :               if(j<limit-i){
    1155             :                 /* dipole */
    1156           0 :                 reM[j] += reA[j];
    1157           0 :                 qeM[j] = fabs(reM[j]);
    1158             :               }else{
    1159             : #if 0
    1160             :                 /* AoTuV */
    1161             :                 /** @ M2 **
    1162             :                     The boost problem by the combination of noise normalization and point stereo is eased.
    1163             :                     However, this is a temporary patch.
    1164             :                     by Aoyumi @ 2004/04/18
    1165             :                 */
    1166             :                 float derate = (1.0 - de*((float)(j-limit+i) / (float)(n-limit)));
    1167             :                 /* elliptical */
    1168             :                 if(reM[j]+reA[j]<0){
    1169             :                   reM[j] = - (qeM[j] = (fabs(reM[j])+fabs(reA[j]))*derate*derate);
    1170             :                 }else{
    1171             :                   reM[j] =   (qeM[j] = (fabs(reM[j])+fabs(reA[j]))*derate*derate);
    1172             :                 }
    1173             : #else
    1174             :                 /* elliptical */
    1175           0 :                 if(reM[j]+reA[j]<0){
    1176           0 :                   reM[j] = - (qeM[j] = fabs(reM[j])+fabs(reA[j]));
    1177             :                 }else{
    1178           0 :                   reM[j] =   (qeM[j] = fabs(reM[j])+fabs(reA[j]));
    1179             :                 }
    1180             : #endif
    1181             : 
    1182             :               }
    1183           0 :               reA[j]=qeA[j]=0.f;
    1184           0 :               fA[j]=1;
    1185           0 :               iA[j]=0;
    1186             :             }
    1187             :           }
    1188           0 :           floorM[j]=floorA[j]=floorM[j]+floorA[j];
    1189             :         }
    1190             :         /* normalize the resulting mag vector */
    1191           0 :         acc[track]=noise_normalize(p,limit,raw[Mi],quant[Mi],floor[Mi],flag[Mi],acc[track],i,jn,iM);
    1192           0 :         track++;
    1193             :       }
    1194             :     }
    1195             :   }
    1196             : 
    1197           0 :   for(i=0;i<vi->coupling_steps;i++){
    1198             :     /* make sure coupling a zero and a nonzero channel results in two
    1199             :        nonzero channels. */
    1200           0 :     if(nonzero[vi->coupling_mag[i]] ||
    1201           0 :        nonzero[vi->coupling_ang[i]]){
    1202           0 :       nonzero[vi->coupling_mag[i]]=1;
    1203           0 :       nonzero[vi->coupling_ang[i]]=1;
    1204             :     }
    1205             :   }
    1206           0 : }

Generated by: LCOV version 1.13