質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Python 2.7

Python 2.7は2.xシリーズでは最後のメジャーバージョンです。Python3.1にある機能の多くが含まれています。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

658閲覧

OpenJtalkを並列化したいので既存コードを書き直したが,動かない

退会済みユーザー

退会済みユーザー

総合スコア0

Python 2.7

Python 2.7は2.xシリーズでは最後のメジャーバージョンです。Python3.1にある機能の多くが含まれています。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2017/12/29 08:30

###前提・実現したいこと
Raspberry PiでOpenJtalkを動かしたのですが,おそすぎるため,調べたところ,文を句読点ごとに区切り,それぞれ処理を並列化し
最終的に再生することで高速化を図るというものがありました
ただし,いちいちテキストファイルにしなければならないので
これをPythonのモジュールにしようと思い,
テキストを受取るようクラスにしてみましたが,なぜかずっと"音声合成の完了待ちです"となってしまい,
処理が終わりません(Python3.5)

少し調査すると,下の""正常に動くコード""はPython2.7ならばうまくいくようで,python3.5だと音声合成の完了待ちです,がずっと続き同じようになります
おそらく互換性がないのか,それ以上はわたしの知識ではわかりませんでした

""ずっと"音声合成の完了待ちです"""のコードはpython2.7,python3.5でもどちらも動きませんでした
###該当のソースコード

Python

1######################ずっと"音声合成の完了待ちです"となる(Python2.7,Python3.5どちらも音声合成中になる) 2class OutSpeak(): 3 # デバッグフラグ 4 DEBUG = True 5 6 # 音声合成の同時処理数 7 MAX_PROCESS = 3 8 9 # open_jtalkコマンドの場所 10 JTALK = '/usr/bin/open_jtalk' 11 12 # aplayコマンドの場所 13 APLAY = '/usr/bin/aplay' 14 15 # 辞書ディレクトリ 16 DICDIR = "/var/lib/mecab/dic/open-jtalk/naist-jdic" 17 18 # 音声ファイル 19 # VOICE = '/home/pi/openjtalk/hts_voice/nitech_jp_atr503_m001.htsvoice' 20 # VOICE = '/home/pi/openjtalk/hts_voice/omoine_ikuru.htsvoice' 21 # VOICE = '/home/pi/openjtalk/hts_voice/syane_homu.htsvoice' 22 # VOICE = '/home/pi/openjtalk/hts_voice/suranki.htsvoice' 23 VOICE = '/home/pi/OpenJtalk/mei_normal.htsvoice' 24 # VOICE = '/home/pi/openjtalk/hts_voice/mei_happy.htsvoice' 25 26 # 話す速度(標準 1.0。0.0以上の値を指定) 27 SPEED = 1.0 28 29 # additional half-tone 30 TONE = 2.0 31 32 # ボリューム 33 VOLUME = 10.0 34 35 alltext="" 36 37 # 作業ディレクトリ 38 WORKDIR = "/home/pi/" 39 40 def _print(self,message): 41 if self.DEBUG: 42 print(message) 43 44 # 音声合成を実行する 45 # 46 def create_wav(self,t): 47 import subprocess 48 self._print("DEBUG: 音声作成開始[%d:%s]" % (t[0], t[1])) 49 # サブプロセス呼び出し 50 outfile = self.WORKDIR + "talk%02d.wav" % t[0] 51 # -g という引数はエラーが出るので削除 52 c = subprocess.Popen( 53 [self.JTALK, '-x', self.DICDIR, '-m', self.VOICE, '-ow', outfile, '-r', str(self.SPEED), '-fm', str(self.TONE)], stdin=subprocess.PIPE) 54 # 音声合成するテキストを入力 55 c.stdin.write(t[1]) 56 # 終了を待つ 57 c.stdin.close() 58 c.wait() 59 self._print("DEBUG: 音声作成終了[%d:%s]" % (t[0], t[1])) 60 t[2].put(t[0]) 61 return c.returncode 62 63 def play_wav(self,listindex): 64 65 66 import subprocess 67 command = list() 68 command.append(self.APLAY) 69 command.append('-q') 70 for index in listindex: 71 command.append(self.WORKDIR + "talk%02d.wav" % index) 72 return subprocess.Popen(command) 73 74 def Speak(self,text): 75 76 77 self.alltext=text 78 import re,time 79 from multiprocessing import Pool, Manager 80 queue = Manager().Queue() 81 82 # テキストを短文に分割。テキストに連番を振ってリストにしておく。 83 index = 0 84 arg = list() 85 #alltextに "." ","が含まれていたらそれを日本語の句読点に変換 86 self.alltext.replace(".","。") 87 self.alltext.replace(",","、") 88 shorttext = re.split(r'、|。', self.alltext) 89 for s in shorttext: 90 if s != "": 91 arg.append((index, s, queue)) 92 index += 1 93 self._print("DEBUG: %d個に分割しました。" % len(arg)) 94 # プロセスプールを作成 95 p = Pool(self.MAX_PROCESS) 96 97 # 音声合成を開始 98 r = p.map_async(self.create_wav, arg) 99 100 # 音声合成の進捗リスト。0は未完了、1は音声合成済み。 101 l = [0 for i in range(len(arg))] 102 103 # 終端の判断のため-1を付加。 104 l.append(-1) 105 106 nowplaying = -1 107 108 # 現在再生中のaplayコマンドのProcess 109 playing = None 110 111 # 進捗を確認しつつ音声を読み上げる 112 while (not r.ready()) or (nowplaying != len(arg)) or (playing is not None): 113 time.sleep(0.5) 114 # 音声合成の終了報告があるかキューを確認する。 115 for _ in range(queue.qsize()): 116 compiled_index = queue.get() 117 l[compiled_index] = 1 118 # 再生できるならしてみる? 119 if nowplaying < len(arg): 120 if playing is None: 121 if l[nowplaying + 1] == 1: 122 # まとめてWAVファイルを指定できるときはする 123 listindex = list() 124 while l[nowplaying + 1] == 1: 125 nowplaying += 1 126 listindex.append(nowplaying) 127 self._print("DEBUG: しゃべるよ![%s]" % str(listindex)) 128 playing = self.play_wav(listindex) 129 elif l[nowplaying + 1] == 0: 130 self._print("DEBUG: 音声合成の完了待ちです!") 131 else: 132 exit() 133 else: 134 if playing.poll() is not None: 135 playing = None

Python

1#######################正常に動くコード(Python3.5ではずっと音声合成中になる) 2# coding: UTF-8 3import sys 4import subprocess 5import re 6import time 7from multiprocessing import Pool, Manager 8 9# デバッグフラグ 10DEBUG = True 11 12# 音声合成の同時処理数 13MAX_PROCESS = 3 14 15# open_jtalkコマンドの場所 16JTALK = '/usr/bin/open_jtalk' 17 18# aplayコマンドの場所 19APLAY = '/usr/bin/aplay' 20 21# 辞書ディレクトリ 22DICDIR = "/var/lib/mecab/dic/open-jtalk/naist-jdic" 23 24# 音声ファイル 25# VOICE = '/home/pi/openjtalk/hts_voice/nitech_jp_atr503_m001.htsvoice' 26# VOICE = '/home/pi/openjtalk/hts_voice/omoine_ikuru.htsvoice' 27# VOICE = '/home/pi/openjtalk/hts_voice/syane_homu.htsvoice' 28# VOICE = '/home/pi/openjtalk/hts_voice/suranki.htsvoice' 29VOICE = '/home/pi/OpenJtalk/mei_normal.htsvoice' 30# VOICE = '/home/pi/openjtalk/hts_voice/mei_happy.htsvoice' 31 32# 話す速度(標準 1.0。0.0以上の値を指定) 33SPEED = 1.0 34 35# additional half-tone 36TONE = 2.0 37 38# ボリューム 39VOLUME = 10.0 40 41# 作業ディレクトリ 42WORKDIR = "/home/pi/" 43 44 45def _print(message): 46 if DEBUG: 47 print(message) 48 49 50# 51# 音声合成を実行する 52# 53def create_wav(t): 54 _print("DEBUG: 音声作成開始[%d:%s]" % (t[0], t[1])) 55 # サブプロセス呼び出し 56 outfile = WORKDIR + "talk%02d.wav" % t[0] 57 c = subprocess.Popen( 58 [JTALK, '-x', DICDIR, '-m', VOICE, '-ow', outfile, '-r', str(SPEED), '-fm', str(TONE)], stdin=subprocess.PIPE) 59 # 音声合成するテキストを入力 60 c.stdin.write(t[1]) 61 # 終了を待つ 62 c.stdin.close() 63 c.wait() 64 _print("DEBUG: 音声作成終了[%d:%s]" % (t[0], t[1])) 65 t[2].put(t[0]) 66 return c.returncode 67 68 69# 70# 音声を(複数まとめて)再生する 71# 72def play_wav(listindex): 73 command = list() 74 command.append(APLAY) 75 command.append('-q') 76 for index in listindex: 77 command.append(WORKDIR + "talk%02d.wav" % index) 78 return subprocess.Popen(command) 79 80 81####################################### 82# 入力 83####################################### 84# 引数を取り込み 85argvs = sys.argv 86 87# 簡単な引数チェック 88if (len(argvs) != 2): 89 print 90 'Usage: # %s textfile' % argvs[0] 91 exit(1) 92 93# 指定されたファイルを読み込み 94alltext = "" 95for line in open(argvs[1]): 96 alltext += line.rstrip() 97 98# 音声合成の進捗を確認するためのキューを作成 99queue = Manager().Queue() 100 101# テキストを短文に分割。テキストに連番を振ってリストにしておく。 102index = 0 103arg = list() 104shorttext = re.split(r'、|。', alltext) 105for s in shorttext: 106 if s != "": 107 arg.append((index, s, queue)) 108 index += 1 109_print("DEBUG: %d個に分割しました。" % len(arg)) 110 111####################################### 112# 合成 113####################################### 114# プロセスプールを作成 115p = Pool(MAX_PROCESS) 116 117# 音声合成を開始 118r = p.map_async(create_wav, arg) 119 120# 音声合成の進捗リスト。0は未完了、1は音声合成済み。 121l = [0 for i in range(len(arg))] 122 123# 終端の判断のため-1を付加。 124l.append(-1) 125 126####################################### 127# 再生 128####################################### 129# 現在再生中の音声のインデックス 130nowplaying = -1 131 132# 現在再生中のaplayコマンドのProcess 133playing = None 134 135# 進捗を確認しつつ音声を読み上げる 136while (not r.ready()) or (nowplaying != len(arg)) or (playing is not None): 137 time.sleep(0.5) 138 # 音声合成の終了報告があるかキューを確認する。 139 for _ in range(queue.qsize()): 140 compiled_index = queue.get() 141 l[compiled_index] = 1 142 # 再生できるならしてみる? 143 if nowplaying < len(arg): 144 if playing is None: 145 if l[nowplaying + 1] == 1: 146 # まとめてWAVファイルを指定できるときはする 147 listindex = list() 148 while l[nowplaying + 1] == 1: 149 nowplaying += 1 150 listindex.append(nowplaying) 151 _print("DEBUG: しゃべるよ![%s]" % str(listindex)) 152 playing = play_wav(listindex) 153 elif l[nowplaying + 1] == 0: 154 _print("DEBUG: 音声合成の完了待ちです!") 155 else: 156 exit() 157 else: 158 if playing.poll() is not None: 159 playing = None

###補足情報(言語/FW/ツール等のバージョンなど)
参考サイト:
http://windvoice.hatenablog.jp/entry/2015/02/22/165457
Raspberry Pi 2 stretch

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

引数に文字列を入れることで"擬似的に"(システムコールによって)
呼び出すことにしました
IOアクセスによるオーバヘッドは少なくなると思います

投稿2017/12/30 09:08

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問