summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMonty <xiphmont@xiph.org>2000-11-04 10:24:15 +0000
committerMonty <xiphmont@xiph.org>2000-11-04 10:24:15 +0000
commitda9ca6a06f2d56401bdb923d3c3e8862b34bd14c (patch)
treef495a667cf5620607c53318b591f0dde26863750
parentc1a5991a5d19aef8f951773f217c562513a160d7 (diff)
downloadlibvorbis-git-branch_beta3.tar.gz
Clamp IIR highpass in envelope code to zero below a threshhold tobranch_beta3
avoid underflow. svn path=/branches/branch_beta3/vorbis/; revision=985
-rw-r--r--lib/envelope.c3
-rw-r--r--lib/iir.c15
-rw-r--r--lib/iir.h12
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;j<v->pcm_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;i<s->stages;i++)
+ if(fabs(zA[i])>=thresh)break;
+
+ if(i<s->stages)
+ 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