python

pythonで自作短時間フーリエ変換を用いたスペクトログラム関数作成!

こちらの記事で作成をした短時間フーリエ変換の関数を用いて、スペクトログラム関数を自作していきます!

pythonのnumpyで自作のSTFT関数とISTFT関数を実装!今年の4月に某大学のデジタル信号を扱う研究室に配属されました! 希望が通り一安心です。 そんな思いで研究をしています...

自作STFT関数

自作のSTFTです。

def STFT(x, window=1024, step=512, win_fc=1.):
    """
    Compute the Short Time Fourier Transform (STFT).
    Parameter
    -----------
    x : array-like
        Time series of measurement values
    window : int, default 1024
        Length of window size
    step : int, default 512
        Length of step size
    win_fc : array-like
        window function
    Return
    ------------
    Z : ndarray
        STFT of x. By default, the last axis of Zxx corresponds to the segment times.
    """
    Z = []
    for i in range((x.shape[0] - window) // step):
        tmp = x[i*step : i*step + window]
        tmp = tmp * win_fc
        tmp = np.fft.fft(tmp)  # get fft data [i*step:i*step+window]
        Z.append(tmp)
    Z = np.array(Z)
    return Z

 

これを用いて、関数を作成します。

自作スペクトログラム関数

色ではデシベル表記になるように数値を計算し直しています。

import numpy as np
import matplotlib.pyplot as plt
from scipy import hamming

def my_spectrogram(x, window=1024, step=512, sr=48000, title="Spectrogram"):
    """
    plot spectrogram
    Parameters
    ----------
    x : array_like
        First one-dimensional input array.
    window : int, default 1024
        Length of window size
    step : int, default 512
        Length of step size
    sr : int, default 48000
        sampling rate of x
    title : str, default "Spectrogram
        title of the picture
    Returns
    -----------
    """
    win_fc = hamming(window)
    spectrogram = STFT(x, window=window, step=step, win_fc=win_fc)
    spectrogram = 20 * np.log10(np.abs(spectrogram.T))[window // 2:]

    # display range
    # left : 0[s], right : max_time[s]
    # bottom : 0[Hz], top : max_freq [Hz]
    max_time = x.shape[0] // sr
    max_freq = sr // 2 
    extent = [0, max_time, 0, max_freq]

    # display spectrogram
    plt.figure(figsize=[12, 6])
    ax = plt.subplot()
    im = plt.imshow(spectrogram, aspect="auto", extent=extent)
    ax.set_title(title, size=16)
    ax.set_xlabel('Time [s]', size=14)
    ax.set_ylabel('Frequency [Hz]', size=14)
    cbar = plt.colorbar(im, format='%+2.0f dB', aspect=100)
    cbar.set_label("Magnitude [dB]", size=14)
    plt.show()

 

こだわりポイントとしては、colorbar(カラーバー)を良い感じの位置に配置することにこだわりました。笑

使用例

実装

def main():
    fname = "signal.wav"
    x, sr = librosa.load(fname, sr=48000)  # [sec], [Hz]
    my_spectrogram(x, window=1024, step=512, sr=48000, title="Original signal spectrogram")
    plt.savefig("Original_signal_spectrogram.png")
    plt.close()

if __name__ == "__main__":
    main()

結果

こんな感じになりました!

最後に

seabornを使用した時と比べてかなり早くなりました。

何度も実行する関数では速度も重要ですね。

また、$x, y$軸も見やすくなるように設定を直しました。

参考になれば幸いです。

オススメのプログラミングスクールをご紹介

タイピングもままならない完全にプログラミング初心者から

アホいぶきんぐ
アホいぶきんぐ
プログラミングってどこの国の言語なの~?

たった二ヶ月で

いぶきんぐ
いぶきんぐ
え!?人工知能めっちゃ簡単にできるじゃん!

応用も簡単にできる…!!

という状態になるまで、一気に成長させてくれたオススメのプログラミングスクールをご紹介します!

テックアカデミーのPython+AIコースを受講した僕が本音のレビュー・割引あり! というプログラミング完全初心者だった僕が Tech Academy(テックアカデミー)のPython×AIコース を二ヶ月間...

COMMENT

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です