人工知能に関する断創録

このブログでは人工知能のさまざまな分野について調査したことをまとめています(更新停止: 2019年12月31日)

ハイパスフィルタ

Pythonで音声信号処理(2011/05/14)

ローパスフィルタ(2011/10/28)の続き。今回は、ハイパスフィルタを実験します。逆フーリエ変換の式が違うだけでほとんどローパスフィルタと同じなんだけどね。

ハイパスフィルタは、ローパスフィルタの逆でエッジ周波数feより大きい周波数領域は通して、小さい領域を0にしてしまうフィルタです。式で書くと、

f:id:aidiary:20111029221135p:plain

となります。ナイキスト周波数fs/2は、fs=1と正規化しているので1/2となります。また、FFTの結果は、0を中心として左右対称になるので負の部分も考慮します。これを逆フーリエ変換してフィルタ係数b(i)を求めると、

f:id:aidiary:20111029221418p:plain

となります。LPFと同様にb(i)は無限個のフィルタ係数を持つ(書き忘れたけど、iは-∞から+∞)ため窓関数をかけて有限で打ち切ります。

LPFのプログラムとほとんど同じなので差分のみ書きます。これだけでは動きません。コード全体は、ローパスフィルタ(2011/10/28)を参照のこと。

def createHPF(fe, delta):
    """ハイパスフィルタを設計、fe:エッジ周波数、delta:遷移帯域幅"""
    # 遷移帯域幅を満たすフィルタ係数の数を計算
    # N+1が奇数になるように調整が必要
    N = round(3.1 / delta) - 1
    if N + 1 % 2 == 0: N += 1
    N = int(N)

    # フィルタ係数を求める
    b = []
    for i in range(-N/2, N/2 + 1):
        b.append(sinc(math.pi * i) - 2 * fe * sinc(2 * math.pi * fe * i))

    # ハニング窓をかける(窓関数法)
    hanningWindow = np.hanning(N + 1)
    for i in range(len(b)):
        b[i] *= hanningWindow[i]

    return b

# LPFを設計
fe = 1000.0 / fs        # 正規化したエッジ周波数
delta = 100.0 / fs      # 正規化した遷移帯域幅
b = createHPF(fe, delta)
y = fir(x, b)

結果は、

f:id:aidiary:20111029220427p:plain

となります。上がb(i)で下がB(f)です。B(f)を見るとエッジ周波数1000Hzより高い領域は1を掛けるのでそのまま通るけど、1000Hzより低い領域は0を掛けるため0に減衰します。ためしに、ホワイトノイズに上のHPFを適用してみました。結果は、

f:id:aidiary:20111029220444p:plain

となります。音は、

です。前回のオリジナルのホワイトノイズと比べると低音のごーがぬけてしゃーという高音だけになっています。次、バンドパスフィルタいきます。