diff options
author | Monty <xiphmont@xiph.org> | 2000-05-02 00:28:58 +0000 |
---|---|---|
committer | Monty <xiphmont@xiph.org> | 2000-05-02 00:28:58 +0000 |
commit | 75b30f91b772e5b0af627e9015b302c615b74da4 (patch) | |
tree | 587036a2be74820b3c5e4d22ba3ab2b5ee648c4b | |
parent | f0652a98004629f8cefe3cbe2b75fd70a6bfce00 (diff) | |
download | libvorbis-git-75b30f91b772e5b0af627e9015b302c615b74da4.tar.gz |
Incremental commit before I 'try something'.
Monty
svn path=/branches/new_acoustics_pending_merge_20000328/vorbis/; revision=355
-rw-r--r-- | lib/masking.h | 79 | ||||
-rw-r--r-- | lib/psy.c | 184 | ||||
-rw-r--r-- | lib/psytune.c | 20 |
3 files changed, 166 insertions, 117 deletions
diff --git a/lib/masking.h b/lib/masking.h index 7b67eb4f..08271a5a 100644 --- a/lib/masking.h +++ b/lib/masking.h @@ -12,7 +12,7 @@ ******************************************************************** function: masking curve data for psychoacoustics - last mod: $Id: masking.h,v 1.1.2.2 2000/03/29 20:08:49 xiphmont Exp $ + last mod: $Id: masking.h,v 1.1.2.2.2.1 2000/05/02 00:28:58 xiphmont Exp $ ********************************************************************/ @@ -120,28 +120,89 @@ double tone_4000_40dB_SL[EHMER_MAX]={ 24, 21, 14, 5, -5, -15, -25, -35, -900,-900,-900,-900,-900,-900,-900,-900, -900,-900,-900,-900,-900,-900,-900,-900, -900,-900,-900,-900,-900,-900,-900,-900, -900,-900,-900,-900,-900,-900,-900,-900}; + double tone_4000_60dB_SL[EHMER_MAX]={ -900,-900,-900,-900,-900,-900,-900,-900, -40, -30, -21, -12, -2, 8, 19, 31, - 38, 34, 24, 17, 14, 13, 11, 7, 3, -2, -6, -10, -14, -20, -26, -32, + 38, 34, 26, 20, 16, 11, 9, 7, 3, -2, -6, -10, -14, -20, -26, -32, -900,-900,-900,-900,-900,-900,-900,-900, -900,-900,-900,-900,-900,-900,-900,-900, -900,-900,-900,-900,-900,-900,-900,-900}; + double tone_4000_80dB_SL[EHMER_MAX]={ -900,-900,-900,-900,-900,-900,-900,-900, -60, -50, -40, -29, -12, 5, 19, 37, - 51, 49, 38, 32, 36, 36, 36, 31, 27, 17, 8, 0, -8, -16, -24, -32, + 51, 49, 38, 32, 36, 36, 36, 31, 30, 22, 15, 5, -5, -16, -24, -32, -900,-900,-900,-900,-900,-900,-900,-900, -900,-900,-900,-900,-900,-900,-900,-900, -900,-900,-900,-900,-900,-900,-900,-900}; + double tone_4000_100dB_SL[EHMER_MAX]={ -20, -12, -8, -4, 0, 4, 8, 11, 15, 22, 26, 28, 32, 36, 43, 52, - 65, 61, 45, 41, 48, 49, 40, 26, 40, 40, 33, 29, 24, 19, 14, 9, - 4, -1, -6, -11, -16, -21, -26, -31, -900,-900,-900,-900,-900,-900,-900,-900, + 65, 61, 45, 41, 48, 49, 40, 30, 45, 30, 20, 10, 0, -10, -19, -28, + -37,-900,-900,-900,-900,-900,-900,-900, -900,-900,-900,-900,-900,-900,-900,-900, +-900,-900,-900,-900,-900,-900,-900,-900}; + +double tone_8000_60dB_SL[EHMER_MAX]={ +-900,-900,-900,-900,-900,-900,-900,-900, -40, -30, -21, -12, -5, 0, 15, 35, + 43, 40, 37, 36, 37, 39, 41, 43, 45, 45, 35, 25, 15, 5, -5, -15, + -25, -35,-900,-900,-900,-900,-900,-900, -900,-900,-900,-900,-900,-900,-900,-900, +-900,-900,-900,-900,-900,-900,-900,-900}; + +double tone_8000_80dB_SL[EHMER_MAX]={ +-900,-900,-900,-900,-900,-900,-900,-900, -1, 2, 6, 10, 13, 19, 25, 35, + 63, 60, 56, 56, 57, 60, 61, 63, 65, 65, 55, 45, 35, 25, 15, 5, + -5, -15, -25, -35,-900,-900,-900,-900, -900,-900,-900,-900,-900,-900,-900,-900, -900,-900,-900,-900,-900,-900,-900,-900}; double tone_8000_100dB_SL[EHMER_MAX]={ -18, -12, -7, -3, 0, 2, 6, 9, 12, 19, 22, 21, 19, 21, 40, 40, - 80, 60, - /* educated guessing from here on out */ - 35, 31, 38, 39, 30, 16, 30, 30, 23, 19, 14, 9, 4, -1, - -6, -11, -16, -21, -26, -31, -36, -41, -900,-900,-900,-900,-900,-900,-900,-900, + 80, 60, 35, 25, 15, 5, -5, -15, -25, -35,-900,-900,-900,-900,-900,-900, +-900,-900,-900,-900,-900,-900,-900,-900, -900,-900,-900,-900,-900,-900,-900,-900, +-900,-900,-900,-900,-900,-900,-900,-900}; + +double noise_500_60dB_SL[EHMER_MAX]={ +-900,-900,-900,-900,-900, -20, -11, -2, 7, 16, 25, 34, 43, 52, 61, 66, + 69, 68, 58, 50, 44, 38, 32, 28, 25, 24, 20, 18, 17, 12, 10, 8, + 5, 0, -5, -8, -12, -15, -18, -22, -900,-900,-900,-900,-900,-900,-900,-900, +-900,-900,-900,-900,-900,-900,-900,-900}; + +double noise_500_80dB_SL[EHMER_MAX]={ +-900,-900,-900, -20, -10, -1, 8, 17, 26, 35, 44, 53, 62, 70, 79, 83, + 85, 85, 81, 77, 74, 71, 68, 63, 61, 59, 56, 55, 54, 52, 48, 47, + 45, 46, 45, 43, 40, 37, 33, 32, 35, 32, 30, 29, 20, 10, 0, -10, + -20, -30,-900,-900,-900,-900,-900,-900}; + +double noise_1000_60dB_SL[EHMER_MAX]={ +-900,-900,-900,-900, -24, -15, -6, 3, 12, 21, 28, 34, 40, 48, 57, 60, + 61, 56, 54, 45, 36, 27, 21, 19, 17, 13, 10, 0, -10, -20, -20,-900, +-900,-900,-900,-900,-900,-900,-900,-900, -900,-900,-900,-900,-900,-900,-900,-900, +-900,-900,-900,-900,-900,-900,-900,-900}; + +double noise_1000_80dB_SL[EHMER_MAX]={ +-900, -26, -17, -8, 1, 10, 19, 28, 37, 41, 46, 51, 58, 68, 74, 81, + 80, 81, 70, 66, 58, 61, 59, 55, 54, 53, 52, 49, 48, 42, 38, 38, + 39, 34, 30, 27, 20, 10, 0, -10, -20, -30,-900,-900,-900,-900,-900,-900, +-900,-900,-900,-900,-900,-900,-900,-900}; + +double noise_2000_60dB_SL[EHMER_MAX]={ +-900,-900,-900, -34, -25, -16, -7, 2, 11, 18, 23, 30, 35, 42, 51, 58, + 58, 57, 50, 40, 30, 21, 15, 10, 0, -10, -20, -30,-900,-900,-900,-900, +-900,-900,-900,-900,-900,-900,-900,-900, -900,-900,-900,-900,-900,-900,-900,-900, +-900,-900,-900,-900,-900,-900,-900,-900}; + +double noise_2000_80dB_SL[EHMER_MAX]={ +-900, -26, -17, -8, 1, 10, 19, 28, 33, 38, 43, 48, 53, 62, 70, 77, + 77, 75, 70, 67, 68, 66, 62, 61, 60, 69, 52, 47, 39, 35, 34, 35, + 35, 33, 30, 27, 20, 10, 0, -10, -20, -30,-900,-900,-900,-900,-900,-900, +-900,-900,-900,-900,-900,-900,-900,-900}; + +double noise_4000_60dB_SL[EHMER_MAX]={ +-900,-900,-900, -34, -25, -16, -7, 2, 11, 20, 25, 31, 37, 45, 56, 62, + 64, 61, 50, 35, 25, 15, 5, -5, -15 -25, -35,-900,-900,-900,-900,-900, +-900,-900,-900,-900,-900,-900,-900,-900, -900,-900,-900,-900,-900,-900,-900,-900, +-900,-900,-900,-900,-900,-900,-900,-900}; + +double noise_4000_80dB_SL[EHMER_MAX]={ +-900, -26, -17, -8, 1, 10, 19, 26, 33, 39, 45, 50, 55, 65, 75, 82, + 84, 81, 78, 72, 70, 69, 66, 61, 50, 48, 46, 40, 35, 30, 25, 20, + 15, 10, 5, 0, -10, -20, -30,-900, -900,-900,-900,-900,-900,-900,-900,-900, -900,-900,-900,-900,-900,-900,-900,-900}; #endif @@ -12,7 +12,7 @@ ******************************************************************** function: psychoacoustics not including preecho - last mod: $Id: psy.c,v 1.16.2.2.2.9 2000/04/21 16:35:39 xiphmont Exp $ + last mod: $Id: psy.c,v 1.16.2.2.2.10 2000/05/02 00:28:58 xiphmont Exp $ ********************************************************************/ @@ -216,9 +216,9 @@ void _vp_psy_init(vorbis_look_psy *p,vorbis_info_psy *vi,int n,long rate){ memcpy(p->curves[8][6],tone_4000_80dB_SL,sizeof(double)*EHMER_MAX); memcpy(p->curves[8][8],tone_4000_100dB_SL,sizeof(double)*EHMER_MAX); - memcpy(p->curves[10][2],tone_4000_40dB_SL,sizeof(double)*EHMER_MAX); - memcpy(p->curves[10][4],tone_4000_60dB_SL,sizeof(double)*EHMER_MAX); - memcpy(p->curves[10][6],tone_4000_80dB_SL,sizeof(double)*EHMER_MAX); + memcpy(p->curves[10][2],tone_8000_60dB_SL,sizeof(double)*EHMER_MAX); + memcpy(p->curves[10][4],tone_8000_60dB_SL,sizeof(double)*EHMER_MAX); + memcpy(p->curves[10][6],tone_8000_80dB_SL,sizeof(double)*EHMER_MAX); memcpy(p->curves[10][8],tone_8000_100dB_SL,sizeof(double)*EHMER_MAX); setup_curve(p->curves[0],0,vi->curveatt_250Hz,vi->peakpre,vi->peakpost); @@ -337,48 +337,23 @@ static void add_seeds(double *floor,int n){ static void _vp_tone_tone_iter(vorbis_look_psy *p, double *f, double *flr, double *mask, - double *decay){ + double specmax){ vorbis_info_psy *vi=p->vi; long n=p->n,i; - double *work=alloca(n*sizeof(double)); - double specmax=0; double acc=0.; - memcpy(work,f,p->n*sizeof(double)); - - /* handle decay */ - if(vi->decayp && decay){ - double decscale=1.-pow(vi->decay_coeff,n); - double attscale=1.-pow(vi->attack_coeff,n); - for(i=0;i<n;i++){ - double del=work[i]-decay[i]; - if(del>0) - /* add energy */ - decay[i]+=del*attscale; - else - /* remove energy */ - decay[i]+=del*decscale; - if(decay[i]>work[i])work[i]=decay[i]; - } - } - - for(i=0;i<n;i++){ - if(work[i]>specmax)specmax=work[i]; - } - - specmax=todB(specmax); memset(flr,0,sizeof(double)*n); /* prime the working vector with peak values */ /* Use the 250 Hz curve up to 250 Hz and 8kHz curve after 8kHz. */ for(i=0;i<n;i++){ - acc+=flr[i]; /* XXX acc is behaving incorrectly. Check it */ - if(work[i]*work[i]>acc){ + /*acc+=flr[i]; XXX acc is behaving incorrectly. Check it */ + if(f[i]>mask[i]){ int o=rint(p->octave[i]*2.); if(o<0)o=0; if(o>10)o=10; - acc+=seed_peaks(flr,p->curves[o],work[i], + /*acc+=*/seed_peaks(flr,p->curves[o],f[i], specmax,p->pre,p->post,i,n,vi->max_curve_dB); } } @@ -386,60 +361,6 @@ static void _vp_tone_tone_iter(vorbis_look_psy *p, /* chase curves down from the peak seeds */ add_seeds(flr,n); - memcpy(mask,flr,n*sizeof(double)); - - /* mask off the ATH */ - if(vi->athp) - for(i=0;i<n;i++) - if(mask[i]<p->ath[i]) - mask[i]=p->ath[i]; - - /* do the peak att with rolloff hack. But I don't know which is - better... doing it to mask or floor. We'll assume mask right now */ - if(vi->peakattp){ - double curmask; - - /* seed peaks for rolloff first so we only do it once */ - for(i=0;i<n;i++){ - if(work[i]>mask[i]){ - double val=todB(work[i]); - int o=p->octave[i]; - int choice=rint((val-specmax+vi->max_curve_dB)/20.)-1; - if(o<0)o=0; - if(o>5)o=5; - if(choice<0)choice=0; - if(choice>4)choice=4; - work[i]=fromdB(val+vi->peakatt[o][choice]); - }else{ - work[i]=0; - } - } - - /* chase down from peaks forward */ - curmask=0.; - for(i=0;i<n-1;i++){ - if(work[i]>curmask)curmask=work[i]; - if(curmask>mask[i]){ - mask[i]=curmask; - /* roll off the curmask */ - curmask*=fromdB(vi->peakpost*(p->octave[i+1]-p->octave[i])); - }else{ - curmask=0; - } - } - /* chase down from peaks backward */ - curmask=0.; - for(i=n-1;i>0;i--){ - if(work[i]>curmask)curmask=work[i]; - if(curmask>=mask[i]){ - mask[i]=curmask; - /* roll off the curmask */ - curmask*=fromdB(vi->peakpre*(p->octave[i]-p->octave[i-1])); - }else{ - curmask=0; - } - } - } } /* stability doesn't matter */ @@ -465,10 +386,10 @@ void _vp_apply_floor(vorbis_look_psy *p,double *f, if(flr[j]<=0) work[j]=0.; else{ - if(fabs(f[j])<mask[j] || fabs(f[j])<flr[j]){ - work[j]=0; - }else{ - double val=f[j]/flr[j]; + double val=rint(f[j]/flr[j]); + if(mask[j]>flr[j] && fabs(f[j])<mask[j]){ + work[j]=0; + }else{ work[j]=val; } } @@ -536,26 +457,93 @@ void _vp_tone_tone_mask(vorbis_look_psy *p,double *f, double *decay){ double *iter=alloca(sizeof(double)*p->n); int i,j,n=p->n; + double specmax=0.; for(i=0;i<n;i++)iter[i]=fabs(f[i]); + f=iter; + iter=alloca(sizeof(double)*p->n); + + /* handle decay */ + if(p->vi->decayp && decay){ + double decscale=1.-pow(p->vi->decay_coeff,n); + double attscale=1.-pow(p->vi->attack_coeff,n); + for(i=0;i<n;i++){ + double del=f[i]-decay[i]; + if(del>0) + /* add energy */ + decay[i]+=del*attscale; + else + /* remove energy */ + decay[i]+=del*decscale; + if(decay[i]>f[i])f[i]=decay[i]; + } + } + + for(i=0;i<n;i++){ + if(f[i]>specmax)specmax=f[i]; + } + specmax=todB(specmax); - /* perform iterative tone-tone masking */ + /* do the peak att with rolloff hack to the mask */ + memset(mask,0,sizeof(double)*n); + if(p->vi->peakattp){ + double curmask; + + /* chase down from peaks forward */ + curmask=0.; + for(i=0;i<n-1;i++){ + if(f[i]>curmask){ + double val=todB(f[i]); + int o=p->octave[i]; + int choice=rint((val-specmax+p->vi->max_curve_dB)/20.)-1; + if(o<0)o=0; + if(o>5)o=5; + if(choice<0)choice=0; + if(choice>4)choice=4; + val=fromdB(val+p->vi->peakatt[o][choice]); + if(val>curmask)curmask=val; + } + mask[i]=curmask; + /* roll off the curmask */ + curmask*=fromdB(p->vi->peakpost*(p->octave[i+1]-p->octave[i])); + } + /* chase down from peaks backward */ + curmask=0.; + for(i=n-1;i>0;i--){ + if(mask[i]>curmask) + curmask=mask[i]; + else + mask[i]=curmask; + /* roll off the curmask */ + curmask*=fromdB(p->vi->peakpre*(p->octave[i]-p->octave[i-1])); + } + } + /* mask off the ATH */ + if(p->vi->athp) + for(i=0;i<n;i++) + if(mask[i]<p->ath[i]) + mask[i]=p->ath[i]; + /* perform iterative additive tone-tone masking */ + for(i=0;i<p->vi->curve_fit_iterations;i++){ if(i==0) - _vp_tone_tone_iter(p,iter,flr,mask,decay); + _vp_tone_tone_iter(p,f,flr,mask,specmax); else{ - _vp_tone_tone_iter(p,iter,iter,mask,decay); - for(j=0;j<n;j++) - flr[j]=(flr[j]+iter[j])/2.; + _vp_tone_tone_iter(p,iter,flr,mask,specmax); } if(i!=p->vi->curve_fit_iterations-1){ for(j=0;j<n;j++) - if(fabs(f[j])<mask[j] && fabs(f[j])<flr[j]) + if(f[j]<mask[j] || f[j]<flr[j]) iter[j]=0.; else - iter[j]=fabs(f[j]); + iter[j]=f[j]; } } + + for(i=0;i<n;i++) + if(mask[i]<flr[i]) + mask[i]=flr[i]; + } diff --git a/lib/psytune.c b/lib/psytune.c index e5d9e6d9..0221553e 100644 --- a/lib/psytune.c +++ b/lib/psytune.c @@ -13,7 +13,7 @@ function: simple utility that runs audio through the psychoacoustics without encoding - last mod: $Id: psytune.c,v 1.1.2.2.2.6 2000/04/21 16:35:39 xiphmont Exp $ + last mod: $Id: psytune.c,v 1.1.2.2.2.7 2000/05/02 00:28:58 xiphmont Exp $ ********************************************************************/ @@ -33,16 +33,16 @@ static vorbis_info_psy _psy_set0={ 1,1,1, - 1,8,4., + 0,8,4., -130., - {-35.,-40.,-60.,-80.,-85.}, - {-35.,-40.,-60.,-80.,-100.}, - {-35.,-40.,-60.,-80.,-100.}, - {-35.,-40.,-60.,-80.,-100.}, - {-35.,-40.,-60.,-80.,-100.}, - {-35.,-40.,-60.,-80.,-100.}, + {-40.,-40.,-60.,-80.,-85.}, + {-40.,-40.,-60.,-80.,-100.}, + {-40.,-40.,-60.,-80.,-100.}, + {-40.,-40.,-60.,-80.,-100.}, + {-40.,-40.,-60.,-80.,-100.}, + {-70.,-70.,-70.,-80.,-100.}, 1, {{-6.,-8.,-12.,-16.,-18.}, @@ -50,10 +50,10 @@ static vorbis_info_psy _psy_set0={ {-6.,-8.,-12.,-16.,-18.}, {-6.,-8.,-12.,-16.,-20.}, {-6.,-8.,-12.,-16.,-20.}, - {-6.,-8.,-10.,-14.,-18.},}, + {-6.,-8.,-12.,-16.,-18.},}, -80.,-40., - 110., + 100., .9998, .9997 /* attack/decay control */ }; |