プログラミングで人の音声のような音を生成する.
最近, parselmouthというライブラリを見つけた. これは, PythonでPraatが使えるようになるライブラリである. これらについて学習を進めていたところ, まず手始めに非常に面白いコードをGeminiが提示してくれた. このコードは, 母音を擬似的に作成するコードである.
実際に作った音を聞いてみると, 確かに目をつぶっていても判別できるくらいに, 「あいうえお」と明確に音が聞こえる. こういった形で音が聞こえると, 人間の音声というのも当然ながら, どこまで行っても物理的な現象であるということがよくわかる.
!pip install praat-parselmouth
!pip install japanize-matplotlib
import numpy as np
import parselmouth
from scipy import signal
def create_vowel(f1, f2, f3, f0=130, duration=0.5, fs=44100):
"""指定したフォルマントで母音を生成する関数"""
t = np.linspace(0, duration, int(fs * duration), endpoint=False)
source = signal.sawtooth(2 * np.pi * f0 * t) # 声帯音源
filtered = source
for f, bw in zip([f1, f2, f3], [50, 100, 150]):
R = np.exp(-np.pi * bw / fs)
theta = 2 * np.pi * f / fs
b, a = [1 - 2*R*np.cos(theta) + R**2], [1, -2*R*np.cos(theta), R**2]
filtered = signal.lfilter(b, a, filtered)
# 正規化
filtered = filtered / np.max(np.abs(filtered)) * 0.5
return parselmouth.Sound(filtered, sampling_frequency=fs)
# 1. 各母音と無音の生成
fs = 44100
snd_a = create_vowel(800, 1200, 2500)
snd_i = create_vowel(300, 2300, 3200)
snd_u = create_vowel(350, 1250, 2500)
snd_e = create_vowel(500, 1900, 2500)
snd_o = create_vowel(500, 800, 2400)
# 0.1秒の無音を作成
silence = parselmouth.Sound(np.zeros(int(fs * 0.1)), sampling_frequency=fs)
# 2. 順番にリストへ格納
# 「あいうえお」の5母音にします
sound_list = [snd_a, silence, snd_i, silence, snd_u, silence, snd_e, silence, snd_o]
# 3. 連結 (Concatenate)
# Praatのコマンドを呼び出します
combined_snd = parselmouth.praat.call(sound_list, "Concatenate")
# 4. 保存
combined_snd.save("aiueo_combined.wav", "WAV")
print("連結ファイル 'aiueo_combined.wav' を作成しました。")
参考文献
- Jadoul, Y., Thompson, B., & de Boer, B. (2018). Introducing Parselmouth: A Python interface to Praat. Journal of Phonetics, 71, 1-15. https://doi.org/10.1016/j.wocn.2018.07.001
- Boersma, P., & Weenink, D. (2021). Praat: doing phonetics by computer Computer program. Version 6.1.38, retrieved 2 January 2021 from http://www.praat.org/