知らないことを調べるブログ

映画の分からないところを調べてまとめる場所にしていきます。

フォルダにある全てのtxtを音声合成mp3にするPythonコード(open-jtalk)

 教科書の復習に音声合成がべんり。Windowsではsoftalkを使っていた。でも、Linuxで使えるソフトがぱっと見つからない。なのでPythonで作った。open-jtalkを使った。

jtalk.py

# -*- coding: utf-8 -*-
u"""フォルダにある全てのtxtを音声合成mp3にする."""
import subprocess
from pydub import AudioSegment
import glob
import os


def jtalk(i, t, n):
    u"""
    日本語テキストから音声合成wavファイルを生成.

    via http://qiita.com/kkoba84/items/b828229c374a249965a9.
    """
    open_jtalk = ['open_jtalk']
    mech = ['-x', '/var/lib/mecab/dic/open-jtalk/naist-jdic']
    htsvoice = ['-m', '/usr/share/hts-voice/mei/mei_normal.htsvoice']
    # 再生速度
    speed = ['-r', '1.3']
    outwav = ['-ow', n + '-' + str(i) + '.wav']
    cmd = open_jtalk + mech + htsvoice + speed + outwav
    c = subprocess.Popen(cmd, stdin=subprocess.PIPE)
    c.stdin.write(t)
    c.stdin.close()
    c.wait()
    # aplay = ['aplay', '-q', 'open_jtalk.wav']
    # wr = subprocess.Popen(aplay)


def text2jtalk():
    u"""フォルダにある全てのtxtを音声合成mp3にする."""
    # フォルダ内にあるtxtの名前をリストにする
    textlist = glob.glob('*.txt')
    for text in textlist:
        n = text.rstrip('.txt')
        # openjtalkは1024バイトまでしか一度に処理できないので、改行で区切る
        ts = open(text, 'r').read().split('\n')
        ts = filter(lambda s: s != '', ts)
        for i, t in enumerate(ts):
            jtalk(i, t, n)
        # 区切って生成したwavを結合する
        s = AudioSegment.from_wav(n + '-0.wav')
        os.remove(n + '-0.wav')
        for i in xrange(len(ts) - 1):
            s += AudioSegment.from_wav(n + '-' + str(i + 1) + '.wav')
            os.remove(n + '-' + str(i + 1) + '.wav')
        # mp3で書き出す
        s.export(n + '.mp3', format='mp3')
        print n + '.mp3'


if __name__ == '__main__':
    text2jtalk()

ほげほげ.txt

今日はいい天気ですね。
ほげー

にゃーん.txt

にゃわわ・・・

 上記3ファイルを同一ディレクトリに配置してjtalk.pyをビルドすると、ほげほげ.mp3とにゃーん.mp3が生成される。


 open-jtalkは、テキストのうち1024バイトまでで処理が止まるようにデフォルトで制限されている。なので、文章を改行で区切って複数個音声を作って、最後にpydubで結合することで対処した。なので改行されずに300文字ちょっと続くとトリミングが起こる。エラーは出ない。適度に改行しよう。

 固定長で300文字ずつ区切ればいいんだけど、Pythonでマルチバイト文字をカウントする方法がわからない。しょうがない。

 ちなみに、open-jtalkはCで書かれたソースファイルの定数に1024と書かれているらしい。それを書き換えればいけるとネットで見た(参考1)。でも、apt-getでインストールしたときどこにソースファイルがあるのかわからない。apt-fileで探しても、

apt-file search open_jtalk
open-jtalk: /usr/bin/open_jtalk
open-jtalk: /usr/share/man/man1/open_jtalk.1.gz

アーカイブの場所しか表示されない。ソースファイルはどこにあるの?

参考1 openJTalkを10.6にインストール(1) « こざくらラボ