Pyworldは音声を基本周波数、スペクトログラム、非周期成分に分解、再合成できる。
基本周波数の抽出にはharvestとdioがある。harvestの方がノイズが少ない感じ。
分解
from scipy.io import wavfile
import pyworld
import numpy as np
WAV_FILE = 'Tomo.wav'
fs, data = wavfile.read(WAV_FILE)
data = data.astype(np.float) # Floatに変換が必要
_f0, t = pyworld.harvest(data, fs) # 基本周波数の抽出
f0 = pyworld.stonemask(data, _f0, t, fs) # 基本周波数の修正
sp = pyworld.cheaptrick(data, f0, t, fs) # スペクトル包絡の抽出
ap = pyworld.d4c(data, f0, t, fs) # 非周期性指標の抽出
再合成
synthesized = pyworld.synthesize(f0, sp, ap, fs)
Example
import librosa
import pyworld as pw
import numpy as np
import sounddevice as sd
import matplotlib.pyplot as plt
import pysptk
import pyworld
from pysptk.conversion import sp2mc, mc2sp
def Play(y, sr=16000):
sd.play(y, sr)
sd.wait()
WAV_FILE = 'Tomo.wav'
SR = 16000
fft_size = pyworld.get_cheaptrick_fft_size(SR)
alpha = pysptk.util.mcepalpha(SR)
mgc_dim = 180
data, sr = librosa.load(WAV_FILE, sr=SR, duration=100000)
data = data.astype(np.float)
def Encode(data, sr=SR):
_f0, t = pyworld.harvest(data, sr) # 基本周波数の抽出
f0 = pyworld.stonemask(data, _f0, t, sr) # 基本周波数の修正
sp = pyworld.cheaptrick(data, f0, t, sr) # スペクトル包絡の抽出
ap = pyworld.d4c(data, f0, t, sr) # 非周期性指標の抽出
mc = sp2mc(sp, mgc_dim, alpha)
cap = pyworld.code_aperiodicity(ap, sr)
f = f0 / 512
return mc, cap, f
def Decode(mc, cap, f, sr=SR):
f0 = f * 512
ap = pyworld.decode_aperiodicity(cap, sr, fft_size)
sp = mc2sp(mc, alpha, fft_size)
synthesized = pw.synthesize(f0 , sp, ap, sr)
return synthesized, f0, sp, ap
mc, cap, f = Encode(data)
synthesized, f0, sp, ap = Decode(mc, cap, f)
Play(synthesized, SR)
plt.imshow(np.log(sp))
plt.colorbar()
plt.show()