やってみよう!

プログラミングとかでぃーぷらーにんぐとかVRとか気になったものをやってみる予定

美少女声への道 1

前回、開発環境をDockerで作った

blog.ascreit.com

ので早速ボイスチェンジャーの作成に取り掛かろうと思います。

ピッチやメルケプストラムの抽出とかは難しすぎて訳わからないので、ライブラリを使わせて頂こうと思います。

まず

aidiary.hatenablog.com

こちらを参考に、SPTKを使ってやってみようと思います。 と言っても、python3用に

print "hoge"

print("hoge")

に直すだけで簡単に動いたのでコードは省略!

簡単に使えるのはいいのですが、どうもwavファイルからしか変換できないみたい(やり方あるのかな?)なので、別のライブラリを探します。

マイクの入力から変換してスピーカーで出力することが目標だからrawデータとかで変換できるとありがたいな〜

といことで、Worldという音声解析ライブラリのPython版 PyWorldVocoder を使ってみようと思います

github.com

実装にあたって、こちらのサイトを参考にさせてもらいました。

qiita.com

wavファイルのデータを加工してスピーカーから流す

from scipy.io import wavfile
import pyworld as pw
import numpy as np
import pyaudio

class World:

    def __init__(self):
        # wavから音声データ取得
        WAV_FILE = 'test.wav'
        fs, data = wavfile.read(WAV_FILE)
        print(data.dtype,  data.size,data.shape )


        #声質変換
        data = data.astype(np.float)  # WORLDはfloat前提のコードになっているのでfloat型にしておく
        _f0, t = pw.dio(data, fs)  # 基本周波数の抽出
        f0 = pw.stonemask(data, _f0, t, fs)  # 基本周波数の修正
        sp = pw.cheaptrick(data, f0, t, fs)  # スペクトル包絡の抽出
        ap = pw.d4c(data, f0, t, fs)  # 非周期性指標の抽出
        print(data.shape)
        data = pw.synthesize(f0*2.0, sp, ap, fs)
        print(data.shape)

        # 再生準備
        p = pyaudio.PyAudio()
        for x in range(0, p.get_device_count()):
            device = p.get_device_info_by_index(x)
            if device['name'] =='HDA NVidia: HDMI 1 (hw:1,7)':
                output_device_index = device['index']
        print(output_device_index)
        if(not output_device_index):
            print("device not found")
            exit()
        stream = p.open(format=pyaudio.paInt16,
                        channels=1,
                        rate=fs,
                        output=True,
                        output_device_index=output_device_index)

        # 再生
        stream.write(data.astype(np.dtype('i2')).tobytes());

if __name__ == "__main__":
    spec = World()

dockerで動かす関係上、ホストOSでdefaultになっているデバイスはコンテナ内では使えないみたいです。 (device busyとかになる)

この部分でスピーカーのデバイス名からインデックスを取得してpyaudioのopenの時にindex指定してます。

        for x in range(0, p.get_device_count()):
            device = p.get_device_info_by_index(x)
            if device['name'] =='HDA NVidia: HDMI 1 (hw:1,7)':
                output_device_index = device['index']
        print(output_device_index)

バイス名は

        for x in range(0, p.get_device_count()):
            device = p.get_device_info_by_index(x)
            print(device['name'])

こんな感じで出力してそれっぽいデバイス名の選んでます。

とりあえず、これでwavファイルから音声いじって再生するところまでできました。

次はマイク入力から音声変換!