From da9ca6a06f2d56401bdb923d3c3e8862b34bd14c Mon Sep 17 00:00:00 2001 From: Monty Date: Sat, 4 Nov 2000 10:24:15 +0000 Subject: Clamp IIR highpass in envelope code to zero below a threshhold to avoid underflow. svn path=/branches/branch_beta3/vorbis/; revision=985 --- lib/envelope.c | 3 ++- lib/iir.c | 15 ++++++++++++--- lib/iir.h | 12 ++++++------ 3 files changed, 20 insertions(+), 10 deletions(-) diff --git a/lib/envelope.c b/lib/envelope.c index 720f9c4f..0914f1c3 100644 --- a/lib/envelope.c +++ b/lib/envelope.c @@ -12,7 +12,7 @@ ******************************************************************** function: PCM data envelope analysis and manipulation - last mod: $Id: envelope.c,v 1.23.2.3 2000/11/04 06:43:49 xiphmont Exp $ + last mod: $Id: envelope.c,v 1.23.2.4 2000/11/04 10:24:15 xiphmont Exp $ Preecho calculation. @@ -174,6 +174,7 @@ long _ve_envelope_search(vorbis_dsp_state *v,long searchpoint){ float *filtered=ve->filtered[i]; float *pcm=v->pcm[i]; IIR_state *iir=ve->iir+i; + IIR_clamp(iir,9e-15); for(j=ve->current;jpcm_current;j++) filtered[j]=IIR_filter(iir,pcm[j]); diff --git a/lib/iir.c b/lib/iir.c index 44fe2470..4a336496 100644 --- a/lib/iir.c +++ b/lib/iir.c @@ -12,7 +12,7 @@ ******************************************************************** function: Direct Form I, II IIR filters, plus some specializations - last mod: $Id: iir.c,v 1.2.2.2 2000/11/04 06:43:50 xiphmont Exp $ + last mod: $Id: iir.c,v 1.2.2.3 2000/11/04 10:24:15 xiphmont Exp $ ********************************************************************/ @@ -32,7 +32,6 @@ void IIR_init(IIR_state *s,int stages,float gain, float *A, float *B){ s->coeff_A=_ogg_malloc(stages*sizeof(float)); s->coeff_B=_ogg_malloc((stages+1)*sizeof(float)); s->z_A=_ogg_calloc(stages*2,sizeof(float)); - s->z_B=_ogg_calloc(stages*2,sizeof(float)); memcpy(s->coeff_A,A,stages*sizeof(float)); memcpy(s->coeff_B,B,(stages+1)*sizeof(float)); @@ -43,7 +42,6 @@ void IIR_clear(IIR_state *s){ free(s->coeff_A); free(s->coeff_B); free(s->z_A); - free(s->z_B); memset(s,0,sizeof(IIR_state)); } } @@ -67,6 +65,17 @@ float IIR_filter(IIR_state *s,float in){ return(newB); } +/* prevents ringing down to underflow */ +void IIR_clamp(IIR_state *s,float thresh){ + float *zA=s->z_A+s->ring; + int i; + for(i=0;istages;i++) + if(fabs(zA[i])>=thresh)break; + + if(istages) + memset(s->z_A,0,sizeof(float)*s->stages*2); +} + /* 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){ diff --git a/lib/iir.h b/lib/iir.h index 9fee1437..4664b38b 100644 --- a/lib/iir.h +++ b/lib/iir.h @@ -12,7 +12,7 @@ ******************************************************************** function: Direct Form I, II IIR filters, plus some specializations - last mod: $Id: iir.h,v 1.2.2.1 2000/11/04 06:21:44 xiphmont Exp $ + last mod: $Id: iir.h,v 1.2.2.2 2000/11/04 10:24:15 xiphmont Exp $ ********************************************************************/ @@ -24,14 +24,14 @@ typedef struct { float *coeff_A; float *coeff_B; float *z_A; - float *z_B; int ring; float gain; } IIR_state; -void IIR_init(IIR_state *s,int stages,float gain, float *A, float *B); -void IIR_clear(IIR_state *s); -float IIR_filter(IIR_state *s,float in); -float IIR_filter_ChebBand(IIR_state *s,float in); +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 void IIR_clamp(IIR_state *s,float thresh); #endif -- cgit v1.2.1