问题
I'm implementing a low pass filter in C wih the PortAudio library. I record my microphone input with a script from PortAudio itself. There I added the following code:
float cutoff = 4000.0;
float filter(float cutofFreq){
float RC = 1.0/(cutofFreq * 2 * M_PI);
float dt = 1.0/SAMPLE_RATE;
float alpha = dt/(RC+dt);
return alpha;
}
float filteredArray[numSamples];
filteredArray[0] = data.recordedSamples[0];
for(i=1; i<numSamples; i++){
if(i%SAMPLE_RATE == 0){
cutoff = cutoff - 400;
}
data.recordedSamples[i] = data.recordedSamples[i-1] + (filter(cutoff)*(data.recordedSamples[i] - data.recordedSamples[i-1]));
}
When I run this script for 5 seconds it works. But when I try to run this for more then 5 seconds it fails. The application records everything, but crashes on playback. If I remove the filter, the application works.
Any advice?
回答1:
The problem:
you are lowering the cutoff frequency by 400 Hz everytime
i%SAMPLE_RATE == 0
- never stop so you go below zero
- this is not done once per second !!!
- instead every time your for passes through second barrier in your data
- that can occur more often then you think if you are not calling your calls in the right place
- which is not seen in your code
you are filtering in wrong oorder
... a[i]=f(a[i],a[i-1]; i++;
- that means you are filtering with already filtered
a[i-1]
value
What to do with it
check the code placement
- it should be in some event like on packed done sompling
- or in thread after some
Sleep(...);
(or inside timer) - change the cut off changing (handle edge cases)
reverse filter for direction
Something like this:
int i_done=0;
void on_some_timer()
{
cutoff-=400;
if (cutoff<1) cutoff=1; // here change 1 for limit frequency
if (numSamples!=i_done)
for (i=numSamples-1,i>=i_done;i--)
data.recordedSamples[i] = data.recordedSamples[i-1] + (filter(cutoff)*(data.recordedSamples[i] - data.recordedSamples[i-1]));
i_done=numSamples;
}
if your code is already OK (you did not post th whole thing so I can missing something)
- then just add the
if (cutoff<1) cutoff=1;
after cutoff change
来源:https://stackoverflow.com/questions/27106205/low-pass-filter-in-c