読者です 読者をやめる 読者になる 読者になる

AIプログラムとかUnityゲーム開発について

探索や学習などを活用したAI系ゲームを作りたいと思います。

VOICEROID+結月ゆかりEXを別のアプリから文字列を指定して発話させる

VOICEROIDは他のアプリとの連携機能がいっさいないらしく、
コマンドライン引数が通るかな? と思って試してみたがダメっぽい
他の連携ソフトはどうやら、クリップボード経由でテキストを貼り付けて発話させる連携をしているらしい。

コマンドラインから使えるようなアプリを配布されている方もいらっしゃいますが、おそらく同様にクリップボード経由だと思う。
VoiceroidEx - 忘備録/創作板

話題のニュースを定期的に読み上げさせたりしたいので、このへんの仕組みを自前で実現したいのですが、手順としては以下のようになると思います。

  • クリップボードに発話させたいテキストを貼り付ける
  • VOICEROIDアプリに、「コントロール+V」を送って、ペーストさせる
  • VOICEROIDアプリに、「発話開始」のショートカットキーを送って、ペーストさせる

本来はプロセス番号を取得してプロセス間通信ってことになるんでしょう。
問題は、発話開始のショートカットがない? そもそもプルダウンメニューに発話開始が無く、あくまで人間が手動で「再生」を押すことを想定している?
そんな馬鹿な! というわけで、色々とキーを押しまくって「F5」で発話することを発見。
というわけで、実現しました!

f:id:yasu9780:20160120154730p:plain

プログラムははじめ、smallBasicでやってみようと思ったんですが、プロセス間通信の仕組みがなく、拡張DLLを探して入れてみましたが、getProcessesとstartしか無かったので、もういいやと思って、HSPでやってみました。


流れとしては

  • apiClipSave関数で発話させたい文字列をクリップボードにコピー
  • execでVOICEROIDを起動し(既に起動してるならアクティブになるだけ)
  • keybd_eventでアクティブになってるVOICEROIDに、Ctrl+Vを送る
  • F5を送る

(注意するのは、キーは、押して、離して、の処理をしないと、押しっぱなしになるようです)


HSPによるVOICEROIDに発話させるプログラム

#uselib "user32.dll"
#func keybd_event "keybd_event" int, int, int, int

#define VK_CONTROL 0x11
#define KEYEVENTF_KEYUP 2

#uselib "Kernel32.dll"
    # func lstrcpy                      "lstrcpyA"                      sptr,sptr
    #cfunc GlobalAlloc                  "GlobalAlloc"                   sptr,sptr
    # func GlobalFree                   "GlobalFree"                    sptr
    #cfunc GlobalSize                   "GlobalSize"                    sptr
    #cfunc GlobalLock                   "GlobalLock"                    sptr
    # func GlobalUnlock                 "GlobalUnlock"                  sptr
#uselib "User32.dll"
    #cfunc OpenClipboard                "OpenClipboard"                 sptr
    # func CloseClipboard               "CloseClipboard"
    # func EmptyClipboard               "EmptyClipboard"
    #cfunc GetClipboardData             "GetClipboardData"              sptr
    # func SetClipboardData             "SetClipboardData"              sptr,sptr
    #cfunc IsClipboardFormatAvailable   "IsClipboardFormatAvailable"    sptr

//--------------------------------------
// Win32API関数の記号定数
//--------------------------------------
#const CF_TEXT          (1)
#const GHND             ($0042)
#const GMEM_SHARE       ($2000)
#const VK_F5            (116)

	apiClipSave "こんにちわ"

	exec "C:/Program Files (x86)/AHS/VOICEROID+/YukariEX/VOICEROID"
	wait 100

	// 押す
	keybd_event VK_CONTROL, 0, 0, 0
	keybd_event 'V', 0, 0, 0
	wait 10
	// 離す
	keybd_event 'V', 0, 2, 0
	keybd_event VK_CONTROL, 0, 2, 0
	wait 10

	// 押す
	keybd_event VK_F5, 0, 0, 0
	wait 10
	// 離す
	keybd_event VK_F5, 0, 2, 0

stop

//--------------------------------------
// クリップボードにテキストを設定
//--------------------------------------
#deffunc apiClipSave str _text_,\
    local hMem,\
    local nSize,\
    local pBuff,\
    local dupStr
    
    nSize=strlen(_text_)+1
    hMem=GlobalAlloc(GHND|GMEM_SHARE,nSize):if(hMem){
        pBuff=GlobalLock(hMem)
        ;文字列型のクローン変数作成
        dupptr dupStr,pBuff,nSize,2
        dupStr=_text_
        GlobalUnlock hMem
        
        if OpenClipboard(hWnd){
            EmptyClipboard
            SetClipboardData CF_TEXT,hMem
            CloseClipboard
            return 1
        }
        GlobalFree hMem
    }
return 0

このへんを参考にさせて頂きました
使いやすいオブジェクト・エディタを紹介して欲しい - HSPTV!掲示板