Ticket #33823

「すべて読み上げ」で改行をまたぐ単語を適切に読み上げない

Open Date: 2014-05-19 09:34 Last Update: 2016-08-24 11:09

Reporter: nishimoto Owner: nishimoto
Type: Feature Requests Status: Closed
Component: 音声合成 MileStone: 2016.3jp (closed)
Priority: 5 - Medium Severity: 5 - Medium
Resolution: Accepted

Details

「すべて読み上げ」で改行をまたぐ単語を適切に読み上げない問題について、 過去に話し合った記憶はありますがチケットがないようなので、作っておきます。

状況としては以下のように改行がはいった場合の読み上げです:

NVDAは、コミュニティーの援
助によりNV Accessが開発しました。

「こみゅにてぃーのえん」「すけにより」 のように1行目の行末と2行目の行頭の単語がつながりません。

ただし、書式設定で「行番号」を通知するようにしてメモ帳で読み上げると、

「ぎょういち こみゅにてぃーのえん」
「ぎょうに すけにより」

のような読み上げになります。

この場合、行1の最後と行2の最初のどちらかで「えんじょ」と読ませてしまってよいのか?

あらゆる条件で破綻がないように実装をするには工夫が必要と思います。

Attachment File List

No attachments

Ticket History (3/17 Histories)

2014-05-19 09:34 Updated by: nishimoto
  • New Ticket "「すべて読み上げ」で改行をまたぐ単語を適切に読み上げない" created
2015-07-12 23:39 Updated by: nishimoto
Comment

ひさしぶりにこの件を確認していますが、 この現象はスペースで単語を区切らない日本語のような言語に固有の問題で、 少なくとも英語については下記で対応済みと思われます。

Say all without unnatural pauses

http://community.nvda-project.org/ticket/149

http://community.nvda-project.org/changeset/e13e64af10d6708413d3b4c87365bb382502c8a5

2015-07-12 23:54 Updated by: nishimoto
Comment

speech.py の re_last_pause の動作を調べる実験:

--- a/source/speech.py
+++ b/source/speech.py
@@ -1555,9 +1555,11 @@ def speakWithoutPauses(speechSequence,detectBreaks=True):
                for index in xrange(len(speechSequence)-1,-1,-1):
                        item=speechSequence[index]
                        if isinstance(item,basestring):
+                               log.info("re_last_pause matching(%s)" % item)
                                m=re_last_pause.match(item)
                                if m:
                                        before,after=m.groups()
+                                       log.info("re_last_pause(%s)(%s)" % (before, after))
                                        if after:
                                                pendingSpeechSequence.append(after)
                                        if before:

読み上げるテキスト

NVDAは、コミュニティーの援
助によりNV Accessが開発しました。

It is
a fine day.

It is?
a fine day.

It is 
another fine day. Is it
really fine day?

ログ

INFO - speech.speakWithoutPauses (23:47:02):
re_last_pause matching(NVDAは、コミュニティーの援

)
INFO - speech.speakWithoutPauses (23:47:02):
re_last_pause matching(助によりNV Accessが開発しました。

)
INFO - speech.speakWithoutPauses (23:47:02):
re_last_pause matching(It is

)
INFO - speech.speakWithoutPauses (23:47:02):
re_last_pause matching(a fine day.

)
INFO - speech.speakWithoutPauses (23:47:02):
re_last_pause(a fine day.

)()
INFO - speech.speakWithoutPauses (23:47:02):
re_last_pause matching(It is?

)
INFO - speech.speakWithoutPauses (23:47:02):
re_last_pause(It is?

)()
INFO - speech.speakWithoutPauses (23:47:02):
re_last_pause matching(a fine day.

)
INFO - speech.speakWithoutPauses (23:47:02):
re_last_pause(a fine day.

)()

INFO - speech.speakWithoutPauses (23:48:47):
re_last_pause matching(It is 

)
INFO - speech.speakWithoutPauses (23:48:47):
re_last_pause matching(another fine day. Is it

)
INFO - speech.speakWithoutPauses (23:48:47):
re_last_pause(another fine day. )(Is it

)
INFO - speech.speakWithoutPauses (23:48:47):
re_last_pause matching(really fine day?

)
INFO - speech.speakWithoutPauses (23:48:47):
re_last_pause(really fine day?

)()
2015-07-13 00:10 Updated by: nishimoto
Comment

仮に全角マルを re_last_pause に追加しても、音声エンジンには下記のようにコマンドが送られており、 IndexCommand で分割されるために、うまく単語がつながらない。

実は英語に関してもコマンドを実行するタイミングをまとめているだけで、文字列はちゃんとセンテンスごとに結合されていない。

IO - speech.speak (00:04:57):
Speaking [IndexCommand(1), IndexCommand(2), LangChangeCommand ('ja'), u'NVDAは、コミュニティーの援', IndexCommand(3), u'助によりNV Accessが開発しました。']
INFO - speech.speakWithoutPauses (00:04:57):
re_last_pause matching(It is)
INFO - speech.speakWithoutPauses (00:04:57):
re_last_pause matching(a fine day.)
INFO - speech.speakWithoutPauses (00:04:57):
re_last_pause(a fine day.)()
IO - speech.speak (00:04:57):
Speaking [IndexCommand(4), IndexCommand(5), LangChangeCommand ('ja'), u'It is', IndexCommand(6), u'a fine day.']
INFO - speech.speakWithoutPauses (00:04:57):
re_last_pause matching(It is?)
INFO - speech.speakWithoutPauses (00:04:57):
re_last_pause(It is?)()
IO - speech.speak (00:04:57):
Speaking [IndexCommand(7), IndexCommand(8), LangChangeCommand ('ja'), u'It is?']
INFO - speech.speakWithoutPauses (00:04:57):
re_last_pause matching(a fine day.)
INFO - speech.speakWithoutPauses (00:04:57):
re_last_pause(a fine day.)()
IO - speech.speak (00:04:57):
Speaking [IndexCommand(9), LangChangeCommand ('ja'), u'a fine day.']
INFO - speech.speakWithoutPauses (00:04:57):
re_last_pause matching(It is)
INFO - speech.speakWithoutPauses (00:04:59):
re_last_pause matching(another fine day. Is it)
INFO - speech.speakWithoutPauses (00:04:59):
re_last_pause(another fine day. )(Is it)
IO - speech.speak (00:04:59):
Speaking [IndexCommand(10), IndexCommand(11), LangChangeCommand ('ja'), u'It is', IndexCommand(12), u'another fine day. ']
INFO - speech.speakWithoutPauses (00:04:59):
re_last_pause matching(really find day?)
INFO - speech.speakWithoutPauses (00:04:59):
re_last_pause(really find day?)()
IO - speech.speak (00:04:59):
Speaking [LangChangeCommand ('ja'), u'Is it', IndexCommand(13), u'really find day?']
2015-07-13 11:15 Updated by: nishimoto
  • Milestone Update from (None) to 2015.3jp (closed)
  • Owner Update from (None) to nishimoto
  • Resolution Update from None to Accepted
  • Component Update from (None) to 音声合成
Comment

finalSpeechSequence を後処理で加工する方法を思いついたので実装してみた:

To git@github.com:nvdajp/nvdajp.git
 * [new branch]      ti33823 -> ti33823
2015-07-13 11:21 Updated by: nishimoto
Comment

書式設定で「行番号」を読み上げる場合はどうしても単語が繋がらないので、 現状ではサポート対象外とします。

2015-07-31 21:22 Updated by: nishimoto
Comment

アドオンマネージャーから「アドオンを入手」で Firefox が開いてコミュニティアドオンの ページが読み上げられるときに下記のエラーが出ている:

ERROR - queueHandler.pumpAll (21:20:38):
error in generator 4
Traceback (most recent call last):
  File "queueHandler.pyo", line 72, in pumpAll
  File "sayAllHandler.pyo", line 128, in readTextHelper_generator
  File "speech.pyo", line 1016, in speakTextInfo
  File "speech.pyo", line 1538, in speakWithoutPauses
  File "speech.pyo", line 1596, in speakWithoutPauses
IndexError: string index out of range
2015-07-31 23:07 Updated by: nishimoto
  • Resolution Update from Accepted to Fixed
Comment

正式な nvda_2015.3jp-beta-150731.exe で修正される予定です。

2015-08-02 08:47 Updated by: nishimoto
Comment

NVDA 2015.3jp-beta-150731

メイン ランドマーク見出し  レベル2

リスト 5項目リンク活動報告書

should be separated such as:

メイン ランドマーク 見出し  レベル2

リスト 5項目 リンク 活動報告書
2015-08-02 16:52 Updated by: nishimoto
Comment

Firefox や IE で「リンク」「リストの外」などが直後のコンテンツとつながって読み上げられてしまう問題への暫定的な対策:

To git@github.com:nvdajp/nvdajp.git
   8586017..5909fea  ti33823 -> ti33823
2015-08-20 13:08 Updated by: nishimoto
  • Ticket Close date is changed to 2015-08-20 13:08
  • Status Update from Open to Closed
2015-10-28 12:34 Updated by: nishimoto
  • Milestone Update from 2015.3jp (closed) to (None)
  • Status Update from Closed to Open
  • Resolution Update from Fixed to None
Comment

以下のサイトを読ませたときに、本文の途中にあるリンクが不適切な順番で 読み上げられるという報告がありました。

http://www.mitsue.co.jp/knowledge/blog/a11y/201510/26_2100.html

確認したところ、本件の実装の不備であると分かったので、 いったんこの処理を無効化したいと思います。

2016-06-23 16:16 Updated by: nishimoto
Comment

2016.3jp に向けてもういちど実装してみる:

https://github.com/nvdajp/nvdajp/issues/8

2016-06-24 21:10 Updated by: nishimoto
  • Resolution Update from None to Fixed
Comment

jpbeta160624 で本件の新しい実装をマージしました。

Firefox で Web ページを読み上げるときに不具合がないこと、 「リンク」などロールの名前とコンテンツが不適切に繋がらないこと、 書式情報で「行番号の報告」をチェックにした場合も行番号とコンテンツが不適切に繋がらないこと、 メモ帳とワードパッドでだいたい期待通りに改行をはさんだ文字列をつないで読み上げること、 などの確認をしていますが、あまり綺麗な実装ではありません。

特定の状況(例えば全角カタカナの単語の途中で改行された場合など)の接続ができない、 という制約も残っています。

どうしても解決できない不具合がでてきたら、 オプションで今回の処理を無効化できるようにしたいと思います。

2016-07-09 19:50 Updated by: nishimoto
Comment

以下のような状況で 「スク」「リーンリーダー」 「コンピュ」「ーター」 をつないで読むことができていない。

オペレーティングシステム用の無料でオープンソースのスク
リーンリーダーです。 NVDAによって視覚障害者は、合成音
声や点字によるフィードバックを通して、Windowsコンピュ
ーターを晴眼者と同じコストで使えるようになります。

後者はルール(ひらがなまたはカタカナと、改行直後の長音記号)を 追加して次のベータ版で改善予定。 前者は(別の状況で副作用があるので)このままとする。

2016-08-10 18:10 Updated by: nishimoto
  • Resolution Update from Fixed to Accepted
Comment

Windows 10 x64 + Internet Explorer 11 で下記のエラーが出る場合がある:

INFO - __main__ (16:53:05):
Starting NVDA
INFO - core.main (16:53:09):
Config dir: C:\Users\nishimotz\AppData\Roaming\nvda
INFO - core.main (16:53:11):
NVDA version 2016.3jp-beta-160810
INFO - core.main (16:53:11):
Using Windows version 10.0.14393 workstation
INFO - core.main (16:53:11):
Using Python version 2.7.12 (v2.7.12:d33e0cf91556, Jun 27 2016, 15:19:22) [MSC v.1500 32 bit (Intel)]
INFO - core.main (16:53:11):
Using comtypes version 0.6.2
INFO - synthDrivers.jtalk.mecab.Mecab_initialize (16:53:16):
dic: C:\Program Files (x86)\NVDA\synthDrivers\jtalk\dic
INFO - synthDrivers.jtalk.mecab.Mecab_initialize (16:53:16):
mecab:0.996 nvdajp-jtalk-dic (utf-8) 20160810-071901
INFO - synthDrivers.jtalk.jtalkDriver.initialize (16:53:17):
loaded C:\Program Files (x86)\NVDA\synthDrivers\jtalk\mei\mei_happy.htsvoice
INFO - synthDriverHandler.setSynth (16:53:17):
Loaded synthDriver nvdajp_jtalk
INFO - core.main (16:53:17):
Using wx version 3.0.2.0 msw (classic)
INFO - braille.initialize (16:53:17):
Using liblouis version 2.6.5
INFO - braille.BrailleHandler.setDisplayByName (16:53:17):
Loaded braille display driver noBraille, current display has 0 cells.
INFO - brailleInput.initialize (16:53:17):
Braille input initialized
WARNING - core.main (16:53:18):
Java Access Bridge not available
INFO - _UIAHandler.UIAHandler.MTAThreadFunc (16:53:18):
UIAutomation: IUIAutomation3
INFO - core.main (16:53:18):
NVDA initialized
INFO - config.ConfigManager.save (16:54:39):
Base configuration saved
INFO - synthDrivers.jtalk.jtalkDriver.initialize (16:57:16):
loaded C:\Program Files (x86)\NVDA\synthDrivers\jtalk\mei\mei_happy.htsvoice
INFO - synthDriverHandler.setSynth (16:57:16):
Loaded synthDriver nvdajp_jtalk
INFO - synthDrivers.jtalk.jtalkDriver.initialize (16:57:28):
loaded C:\Program Files (x86)\NVDA\synthDrivers\jtalk\lite\voice.htsvoice
INFO - config.ConfigManager.save (16:57:48):
Base configuration saved
ERROR - queueHandler.pumpAll (17:04:10):
error in generator 23
Traceback (most recent call last):
  File "queueHandler.pyo", line 72, in pumpAll
  File "sayAllHandler.pyo", line 123, in readTextHelper_generator
  File "textInfos\offsets.pyo", line 446, in move
  File "virtualBuffers\__init__.pyo", line 214, in _getStoryLength
WindowsError: [Error 1775] リモート プロシージャ コール中にクライアントからホストに NULL コンテキスト ハンドルが渡されました。
INFO - config.ConfigManager.save (17:15:30):
Base configuration saved
ERROR - queueHandler.pumpAll (17:17:58):
error in generator 57
Traceback (most recent call last):
  File "queueHandler.pyo", line 72, in pumpAll
  File "sayAllHandler.pyo", line 149, in readTextHelper_generator
  File "treeInterceptorHandler.pyo", line 143, in makeTextInfo
  File "virtualBuffers\__init__.pyo", line 196, in __init__
  File "textInfos\offsets.pyo", line 311, in __init__
  File "virtualBuffers\__init__.pyo", line 214, in _getStoryLength
WindowsError: [Error 1775] リモート プロシージャ コール中にクライアントからホストに NULL コンテキスト ハンドルが渡されました。
2016-08-24 11:09 Updated by: nishimoto
  • Ticket Close date is changed to 2016-08-24 11:09
  • Status Update from Open to Closed

Edit

Please login to add comment to this ticket » Login