エコー キャンセレーション (AEC) の原理、アルゴリズム、および実践 - カルマン フィルター

カルマン フィルターとは

カルマン フィルター処理は、線形システム状態方程式を使用して、システムによって入力された観測データからシステム状態を最適に推定するアルゴリズムです。観測データにはシステム ノイズや干渉の影響が含まれているため、最適推定はフィルタリング処理と見なすこともできます。

カルマン フィルター処理では、測定分散が既知の場合、測定ノイズを含む一連のデータから動的システムの状態を推定できます。

不確実な情報を含む任意の動的システムでカルマン フィルター処理を使用して、システムの次のステップについて知識に基づいた予測を行うことができます. さまざまな外乱があっても、カルマン フィルター処理は常に実際に起こったことを示すことができます.

連続的に変化するシステムでカルマン フィルター処理を使用するのは非常に理想的です. 小さなメモリを占有するという利点があり (以前の状態量を除いて、他の履歴データを保持する必要はありません)、非常に高速です.リアルタイムの問題

 

コードは以下のように表示されます:

import numpy as np
import librosa
import soundfile as sf
import pyroomacoustics as pra


def kalman(x, d, N = 64, sgm2v=1e-4):
  nIters = min(len(x),len(d)) - N
  u = np.zeros(N)
  w = np.zeros(N)
  Q = np.eye(N)*sgm2v
  P = np.eye(N)*sgm2v
  I = np.eye(N)
  e = np.zeros(nIters)
  for n in range(nIters):
    u[1:] = u[:-1]
    u[0] = x[n]
    e_n =  d[n] - np.dot(u, w)
    R = e_n**2+1e-10
    Pn = P + Q
    r = np.dot(Pn,u)
    K = r / (np.dot(u, r) + R + 1e-10)
    w = w + np.dot(K, e_n)
    P = np.dot(I - np.outer(K, u), Pn)
    e[n] = e_n

  return e
  
  
# x 原始参考信号
# v 理想mic信号 
# 生成模拟的mic信号和参考信号
def creat_sim_sound(x,v):
    rt60_tgt = 0.08
    room_dim = [2, 2, 2]

    e_absorption, max_order = pra.inverse_sabine(rt60_tgt, room_dim)
    room = pra.ShoeBox(room_dim, fs=sr, materials=pra.Material(e_absorption), max_order=max_order)
    room.add_source([1.5, 1.5, 1.5])
    room.add_microphone([0.1, 0.5, 0.1])
    room.compute_rir()
    rir = room.rir[0][0]
    rir = rir[np.argmax(rir):]
    # x 经过房间反射得到 y
    y = np.convolve(x,rir)
    scale = np.sqrt(np.mean(x**2)) /  np.sqrt(np.mean(y**2))
    # y 为经过反射后到达麦克风的声音
    y = y*scale

    L = max(len(y),len(v))
    y = np.pad(y,[0,L-len(y)])
    v = np.pad(v,[L-len(v),0])
    x = np.pad(x,[0,L-len(x)])
    d = v + y
    return x,d

if __name__ == "__main__":
    x_org, sr  = librosa.load('female.wav',sr=8000)
    v_org, sr  = librosa.load('male.wav',sr=8000)

    x,d = creat_sim_sound(x_org,v_org)

    e = kalman(x, d, N=256)
    e = np.clip(e,-1,1)
    
    sf.write('x.wav', x, sr, subtype='PCM_16')
    sf.write('d.wav', d, sr, subtype='PCM_16')
    sf.write('kalman.wav', e, sr, subtype='PCM_16')

参考文献:

https://www.bilibili.com/video/BV1Fd4y1R7ap/?spm_id_from=333.788&vd_source=77c874a500ef21df351103560dada737

https://blog.csdn.net/u010720661/article/details/63253509?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522168162249216800225558520%2522%252C%2522scm%2 522%253A%252220140713.130102334..%2522%257D&request_id =168162249216800225558520&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_positive~default-1-63253509-null-null.142^v83^insert_down38,239^v2^insert_chatgpt&utm_term=%E 5%8D%A1% E5%B0%94%E6%9B%BC%E6%BB%A4%E6%B3%A2&spm=1018.2226.3001.4187 

おすすめ

転載: blog.csdn.net/qq_42233059/article/details/130187225