Reputation: 11
I am currently trying to implement a 4th order butterworth, band-pass filter with cutoff 0.05 Hz to 0.15Hz.
The following is my attempt, but the result is not good in the sense that a lot of other frequencies are still getting through.
// Function to compute bandpass filter coefficients based on center frequency and quality factor.
func makeBandpassFilterWithFcAndQ(filter: inout [Double], Fs: Double, Fc: Double, Q: Double) {
let K = tan(.pi * Fc / Fs)
let norm = 1.0 / (1.0 + K / Q + K * K)
filter[0] = K / Q * norm
filter[1] = 0.0
filter[2] = -filter[0]
filter[3] = 2.0 * (K * K - 1.0) * norm
filter[4] = (1.0 - K / Q + K * K) * norm
}
// Function to compute bandpass filter coefficients based on frequency range.
func makeBandpassFilterWithFreqRange(filter: inout [Double], Fs: Double, Fbtm: Double, Ftop: Double) {
//let Fc = sqrt(Fbtm * Ftop)
let Fc = 0.10
let Q = Fc / (Ftop - Fbtm)
//let Q = 0.99
makeBandpassFilterWithFcAndQ(filter: &filter, Fs: Fs, Fc: Fc, Q: Q)
}
// Function to apply bandpass filtering to a signal
func applyBandpassFilter(signal: [Double], fs: Double, filterCoefficients: [Double]) -> [Double] {
let numRawDoubles = vDSP_Length(signal.count)
var rawDoubles = signal
var filteredDoubles = [Double](repeating: 0.0, count: signal.count)
let rawStride = vDSP_Stride(1)
let filteredStride = vDSP_Stride(1)
// Apply the filter using vDSP_deq22
vDSP_deq22D(&rawDoubles, rawStride, filterCoefficients, &filteredDoubles, filteredStride, numRawDoubles - 2)
return filteredDoubles
}
// Function to apply a 4th order Butterworth bandpass filter
func apply4thOrderButterworthBandpassFilter(signal: [Double], fs: Double, Fbtm: Double, Ftop: Double) -> [Double] {
// First set of coefficients
var filterCoefficients1 = [Double](repeating: 0.0, count: 5)
makeBandpassFilterWithFreqRange(filter: &filterCoefficients1, Fs: fs, Fbtm: Fbtm, Ftop: Ftop)
// Apply the first filter
let filteredSignal1 = applyBandpassFilter(signal: signal, fs: fs, filterCoefficients: filterCoefficients1)
// Second set of coefficients (same as the first for Butterworth filter)
var filterCoefficients2 = [Double](repeating: 0.0, count: 5)
makeBandpassFilterWithFreqRange(filter: &filterCoefficients2, Fs: fs, Fbtm: Fbtm, Ftop: Ftop)
// Apply the second filter
let filteredSignal2 = applyBandpassFilter(signal: filteredSignal1, fs: fs, filterCoefficients: filterCoefficients2)
return filteredSignal2
}
I have tried cascading two second order filters with no luck.
Upvotes: 1
Views: 91