音声をフーリエ解析してみよう~とりあえずscipyライブラリで~

  • #技術ブログ 

こんにちは!
前回の更新って、夏だった気がしている、うえピーです。
いや~、光陰矢の如しですね~。さぼり始めると止まらない・・・。

ということで今回は、結構時間がたったはずなのに未だ勉強中のフーリエ解析の第2回です。
scipyライブラリで短時間フーリエ変換をします。
それを入力にスペクトログラム的なものを表示してフーリエ変換した感を出してみたいと思います。

では、早速、scipy.signal.stftのサンプルコードを参考にして、正弦波を生成してみましょう。

import numpy as np
import sounddevice as sd
fs = 10e3
N = 1e5
amp = 2 * np.sqrt(2)
time = np.arange(N) / float(fs)
mod = 500 * np.cos(2 * np.pi * 0.25 * time)
carrier = amp * np.sin(2 * np.pi * 3e3 * time + mod)
sd.play(carrier, fs)
print("再生開始")
# 再生が終わるまで待つ
status=sd.wait()
# wavファイルに書き込む
# 2バイトのデータとして書き込むためにスケールを調整
data_scale_adjust=carrier*np.iinfo(np.int16).max
# 2バイトのデータに変換
data_scale_adjust=data_scale_adjust.astype(np.int16)
wave_out=wave.open("./sound_01.wav", 'w')
wave_out.setnchannels(1)
wave_out.setsampwidth(2)
wave_out.setframerate(fs)
wave_out.writeframes(data_scale_adjust)
wave_out.close()

うわ~、一定周期の音って不快っすね~。(再生する際は、音量は小さめでお願いします)

これを短時間フーリエ変換して、スペクトログラム的なものを表示してみましょう。

import scipy.signal as sp
import matplotlib.pyplot as plt
f, t, Zxx = sp.stft(carrier, fs, nperseg=1000)
plt.pcolormesh(t, f, np.abs(Zxx), vmin=0, vmax=amp, shading='gouraud')
plt.title('STFT Magnitude')
plt.ylabel('Frequency [Hz]')
plt.xlabel('Time [sec]')


耳で聞いた音の不快感と相反してきれいな見た目ですなー。
ではでは、今回は使いませんが、憧れのpyroomacousticsライブラリから人の声をダウンロードして、こちらもスペクトログラム的なものを表示してみましょう。

import pyroomacoustics as pa
pa.datasets.CMUArcticCorpus(basedir="./CMU_ARCTIC", download=True, speaker=["aew", "axb"])
sample_wave_file="./CMU_ARCTIC/cmu_us_aew_arctic/wav/arctic_a0001.wav"
wav=wave.open(sample_wave_file)
# PCM形式の波形データを読み込み
data=wav.readframes(wav.getnframes())
# dataを2バイトの数値列に変換
data=np.frombuffer(data, dtype=np.int16)
sd.play(data, wav.getframerate())
# 再生が終わるまで待つ
status=sd.wait()

ほぉほぉ、イケメンの声がします。

どんな感じのスペクトログラムになるのかしら?

f,t,stft_data=sp.stft(data, fs=wav.getframerate(), window="hann", nperseg=512, noverlap=256)
plt.pcolormesh(t, f, np.abs(stft_data), shading='gouraud')
plt.title('STFT Magnitude')
plt.ylabel('Frequency [Hz]')
plt.xlabel('Time [sec]')

何やら、指紋のようなものがもやもや~っと。

多分、これがイケメンの声紋なのでしょう。
ふーん、と思ったところで今日はこれくらいにしておきます。
修行をするとスペクトログラムから何をしゃべっているか判断できるらしいです!!
そんなすごい能力、是非身につけてみたいと思いながら、いざ年末へ、Let’s go.