Praat in Pythonでフォルマント分析してみる.
Praat (プラート) と呼ばれる音声分析向けオープンソースをPythonでラッパーした Parselmouth というライブラリを紹介していただいたので触ってみました.公式サイトより,ParselmouthはPraatのC/C++コードに直接アクセスするため,本体と同じアルゴリズム・出力で使うことができるようです.
今回は,音源のフォルマント分析をやってみました.
環境 (2022/11/03時点)
macOS Monterey12.6
Python 3.8.5
parselmouth 0.4.1
parselmouthをインストールする
他の一般的なライブラリと同じように,pip を使ってインストールできました.praat-parselmouth という名前になっていることに注意が必要です.
% pip install praat-parselmouth
関数あれこれ
parselmouthリポジトリ では,波形表示やスペクトログラムを求めるサンプルはまとめられています.
音声を読み込む
parselmouth.Sound で音源を読み込みます.読み込んだ音声そのものや時間情報,サンプリング周波数などがオブジェクトで返ってきます.
snd = parselmouth.Sound("*.wav")
print(snd)
---
Object type: Sound
Object name: <no name>
Date: Sat Nov 5 12:56:41 2022
Number of channels: 1 (mono)
Time domain:
Start time: 0 seconds
End time: 0.7936507936507936 seconds
Total duration: 0.7936507936507936 seconds
Time sampling:
Number of samples: 17500
Sampling period: 4.5351473922902495e-05 seconds
Sampling frequency: 22050 Hz
First sample centred at: 2.2675736961451248e-05 seconds
Amplitude:
Minimum: -0.585998535 Pascal
Maximum: 0.367156982 Pascal
Mean: 0.000865035575 Pascal
Root-mean-square: 0.0739016884 Pascal
Total energy: 0.00433449171 Pascal² sec (energy in air: 1.08362293e-05 Joule/m²)
Mean power (intensity) in air: 1.36536489e-05 Watt/m² = 71.35 dB
Standard deviation in channel 1: 0.073898737 Pascal
snd.sampling_frequency (サンプリングレート), snd.values (音声そのもの) のように使うことができるようです.
フォルマント分析
burg法と呼ばれる手法でフォルマント周波数を求める to_formant_burg() を使います.引数として入れたパラメータは,デフォルト値です.得られたオブジェクトで返ってきます.
formants_burg = snd.to_formant_burg(max_number_of_formants=5.0, maximum_formant=5500.0, window_length=0.025, pre_emphasis_from=50.0)
次に,特定の時刻におけるフォルマントは,get_value_at_time() を用いて,引数としてフォルマントの次数と取得する時刻を指定します.
# 時刻0.5における第1フォルマントを求める
formants_burg.get_value_at_time(formant_number=1,time=0.5,unit='HERTZ')
これでフォルマント分析ができるようになります.
参考までに,第1~第4フォルマントを取得し,pandasライブラリを用いてデータ成形するスクリプトを置いておきます.
成形したフォルマント結果が以下のように得られます.
Praatアプリでも同じパラメータでフォルマント分析したところ,同じような結果が得られました.
print(df)
-----
1 2 3 4
0.028075 389.704421 1154.854367 2332.970294 3736.784121
0.034325 1081.516778 2283.759561 3275.008440 4300.344732
0.040575 987.612264 2240.003357 3247.455787 4393.081085
0.046825 1155.553993 2619.801213 3628.753130 4917.639442
0.053075 834.875738 1454.517609 2745.292070 3791.734046
... ... ... ... ...
0.740575 554.677512 630.537218 2651.535003 3333.725797
0.746825 565.164887 2675.616924 3295.872303 4891.901757
0.753075 536.243440 1038.078987 2796.206271 3722.752906
0.759325 508.837331 1520.039972 2662.502182 3749.496279
0.765575 603.552488 1947.981480 2640.207217 4220.725973
[119 rows x 4 columns]
こちらの記事 によると,call()という関数を使うことでPraatアプリよりの操作感で実行できるようです.
formants = praat.call(snd, "To Formant (burg)", 0.0, 5, 5500, 0.025, 50)
終わりに
自分もPraatを使い始めたばかりで,細かいパラメータまでは把握できていませんが,Pythonで呼び出せることで使う幅が広がりそうです.
今回は,以上になります.お読みいただきありがとうございました.