【Python】1/fゆらぎ(ピンクノイズ)のデジタルフィルタ

【Python】1/fゆらぎ(ピンクノイズ)のデジタルフィルタ
【Python】1/fゆらぎ(ピンクノイズ)のデジタルフィルタ

前回の記事では、電子回路のラグ・リードフィルタを使ってアナログ的にピンクノイズを作ってみた。今回は、プログラミングでデジタルピンクノイズを作ってみようと思う。なお、プログラミング言語はPythonで行った。

ピンクノイズフィルタのプログラミング

こちらのは、ホワイトノイズにピンクノイズフィルタを掛けてwaveファイル出力するプログラムである。IIRフィルタを使用している。正確な1/fノイズ(ピンクノイズ)フィルタのアルゴリズムは、今だに解明されていないようである。よって、こちらのサイトを参考に近似的なフィルタでピンクノイズを実現している。 Example: Synthesis of 1/F Noise (PinkNoise)

py
import numpy as np
import matplotlib.pyplot as plt
from scipy import signal
from scipy.io.wavfile import write

def output_wav(filename, rate, data):
    write(filename, rate, data.astype(np.int16))

if __name__ == '__main__':
    rate = 44100
    T = np.arange(0, 2, 1 / rate)
    white = np.random.rand(len(T)) - 0.5
    data = white * 32767
    output_wav('white_noise.wav', rate, data.astype(np.int16))

    B = [0.049922035, -0.095993537, 0.050612699, -0.004408786]
    A = [1, -2.494956002, 2.017265875, -0.522189400]
    # a[0]*y[n] = b[0]*x[n] + b[1]*x[n-1] + ... + b[M]*x[n-M]
    #                       - a[1]*y[n-1] - ... - a[N]*y[n-N]
    pink = signal.lfilter(B, A, white) * 8

    fft_data = 10*np.log(np.abs(np.fft.rfft(pink)))  # 縦軸
    freqList = np.fft.rfftfreq(len(pink), 1.0 / rate)  # 横軸
    ax = plt.subplot()
    ax.set_xlim([10, 20000])
    ax.set_ylim([5, 100])
    plt.loglog(freqList, fft_data)
    plt.xlabel('Frequency')
    plt.ylabel('Power')
    plt.show()

    data = pink * 32767
    output_wav('pink_noise.wav', rate, data.astype(np.int16))

サウンドプログラミングにおすすめの書籍はこちら。

ピンクノイズの周波数特性

ピンクノイズの周波数特性
ピンクノイズの周波数特性
上記のプログラムを実行して出力されたWaveファイルの周波数特性を調べると図のようになった。-3dB/oct(-10dB/dec)となっていることがわかる。 Pink Noise by IIR Filter

ピンクノイズを作る方法は、これ以外にも「The Voss algorithm」「The Voss-McCartney algorithm」などが存在する。詳しくはこちらのサイトを参考に。 DSP Generation of Pink Noise

他にもピンクノイズのフィルタに関する海外のサイトが役立ったので紹介しておこう。 Design a 1/f spectrum shaping (pink-noise) filter Digital Filters

関連記事

最後までご覧いただきありがとうございます!

▼ 記事に関するご質問やお仕事のご相談は以下よりお願いいたします。
お問い合わせフォーム

関連記事