应用IIR滤波器,心跳声中会出现额外的说话声

问题描述 投票:0回答:1

在我的 iOS 应用程序中,使用 swift

我正在从数字健康设备 (BLE) 获取音频。以音频数据的形式,听到心跳声。

  1. 我们对接收到的数据应用 ADPCM 解码器。播放时有背景噪音和心跳声。

  2. 为了过滤它,我们应用过滤器来消除背景噪音。它是带通 IIR 滤波器。

频率 20 - 200 Hz 的 IIR 参数

B 0.3468218078469383,0.0,-1.3872872313877531,0.0,2.0809308470816297,0.0,-1.3872872313877531,0.0,0.346821807846938

A 1.0,-0.692931448722861,-1.7554648142444358,0.7966332180729667,1.6060001719379677,-0.4353468784755548,-0.691339842239745,0.0 8285290618602029,0.12038959989624454

下面是过滤代码

func applyFilterToData(decoded: Data) -> Data {

        // Example usage    
        var lastData = Data()
        for decodedData in decoded {
            let unsignedData = UInt8(decodedData)
            let lowPassUInt8 = iirFilterNew.filter(Double(unsignedData))
            lastData.append(lowPassUInt8)
            filteredDataToShare.append(lastData)
            self.n = (self.n + 1) % 9
        }
        // Receive UInt8 -> Data
        return lastData

    }


func filter(_ input: Double) -> UInt8 {
        // Update input history
        xHistory.insert(input, at: 0)
        xHistory.removeLast()
        
        // Calculate output
        var output = b[0] * xHistory[0]
        
        for i in 1..<b.count {
            output += b[i] * xHistory[i]
        }
        
        for i in 1..<a.count {
            output -= a[i] * yHistory[i - 1]
        }
    
        // Update output history
        yHistory.insert(output, at: 0)
        yHistory.removeLast()
        
        return convertDoubleToUInt8(decoded : output)
    }

//If below function i apply then white noise comes 

   func convertDoubleToUInt8(value: Double) -> UInt8  {
        var val = value
        val.round()
        if val > 127.0 {
            val = 127.0
        }
        if val < -128.0 {
            val = -128.0
        }
        var signedInt: Int8 = 0
        if val.isNaN {
            signedInt = 0
        } else {
            signedInt = Int8(val)
        }
        return UInt8.init(bitPattern: Int8(signedInt))
    }

以下是要过滤的音频样本:

https://drive.google.com/file/d/1qV8YBFhz3HVVKfrRz8muMRn0CqR68GaO/view?usp=sharing

python ios swift audio iirf
1个回答
0
投票
    func applyFilterToData(decoded: Data, filterEnabled: Bool = true) -> Data {
    var lastData = Data()
    for decodedData in decoded {
        let unsignedData = UInt8(decodedData)
        let scaledInput = Double(unsignedData) / 128.0 - 1.0  // Assuming 0-255 range

        var filteredOutput: Double
        if filterEnabled {
            filteredOutput = iirFilterNew.filter(scaledInput)
        } else {
            filteredOutput = scaledInput
        }

        // Scaling output (adjust if needed)
        let scaledOutput = filteredOutput * 128.0 + 128.0
        let outputUInt8 = UInt8(clamping: Int(round(scaledOutput)))

        lastData.append(outputUInt8)
    }
    return lastData
}

// Improved conversion with clamping
func convertDoubleToUInt8(value: Double) -> UInt8 {
    return UInt8(clamping: Int(round(value)))
}
© www.soinside.com 2019 - 2024. All rights reserved.