From: Monty Date: Thu, 15 Feb 2001 19:06:02 +0000 (+0000) Subject: Some new preecho code; split energy threshholding up into a few bands. X-Git-Tag: v1.3.3~1033 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=9eb5b1e302d6b5ca9ce332efe749c394414f01ac;p=platform%2Fupstream%2Flibvorbis.git Some new preecho code; split energy threshholding up into a few bands. Monty svn path=/trunk/vorbis/; revision=1279 --- diff --git a/lib/block.c b/lib/block.c index fe2cd19..e3dbc2d 100644 --- a/lib/block.c +++ b/lib/block.c @@ -11,7 +11,7 @@ ******************************************************************** function: PCM data vector blocking, windowing and dis/reassembly - last mod: $Id: block.c,v 1.44 2001/02/02 03:51:55 xiphmont Exp $ + last mod: $Id: block.c,v 1.45 2001/02/15 19:05:45 xiphmont Exp $ Handle windowing, overlap-add, etc of the PCM vectors. This is made more amusing by Vorbis' current two allowed block sizes. @@ -493,7 +493,7 @@ int vorbis_analysis_blockout(vorbis_dsp_state *v,vorbis_block *vb){ largebound=v->centerW+ci->blocksizes[1]*3/4+ci->blocksizes[0]/4; else /* min boundary; nW large, next small */ - largebound=v->centerW+ci->blocksizes[1]*3/4+ci->blocksizes[0]*3/4; + largebound=v->centerW+ci->blocksizes[1]/2+ci->blocksizes[0]/2; bp=_ve_envelope_search(v,largebound); if(bp==-1)return(0); /* not enough data currently to search for a diff --git a/lib/codec_internal.h b/lib/codec_internal.h index f0b0892..61420a3 100644 --- a/lib/codec_internal.h +++ b/lib/codec_internal.h @@ -11,7 +11,7 @@ ******************************************************************** function: libvorbis codec headers - last mod: $Id: codec_internal.h,v 1.5 2001/02/02 03:51:56 xiphmont Exp $ + last mod: $Id: codec_internal.h,v 1.6 2001/02/15 19:05:45 xiphmont Exp $ ********************************************************************/ @@ -110,8 +110,8 @@ typedef struct codec_setup_info { /* for block long/sort tuning; encode only */ int envelopesa; - float preecho_thresh; - float postecho_thresh; + float preecho_thresh[4]; + float postecho_thresh[4]; float preecho_minenergy; float ampmax_att_per_sec; diff --git a/lib/envelope.c b/lib/envelope.c index b023992..05999c3 100644 --- a/lib/envelope.c +++ b/lib/envelope.c @@ -11,7 +11,7 @@ ******************************************************************** function: PCM data envelope analysis and manipulation - last mod: $Id: envelope.c,v 1.31 2001/02/02 03:51:56 xiphmont Exp $ + last mod: $Id: envelope.c,v 1.32 2001/02/15 19:05:45 xiphmont Exp $ Preecho calculation. @@ -30,65 +30,57 @@ #include "envelope.h" #include "misc.h" -/* Digital filter designed by mkfilter/mkshape/gencode A.J. Fisher - Command line: /www/usr/fisher/helpers/mkfilter -Ch \ - -6.0000000000e+00 -Bp -o 5 -a 1.3605442177e-01 3.1746031746e-01 -l */ - -#if 0 -static int cheb_bandpass_stages=10; -static float cheb_bandpass_gain=5.589612458e+01f; -static float cheb_bandpass_B[]={-1.f,0.f,5.f,0.f,-10.f,0.f, - 10.f,0.f,-5.f,0.f,1f}; -static float cheb_bandpass_A[]={ - -0.1917409386f, - 0.0078657069f, - -0.7126903444f, - 0.0266343467f, - -1.4047174730f, - 0.0466964232f, - -1.9032773429f, - 0.0451493360f, - -1.4471447397f, - 0.0303413711f}; -#endif - -/* 4kHz Chebyshev highpass */ -static int cheb_highpass_stages=10; -static float cheb_highpass_gain= 1.314337427e+01f; -/* z^-stage, z^-stage+1... */ -static float cheb_highpass_B[]={1.f,-10.f,45.f,-120.f,210.f, - -252.f,210.f,-120.f,45.f,-10.f,1.f}; -static float cheb_highpass_A[]={ - -0.1013448254f, - 0.4524819695f, - -1.3268091670f, - 3.2875726855f, - -7.2782468961f, - 13.0298867474f, - -17.6698599469f, - 17.2757670409f, - -11.6207967046f, - 4.8672119675f}; - -#if 0 -/* 6kHz Chebyshev highpass */ -static int cheb_highpass_stages=10; -static float cheb_highpass_gain= 5.291963434e+01f; -/* z^-stage, z^-stage+1... */ -static float cheb_highpass_B[]={1.f,-10.f,45.f,-120.f,210.f, - -252.f,210.f,-120.f,45.f,-10.f,1.f}; -static float cheb_highpass_A[]={ - -0.1247628029f, - 0.1334086523f, - -0.3997715614f, - 0.3213011089f, - -1.1131924119f, - 1.7692446626f, - -3.6241199038f, - 4.1950871291f, - -4.2771757867f, - 2.3920318913f}; -#endif +/* Digital filter designed by mkfilter/mkshape/gencode A.J. Fisher */ + + + +static int cheb_highpass_stages=6; +static float cheb_highpass_B[]={1.f,-6.f,15.f,-20.f,15.f,-6.f,1.f}; + +static int cheb_bandpass_stages=6; +static float cheb_bandpass_B[]={-1.f,0.f,3.f,0.f,-3.f,0.f,1.f}; + + +/* 10kHz Chebyshev highpass */ +static float cheb_highpass10k_gain= 54.34519586f; +static float cheb_highpass10k_A[]={ + -0.2064797169f, + -0.5609713214f, + -1.1352465327f, + -1.4495555418f, + -1.7938140760f, + -0.9473564683f}; + +/* 6kHz-10kHz Chebyshev bandpass */ +static float cheb_bandpass6k_gain=113.4643935f; +static float cheb_bandpass6k_A[]={ + -0.5712621337f, + 1.5626130710f, + -3.3348854983f, + 4.0471340821f, + -4.0051680331f, + 2.2786325610f}; + +/* 3kHz-6kHz Chebyshev bandpass */ +static float cheb_bandpass3k_gain= 248.8359377f; +static float cheb_bandpass3k_A[]={ + -0.6564230022f, + 3.3747911257f, + -8.0098635981f, + 11.0040876874f, + -9.2250963484f, + 4.4760355389f}; + +/* 1.5kHz-3kHz Chebyshev bandpass */ +static float cheb_bandpass1k_gain= 1798.537183f; +static float cheb_bandpass1k_A[]={ + -0.8097527363f, + 4.7725742682f, + -11.9800219408f, + 16.3770336223f, + -12.8553129536f, + 5.4948074309f}; + void _ve_envelope_init(envelope_lookup *e,vorbis_info *vi){ codec_setup_info *ci=vi->codec_setup; @@ -97,31 +89,35 @@ void _ve_envelope_init(envelope_lookup *e,vorbis_info *vi){ int i; e->winlength=window; e->minenergy=fromdB(ci->preecho_minenergy); - e->iir=_ogg_calloc(ch,sizeof(IIR_state)); - e->filtered=_ogg_calloc(ch,sizeof(float *)); + e->iir=_ogg_calloc(ch*4,sizeof(IIR_state)); + e->filtered=_ogg_calloc(ch*4,sizeof(float *)); e->ch=ch; e->storage=128; - for(i=0;iiir+i,cheb_highpass_stages,cheb_highpass_gain, - cheb_highpass_A,cheb_highpass_B); + for(i=0;iiir+i,cheb_highpass_stages,cheb_highpass10k_gain, + cheb_highpass10k_A,cheb_highpass_B); + IIR_init(e->iir+i+1,cheb_bandpass_stages,cheb_bandpass6k_gain, + cheb_bandpass6k_A,cheb_bandpass_B); + IIR_init(e->iir+i+2,cheb_bandpass_stages,cheb_bandpass3k_gain, + cheb_bandpass3k_A,cheb_bandpass_B); + IIR_init(e->iir+i+3,cheb_bandpass_stages,cheb_bandpass1k_gain, + cheb_bandpass1k_A,cheb_bandpass_B); + e->filtered[i]=_ogg_calloc(e->storage,sizeof(float)); + e->filtered[i+1]=_ogg_calloc(e->storage,sizeof(float)); + e->filtered[i+2]=_ogg_calloc(e->storage,sizeof(float)); + e->filtered[i+3]=_ogg_calloc(e->storage,sizeof(float)); } - drft_init(&e->drft,window); - e->window=_ogg_malloc(e->winlength*sizeof(float)); - /* We just use a straight sin(x) window for this */ - for(i=0;iwinlength;i++) - e->window[i]=sin((i+.5)/e->winlength*M_PI); } void _ve_envelope_clear(envelope_lookup *e){ int i; - for(i=0;ich;i++){ + for(i=0;ich*4;i++){ IIR_clear((e->iir+i)); _ogg_free(e->filtered[i]); } - drft_clear(&e->drft); - _ogg_free(e->window); _ogg_free(e->filtered); _ogg_free(e->iir); memset(e,0,sizeof(envelope_lookup)); @@ -156,52 +152,58 @@ static float _ve_deltai(envelope_lookup *ve,float *pre,float *post){ return(B-A); } -static float _ve_ampi(envelope_lookup *ve,float *pre){ - long n=ve->winlength; - - long i; - - /* we want to have a 'minimum bar' for energy, else we're just - basing blocks on quantization noise that outweighs the signal - itself (for low power signals) */ - - float min=ve->minenergy; - float A=min*min*n; - - for(i=0;ivi; codec_setup_info *ci=vi->codec_setup; envelope_lookup *ve=((backend_lookup_state *)(v->backend_state))->ve; - long i,j,k; + long i,j,k,l; float *work=alloca(sizeof(float)*ve->winlength*2); + static int seq=0; /* make sure we have enough storage to match the PCM */ if(v->pcm_storage>ve->storage){ ve->storage=v->pcm_storage; - for(i=0;ich;i++) + for(i=0;ich*4;i++) ve->filtered[i]=_ogg_realloc(ve->filtered[i],ve->storage*sizeof(float)); } /* catch up the highpass to match the pcm */ for(i=0;ich;i++){ - float *filtered=ve->filtered[i]; float *pcm=v->pcm[i]; - IIR_state *iir=ve->iir+i; + float *filtered0=ve->filtered[i*4]; + float *filtered1=ve->filtered[i*4+1]; + float *filtered2=ve->filtered[i*4+2]; + float *filtered3=ve->filtered[i*4+3]; + IIR_state *iir0=ve->iir+i*4; + IIR_state *iir1=ve->iir+i*4+1; + IIR_state *iir2=ve->iir+i*4+2; + IIR_state *iir3=ve->iir+i*4+3; int flag=1; for(j=ve->current;jpcm_current;j++){ - filtered[j]=IIR_filter(iir,pcm[j]); + filtered0[j]=IIR_filter(iir0,pcm[j]); + filtered1[j]=IIR_filter(iir1,pcm[j]); + filtered2[j]=IIR_filter(iir2,pcm[j]); + filtered3[j]=IIR_filter(iir3,pcm[j]); if(pcm[j])flag=0; } - if(flag && ve->current+64pcm_current)IIR_reset(iir); + if(flag && ve->current+64pcm_current){ + IIR_reset(iir0); + IIR_reset(iir1); + IIR_reset(iir2); + IIR_reset(iir3); + } + + _analysis_output("pcm",seq,pcm+v->centerW,v->pcm_current-v->centerW,0,0); + _analysis_output("f0",seq,filtered0+v->centerW,v->pcm_current-v->centerW, + 0,0); + _analysis_output("f1",seq,filtered1+v->centerW,v->pcm_current-v->centerW, + 0,0); + _analysis_output("f2",seq,filtered2+v->centerW,v->pcm_current-v->centerW, + 0,0); + _analysis_output("f3",seq++,filtered3+v->centerW,v->pcm_current-v->centerW, + 0,0); + } ve->current=v->pcm_current; @@ -215,44 +217,22 @@ long _ve_envelope_search(vorbis_dsp_state *v,long searchpoint){ while(j+ve->winlength<=v->pcm_current){ for(i=0;ich;i++){ - float *filtered=ve->filtered[i]+j; - float m=_ve_deltai(ve,filtered-ve->winlength,filtered); - - if(m>ci->preecho_thresh){ - /*granulepos++;*/ - return(0); - } - if(mpostecho_thresh){ - /*granulepos++;*/ - return(0); - } - /*granulepos++;*/ - } - - /* look also for preecho in coupled channel pairs with the center - subtracted out (A-B) */ - for(i=1;ich;i+=2){ - float *filteredA=ve->filtered[i-1]+j-ve->winlength; - float *filteredB=ve->filtered[i]+j-ve->winlength; - float m; - - for(k=0;kwinlength*2;k++) - work[k]=filteredA[k]-filteredB[k]; - - m=_ve_deltai(ve,work,work+ve->winlength); + for(k=0;k<4;k++){ + float *filtered=ve->filtered[i*4+k]+j; + float m=_ve_deltai(ve,filtered-ve->winlength,filtered); - if(m>ci->preecho_thresh){ - /*granulepos++;*/ - return(0); - } - if(mpostecho_thresh){ + if(m>ci->preecho_thresh[k]){ + /*granulepos++;*/ + return(0); + } + if(mpostecho_thresh[k]){ + /*granulepos++;*/ + return(0); + } /*granulepos++;*/ - return(0); } - /*granulepos++;*/ } - j+=min(ci->blocksizes[0],ve->winlength)/2; if(j>=searchpoint){ @@ -265,7 +245,7 @@ long _ve_envelope_search(vorbis_dsp_state *v,long searchpoint){ void _ve_envelope_shift(envelope_lookup *e,long shift){ int i; - for(i=0;ich;i++) + for(i=0;ich*4;i++) memmove(e->filtered[i],e->filtered[i]+shift,(e->current-shift)* sizeof(float)); e->current-=shift; diff --git a/lib/envelope.h b/lib/envelope.h index cfb0ca5..c889ca5 100644 --- a/lib/envelope.h +++ b/lib/envelope.h @@ -11,7 +11,7 @@ ******************************************************************** function: PCM data envelope analysis and manipulation - last mod: $Id: envelope.h,v 1.12 2001/02/02 03:51:56 xiphmont Exp $ + last mod: $Id: envelope.h,v 1.13 2001/02/15 19:05:45 xiphmont Exp $ ********************************************************************/ @@ -31,11 +31,10 @@ typedef struct { IIR_state *iir; float **filtered; + long storage; long current; - drft_lookup drft; - float *window; } envelope_lookup; extern void _ve_envelope_init(envelope_lookup *e,vorbis_info *vi); diff --git a/lib/iir.c b/lib/iir.c index ecf03d8..9d55d91 100644 --- a/lib/iir.c +++ b/lib/iir.c @@ -11,7 +11,7 @@ ******************************************************************** function: Direct Form I, II IIR filters, plus some specializations - last mod: $Id: iir.c,v 1.7 2001/02/02 03:51:56 xiphmont Exp $ + last mod: $Id: iir.c,v 1.8 2001/02/15 19:05:45 xiphmont Exp $ ********************************************************************/ @@ -69,8 +69,8 @@ float IIR_filter(IIR_state *s,float in){ } /* this assumes the symmetrical structure of the feed-forward stage of - a Chebyshev bandpass to save multiplies */ -float IIR_filter_ChebBand(IIR_state *s,float in){ + a typical bandpass to save multiplies */ +float IIR_filter_Band(IIR_state *s,float in){ int stages=s->stages,i; float newA; float newB=0; diff --git a/lib/iir.h b/lib/iir.h index 1fab188..c220f2c 100644 --- a/lib/iir.h +++ b/lib/iir.h @@ -11,7 +11,7 @@ ******************************************************************** function: Direct Form I, II IIR filters, plus some specializations - last mod: $Id: iir.h,v 1.5 2001/02/02 03:51:56 xiphmont Exp $ + last mod: $Id: iir.h,v 1.6 2001/02/15 19:05:45 xiphmont Exp $ ********************************************************************/ @@ -30,7 +30,7 @@ typedef struct { extern void IIR_init(IIR_state *s,int stages,float gain, float *A, float *B); extern void IIR_clear(IIR_state *s); extern float IIR_filter(IIR_state *s,float in); -extern float IIR_filter_ChebBand(IIR_state *s,float in); +extern float IIR_filter_Band(IIR_state *s,float in); extern void IIR_reset(IIR_state *s); #endif diff --git a/lib/modes/mode_A.h b/lib/modes/mode_A.h index 0f1b868..d2682d4 100644 --- a/lib/modes/mode_A.h +++ b/lib/modes/mode_A.h @@ -11,7 +11,7 @@ ******************************************************************** function: predefined encoding modes - last mod: $Id: mode_A.h,v 1.11 2001/02/02 03:52:24 xiphmont Exp $ + last mod: $Id: mode_A.h,v 1.12 2001/02/15 19:06:02 xiphmont Exp $ ********************************************************************/ @@ -310,8 +310,9 @@ codec_setup_info info_A={ }, /* psy */ {&_psy_set_A0,&_psy_set_A}, + /* thresh sample period, preecho clamp trigger threshhold, range, minenergy */ - 256, 20.f, -26.f, -96.f, + 256, {26.f,26.f,26.f,30.f}, {-90.f,-90.f,-90.f,-90.f}, -90.f, -10., diff --git a/lib/modes/mode_AA.h b/lib/modes/mode_AA.h index 233d1cc..c400abd 100644 --- a/lib/modes/mode_AA.h +++ b/lib/modes/mode_AA.h @@ -11,7 +11,7 @@ ******************************************************************** function: predefined encoding modes - last mod: $Id: mode_AA.h,v 1.7 2001/02/02 03:52:25 xiphmont Exp $ + last mod: $Id: mode_AA.h,v 1.8 2001/02/15 19:06:02 xiphmont Exp $ ********************************************************************/ @@ -240,7 +240,7 @@ static vorbis_info_floor0 _floor_set0AA={9, 44100, 64, 10,130, 2, {0,1}, 0.246f, .387f}; static vorbis_info_floor0 _floor_set1AA={30, 44100, 256, 12,150, 2, {2,3}, .082f, .126f}; -static vorbis_info_residue0 _residue_set0AA={0,64,16,6,4, +static vorbis_info_residue0 _residue_set0AA={0,192,16,6,4, {0,1,1,1,1,1}, {6,7,8,9,10}, @@ -269,7 +269,7 @@ static vorbis_info_mode _mode_set1AA={1,0,0,1}; codec_setup_info info_AA={ /* smallblock, largeblock */ - {256, 2048}, + {512, 2048}, /* modes,maps,times,floors,residues,books,psys */ 2, 2, 1, 2, 2, 20, 2, /* modes */ @@ -311,7 +311,7 @@ codec_setup_info info_AA={ /* psy */ {&_psy_set_AA0,&_psy_set_AA}, /* thresh sample period, preecho clamp trigger threshhold, range, minenergy */ - 256, 24.f, -28.f, -96.f, + 256, {30.f,30.f,30.f,34.f}, {-90.f,-90.f,-90.f,-90.f}, -90.f, -10., diff --git a/lib/modes/mode_B.h b/lib/modes/mode_B.h index 76aa778..6870936 100644 --- a/lib/modes/mode_B.h +++ b/lib/modes/mode_B.h @@ -11,7 +11,7 @@ ******************************************************************** function: predefined encoding modes - last mod: $Id: mode_B.h,v 1.10 2001/02/02 03:52:25 xiphmont Exp $ + last mod: $Id: mode_B.h,v 1.11 2001/02/15 19:06:02 xiphmont Exp $ ********************************************************************/ @@ -311,7 +311,7 @@ codec_setup_info info_B={ /* psy */ {&_psy_set_B0,&_psy_set_B}, /* thresh sample period, preecho clamp trigger threshhold, range, minenergy */ - 256, 20.f, -24.f, -96.f, + 256, {26.f,26.f,26.f,30.f}, {-90.f,-90.f,-90.f,-90.f}, -90.f, -10., diff --git a/lib/modes/mode_C.h b/lib/modes/mode_C.h index 7843e6c..23c4e5c 100644 --- a/lib/modes/mode_C.h +++ b/lib/modes/mode_C.h @@ -11,7 +11,7 @@ ******************************************************************** function: predefined encoding modes - last mod: $Id: mode_C.h,v 1.9 2001/02/02 03:52:25 xiphmont Exp $ + last mod: $Id: mode_C.h,v 1.10 2001/02/15 19:06:02 xiphmont Exp $ ********************************************************************/ @@ -311,7 +311,7 @@ codec_setup_info info_C={ /* psy */ {&_psy_set_C0,&_psy_set_C}, /* thresh sample period, preecho clamp trigger threshhold, range, minenergy */ - 256, 20.f, -20.f, -96.f, + 256, {26.f,26.f,26.f,30.f}, {-90.f,-90.f,-90.f,-90.f}, -90.f, -15., diff --git a/lib/modes/mode_D.h b/lib/modes/mode_D.h index 7578fbe..443aebb 100644 --- a/lib/modes/mode_D.h +++ b/lib/modes/mode_D.h @@ -11,7 +11,7 @@ ******************************************************************** function: predefined encoding modes - last mod: $Id: mode_D.h,v 1.10 2001/02/02 03:52:25 xiphmont Exp $ + last mod: $Id: mode_D.h,v 1.11 2001/02/15 19:06:02 xiphmont Exp $ ********************************************************************/ @@ -308,7 +308,7 @@ codec_setup_info info_D={ /* psy */ {&_psy_set_D0,&_psy_set_D}, /* thresh sample period, preecho clamp trigger threshhold, range, minenergy */ - 256, 18.f, -18.f, -96.f, + 256, {26.f,26.f,26.f,30.f}, {-90.f,-90.f,-90.f,-90.f}, -90.f, -15., diff --git a/lib/modes/mode_E.h b/lib/modes/mode_E.h index ec6c479..b7cfa95 100644 --- a/lib/modes/mode_E.h +++ b/lib/modes/mode_E.h @@ -11,7 +11,7 @@ ******************************************************************** function: predefined encoding modes - last mod: $Id: mode_E.h,v 1.8 2001/02/02 03:52:25 xiphmont Exp $ + last mod: $Id: mode_E.h,v 1.9 2001/02/15 19:06:02 xiphmont Exp $ ********************************************************************/ @@ -306,7 +306,7 @@ codec_setup_info info_E={ /* psy */ {&_psy_set_E0,&_psy_set_E}, /* thresh sample period, preecho clamp trigger threshhold, range, minenergy */ - 256, 18.f, -18.f, -96.f, + 256, {26.f,26.f,26.f,30.f}, {-90.f,-90.f,-90.f,-90.f}, -90.f, -15.,