プログラミングで人の音声のような音を生成する.


最近, 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/

コメントを残す

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