LCOV - code coverage report
Current view: directory - media/libvorbis/lib - vorbis_psy.c (source / functions) Found Hit Coverage
Test: app.info Lines: 578 0 0.0 %
Date: 2012-06-02 Functions: 23 0 0.0 %

       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 18077 2011-09-02 02:49:00Z giles $
      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               0 :       }
     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               0 :   }
     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               0 :   }
     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               0 :   }
     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               0 :   }
     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.7