pyworldでピッチ・フォルマントシフト(+wav入力、音声再生、周波数プロット)

import numpy as np
from scipy.io import wavfile
import simpleaudio as sa
import pyworld as pw
import matplotlib.pyplot as plt

# wavファイルの入力
sample_rate, data_int = wavfile.read('input.wav')

# 基本周波数、スペクトル包絡、非周期性指標の抽出
data_float = data_int.astype(np.float)
f0, t = pw.dio(data_float, sample_rate) # 基本周波数の抽出
f0 = pw.stonemask(data_float, f0, t, sample_rate) # refinement
sp = pw.cheaptrick(data_float, f0, t, sample_rate) # スペクトル包絡の抽出
ap = pw.d4c(data_float, f0, t, sample_rate) # 非周期性指標の抽出

# ピッチシフト
f0_rate = 1.5
f0_modified = modified_f0 = f0_rate * f0

# フォルマントシフト
sp_rate = 0.75
sp_modified = np.zeros_like(sp)
sp_range = int(sp_modified.shape[1] * sp_rate)
for f in range(sp_modified.shape[1]):
sp_modified[:, f] = sp[:, int(sp_rate * f)]

# 再合成
synth_float = pw.synthesize(f0_modified, sp_modified, ap, sample_rate)
synth_float *= 32767 / max(abs(synth_float))
synth_int = synth_float.astype(np.int16)

# 再生
play_obj = sa.play_buffer(data_int, 1, 2, sample_rate)
play_obj.wait_done()
play_obj = sa.play_buffer(synth_int, 1, 2, sample_rate)
play_obj.wait_done()

# 基本周波数のプロット
plt.plot(f0)
plt.show()

 

参考ページ

PyAudioとPyWorldで音声を逐次分析合成しつづけるPythonスクリプト - 備忘録