Commit da9ca6a0 authored by Monty's avatar Monty

Clamp IIR highpass in envelope code to zero below a threshhold to
avoid underflow.

svn path=/branches/branch_beta3/vorbis/; revision=985
parent c1a5991a
......@@ -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]);
......
......@@ -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){
......
......@@ -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
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment