Created
February 14, 2015 16:50
-
-
Save r9y9/ef3b9e73a7a7e79e7e72 to your computer and use it in GitHub Desktop.
こんな感じでVCできたらいいなぁという設計の例
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
こんな感じでVCできたらいいなぁという設計の例 | |
""" | |
class Analyizer(object): | |
""" | |
音声分析のインタフェース | |
""" | |
def __init__(self): | |
pass | |
def analyze(self, x): | |
raise "Not implemented" | |
class Synthesizer(object): | |
""" | |
音声合成のインタフェース | |
""" | |
def __init__(self): | |
pass | |
def synthesis(self, param): | |
raise "Not implemented" | |
class SpeechParameter(object): | |
""" | |
音声のパラメータ表現 | |
""" | |
def __init__(self, f0, envelope, aperiodicity): | |
self.f0 = f0 | |
self.envelope = envelope | |
self.aperiodicity = aperiodicity | |
class WORLD(Analyzer, Synthesizer): | |
""" | |
WORLDは、分析・合成のどちらもできる | |
""" | |
def __init__(self): | |
__init__(super(self)) | |
def analyze(self, x): | |
""" | |
TODO | |
""" | |
pass | |
def synthesis(self, param): | |
""" | |
TODO | |
""" | |
assert isinstance(param, SpeechParameter) | |
pass | |
class STRAIGHT(Analyzer, Synthesizer): | |
""" | |
STRAIGHTも、分析・合成のどちらもできる | |
(※ただの例) | |
""" | |
def __init__(self): | |
__init__(super(self)) | |
def analyze(self, x): | |
""" | |
TODO | |
""" | |
pass | |
def synthesis(self, param): | |
""" | |
TODO | |
""" | |
assert isinstance(param, SpeechParameter) | |
pass | |
class VoiceConverter(object): | |
""" | |
もろもろよろしくやってくれる、親玉クラス | |
""" | |
def __init__(self, | |
f0_converter=None, | |
envelope_converter=None, | |
aperiodicity_conveter=None, | |
analyzer=WORLD() # デフォはWORLDを使う的な | |
synthesizer=WORLD() # デフォはWORLDを使う的な | |
): | |
self.f0_conveter = f0_converter | |
self.envelope_converter = envelope_converter | |
self.aperiodicity_conveter = aperiodicity_conveter | |
# 分析結果がはいる | |
self.param = None | |
def analyze(self, x): | |
""" | |
音声を分析して、パラメータに分解する | |
""" | |
self.param = engine.analyze(x) | |
def convert(self): | |
""" | |
特徴量の変換をする | |
""" | |
if self.param == None: | |
raise "先にanalyzeを呼べ" | |
pass | |
if self.f0_conveter != None: | |
self.param.f0 = self.f0_converter.convert(self.param.f0) | |
if self.envelope_converter != None: | |
self.param.envelop = self.envelop_converter.convert( | |
self.param.envelop) | |
if self.aperiodicity_converter != None: | |
self.param.aperiodicity = self.aperiodicity_converter.convert( | |
self.param.aperiodicity) | |
def synthesis(self): | |
""" | |
音声を合成する | |
""" | |
if self.param == None: | |
raise "先にanalyzeを呼べ" | |
return synthesizer.synthesis(self.param) | |
class EnvelopeConverter(object): | |
""" | |
スペクトル包絡の変換器の抽象インタフェース | |
すべてのスペクトル包絡変換器はこのクラスを継承すべき的な | |
""" | |
def __init__(self): | |
pass | |
def convert(self, envelop): | |
raise "not implemented" | |
class GMMMap(EnvelopeConverter): | |
""" | |
GMMベースの変換(ダミー) | |
""" | |
def __init__(self, model): | |
self.model = model | |
pass | |
def convert(self, envelop): | |
self.model.convert(envelop) | |
if __name__ == "__main__": | |
from scipy.io import wavfile | |
# 設計: | |
# 1. F0, スペクトル包絡、非周期成分、好きなように変換器を設定できる | |
# 2, 分析エンジンを簡単に切り替えられる | |
# 3. 合成エンジンを切り替えられる | |
# この例だと、スペクトル包絡だけ変換する | |
vc = VoiceConverter(f0_conveter=None, | |
envelope_converter=GMMMap(model="gmm.pkl"), | |
aperiodicity_converter=None, | |
analyzer=STRAIGHT(), | |
synthesizer=WORLD() | |
) | |
fs, x = wavfile.read("音声ファイル") | |
vc.analyze(x) | |
vc.convert() | |
y = vc.synthesis() | |
wavfile.write(y, fs, "出力ファイル") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment