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で呼び出せることで使う幅が広がりそうです.
今回は,以上になります.お読みいただきありがとうございました.

この記事が参加している募集

#今日やったこと

30,962件

この記事が気に入ったらサポートをしてみませんか?