examples/sfexamples/oggvorbiscodec/src/libvorbis/lib/psy.c

00001 /********************************************************************
00002  *                                                                  *
00003  * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
00004  * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
00005  * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
00006  * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
00007  *                                                                  *
00008  * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002             *
00009  * by the XIPHOPHORUS Company http://www.xiph.org/                  *
00010  *                                                                  *
00011  ********************************************************************
00012 
00013  function: psychoacoustics not including preecho
00014  last mod: $Id: psy.c 7187 2004-07-20 07:24:27Z xiphmont $
00015 
00016  ********************************************************************/
00017 #include <stdio.h>
00018 #include <stdlib.h>
00019 #include <math.h>
00020 #include <string.h>
00021 #include "vorbis/codec.h"
00022 #include "codec_internal.h"
00023 #include "masking.h"
00024 #include "psy.h"
00025 #include "os.h"
00026 #include "lpc.h"
00027 #include "smallft.h"
00028 #include "scales.h"
00029 #include "misc.h"
00030 
00031 #define NEGINF -9999.f
00032 static double stereo_threshholds[]={0.0, .5, 1.0, 1.5, 2.5, 4.5, 8.5, 16.5, 9e10};
00033 static double stereo_threshholds_limited[]={0.0, .5, 1.0, 1.5, 2.0, 2.5, 4.5, 8.5, 9e10};
00034 
00035 vorbis_look_psy_global *_vp_global_look(vorbis_info *vi){
00036   codec_setup_info *ci=(codec_setup_info*)vi->codec_setup;
00037   vorbis_info_psy_global *gi=&ci->psy_g_param;
00038   vorbis_look_psy_global *look=(vorbis_look_psy_global*)_ogg_calloc(1,sizeof(*look));
00039 
00040   look->channels=vi->channels;
00041 
00042   look->ampmax=-9999.;
00043   look->gi=gi;
00044   return(look);
00045 }
00046 
00047 void _vp_global_free(vorbis_look_psy_global *look){
00048   if(look){
00049     memset(look,0,sizeof(*look));
00050     _ogg_free(look);
00051   }
00052 }
00053 
00054 void _vi_gpsy_free(vorbis_info_psy_global *i){
00055   if(i){
00056     memset(i,0,sizeof(*i));
00057     _ogg_free(i);
00058   }
00059 }
00060 
00061 void _vi_psy_free(vorbis_info_psy *i){
00062   if(i){
00063     memset(i,0,sizeof(*i));
00064     _ogg_free(i);
00065   }
00066 }
00067 
00068 static void min_curve(float *c,
00069                        float *c2){
00070   int i;  
00071   for(i=0;i<EHMER_MAX;i++)if(c2[i]<c[i])c[i]=c2[i];
00072 }
00073 static void max_curve(float *c,
00074                        float *c2){
00075   int i;  
00076   for(i=0;i<EHMER_MAX;i++)if(c2[i]>c[i])c[i]=c2[i];
00077 }
00078 
00079 static void attenuate_curve(float *c,float att){
00080   int i;
00081   for(i=0;i<EHMER_MAX;i++)
00082     c[i]+=att;
00083 }
00084 
00085 
00086 static float ***setup_tone_curves(float curveatt_dB[P_BANDS],float binHz,int n,
00087                                   float center_boost, float center_decay_rate){
00088   int i,j,k,m;
00089   float ath[EHMER_MAX];
00090   //float workc[P_BANDS][P_LEVELS][EHMER_MAX];
00091   //float athc[P_LEVELS][EHMER_MAX];
00092   float *brute_buffer= (float*)_ogg_malloc(n*sizeof(*brute_buffer));//alloca(n*sizeof(*brute_buffer));//patch
00093   float *brute_buffer_cpy = brute_buffer;
00094 
00095   float ***ret=(float***)_ogg_malloc(sizeof(*ret)*P_BANDS);
00096   float ***workc = (float***)_ogg_malloc(sizeof(*workc)*P_BANDS);       
00097   //added to fix the stack overflow on H4
00098   float **athc = (float**)_ogg_malloc(sizeof(*athc)*P_LEVELS);;
00099   for(i=0;i<P_LEVELS;i++)
00100         {
00101         athc[i]=(float*)_ogg_malloc(sizeof(**athc)*EHMER_MAX);
00102         for(j=0;j<EHMER_MAX;j++)
00103                 {
00104         athc[i][j] = 0;
00105                 }
00106         }//fix end
00107         
00108   //added to fix the stack overflow on H4
00109   for(i=0;i<P_BANDS;i++)
00110         {
00111         workc[i]=(float**)_ogg_malloc(sizeof(**workc)*P_LEVELS);
00112         for(j=0;j<P_LEVELS;j++)
00113                 {
00114         workc[i][j]=(float*)_ogg_malloc(sizeof(***workc)*(EHMER_MAX));
00115                 for(k=0;k<EHMER_MAX;k++)
00116                         {
00117                 workc[i][j][k] = 0;
00118                         }
00119                 }
00120         }//fix end
00121   
00122   
00123   //memset(workc,0,sizeof(workc));
00124         
00125   for(i=0;i<P_BANDS;i++){
00126     /* we add back in the ATH to avoid low level curves falling off to
00127        -infinity and unnecessarily cutting off high level curves in the
00128        curve limiting (last step). */
00129 
00130     /* A half-band's settings must be valid over the whole band, and
00131        it's better to mask too little than too much */  
00132     int ath_offset=i*4;
00133     for(j=0;j<EHMER_MAX;j++){
00134       float min=999.;
00135       for(k=0;k<4;k++)
00136         if(j+k+ath_offset<MAX_ATH){
00137           if(min>ATH[j+k+ath_offset])min=ATH[j+k+ath_offset];
00138         }else{
00139           if(min>ATH[MAX_ATH-1])min=ATH[MAX_ATH-1];
00140         }
00141       ath[j]=min;
00142     }
00143 
00144     /* copy curves into working space, replicate the 50dB curve to 30
00145        and 40, replicate the 100dB curve to 110 */
00146     for(j=0;j<6;j++)
00147       memcpy(workc[i][j+2],tonemasks[i][j],EHMER_MAX*sizeof(*tonemasks[i][j]));
00148     memcpy(workc[i][0],tonemasks[i][0],EHMER_MAX*sizeof(*tonemasks[i][0]));
00149     memcpy(workc[i][1],tonemasks[i][0],EHMER_MAX*sizeof(*tonemasks[i][0]));
00150     
00151     /* apply centered curve boost/decay */
00152     for(j=0;j<P_LEVELS;j++){
00153       for(k=0;k<EHMER_MAX;k++){
00154         float adj=center_boost+abs(EHMER_OFFSET-k)*center_decay_rate;
00155         if(adj<0. && center_boost>0)adj=0.;
00156         if(adj>0. && center_boost<0)adj=0.;
00157         workc[i][j][k]+=adj;
00158       }
00159     }
00160 
00161     /* normalize curves so the driving amplitude is 0dB */
00162     /* make temp curves with the ATH overlayed */
00163     for(j=0;j<P_LEVELS;j++){
00164       attenuate_curve(workc[i][j],curveatt_dB[i]+100.-(j<2?2:j)*10.-P_LEVEL_0);
00165       memcpy(athc[j],ath,EHMER_MAX*sizeof(**athc));
00166       attenuate_curve(athc[j],+100.-j*10.f-P_LEVEL_0);
00167       max_curve(athc[j],workc[i][j]);
00168     }
00169 
00170     /* Now limit the louder curves.
00171        
00172        the idea is this: We don't know what the playback attenuation
00173        will be; 0dB SL moves every time the user twiddles the volume
00174        knob. So that means we have to use a single 'most pessimal' curve
00175        for all masking amplitudes, right?  Wrong.  The *loudest* sound
00176        can be in (we assume) a range of ...+100dB] SL.  However, sounds
00177        20dB down will be in a range ...+80], 40dB down is from ...+60],
00178        etc... */
00179     
00180     for(j=1;j<P_LEVELS;j++){
00181       min_curve(athc[j],athc[j-1]);
00182       min_curve(workc[i][j],athc[j]);
00183     }
00184   }
00185 
00186   for(i=0;i<P_BANDS;i++){
00187     int hi_curve,lo_curve,bin;
00188     ret[i]=(float**)_ogg_malloc(sizeof(**ret)*P_LEVELS);
00189 
00190     /* low frequency curves are measured with greater resolution than
00191        the MDCT/FFT will actually give us; we want the curve applied
00192        to the tone data to be pessimistic and thus apply the minimum
00193        masking possible for a given bin.  That means that a single bin
00194        could span more than one octave and that the curve will be a
00195        composite of multiple octaves.  It also may mean that a single
00196        bin may span > an eighth of an octave and that the eighth
00197        octave values may also be composited. */
00198     
00199     /* which octave curves will we be compositing? */
00200     bin=floor(fromOC(i*.5)/binHz);
00201     lo_curve=  ceil(toOC(bin*binHz+1)*2);
00202     hi_curve=  floor(toOC((bin+1)*binHz)*2);
00203     if(lo_curve>i)lo_curve=i;
00204     if(lo_curve<0)lo_curve=0;
00205     if(hi_curve>=P_BANDS)hi_curve=P_BANDS-1;
00206 
00207     for(m=0;m<P_LEVELS;m++){
00208       ret[i][m]=(float*)_ogg_malloc(sizeof(***ret)*(EHMER_MAX+2));
00209       
00210       for(j=0;j<n;j++)brute_buffer[j]=999.;
00211       
00212       /* render the curve into bins, then pull values back into curve.
00213          The point is that any inherent subsampling aliasing results in
00214          a safe minimum */
00215       for(k=lo_curve;k<=hi_curve;k++){
00216         int l=0;
00217 
00218         for(j=0;j<EHMER_MAX;j++){
00219           int lo_bin= fromOC(j*.125+k*.5-2.0625)/binHz;
00220           int hi_bin= fromOC(j*.125+k*.5-1.9375)/binHz+1;
00221           
00222           if(lo_bin<0)lo_bin=0;
00223           if(lo_bin>n)lo_bin=n;
00224           if(lo_bin<l)l=lo_bin;
00225           if(hi_bin<0)hi_bin=0;
00226           if(hi_bin>n)hi_bin=n;
00227 
00228           for(;l<hi_bin && l<n;l++)
00229             if(brute_buffer[l]>workc[k][m][j])
00230               brute_buffer[l]=workc[k][m][j];
00231         }
00232 
00233         for(;l<n;l++)
00234           if(brute_buffer[l]>workc[k][m][EHMER_MAX-1])
00235             brute_buffer[l]=workc[k][m][EHMER_MAX-1];
00236 
00237       }
00238 
00239       /* be equally paranoid about being valid up to next half ocatve */
00240       if(i+1<P_BANDS){
00241         int l=0;
00242         k=i+1;
00243         for(j=0;j<EHMER_MAX;j++){
00244           int lo_bin= fromOC(j*.125+i*.5-2.0625)/binHz;
00245           int hi_bin= fromOC(j*.125+i*.5-1.9375)/binHz+1;
00246           
00247           if(lo_bin<0)lo_bin=0;
00248           if(lo_bin>n)lo_bin=n;
00249           if(lo_bin<l)l=lo_bin;
00250           if(hi_bin<0)hi_bin=0;
00251           if(hi_bin>n)hi_bin=n;
00252 
00253           for(;l<hi_bin && l<n;l++)
00254             if(brute_buffer[l]>workc[k][m][j])
00255               brute_buffer[l]=workc[k][m][j];
00256         }
00257 
00258         for(;l<n;l++)
00259           if(brute_buffer[l]>workc[k][m][EHMER_MAX-1])
00260             brute_buffer[l]=workc[k][m][EHMER_MAX-1];
00261 
00262       }
00263 
00264 
00265       for(j=0;j<EHMER_MAX;j++){
00266         int bin=fromOC(j*.125+i*.5-2.)/binHz;
00267         if(bin<0){
00268           ret[i][m][j+2]=-999.;
00269         }else{
00270           if(bin>=n){
00271             ret[i][m][j+2]=-999.;
00272           }else{
00273             ret[i][m][j+2]=brute_buffer[bin];
00274           }
00275         }
00276       }
00277 
00278       /* add fenceposts */
00279       for(j=0;j<EHMER_OFFSET;j++)
00280         if(ret[i][m][j+2]>-200.f)break;  
00281       ret[i][m][0]=j;
00282       
00283       for(j=EHMER_MAX-1;j>EHMER_OFFSET+1;j--)
00284         if(ret[i][m][j+2]>-200.f)
00285           break;
00286       ret[i][m][1]=j;
00287 
00288     }
00289   }
00290   
00291   free(brute_buffer_cpy);       
00292   
00293   for(i=0;i<P_BANDS;i++) 
00294         { 
00295     for(j=0;j<P_LEVELS;j++) 
00296         {
00297         _ogg_free(workc[i][j]);
00298         } 
00299         _ogg_free(workc[i]); 
00300     } 
00301   _ogg_free(workc); 
00302   for(i=0;i<P_LEVELS;i++)
00303         {
00304         _ogg_free(athc[i]);
00305         }
00306   _ogg_free(athc);
00307   return(ret);
00308 }
00309 
00310 
00311 void _vp_psy_init(vorbis_look_psy *p,vorbis_info_psy *vi,
00312                   vorbis_info_psy_global *gi,int n,long rate){
00313   long i,j,lo=-99,hi=1;
00314   long maxoc;
00315   memset(p,0,sizeof(*p));
00316 
00317   p->eighth_octave_lines=gi->eighth_octave_lines;
00318   p->shiftoc=rint(log(gi->eighth_octave_lines*8.f)/log(2.f))-1;
00319 
00320   p->firstoc=toOC(.25f*rate*.5/n)*(1<<(p->shiftoc+1))-gi->eighth_octave_lines;
00321   maxoc=toOC((n+.25f)*rate*.5/n)*(1<<(p->shiftoc+1))+.5f;
00322   p->total_octave_lines=maxoc-p->firstoc+1;
00323   p->ath=(float*)_ogg_malloc(n*sizeof(*p->ath));
00324 
00325   p->octave=(long int*)_ogg_malloc(n*sizeof(*p->octave));
00326   p->bark=(long int*)_ogg_malloc(n*sizeof(*p->bark));
00327   p->vi=vi;
00328   p->n=n;
00329   p->rate=rate;
00330 
00331   /* AoTuV HF weighting */
00332   p->m_val = 1.;
00333   if(rate < 26000) p->m_val = 0;
00334   else if(rate < 38000) p->m_val = .94;   /* 32kHz */
00335   else if(rate > 46000) p->m_val = 1.275; /* 48kHz */
00336   
00337   /* set up the lookups for a given blocksize and sample rate */
00338 
00339   for(i=0,j=0;i<MAX_ATH-1;i++){
00340     int endpos=rint(fromOC((i+1)*.125-2.)*2*n/rate);
00341     float base=ATH[i];
00342     if(j<endpos){
00343       float delta=(ATH[i+1]-base)/(endpos-j);
00344       for(;j<endpos && j<n;j++){
00345         p->ath[j]=base+100.;
00346         base+=delta;
00347       }
00348     }
00349   }
00350 
00351   for(i=0;i<n;i++){
00352     float bark=toBARK(rate/(2*n)*i); 
00353 
00354     for(;lo+vi->noisewindowlomin<i && 
00355           toBARK(rate/(2*n)*lo)<(bark-vi->noisewindowlo);lo++)
00356     
00357     for(;hi<=n && (hi<i+vi->noisewindowhimin ||
00358           toBARK(rate/(2*n)*hi)<(bark+vi->noisewindowhi));hi++)
00359     
00360     p->bark[i]=((lo-1)<<16)+(hi-1);
00361 
00362   }
00363 
00364   for(i=0;i<n;i++)
00365     p->octave[i]=toOC((i+.25f)*.5*rate/n)*(1<<(p->shiftoc+1))+.5f;
00366 
00367   p->tonecurves=setup_tone_curves(vi->toneatt,rate*.5/n,n,
00368                                   vi->tone_centerboost,vi->tone_decay);
00369   
00370 
00371   /* set up rolling noise median */
00372   p->noiseoffset=(float**)_ogg_malloc(P_NOISECURVES*sizeof(*p->noiseoffset));
00373   for(i=0;i<P_NOISECURVES;i ++)
00374     p->noiseoffset[i]=(float*)_ogg_malloc(n*sizeof(**p->noiseoffset));
00375   
00376   for(i=0;i<n;i++){
00377     float halfoc=toOC((i+.5)*rate/(2.*n))*2.;
00378     int inthalfoc;
00379     float del;
00380     
00381     if(halfoc<0)halfoc=0;
00382     if(halfoc>=P_BANDS-1)halfoc=P_BANDS-1;
00383     inthalfoc=(int)halfoc;
00384     del=halfoc-inthalfoc;
00385     
00386     for(j=0;j<P_NOISECURVES;j++)
00387       p->noiseoffset[j][i]=
00388         p->vi->noiseoff[j][inthalfoc]*(1.-del) + 
00389         p->vi->noiseoff[j][inthalfoc+1]*del;
00390     
00391   }
00392 #if 0
00393   {
00394     static int ls=0;
00395     _analysis_output_always("noiseoff0",ls,p->noiseoffset[0],n,1,0,0);
00396     _analysis_output_always("noiseoff1",ls,p->noiseoffset[1],n,1,0,0);
00397     _analysis_output_always("noiseoff2",ls++,p->noiseoffset[2],n,1,0,0);
00398   }
00399 #endif
00400 }
00401 
00402 void _vp_psy_clear(vorbis_look_psy *p){
00403   int i,j;
00404   if(p){
00405     if(p->ath)_ogg_free(p->ath);
00406     if(p->octave)_ogg_free(p->octave);
00407     if(p->bark)_ogg_free(p->bark);
00408     if(p->tonecurves){
00409       for(i=0;i<P_BANDS;i++){
00410         for(j=0;j<P_LEVELS;j++){
00411           _ogg_free(p->tonecurves[i][j]);
00412         }
00413         _ogg_free(p->tonecurves[i]);
00414       }
00415       _ogg_free(p->tonecurves);
00416     }
00417     if(p->noiseoffset){
00418       for(i=0;i<P_NOISECURVES;i++){
00419         _ogg_free(p->noiseoffset[i]);
00420       }
00421       _ogg_free(p->noiseoffset);
00422     }
00423     memset(p,0,sizeof(*p));
00424   }
00425 }
00426 
00427 /* octave/(8*eighth_octave_lines) x scale and dB y scale */
00428 static void seed_curve(float *seed,
00429                        const float **curves,
00430                        float amp,
00431                        int oc, int n,
00432                        int linesper,float dBoffset){
00433   int i,post1;
00434   int seedptr;
00435   const float *posts,*curve;
00436 
00437   int choice=(int)((amp+dBoffset-P_LEVEL_0)*.1f);
00438   choice=max(choice,0);
00439   choice=min(choice,P_LEVELS-1);
00440   posts=curves[choice];
00441   curve=posts+2;
00442   post1=(int)posts[1];
00443   seedptr=oc+(posts[0]-EHMER_OFFSET)*linesper-(linesper>>1);
00444 
00445   for(i=posts[0];i<post1;i++){
00446     if(seedptr>0){
00447       float lin=amp+curve[i];
00448       if(seed[seedptr]<lin)seed[seedptr]=lin;
00449     }
00450     seedptr+=linesper;
00451     if(seedptr>=n)break;
00452   }
00453 }
00454 
00455 static void seed_loop(vorbis_look_psy *p,
00456                       const float ***curves,
00457                       const float *f, 
00458                       const float *flr,
00459                       float *seed,
00460                       float specmax){
00461   vorbis_info_psy *vi=p->vi;
00462   long n=p->n,i;
00463   float dBoffset=vi->max_curve_dB-specmax;
00464 
00465   /* prime the working vector with peak values */
00466 
00467   for(i=0;i<n;i++){
00468     float max=f[i];
00469     long oc=p->octave[i];
00470     while(i+1<n && p->octave[i+1]==oc){
00471       i++;
00472       if(f[i]>max)max=f[i];
00473     }
00474     
00475     if(max+6.f>flr[i]){
00476       oc=oc>>p->shiftoc;
00477 
00478       if(oc>=P_BANDS)oc=P_BANDS-1;
00479       if(oc<0)oc=0;
00480 
00481       seed_curve(seed,
00482                  curves[oc],
00483                  max,
00484                  p->octave[i]-p->firstoc,
00485                  p->total_octave_lines,
00486                  p->eighth_octave_lines,
00487                  dBoffset);
00488     }
00489   }
00490 }
00491 
00492 static void seed_chase(float *seeds, int linesper, long n){
00493   long  *posstack= (long*)_ogg_malloc(n*sizeof(*posstack));//alloca(n*sizeof(*posstack)); //patch
00494   float *ampstack= (float*)_ogg_malloc(n*sizeof(*ampstack));//alloca(n*sizeof(*ampstack)); //patch 
00495   long *posstack_cpy = posstack;
00496   float *ampstack_cpy = ampstack;
00497   long   stack=0;
00498   long   pos=0;
00499   long   i;
00500 
00501   for(i=0;i<n;i++){
00502     if(stack<2){
00503       posstack[stack]=i;
00504       ampstack[stack++]=seeds[i];
00505     }else{
00506       while(1){
00507         if(seeds[i]<ampstack[stack-1]){
00508           posstack[stack]=i;
00509           ampstack[stack++]=seeds[i];
00510           break;
00511         }else{
00512           if(i<posstack[stack-1]+linesper){
00513             if(stack>1 && ampstack[stack-1]<=ampstack[stack-2] &&
00514                i<posstack[stack-2]+linesper){
00515               /* we completely overlap, making stack-1 irrelevant.  pop it */
00516               stack--;
00517               continue;
00518             }
00519           }
00520           posstack[stack]=i;
00521           ampstack[stack++]=seeds[i];
00522           break;
00523 
00524         }
00525       }
00526     }
00527   }
00528 
00529   /* the stack now contains only the positions that are relevant. Scan
00530      'em straight through */
00531 
00532   for(i=0;i<stack;i++){
00533     long endpos;
00534     if(i<stack-1 && ampstack[i+1]>ampstack[i]){
00535       endpos=posstack[i+1];
00536     }else{
00537       endpos=posstack[i]+linesper+1; /* +1 is important, else bin 0 is
00538                                         discarded in short frames */
00539     }
00540     if(endpos>n)endpos=n;
00541     for(;pos<endpos;pos++)
00542       seeds[pos]=ampstack[i];
00543   }
00544   
00545   /* there.  Linear time.  I now remember this was on a problem set I
00546      had in Grad Skool... I didn't solve it at the time ;-) */
00547 free(posstack_cpy);
00548 free(ampstack_cpy);
00549 }
00550 
00551 /* bleaugh, this is more complicated than it needs to be */
00552 #include<stdio.h>
00553 static void max_seeds(vorbis_look_psy *p,
00554                       float *seed,
00555                       float *flr){
00556   long   n=p->total_octave_lines;
00557   int    linesper=p->eighth_octave_lines;
00558   long   linpos=0;
00559   long   pos;
00560 
00561   seed_chase(seed,linesper,n); /* for masking */
00562  
00563   pos=p->octave[0]-p->firstoc-(linesper>>1);
00564 
00565   while(linpos+1<p->n){
00566     float minV=seed[pos];
00567     long end=((p->octave[linpos]+p->octave[linpos+1])>>1)-p->firstoc;
00568     if(minV>p->vi->tone_abs_limit)minV=p->vi->tone_abs_limit;
00569     while(pos+1<=end){
00570       pos++;
00571       if((seed[pos]>NEGINF && seed[pos]<minV) || minV==NEGINF)
00572         minV=seed[pos];
00573     }
00574     
00575     end=pos+p->firstoc;
00576     for(;linpos<p->n && p->octave[linpos]<=end;linpos++)
00577       if(flr[linpos]<minV)flr[linpos]=minV;
00578   }
00579   
00580   {
00581     float minV=seed[p->total_octave_lines-1];
00582     for(;linpos<p->n;linpos++)
00583       if(flr[linpos]<minV)flr[linpos]=minV;
00584   }
00585   
00586 }
00587 
00588 static void bark_noise_hybridmp(int n,const long *b,
00589                                 const float *f,
00590                                 float *noise,
00591                                 const float offset,
00592                                 const int fixed){
00593   /*
00594   float *N=alloca(n*sizeof(*N));
00595   float *X=alloca(n*sizeof(*N));
00596   float *XX=alloca(n*sizeof(*N));
00597   float *Y=alloca(n*sizeof(*N));
00598   float *XY=alloca(n*sizeof(*N));
00599   */
00600   float *N=(float*)_ogg_malloc(n*sizeof(*N));
00601   float *X=(float*)_ogg_malloc(n*sizeof(*N));
00602   float *XX=(float*)_ogg_malloc(n*sizeof(*N));
00603   float *Y=(float*)_ogg_malloc(n*sizeof(*N));
00604   float *XY=(float*)_ogg_malloc(n*sizeof(*N));
00605   
00606   float *N_cpy = N;
00607   float *X_cpy = X;
00608   float *XX_cpy = XX;
00609   float *Y_cpy = Y;
00610   float *XY_cpy = XY;
00611   //--------------------------------------patch 
00612   float tN, tX, tXX, tY, tXY;
00613   int i;
00614 
00615   int lo, hi;
00616   float R, A = 0.f, B = 0.f, D = 0.f;
00617   float w, x, y;
00618 
00619   tN = tX = tXX = tY = tXY = 0.f;
00620 
00621   y = f[0] + offset;
00622   if (y < 1.f) y = 1.f;
00623 
00624   w = y * y * .5;
00625     
00626   tN += w;
00627   tX += w;
00628   tY += w * y;
00629 
00630   N[0] = tN;
00631   X[0] = tX;
00632   XX[0] = tXX;
00633   Y[0] = tY;
00634   XY[0] = tXY;
00635 
00636   for (i = 1, x = 1.f; i < n; i++, x += 1.f) {
00637     
00638     y = f[i] + offset;
00639     if (y < 1.f) y = 1.f;
00640 
00641     w = y * y;
00642     
00643     tN += w;
00644     tX += w * x;
00645     tXX += w * x * x;
00646     tY += w * y;
00647     tXY += w * x * y;
00648 
00649     N[i] = tN;
00650     X[i] = tX;
00651     XX[i] = tXX;
00652     Y[i] = tY;
00653     XY[i] = tXY;
00654   }
00655   
00656   for (i = 0, x = 0.f;; i++, x += 1.f) {
00657     
00658     lo = b[i] >> 16;
00659     if( lo>=0 ) break;
00660     hi = b[i] & 0xffff;
00661     
00662     tN = N[hi] + N[-lo];
00663     tX = X[hi] - X[-lo];
00664     tXX = XX[hi] + XX[-lo];
00665     tY = Y[hi] + Y[-lo];    
00666     tXY = XY[hi] - XY[-lo];
00667     
00668     A = tY * tXX - tX * tXY;
00669     B = tN * tXY - tX * tY;
00670     D = tN * tXX - tX * tX;
00671     R = (A + x * B) / D;
00672     if (R < 0.f)
00673       R = 0.f;
00674     
00675     noise[i] = R - offset;
00676   }
00677   
00678   for ( ;; i++, x += 1.f) {
00679     
00680     lo = b[i] >> 16;
00681     hi = b[i] & 0xffff;
00682     if(hi>=n)break;
00683     
00684     tN = N[hi] - N[lo];
00685     tX = X[hi] - X[lo];
00686     tXX = XX[hi] - XX[lo];
00687     tY = Y[hi] - Y[lo];
00688     tXY = XY[hi] - XY[lo];
00689     
00690     A = tY * tXX - tX * tXY;
00691     B = tN * tXY - tX * tY;
00692     D = tN * tXX - tX * tX;
00693     R = (A + x * B) / D;
00694     if (R < 0.f) R = 0.f;
00695     
00696     noise[i] = R - offset;
00697   }
00698   for ( ; i < n; i++, x += 1.f) {
00699     
00700     R = (A + x * B) / D;
00701     if (R < 0.f) R = 0.f;
00702     
00703     noise[i] = R - offset;
00704   }
00705   
00706   //if (fixed <= 0) return; //patch
00707   //------------------
00708   if (fixed <= 0)
00709   {
00710   free(N_cpy);
00711   free(X_cpy);
00712   free(XX_cpy);
00713   free(Y_cpy);
00714   free(XY_cpy);
00715   return;
00716   }
00717   //----------------------
00718   
00719   for (i = 0, x = 0.f;; i++, x += 1.f) {
00720     hi = i + fixed / 2;
00721     lo = hi - fixed;
00722     if(lo>=0)break;
00723 
00724     tN = N[hi] + N[-lo];
00725     tX = X[hi] - X[-lo];
00726     tXX = XX[hi] + XX[-lo];
00727     tY = Y[hi] + Y[-lo];
00728     tXY = XY[hi] - XY[-lo];
00729     
00730     
00731     A = tY * tXX - tX * tXY;
00732     B = tN * tXY - tX * tY;
00733     D = tN * tXX - tX * tX;
00734     R = (A + x * B) / D;
00735 
00736     if (R - offset < noise[i]) noise[i] = R - offset;
00737   }
00738   for ( ;; i++, x += 1.f) {
00739     
00740     hi = i + fixed / 2;
00741     lo = hi - fixed;
00742     if(hi>=n)break;
00743     
00744     tN = N[hi] - N[lo];
00745     tX = X[hi] - X[lo];
00746     tXX = XX[hi] - XX[lo];
00747     tY = Y[hi] - Y[lo];
00748     tXY = XY[hi] - XY[lo];
00749     
00750     A = tY * tXX - tX * tXY;
00751     B = tN * tXY - tX * tY;
00752     D = tN * tXX - tX * tX;
00753     R = (A + x * B) / D;
00754     
00755     if (R - offset < noise[i]) noise[i] = R - offset;
00756   }
00757   for ( ; i < n; i++, x += 1.f) {
00758     R = (A + x * B) / D;
00759     if (R - offset < noise[i]) noise[i] = R - offset;
00760   }
00761   //----------------patch----
00762   free(N_cpy); 
00763   free(X_cpy);
00764   free(XX_cpy);
00765   free(Y_cpy);
00766   free(XY_cpy);
00767   //----------------
00768 }
00769 
00770 static float FLOOR1_fromdB_INV_LOOKUP[256]={
00771   0.F, 8.81683e+06F, 8.27882e+06F, 7.77365e+06F, 
00772   7.29930e+06F, 6.85389e+06F, 6.43567e+06F, 6.04296e+06F, 
00773   5.67422e+06F, 5.32798e+06F, 5.00286e+06F, 4.69759e+06F, 
00774   4.41094e+06F, 4.14178e+06F, 3.88905e+06F, 3.65174e+06F, 
00775   3.42891e+06F, 3.21968e+06F, 3.02321e+06F, 2.83873e+06F, 
00776   2.66551e+06F, 2.50286e+06F, 2.35014e+06F, 2.20673e+06F, 
00777   2.07208e+06F, 1.94564e+06F, 1.82692e+06F, 1.71544e+06F, 
00778   1.61076e+06F, 1.51247e+06F, 1.42018e+06F, 1.33352e+06F, 
00779   1.25215e+06F, 1.17574e+06F, 1.10400e+06F, 1.03663e+06F, 
00780   973377.F, 913981.F, 858210.F, 805842.F, 
00781   756669.F, 710497.F, 667142.F, 626433.F, 
00782   588208.F, 552316.F, 518613.F, 486967.F, 
00783   457252.F, 429351.F, 403152.F, 378551.F, 
00784   355452.F, 333762.F, 313396.F, 294273.F, 
00785   276316.F, 259455.F, 243623.F, 228757.F, 
00786   214798.F, 201691.F, 189384.F, 177828.F, 
00787   166977.F, 156788.F, 147221.F, 138237.F, 
00788   129802.F, 121881.F, 114444.F, 107461.F, 
00789   100903.F, 94746.3F, 88964.9F, 83536.2F, 
00790   78438.8F, 73652.5F, 69158.2F, 64938.1F, 
00791   60975.6F, 57254.9F, 53761.2F, 50480.6F, 
00792   47400.3F, 44507.9F, 41792.0F, 39241.9F, 
00793   36847.3F, 34598.9F, 32487.7F, 30505.3F, 
00794   28643.8F, 26896.0F, 25254.8F, 23713.7F, 
00795   22266.7F, 20908.0F, 19632.2F, 18434.2F, 
00796   17309.4F, 16253.1F, 15261.4F, 14330.1F, 
00797   13455.7F, 12634.6F, 11863.7F, 11139.7F, 
00798   10460.0F, 9821.72F, 9222.39F, 8659.64F, 
00799   8131.23F, 7635.06F, 7169.17F, 6731.70F, 
00800   6320.93F, 5935.23F, 5573.06F, 5232.99F, 
00801   4913.67F, 4613.84F, 4332.30F, 4067.94F, 
00802   3819.72F, 3586.64F, 3367.78F, 3162.28F, 
00803   2969.31F, 2788.13F, 2617.99F, 2458.24F, 
00804   2308.24F, 2167.39F, 2035.14F, 1910.95F, 
00805   1794.35F, 1684.85F, 1582.04F, 1485.51F, 
00806   1394.86F, 1309.75F, 1229.83F, 1154.78F, 
00807   1084.32F, 1018.15F, 956.024F, 897.687F, 
00808   842.910F, 791.475F, 743.179F, 697.830F, 
00809   655.249F, 615.265F, 577.722F, 542.469F, 
00810   509.367F, 478.286F, 449.101F, 421.696F, 
00811   395.964F, 371.803F, 349.115F, 327.812F, 
00812   307.809F, 289.026F, 271.390F, 254.830F, 
00813   239.280F, 224.679F, 210.969F, 198.096F, 
00814   186.008F, 174.658F, 164.000F, 153.993F, 
00815   144.596F, 135.773F, 127.488F, 119.708F, 
00816   112.404F, 105.545F, 99.1046F, 93.0572F, 
00817   87.3788F, 82.0469F, 77.0404F, 72.3394F, 
00818   67.9252F, 63.7804F, 59.8885F, 56.2341F, 
00819   52.8027F, 49.5807F, 46.5553F, 43.7144F, 
00820   41.0470F, 38.5423F, 36.1904F, 33.9821F, 
00821   31.9085F, 29.9614F, 28.1332F, 26.4165F, 
00822   24.8045F, 23.2910F, 21.8697F, 20.5352F, 
00823   19.2822F, 18.1056F, 17.0008F, 15.9634F, 
00824   14.9893F, 14.0746F, 13.2158F, 12.4094F, 
00825   11.6522F, 10.9411F, 10.2735F, 9.64662F, 
00826   9.05798F, 8.50526F, 7.98626F, 7.49894F, 
00827   7.04135F, 6.61169F, 6.20824F, 5.82941F, 
00828   5.47370F, 5.13970F, 4.82607F, 4.53158F, 
00829   4.25507F, 3.99542F, 3.75162F, 3.52269F, 
00830   3.30774F, 3.10590F, 2.91638F, 2.73842F, 
00831   2.57132F, 2.41442F, 2.26709F, 2.12875F, 
00832   1.99885F, 1.87688F, 1.76236F, 1.65482F, 
00833   1.55384F, 1.45902F, 1.36999F, 1.28640F, 
00834   1.20790F, 1.13419F, 1.06499F, 1.F
00835 };
00836 
00837 void _vp_remove_floor(vorbis_look_psy *p,
00838                       float *mdct,
00839                       int *codedflr,
00840                       float *residue,
00841                       int sliding_lowpass){ 
00842 
00843   int i,n=p->n;
00844  
00845   if(sliding_lowpass>n)sliding_lowpass=n;
00846   
00847   for(i=0;i<sliding_lowpass;i++){
00848     residue[i]=
00849       mdct[i]*FLOOR1_fromdB_INV_LOOKUP[codedflr[i]];
00850   }
00851 
00852   for(;i<n;i++)
00853     residue[i]=0.;
00854 }
00855 
00856 void _vp_noisemask(vorbis_look_psy *p,
00857                    float *logmdct, 
00858                    float *logmask){
00859 
00860   int i,n=p->n;
00861   float *work=(float*)_ogg_malloc(n*sizeof(*work));//alloca(n*sizeof(*work)); //patch
00862   float *work_cpy = work;
00863         
00864   bark_noise_hybridmp(n,p->bark,logmdct,logmask,
00865                       140.,-1);
00866 
00867   for(i=0;i<n;i++)work[i]=logmdct[i]-logmask[i];
00868 
00869   bark_noise_hybridmp(n,p->bark,work,logmask,0.,
00870                       p->vi->noisewindowfixed);
00871 
00872   for(i=0;i<n;i++)work[i]=logmdct[i]-work[i];
00873   
00874 #if 0
00875   {
00876     static int seq=0;
00877 
00878     float work2[n];
00879     for(i=0;i<n;i++){
00880       work2[i]=logmask[i]+work[i];
00881     }
00882     
00883     if(seq&1)
00884       _analysis_output("median2R",seq/2,work,n,1,0,0);
00885     else
00886       _analysis_output("median2L",seq/2,work,n,1,0,0);
00887     
00888     if(seq&1)
00889       _analysis_output("envelope2R",seq/2,work2,n,1,0,0);
00890     else
00891       _analysis_output("envelope2L",seq/2,work2,n,1,0,0);
00892     seq++;
00893   }
00894 #endif
00895 
00896   for(i=0;i<n;i++){
00897     int dB=logmask[i]+.5;
00898     if(dB>=NOISE_COMPAND_LEVELS)dB=NOISE_COMPAND_LEVELS-1;
00899     if(dB<0)dB=0;
00900     logmask[i]= work[i]+p->vi->noisecompand[dB];
00901   }
00902  free(work_cpy); //patch        
00903 }
00904 
00905 void _vp_tonemask(vorbis_look_psy *p,
00906                   float *logfft,
00907                   float *logmask,
00908                   float global_specmax,
00909                   float local_specmax){
00910 
00911   int i,n=p->n;
00912 
00913   float *seed= (float*)_ogg_malloc(sizeof(*seed)*p->total_octave_lines);//alloca(sizeof(*seed)*p->total_octave_lines); //patch
00914   float *seed_cpy = seed;
00915   float att=local_specmax+p->vi->ath_adjatt;
00916   for(i=0;i<p->total_octave_lines;i++)seed[i]=NEGINF;
00917   
00918   /* set the ATH (floating below localmax, not global max by a
00919      specified att) */
00920   if(att<p->vi->ath_maxatt)att=p->vi->ath_maxatt;
00921   
00922   for(i=0;i<n;i++)
00923     logmask[i]=p->ath[i]+att;
00924 
00925   /* tone masking */
00926   seed_loop(p,(const float ***)p->tonecurves,logfft,logmask,seed,global_specmax);
00927   max_seeds(p,seed,logmask);
00928   free(seed_cpy);       //patch
00929 }
00930 
00931 void _vp_offset_and_mix(vorbis_look_psy *p,
00932                         float *noise,
00933                         float *tone,
00934                         int offset_select,
00935                         float *logmask,
00936                         float *mdct,
00937                         float *logmdct){
00938   int i,n=p->n;
00939   float de, coeffi, cx;/* AoTuV */
00940   float toneatt=p->vi->tone_masteratt[offset_select];
00941 
00942   cx = p->m_val;
00943   
00944   for(i=0;i<n;i++){
00945     float val= noise[i]+p->noiseoffset[offset_select][i];
00946     if(val>p->vi->noisemaxsupp)val=p->vi->noisemaxsupp;
00947     logmask[i]=max(val,tone[i]+toneatt);
00948 
00949 
00950     /* AoTuV */
00959     if(offset_select == 1) {
00960       coeffi = -17.2;       /* coeffi is a -17.2dB threshold */
00961       val = val - logmdct[i];  /* val == mdct line value relative to floor in dB */
00962       
00963       if(val > coeffi){
00964         /* mdct value is > -17.2 dB below floor */
00965         
00966         de = 1.0-((val-coeffi)*0.005*cx);
00967         /* pro-rated attenuation:
00968            -0.00 dB boost if mdct value is -17.2dB (relative to floor) 
00969            -0.77 dB boost if mdct value is 0dB (relative to floor) 
00970            -1.64 dB boost if mdct value is +17.2dB (relative to floor) 
00971            etc... */
00972         
00973         if(de < 0) de = 0.0001;
00974       }else
00975         /* mdct value is <= -17.2 dB below floor */
00976         
00977         de = 1.0-((val-coeffi)*0.0003*cx);
00978       /* pro-rated attenuation:
00979          +0.00 dB atten if mdct value is -17.2dB (relative to floor) 
00980          +0.45 dB atten if mdct value is -34.4dB (relative to floor) 
00981          etc... */
00982       
00983       mdct[i] *= de;
00984       
00985     }
00986   }
00987 }
00988 
00989 float _vp_ampmax_decay(float amp,vorbis_dsp_state *vd){
00990   vorbis_info *vi=vd->vi;
00991   codec_setup_info *ci=(codec_setup_info*)vi->codec_setup;
00992   vorbis_info_psy_global *gi=&ci->psy_g_param;
00993 
00994   int n=ci->blocksizes[vd->W]/2;
00995   float secs=(float)n/vi->rate;
00996 
00997   amp+=secs*gi->ampmax_att_per_sec;
00998   if(amp<-9999)amp=-9999;
00999   return(amp);
01000 }
01001 
01002 static void couple_lossless(float A, float B, 
01003                             float *qA, float *qB){
01004   int test1=fabs(*qA)>fabs(*qB);
01005   test1-= fabs(*qA)<fabs(*qB);
01006   
01007   if(!test1)test1=((fabs(A)>fabs(B))<<1)-1;
01008   if(test1==1){
01009     *qB=(*qA>0.f?*qA-*qB:*qB-*qA);
01010   }else{
01011     float temp=*qB;  
01012     *qB=(*qB>0.f?*qA-*qB:*qB-*qA);
01013     *qA=temp;
01014   }
01015 
01016   if(*qB>fabs(*qA)*1.9999f){
01017     *qB= -fabs(*qA)*2.f;
01018     *qA= -*qA;
01019   }
01020 }
01021 
01022 static float hypot_lookup[32]={
01023   -0.009935, -0.011245, -0.012726, -0.014397, 
01024   -0.016282, -0.018407, -0.020800, -0.023494, 
01025   -0.026522, -0.029923, -0.033737, -0.038010, 
01026   -0.042787, -0.048121, -0.054064, -0.060671, 
01027   -0.068000, -0.076109, -0.085054, -0.094892, 
01028   -0.105675, -0.117451, -0.130260, -0.144134, 
01029   -0.159093, -0.175146, -0.192286, -0.210490, 
01030   -0.229718, -0.249913, -0.271001, -0.292893};
01031 
01032 static void precomputed_couple_point(float premag,
01033                                      int floorA,int floorB,
01034                                      float *mag, float *ang){
01035   
01036   int test=(floorA>floorB)-1;
01037   int offset=31-abs(floorA-floorB);
01038   float floormag=hypot_lookup[((offset<0)-1)&offset]+1.f;
01039 
01040   floormag*=FLOOR1_fromdB_INV_LOOKUP[(floorB&test)|(floorA&(~test))];
01041 
01042   *mag=premag*floormag;
01043   *ang=0.f;
01044 }
01045 
01046 /* just like below, this is currently set up to only do
01047    single-step-depth coupling.  Otherwise, we'd have to do more
01048    copying (which will be inevitable later) */
01049 
01050 /* doing the real circular magnitude calculation is audibly superior
01051    to (A+B)/sqrt(2) */
01052 static float dipole_hypot(float a, float b){
01053   if(a>0.){
01054     if(b>0.)return sqrt(a*a+b*b);
01055     if(a>-b)return sqrt(a*a-b*b);
01056     return -sqrt(b*b-a*a);
01057   }
01058   if(b<0.)return -sqrt(a*a+b*b);
01059   if(-a>b)return -sqrt(a*a-b*b);
01060   return sqrt(b*b-a*a);
01061 }
01062 static float round_hypot(float a, float b){
01063   if(a>0.){
01064     if(b>0.)return sqrt(a*a+b*b);
01065     if(a>-b)return sqrt(a*a+b*b);
01066     return -sqrt(b*b+a*a);
01067   }
01068   if(b<0.)return -sqrt(a*a+b*b);
01069   if(-a>b)return -sqrt(a*a+b*b);
01070   return sqrt(b*b+a*a);
01071 }
01072 
01073 /* revert to round hypot for now */
01074 float **_vp_quantize_couple_memo(vorbis_block *vb,
01075                                  vorbis_info_psy_global *g,
01076                                  vorbis_look_psy *p,
01077                                  vorbis_info_mapping0 *vi,
01078                                  float **mdct){
01079   
01080   int i,j,n=p->n;
01081   float **ret=(float**)_vorbis_block_alloc(vb,vi->coupling_steps*sizeof(*ret));
01082   int limit=g->coupling_pointlimit[p->vi->blockflag][PACKETBLOBS/2];
01083   
01084   for(i=0;i<vi->coupling_steps;i++){
01085     float *mdctM=mdct[vi->coupling_mag[i]];
01086     float *mdctA=mdct[vi->coupling_ang[i]];
01087     ret[i]=(float*)_vorbis_block_alloc(vb,n*sizeof(**ret));
01088     for(j=0;j<limit;j++)
01089       ret[i][j]=dipole_hypot(mdctM[j],mdctA[j]);
01090     for(;j<n;j++)
01091       ret[i][j]=round_hypot(mdctM[j],mdctA[j]);
01092   }
01093 
01094   return(ret);
01095 }
01096 
01097 /* this is for per-channel noise normalization */
01098 static int apsort(const void *a, const void *b){
01099   float f1=fabs(**(float**)a);
01100   float f2=fabs(**(float**)b);
01101   return (f1<f2)-(f1>f2);
01102 }
01103 
01104 int **_vp_quantize_couple_sort(vorbis_block *vb,
01105                                vorbis_look_psy *p,
01106                                vorbis_info_mapping0 *vi,
01107                                float **mags){
01108 
01109 
01110   if(p->vi->normal_point_p){
01111     int i,j,k,n=p->n;
01112     int **ret=(int**)_vorbis_block_alloc(vb,vi->coupling_steps*sizeof(*ret));
01113     int partition=p->vi->normal_partition;
01114     float **work= (float**)_ogg_malloc(sizeof(*work)*partition);//alloca(sizeof(*work)*partition); //patch
01115     float **work_cpy = work;
01116     for(i=0;i<vi->coupling_steps;i++){
01117       ret[i]=(int*)_vorbis_block_alloc(vb,n*sizeof(**ret));
01118       
01119       for(j=0;j<n;j+=partition){
01120         for(k=0;k<partition;k++)work[k]=mags[i]+k+j;
01121         qsort(work,partition,sizeof(*work),apsort);
01122         for(k=0;k<partition;k++)ret[i][k+j]=work[k]-mags[i];
01123       }
01124     }
01125     free(work_cpy); //patch
01126     return(ret);
01127   }
01128   return(NULL);
01129 }
01130 
01131 void _vp_noise_normalize_sort(vorbis_look_psy *p,
01132                               float *magnitudes,int *sortedindex){
01133   int i,j,n=p->n;
01134   vorbis_info_psy *vi=p->vi;
01135   int partition=vi->normal_partition;
01136   float **work=(float**)_ogg_malloc(sizeof(*work)*partition);//alloca(sizeof(*work)*partition);//patch
01137   float **work_cpy = work; //patch
01138   int start=vi->normal_start;
01139 
01140   for(j=start;j<n;j+=partition){
01141     if(j+partition>n)partition=n-j;
01142     for(i=0;i<partition;i++)work[i]=magnitudes+i+j;
01143     qsort(work,partition,sizeof(*work),apsort);
01144     for(i=0;i<partition;i++){
01145       sortedindex[i+j-start]=work[i]-magnitudes;
01146     }
01147   }
01148   free(work_cpy); //patch
01149 }
01150 
01151 void _vp_noise_normalize(vorbis_look_psy *p,
01152                          float *in,float *out,int *sortedindex){
01153   int /*flag=0,*/i,j=0,n=p->n;//warning
01154   vorbis_info_psy *vi=p->vi;
01155   int partition=vi->normal_partition;
01156   int start=vi->normal_start;
01157 
01158   if(start>n)start=n;
01159 
01160   if(vi->normal_channel_p){
01161     for(;j<start;j++)
01162       out[j]=rint(in[j]);
01163     
01164     for(;j+partition<=n;j+=partition){
01165       float acc=0.;
01166       int k;
01167       
01168       for(i=j;i<j+partition;i++)
01169         acc+=in[i]*in[i];
01170       
01171       for(i=0;i<partition;i++){
01172         k=sortedindex[i+j-start];
01173         
01174         if(in[k]*in[k]>=.25f){
01175           out[k]=rint(in[k]);
01176           acc-=in[k]*in[k];
01177           //flag=1;
01178         }else{
01179           if(acc<vi->normal_thresh)break;
01180           out[k]=unitnorm(in[k]);
01181           acc-=1.;
01182         }
01183       }
01184       
01185       for(;i<partition;i++){
01186         k=sortedindex[i+j-start];
01187         out[k]=0.;
01188       }
01189     }
01190   }
01191   
01192   for(;j<n;j++)
01193     out[j]=rint(in[j]);
01194   
01195 }
01196 
01197 void _vp_couple(int blobno,
01198                 vorbis_info_psy_global *g,
01199                 vorbis_look_psy *p,
01200                 vorbis_info_mapping0 *vi,
01201                 float **res,
01202                 float **mag_memo,
01203                 int   **mag_sort,
01204                 int   **ifloor,
01205                 int   *nonzero,
01206                 int  sliding_lowpass){
01207 
01208   int i,j,k,n=p->n;
01209 
01210   /* perform any requested channel coupling */
01211   /* point stereo can only be used in a first stage (in this encoder)
01212      because of the dependency on floor lookups */
01213   for(i=0;i<vi->coupling_steps;i++){
01214 
01215     /* once we're doing multistage coupling in which a channel goes
01216        through more than one coupling step, the floor vector
01217        magnitudes will also have to be recalculated an propogated
01218        along with PCM.  Right now, we're not (that will wait until 5.1
01219        most likely), so the code isn't here yet. The memory management
01220        here is all assuming single depth couplings anyway. */
01221 
01222     /* make sure coupling a zero and a nonzero channel results in two
01223        nonzero channels. */
01224     if(nonzero[vi->coupling_mag[i]] ||
01225        nonzero[vi->coupling_ang[i]]){
01226      
01227 
01228       float *rM=res[vi->coupling_mag[i]];
01229       float *rA=res[vi->coupling_ang[i]];
01230       float *qM=rM+n;
01231       float *qA=rA+n;
01232       int *floorM=ifloor[vi->coupling_mag[i]];
01233       int *floorA=ifloor[vi->coupling_ang[i]];
01234       float prepoint=stereo_threshholds[g->coupling_prepointamp[blobno]];
01235       float postpoint=stereo_threshholds[g->coupling_postpointamp[blobno]];
01236       int partition=(p->vi->normal_point_p?p->vi->normal_partition:p->n);
01237       int limit=g->coupling_pointlimit[p->vi->blockflag][blobno];
01238       int pointlimit=limit;
01239 
01240       nonzero[vi->coupling_mag[i]]=1; 
01241       nonzero[vi->coupling_ang[i]]=1; 
01242 
01243        /* The threshold of a stereo is changed with the size of n */
01244        if(n > 1000)
01245          postpoint=stereo_threshholds_limited[g->coupling_postpointamp[blobno]]; 
01246  
01247       for(j=0;j<p->n;j+=partition){
01248         float acc=0.f;
01249 
01250         for(k=0;k<partition;k++){
01251           int l=k+j;
01252 
01253           if(l<sliding_lowpass){
01254             if((l>=limit && fabs(rM[l])<postpoint && fabs(rA[l])<postpoint) ||
01255                (fabs(rM[l])<prepoint && fabs(rA[l])<prepoint)){
01256 
01257 
01258               precomputed_couple_point(mag_memo[i][l],
01259                                        floorM[l],floorA[l],
01260                                        qM+l,qA+l);
01261 
01262               if(rint(qM[l])==0.f)acc+=qM[l]*qM[l];
01263             }else{
01264               couple_lossless(rM[l],rA[l],qM+l,qA+l);
01265             }
01266           }else{
01267             qM[l]=0.;
01268             qA[l]=0.;
01269           }
01270         }
01271         
01272         if(p->vi->normal_point_p){
01273           for(k=0;k<partition && acc>=p->vi->normal_thresh;k++){
01274             int l=mag_sort[i][j+k];
01275             if(l<sliding_lowpass && l>=pointlimit && rint(qM[l])==0.f){
01276               qM[l]=unitnorm(qM[l]);
01277               acc-=1.f;
01278             }
01279           } 
01280         }
01281       }
01282     }
01283   }
01284 }
01285 
01286 /* AoTuV */
01293 void hf_reduction(vorbis_info_psy_global *g,
01294                       vorbis_look_psy *p, 
01295                       vorbis_info_mapping0 *vi,
01296                       float **mdct){
01297  
01298   int i,j,n=p->n, de=0.3*p->m_val;
01299   int limit=g->coupling_pointlimit[p->vi->blockflag][PACKETBLOBS/2];
01300   //int start=p->vi->normal_start;//warning
01301   
01302   for(i=0; i<vi->coupling_steps; i++){
01303     /* for(j=start; j<limit; j++){} // ???*/
01304     for(j=limit; j<n; j++) 
01305       mdct[i][j] *= (1.0 - de*((float)(j-limit) / (float)(n-limit)));
01306   }
01307 }

Generated by  doxygen 1.6.2