努力したWiki

推敲の足りないメモ書き多数

ユーザ用ツール

サイト用ツール


documents:voiceroid:voiceroid-001

VOICEROID+EXを制御するDLL

2017/12/18

  • クリップボード操作での指摘を頂き、APIパラメタに制御用引数追加。

2017/08/16

  • VOICEROID操作部分をDLLに分離したので、専用ページに分割。

注意

■公開しているDLLを利用する事自体は問題ありませんが、ご自身のアプリに同梱して配布するような事は許可しておりません。
同梱したい場合はその旨ご連絡を頂ければ確認後に回答させていただきます。

■ご自身で作成するアプリケーションの参考にソースの参照を行っていただくのは構いませんしそのように利用してもらう事を意図しています。
ですが、そのままコピーしてロジックはそのままにクラス名称やメソッド名称を一部替えただけのソースで「オリジナルライブラリである」と言い張るのはやめてください。
例: http://www.nicovideo.jp/watch/sm32503951 →  http://www.nicovideo.jp/watch/sm32553816

■公開しているDLL、ソースコードを「すまーときりたん」で使用する事はご遠慮ください。
誠に恐れ入りますが、激しい力技を使っていないスマートなライブラリで代替いただきますようお願いいたします。

概要

echoseika.exeseikaserver.exe で使っているDLLのソース公開Wikiページを新たに作りました。

起動しているVOICEROIDにウインドウメッセージでテキストを送り、発声させたり、音声データを保存させたり、ができます。
元のページは、VOICEROID操作方法ロジック公開の意味がありました。
ですが、さすがに余分なコードの量が増えてきて見辛くなってしまったので、新たにページを起こすことにしました。

DLLダウンロード

echoSeikAPI.dll 2017/12/18公開。指摘があったクリップボード操作時のText形式を選択可能にした。
echoSeikAPI.dll 2017/12/16公開。廃止予定API削除と整理。
echoSeikAPI.dll 2017/09/11公開 ※“音街ウナTalk Ex”サポートコードの追加。Google本屋君はこちらのDLLをお使いください。

DLLの使用例

元の echoseika.exe 公開版ソースからVOICEROID制御部分をDLLに分離しました。
DLLはWindows 10 Pro 64bit版 + .NET Framework 4.5.2環境でコンパイルされています。

2017/12/18公開版での記述を以下に示します。

以下は VOICEROID+京町セイカ EX を発声させる最少コードです。

sample.cs
using System;
using echoSeikaAPI;
 
namespace sample
{
    class Program
    {
        static void Main()
        {
            vRoidController vRoidControl = new vRoidController();            // DLLのVOICEROIDコントローラオブジェクト生成
            vRoidControl.Register_vRoid(vRoidAvator.SEIKA);                  // VOICEROID+京町セイカ EXを実行対象に登録
            vRoidControl.Play(vRoidAvator.SEIKA, "暑い日が続きますね");        // VOICEROID+京町セイカ EX 発声
        }
    }
}

vRoidControllerクラスのインスタンスを作成し、操作対象のVOICEROIDを登録します。登録されたVOICEROIDに対してアクションを指定します。

2107/12/18 追記
もしテキストが文字化けしてVOICEROIDに貼り付けされてしまう場合、以下のようにコードを変更してみてください。解消する可能性があります。

sample.cs
using System;
using echoSeikaAPI;
 
namespace sample
{
    class Program
    {
        static void Main()
        {
            vRoidController vRoidControl = new vRoidController();                // DLLのVOICEROIDコントローラオブジェクト生成
            vRoidControl.Register_vRoid(vRoidAvator.SEIKA);                      // VOICEROID+京町セイカ EXを実行対象に登録
            vRoidControl.Play(vRoidAvator.SEIKA, "暑い日が続きますね", true);      // VOICEROID+京町セイカ EX 発声
        }
    }
}

DLLの説明

現在以下のエントリが公開されています。

public bool isRegistered_vRoid(vRoidAvator cv);                        // VOICEROIDがコントローラ登録済みか確認する
public bool isAlive_vRoid(vRoidAvator cv);                            // VOICEROIDがメモリに存在しているか確認する
public bool isAvailable_vRoid_VoiceEffect(vRoidAvator cv);             // VOICEROIDの音声効果が利用可能か確認する
public bool Register_vRoid(vRoidAvator cv);                            // VOICEROIDをコントローラーに登録する
public bool RegisterAll_vRoid();                                       // 現在起動されているVOICEROIDをすべてコントローラに登録する
public bool Remove_vRoid(vRoidAvator cv);                              // VOICEROIDをコントローラの登録から外す
public bool Rescan_vRoid(vRoidAvator cv);                              // VOICEROIDのウインドウハンドルを再登録する
public bool RescanAll_vRoid();                                         // コントローラに登録されている全VOICEROIDのウインドウハンドルを再登録する
 
public void Play(vRoidAvator cv, string talkText);                             // VOICEROIDを発声させる
public void PlayWithSave(vRoidAvator cv, string talkText, string WavFilePath); // VOICEROIDを発声させ音声データを保存する
public void Save(vRoidAvator cv, string talkText, string WavFilePath);         // VOICEROIDを発声させず音声データを保存する
 
public void SetVoiceEffectParam(vRoidAvator cv, vRoidVoiceEffectParam ve, decimal param); // VOICEROIDに音声効果を設定する

使用するVOICEROIDの登録

登録できるのは、DLL呼び出しより先に起動しているVOICEROIDだけです。
RegisterAll_vRoid()を呼び出すと、起動している全VOICEROIDを実行対象に登録します。ですが、少々時間がかかります。

vRoidControl.Register_vRoid(vRoidAvator.SEIKA);    // VOICEROID+京町セイカ EXを実行対象に登録
vRoidControl.RegisterAll_vRoid();                  // 起動している全VOICEROIDを実行対象に登録

WinFormなアプリの場合、Register_vRoid()は1回だけ実行できればよいです。どこかのサンプルコードのように、ボタンを押すたびに実行する必要はありません。

音声効果設定

音声効果の指定は、VOICEROID+ 東北ずん子 と VOICEROID+ 琴葉姉妹、VOICEROID+EX のシリーズのみ有効です。抑揚、高さ、話速、音量のパラメタを設定できます。

vRoidControl.SetVoiceEffectParam(vRoidAvator.SEIKA, vRoidVoiceEffectParam.intonation, intonation); // 抑揚
vRoidControl.SetVoiceEffectParam(vRoidAvator.SEIKA, vRoidVoiceEffectParam.pitch, pitch);           // 高さ
vRoidControl.SetVoiceEffectParam(vRoidAvator.SEIKA, vRoidVoiceEffectParam.speed, speed);           // 話速
vRoidControl.SetVoiceEffectParam(vRoidAvator.SEIKA, vRoidVoiceEffectParam.volume, volume);         // 音量

音声効果を使う場合は、あらかじめこの画面のようにVOICEROID+/VOICEROID+EXの音声効果ウインドウ(音声効果タブ)を表示しておきます。
大丈夫な設定

以下の画面のままだと、コマンドラインで指定した音声効果パラメタが反映されません。
駄目な設定

VOICERID+ 結月ゆかり、民安ともえ、鷹の爪吉田君 (VOICEROID+ EXではないもの) はこのように音声効果ウインドウを表示させておきます。 この時、キーボード(キーボードショートカット)で音声効果パラメタを操作しないでください。やってしまうとおそらく制御不能になります。

この画面は、キーボード(キーボードショートカット)で音声効果を操作してしまい、ピッチにフォーカスが当たったままになっている例です。 画面を閉じて、再度音声効果のウインドウを開き直してください。

発声、音声データ保存

vRoidControl.Play(vRoidAvator.SEIKA,         "暑い日が続きますね" );             // 発声させる
vRoidControl.Save(vRoidAvator.SEIKA,         "暑い日が続きますね", "seika.wav"); // 発声させず音声データ保存する
vRoidControl.PlayWithSave(vRoidAvator.SEIKA, "暑い日が続きますね", "seika.wav"); // 発声させ音声データ保存する

発声、保存、発声と保存、の3種類のアクションを指定できます。

DLLのソース

vRoidInstanceクラス内のコードが、VOICEROID制御のコードになります。

echoSeikadll.cs
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Windows.Forms;
 
namespace echoSeikaAPI
{
    /// <summary>
    /// VOICEROIDコントローラ
    /// </summary>
    public class vRoidController
    {
        private Dictionary<string, vRoidInstance> vRoids;
 
        /// <summary>
        /// VOICEROIDコントローラのコンストラクタ
        /// </summary>
        public vRoidController()
        {
            vRoids = new Dictionary<string, vRoidInstance>();
        }
 
        /// <summary>
        /// VOICEROIDがコントローラ登録済みか確認する
        /// </summary>
        /// <param name="cv">確認するVOICEROID</param>
        /// <returns>登録されているなら真</returns>
        public bool isRegistered_vRoid(vRoidAvator cv)
        {
            bool ans = false;
 
            if (vRoids.ContainsKey(cv.ToString()))
            {
                ans = true;
            }
 
            return ans;
        }
 
        /// <summary>
        /// VOICEROIDがメモリに存在しているか確認する
        /// </summary>
        /// <param name="cv">確認するVOICEROID</param>
        /// <returns>存在しているなら真</returns>
        public bool isAlive_vRoid(vRoidAvator cv)
        {
            bool ans = false;
 
            if (vRoids.ContainsKey(cv.ToString()))
            {
                ans = vRoids[cv.ToString()].isAlive;
            }
 
            return ans;
        }
 
        /// <summary>
        /// VOICEROIDの音声効果が利用可能か確認する
        /// </summary>
        /// <param name="cv">確認するVOICEROID</param>
        /// <returns>利用可能状態なら真</returns>
        public bool isAvailable_vRoid_VoiceEffect(vRoidAvator cv)
        {
            bool ans = false;
 
            if (vRoids.ContainsKey(cv.ToString()))
            {
                ans = vRoids[cv.ToString()].isVoiceEffectAvailable;
            }
 
            return ans;
        }
 
        /// <summary>
        /// VOICEROIDをコントローラーに登録する
        /// </summary>
        /// <param name="cv">登録するVOICEROID</param>
        /// <returns>登録に成功すれば真</returns>
        public bool Register_vRoid(vRoidAvator cv)
        {
            bool ans = false;
 
            switch(cv)
            {
                case vRoidAvator.MS_TTS:
                    break;
 
                default:
                    if (!vRoids.ContainsKey(cv.ToString()))
                    {
                        vRoidInstance c = new vRoidInstance(cv);
                        if (c.isUsable)
                        {
                            vRoids.Add(cv.ToString(), c);
                            ans = true;
                        }
                    }
                    break;
            }
 
            return ans;
        }
 
        /// <summary>
        /// 現在起動されているVOICEROIDをすべてコントローラに登録する
        /// </summary>
        /// <returns>1つ以上失敗すれば偽</returns>
        public bool RegisterAll_vRoid()
        {
            bool ans = true;
 
            foreach (vRoidAvator cv in Enum.GetValues(typeof(vRoidAvator)))
            {
                switch(cv)
                {
                    case vRoidAvator.MS_TTS:
                        break;
 
                    default:
                        if (!isRegistered_vRoid(cv))
                        {
                            if (!Register_vRoid(cv))
                            {
                                ans = false;
                            }
                        }
                        break;
                }
            }
 
            return ans;
        }
 
        /// <summary>
        /// VOICEROIDをコントローラの登録から外す
        /// </summary>
        /// <param name="cv">外すVOICEROID</param>
        /// <returns>外せたら真</returns>
        public bool Remove_vRoid(vRoidAvator cv)
        {
            bool ans = false;
 
            if (vRoids.ContainsKey(cv.ToString()))
            {
                vRoids.Remove(cv.ToString());
                ans = true;
            }
 
            return ans;
        }
 
        /// <summary>
        /// VOICEROIDのウインドウハンドルを再登録する
        /// </summary>
        /// <param name="cv">再登録するVOICEROID</param>
        /// <returns>再登録出来たら真</returns>
        public bool Rescan_vRoid(vRoidAvator cv)
        {
            bool ans = false;
 
            if (vRoids.ContainsKey(cv.ToString()))
            {
                if (vRoids[cv.ToString()].isAlive)
                {
                    vRoids[cv.ToString()].ReScanWindowHandle();
                    ans = vRoids[cv.ToString()].isUsable;
                }
            }
 
            return ans;
        }
 
        /// <summary>
        /// コントローラに登録されている全VOICEROIDのウインドウハンドルを再登録する
        /// </summary>
        /// <returns>1つ以上失敗すれば偽</returns>
        public bool RescanAll_vRoid()
        {
            bool ans = true;
 
            foreach (vRoidAvator cv in Enum.GetValues(typeof(vRoidAvator)))
            {
                if (vRoids.ContainsKey(cv.ToString()))
                {
                    if (vRoids[cv.ToString()].isAlive)
                    {
                        vRoids[cv.ToString()].ReScanWindowHandle();
                        if (!vRoids[cv.ToString()].isUsable)
                        {
                            ans = false;
                        }
                    }
                }
            }
 
            return ans;
        }
 
        /// <summary>
        /// VOICEROIDに発声させる
        /// </summary>
        /// <param name="cv">発声させるVOICEROID</param>
        [Obsolete("廃止予定です")]
        public void Play(vRoidAvator cv)
        {
            if (vRoids.ContainsKey(cv.ToString()))
            {
                vRoids[cv.ToString()].PlayVoice(true);
            }
        }
 
        /// <summary>
        /// VOICEROIDに発声させる
        /// </summary>
        /// <param name="cv">発声させるVOICEROID</param>
        /// <param name="talkText">読み上げるテキスト</param>
        /// <param name="unicodeText">Unicodeテキストと意識するか否か</param>
        public void Play(vRoidAvator cv, string talkText, bool unicodeText = false)
        {
            PlayAsync(cv, talkText, unicodeText);
        }
 
        /// <summary>
        /// VOICEROIDに発声させる(非同期)
        /// </summary>
        /// <param name="cv">発声させるVOICEROID</param>
        /// <param name="talkText">読み上げるテキスト</param>
        /// <param name="unicodeText">Unicodeテキストと意識するか否か</param>
        public void PlayAsync(vRoidAvator cv, string talkText, bool unicodeText = false)
        {
            if (vRoids.ContainsKey(cv.ToString()))
            {
                vRoids[cv.ToString()].TalkText = talkText;
                vRoids[cv.ToString()].UnicodeText = unicodeText;
                vRoids[cv.ToString()].PlayVoice(true);
            }
        }
 
        /// <summary>
        /// VOICEROIDに発声させる(同期)
        /// </summary>
        /// <param name="cv">発声させるVOICEROID</param>
        /// <param name="talkText">読み上げるテキスト</param>
        /// <param name="unicodeText">Unicodeテキストと意識するか否か</param>
        public void PlaySync(vRoidAvator cv, string talkText, bool unicodeText = false)
        {
            if (vRoids.ContainsKey(cv.ToString()))
            {
                vRoids[cv.ToString()].TalkText = talkText;
                vRoids[cv.ToString()].UnicodeText = unicodeText;
                vRoids[cv.ToString()].PlayVoice(false);
            }
        }
 
        /// <summary>
        /// VOICEROIDに発声させず音声データを保存する
        /// </summary>
        /// <param name="cv">発声させるVOICEROID</param>
        [Obsolete("廃止予定です")]
        public void Save(vRoidAvator cv)
        {
            if (vRoids.ContainsKey(cv.ToString()))
            {
                vRoids[cv.ToString()].SaveVoice();
            }
        }
 
        /// <summary>
        /// VOICEROIDに発声させず音声データを保存する
        /// </summary>
        /// <param name="cv">発声させるVOICEROID</param>
        /// <param name="talkText">読み上げるテキスト</param>
        /// <param name="WavFilePath">保存ファイルパス</param>
        /// <param name="unicodeText">Unicodeテキストと意識するか否か</param>
        public void Save(vRoidAvator cv, string talkText, string WavFilePath, bool unicodeText = false)
        {
            if (vRoids.ContainsKey(cv.ToString()))
            {
                vRoids[cv.ToString()].TalkText = talkText;
                vRoids[cv.ToString()].UnicodeText = unicodeText;
                vRoids[cv.ToString()].WavFilePath = WavFilePath;
                vRoids[cv.ToString()].SaveVoice();
            }
        }
 
        /// <summary>
        /// VOICEROIDに発声させ音声データを保存する
        /// </summary>
        /// <param name="cv">発声させるVOICEROID</param>
        [Obsolete("廃止予定です")]
        public void PlayWithSave(vRoidAvator cv)
        {
            if (vRoids.ContainsKey(cv.ToString()))
            {
                vRoids[cv.ToString()].PlayVoiceWithSave();
            }
        }
 
        /// <summary>
        /// VOICEROIDに発声させ音声データを保存する
        /// </summary>
        /// <param name="cv">発声させるVOICEROID</param>
        /// <param name="talkText">読み上げるテキスト</param>
        /// <param name="WavFilePath">保存ファイルパス</param>
        /// <param name="unicodeText">Unicodeテキストと意識するか否か</param>
        public void PlayWithSave(vRoidAvator cv, string talkText, string WavFilePath, bool unicodeText = false)
        {
            if (vRoids.ContainsKey(cv.ToString()))
            {
                vRoids[cv.ToString()].TalkText = talkText;
                vRoids[cv.ToString()].UnicodeText = unicodeText;
                vRoids[cv.ToString()].WavFilePath = WavFilePath;
                vRoids[cv.ToString()].PlayVoiceWithSave();
            }
        }
 
        /// <summary>
        /// VOICEROIDに発声するテキストを設定する
        /// </summary>
        /// <param name="cv">設定するVOICEROID</param>
        /// <param name="TalkText">テキスト</param>
        [Obsolete("廃止予定です")]
        public void SetTalkText(vRoidAvator cv, string TalkText)
        {
            if (vRoids.ContainsKey(cv.ToString()))
            {
                vRoids[cv.ToString()].TalkText = TalkText;
            }
        }
 
        /// <summary>
        /// VOICEROIDに音声データの保存ファイルパス(ファイル名)を設定する
        /// </summary>
        /// <param name="cv">設定するVOICEROID</param>
        /// <param name="WavFilePath">保存ファイルパス</param>
        [Obsolete("廃止予定です")]
        public void SetWavFilePath(vRoidAvator cv, string WavFilePath)
        {
            if (vRoids.ContainsKey(cv.ToString()))
            {
                vRoids[cv.ToString()].WavFilePath = WavFilePath;
            }
        }
 
        /// <summary>
        /// VOICEROIDに音声効果適用方式を設定する
        /// </summary>
        /// <param name="cv">音声効果適用方式を設定するVOICEROID</param>
        /// <param name="am">設定する適用方式</param>
        public void SetVoiceEffectApplyMode(vRoidAvator cv, vRoidVoiceEffectApplyMode am)
        {
            if (vRoids.ContainsKey(cv.ToString()))
            {
                vRoids[cv.ToString()].VoiceEffectApplyMode = am;
            }
        }
 
        /// <summary>
        /// VOICEROIDに音声効果を設定する
        /// </summary>
        /// <param name="cv">音声効果を設定するVOICEROID</param>
        /// <param name="ve">設定する効果</param>
        /// <param name="param">設定値</param>
        public void SetVoiceEffectParam(vRoidAvator cv, vRoidVoiceEffectParam ve, decimal param)
        {
            if (vRoids.ContainsKey(cv.ToString()))
            {
                switch (ve)
                {
                    case vRoidVoiceEffectParam.intonation:
                        vRoids[cv.ToString()].Intonation = param;
                        break;
                    case vRoidVoiceEffectParam.pitch:
                        vRoids[cv.ToString()].Pitch = param;
                        break;
                    case vRoidVoiceEffectParam.speed:
                        vRoids[cv.ToString()].Speed = param;
                        break;
                    case vRoidVoiceEffectParam.volume:
                        vRoids[cv.ToString()].Volume = param;
                        break;
                    case vRoidVoiceEffectParam.whisper:
                        vRoids[cv.ToString()].Whisper = param;
                        break;
                    case vRoidVoiceEffectParam.emotion_anger:
                        vRoids[cv.ToString()].Emotion_anger = param;
                        break;
                    case vRoidVoiceEffectParam.emotion_happy:
                        vRoids[cv.ToString()].Emotion_happy = param;
                        break;
                    case vRoidVoiceEffectParam.emotion_sad:
                        vRoids[cv.ToString()].Emotion_sad = param;
                        break;
                }
            }
        }
 
        /// <summary>
        /// VOICEROIDの実行プログラムのパスを設定する
        /// </summary>
        /// <param name="cv">設定するVOICEROID</param>
        /// <param name="ExecutionPath">実行ファイルのパス</param>
        [Obsolete("まだこれを使う機能は実装されていません", true)]
        public void SetExecPath(vRoidAvator cv, string ExecutionPath)
        {
            if (vRoids.ContainsKey(cv.ToString()))
            {
                vRoids[cv.ToString()].ExecutionPath = ExecutionPath;
            }
        }
 
        /// <summary>
        /// VOICEROIDインスタンス情報
        /// </summary>
        private class vRoidInstance
        {
            public vRoidInstance(vRoidAvator cv)
            {
                hMainWnds = new Dictionary<UIhWnds, IntPtr>();
                hDlgWnds = new Dictionary<UIhWnds, IntPtr>();
                volume = volume_prev = 1.00m;
                pitch = pitch_prev = 1.00m;
                intonation = intonation_prev = 1.00m;
                speed = speed_prev = 1.00m;
                whisper = 0.97m;
                emotion_anger = 0.0m;
                emotion_happy = 0.0m;
                emotion_sad = 0.0m;
 
                voiceEffectApplyMode = vRoidVoiceEffectApplyMode.resetStateAndApply;
                RetryCount = 3;
                RetryWaitms = 1000;
                voiceroid = cv;
                TalkText = "";
                WavFilePath = "";
                ExecutionPath = "";
 
                ScanWindowHandles();
            }
            public void PlayVoice(bool async=true)
            {
                if (TalkTextSb.Length == 0) return;
 
                switch (voiceroid)
                {
                    case vRoidAvator.TAMMY:
                    case vRoidAvator.YOSHIDA:
                        SetVoiceEffect_Voiceroid_Plus();
                        CopyTalkText_voiceroid_Plus();
                        PlayVoice_Voiceroid_Plus();
                        if (!async) WaitPlaying2();
                        break;
 
                    case vRoidAvator.YUKARI:
                        SetVoiceEffect_Voiceroid_Plus_2();
                        CopyTalkText_voiceroid_Plus();
                        PlayVoice_Voiceroid_Plus();
                        if (!async) WaitPlaying2();
                        break;
 
                    case vRoidAvator.ZUNKO:
                        SetVoiceEffect_Voiceroid_Plus_Ex();
                        CopyTalkText_voiceroid_Plus_Ex();
                        PlayVoice_Voiceroid_Plus_Ex();
                        if (!async) WaitPlaying2();
                        break;
 
                    case vRoidAvator.MS_TTS:
                    case vRoidAvator.VOICEROID2:
                        break;
 
                    default:
                        SetVoiceEffect_Voiceroid_Plus_Ex();
                        CopyTalkText_voiceroid_Plus_Ex();
                        PlayVoice_Voiceroid_Plus_Ex();
                        if (!async) WaitPlaying2();
                        break;
                }
            }
            public void PlayVoiceWithSave()
            {
                if (TalkTextSb.Length == 0) return;
 
                switch (voiceroid)
                {
                    case vRoidAvator.TAMMY:
                    case vRoidAvator.YOSHIDA:
                        SetVoiceEffect_Voiceroid_Plus();
                        CopyTalkText_voiceroid_Plus();
                        SaveVoice_voiceroid_Plus();
                        PlayVoice_Voiceroid_Plus();
                        break;
 
                    case vRoidAvator.YUKARI:
                        SetVoiceEffect_Voiceroid_Plus_2();
                        CopyTalkText_voiceroid_Plus();
                        SaveVoice_voiceroid_Plus();
                        PlayVoice_Voiceroid_Plus();
                        break;
 
                    case vRoidAvator.ZUNKO:
                        SetVoiceEffect_Voiceroid_Plus_Ex();
                        CopyTalkText_voiceroid_Plus_Ex();
                        SaveVoice_voiceroid_Plus_2();
                        PlayVoice_Voiceroid_Plus_Ex();
                        break;
 
                    case vRoidAvator.MS_TTS:
                    case vRoidAvator.VOICEROID2:
                        break;
 
                    default:
                        SetVoiceEffect_Voiceroid_Plus_Ex();
                        CopyTalkText_voiceroid_Plus_Ex();
                        SaveVoice_voiceroid_Plus_Ex();
                        PlayVoice_Voiceroid_Plus_Ex();
                        break;
                }
            }
            public void SaveVoice()
            {
                if (TalkTextSb.Length == 0) return;
 
                switch (voiceroid)
                {
                    case vRoidAvator.TAMMY:
                    case vRoidAvator.YOSHIDA:
                        SetVoiceEffect_Voiceroid_Plus();
                        CopyTalkText_voiceroid_Plus();
                        SaveVoice_voiceroid_Plus();
                        break;
 
                    case vRoidAvator.YUKARI:
                        SetVoiceEffect_Voiceroid_Plus_2();
                        CopyTalkText_voiceroid_Plus();
                        SaveVoice_voiceroid_Plus();
                        break;
 
                    case vRoidAvator.ZUNKO:
                        SetVoiceEffect_Voiceroid_Plus_Ex();
                        CopyTalkText_voiceroid_Plus_Ex();
                        SaveVoice_voiceroid_Plus_2();
                        break;
 
                    case vRoidAvator.MS_TTS:
                    case vRoidAvator.VOICEROID2:
                        break;
 
                    default:
                        SetVoiceEffect_Voiceroid_Plus_Ex();
                        CopyTalkText_voiceroid_Plus_Ex();
                        SaveVoice_voiceroid_Plus_Ex();
                        break;
                }
            }
            public void ReScanWindowHandle()
            {
                hMainWnds.Clear();
                hDlgWnds.Clear();
 
                ScanWindowHandles();
            }
            public bool isOldType
            {
                get
                {
                    return voiceroid.isOldType();
                }
            }
            public bool isUsable
            {
                get
                {
                    IntPtr ans = hMainWnds[UIhWnds.voiceroid_mainwindow];
                    return ans.Equals(IntPtr.Zero) ? false : true;
                }
            }
            public bool isAlive
            {
                get
                {
                    bool ans = false;
                    try
                    {
                        ans = Process.GetProcessById((int)hMainWnds[UIhWnds.voiceroid_processid]).HasExited;
                    }
                    catch(Exception)
                    {
                        ans = true;
                    }
                    return !ans;
                }
            }
            public bool isVoiceEffectAvailable
            {
                get
                {
                    IntPtr ans = hMainWnds[UIhWnds.voiceroid_effect_window];
                    return ans.Equals(IntPtr.Zero) ? false : true;
                }
            }
 
            private void GetMainWindowHandle(vRoidAvator cv)
            {
                string winTitle1 = cv.ProdName();
                string winTitle2 = winTitle1 + "*";
 
                if (cv.isOldType())
                {
                    for (int i = 0; i < RetryCount; i++)
                    {
                        IntPtr hWnd1 = FindWindow("TkTopLevel", winTitle1);
                        IntPtr hWnd2 = FindWindow("TkTopLevel", winTitle2);
 
                        if (hWnd1 != IntPtr.Zero)
                        {
                            int processId1 = 0;
                            GetWindowThreadProcessId(hWnd1, out processId1);
 
                            hMainWnds.Add(UIhWnds.voiceroid_mainwindow, hWnd1);
                            hMainWnds.Add(UIhWnds.voiceroid_processid, (IntPtr)processId1);
                        }
                        if (hWnd2 != IntPtr.Zero)
                        {
                            int processId2 = 0;
                            GetWindowThreadProcessId(hWnd2, out processId2);
 
                            hMainWnds.Add(UIhWnds.voiceroid_mainwindow, hWnd2);
                            hMainWnds.Add(UIhWnds.voiceroid_processid, (IntPtr)processId2);
                        }
                        if ((hWnd1 != IntPtr.Zero) || (hWnd2 != IntPtr.Zero)) break;
                        if (i < (RetryCount - 1)) Thread.Sleep(RetryWaitms);
                    }
                }
                else
                {
                    IntPtr hWnd = IntPtr.Zero;
                    IntPtr hWndDaddy = IntPtr.Zero;
                    int processId = 0;
 
                    for (int i = 0; i < RetryCount; i++)
                    {
                        Process[] ps = Process.GetProcesses();
 
                        foreach (Process pitem in ps)
                        {
                            if ((pitem.MainWindowHandle != IntPtr.Zero) &&
                                   ((pitem.MainWindowTitle.Equals(winTitle1)) || (pitem.MainWindowTitle.Equals(winTitle2))))
                            {
                                hWnd = pitem.MainWindowHandle;
                                processId = pitem.Id;
                                hMainWnds.Add(UIhWnds.voiceroid_mainwindow, hWnd);
                                hMainWnds.Add(UIhWnds.voiceroid_processid, (IntPtr)processId);
                            }
                        }
                        if (hWnd != IntPtr.Zero) break;
                        if (i < (RetryCount - 1)) Thread.Sleep(RetryWaitms);
                    }
                }
 
                if (!hMainWnds.ContainsKey(UIhWnds.voiceroid_mainwindow))
                {
                    hMainWnds.Add(UIhWnds.voiceroid_mainwindow, IntPtr.Zero);
                    hMainWnds.Add(UIhWnds.voiceroid_processid, IntPtr.Zero);
                }
            }
            private void GetMainWindowControlHandle_Voiceroid_Plus_Ex()
            {
                IntPtr hWndMainWinPtr = hMainWnds[UIhWnds.voiceroid_mainwindow];
 
                if (hWndMainWinPtr == IntPtr.Zero)
                {
                    hMainWnds.Add(UIhWnds.voiceroid_textbox, IntPtr.Zero);
                    hMainWnds.Add(UIhWnds.voiceroid_playbutton, IntPtr.Zero);
                    hMainWnds.Add(UIhWnds.voiceroid_savebutton, IntPtr.Zero);
                    return;
                }
 
                IntPtr hWndWorkPtr = IntPtr.Zero;
 
                // テキストボックス
                hWndWorkPtr = hWndMainWinPtr;
                hWndWorkPtr = GetWindow(hWndWorkPtr, GW_CHILD);    // 第1層ウインドウ
                hMainWnds.Add(UIhWnds.voiceroid_mainwindow_child, hWndWorkPtr);
 
                hWndWorkPtr = GetWindow(hWndWorkPtr, GW_CHILD);    // 第2層ウインドウ
                hWndWorkPtr = GetWindow(hWndWorkPtr, GW_HWNDNEXT); // 第2層2番目ウインドウ
                hWndWorkPtr = GetWindow(hWndWorkPtr, GW_CHILD);    // 第3層ウインドウ
                hWndWorkPtr = GetWindow(hWndWorkPtr, GW_CHILD);    // 第4層ウインドウ
                hWndWorkPtr = GetWindow(hWndWorkPtr, GW_CHILD);    // 第5層ウインドウ
                hWndWorkPtr = GetWindow(hWndWorkPtr, GW_CHILD);    // 第6層ウインドウ
                hWndWorkPtr = GetWindow(hWndWorkPtr, GW_CHILD);    // 第7層ウインドウ
                hWndWorkPtr = GetWindow(hWndWorkPtr, GW_CHILD);    // 第8層ウインドウ(テキストボックス) 
                hMainWnds.Add(UIhWnds.voiceroid_textbox, hWndWorkPtr);
 
                // 再生ボタン
                hWndWorkPtr = hWndMainWinPtr;
                hWndWorkPtr = GetWindow(hWndWorkPtr, GW_CHILD);    // 第1層ウインドウ
                hWndWorkPtr = GetWindow(hWndWorkPtr, GW_CHILD);    // 第2層ウインドウ
                hWndWorkPtr = GetWindow(hWndWorkPtr, GW_HWNDNEXT); // 第2層2番目ウインドウ
                hWndWorkPtr = GetWindow(hWndWorkPtr, GW_CHILD);    // 第3層ウインドウ
                hWndWorkPtr = GetWindow(hWndWorkPtr, GW_CHILD);    // 第4層ウインドウ
                hWndWorkPtr = GetWindow(hWndWorkPtr, GW_CHILD);    // 第5層ウインドウ
                hWndWorkPtr = GetWindow(hWndWorkPtr, GW_CHILD);    // 第6層ウインドウ
                hWndWorkPtr = GetWindow(hWndWorkPtr, GW_CHILD);    // 第7層ウインドウ
                hWndWorkPtr = GetWindow(hWndWorkPtr, GW_HWNDNEXT); // 第7層2番目ウインドウ
                hWndWorkPtr = GetWindow(hWndWorkPtr, GW_CHILD);    // 第8層ウインドウ(再生ボタン)
                hMainWnds.Add(UIhWnds.voiceroid_playbutton, hWndWorkPtr);
 
                // 音声保存ボタン
                hWndWorkPtr = GetWindow(hWndWorkPtr, GW_HWNDNEXT);    // 第8層2番目ウインドウ(停止ボタン)
                hWndWorkPtr = GetWindow(hWndWorkPtr, GW_HWNDNEXT);    // 第8層3番目ウインドウ(音声保存ボタン)
                hMainWnds.Add(UIhWnds.voiceroid_savebutton, hWndWorkPtr);
            }
            private void GetMainWindowControlHandle_Voiceroid_Plus_2()
            {
                IntPtr hWndMainWinPtr = hMainWnds[UIhWnds.voiceroid_mainwindow];
 
                if (hWndMainWinPtr == IntPtr.Zero)
                {
                    hMainWnds.Add(UIhWnds.voiceroid_textbox, IntPtr.Zero);
                    hMainWnds.Add(UIhWnds.voiceroid_playbutton, IntPtr.Zero);
                    hMainWnds.Add(UIhWnds.voiceroid_savebutton, IntPtr.Zero);
                    return;
                }
 
                IntPtr hWndWorkPtr = IntPtr.Zero;
 
                //テキストボックス
                hWndWorkPtr = hWndMainWinPtr;
                hWndWorkPtr = GetWindow(hWndWorkPtr, GW_CHILD);    // 第1層ウインドウ
                hMainWnds.Add(UIhWnds.voiceroid_mainwindow_child, hWndWorkPtr);
 
                hWndWorkPtr = GetWindow(hWndWorkPtr, GW_CHILD);    // 第2層ウインドウ
                hWndWorkPtr = GetWindow(hWndWorkPtr, GW_HWNDNEXT); // 第2層2番目ウインドウ
                hWndWorkPtr = GetWindow(hWndWorkPtr, GW_CHILD);    // 第3層ウインドウ
                hWndWorkPtr = GetWindow(hWndWorkPtr, GW_CHILD);    // 第4層ウインドウ
                hWndWorkPtr = GetWindow(hWndWorkPtr, GW_CHILD);    // 第5層ウインドウ
                hWndWorkPtr = GetWindow(hWndWorkPtr, GW_CHILD);    // 第6層ウインドウ
                hWndWorkPtr = GetWindow(hWndWorkPtr, GW_CHILD);    // 第7層ウインドウ(テキストボックス) 
                hMainWnds.Add(UIhWnds.voiceroid_textbox, hWndWorkPtr);
 
                //再生ボタン
                hWndWorkPtr = GetWindow(hWndWorkPtr, GW_HWNDNEXT); // 第7層2番目ウインドウ
                hWndWorkPtr = GetWindow(hWndWorkPtr, GW_CHILD);    // 第8層ウインドウ(再生ボタン)
                hMainWnds.Add(UIhWnds.voiceroid_playbutton, hWndWorkPtr);
 
                //保存ボタン
                hWndWorkPtr = GetWindow(hWndWorkPtr, GW_HWNDNEXT); // 第8層2番目ウインドウ
                hWndWorkPtr = GetWindow(hWndWorkPtr, GW_HWNDNEXT); // 第8層3番目ウインドウ(音声保存ボタン)
                hMainWnds.Add(UIhWnds.voiceroid_savebutton, hWndWorkPtr);
            }
            private void GetMainWindowControlHandle_Voiceroid_Plus()
            {
                IntPtr hWndMainWinPtr = hMainWnds[UIhWnds.voiceroid_mainwindow];
 
                if (hWndMainWinPtr == IntPtr.Zero)
                {
                    hMainWnds.Add(UIhWnds.voiceroid_textbox, IntPtr.Zero);
                    hMainWnds.Add(UIhWnds.voiceroid_playbutton, IntPtr.Zero);
                    hMainWnds.Add(UIhWnds.voiceroid_savebutton, IntPtr.Zero);
                    return;
                }
 
                IntPtr hWndWorkPtr = IntPtr.Zero;
 
                //テキストボックス
                hWndWorkPtr = hWndMainWinPtr;
                hWndWorkPtr = GetWindow(hWndWorkPtr, GW_CHILD);    // 第1層ウインドウ
                hMainWnds.Add(UIhWnds.voiceroid_mainwindow_child, hWndWorkPtr);
 
                hWndWorkPtr = GetWindow(hWndWorkPtr, GW_CHILD);    // 第2層ウインドウ
                hWndWorkPtr = GetWindow(hWndWorkPtr, GW_HWNDNEXT); // 第2層2番目ウインドウ
                hWndWorkPtr = GetWindow(hWndWorkPtr, GW_HWNDNEXT); // 第2層3番目ウインドウ
                hWndWorkPtr = GetWindow(hWndWorkPtr, GW_CHILD);    // 第3層ウインドウ
                hWndWorkPtr = GetWindow(hWndWorkPtr, GW_HWNDNEXT); // 第3層2番目ウインドウ(テキストボックス) 
                hMainWnds.Add(UIhWnds.voiceroid_textbox, hWndWorkPtr);
 
                //保存ボタン
                hWndWorkPtr = hWndMainWinPtr;
                hWndWorkPtr = GetWindow(hWndWorkPtr, GW_CHILD);    // 第1層ウインドウ
                hWndWorkPtr = GetWindow(hWndWorkPtr, GW_CHILD);    // 第2層ウインドウ
                hWndWorkPtr = GetWindow(hWndWorkPtr, GW_HWNDNEXT); // 第2層2番目ウインドウ
                hWndWorkPtr = GetWindow(hWndWorkPtr, GW_CHILD);    // 第3層ウインドウ
                hWndWorkPtr = GetWindow(hWndWorkPtr, GW_HWNDNEXT); // 第3層2番目ウインドウ
                hWndWorkPtr = GetWindow(hWndWorkPtr, GW_HWNDNEXT); // 第3層3番目ウインドウ(保存ボタン)
                hMainWnds.Add(UIhWnds.voiceroid_savebutton, hWndWorkPtr);
 
                //再生ボタン
                hWndWorkPtr = GetWindow(hWndWorkPtr, GW_HWNDNEXT); // 第3層4番目ウインドウ
                hWndWorkPtr = GetWindow(hWndWorkPtr, GW_HWNDNEXT); // 第3層5番目ウインドウ(再生ボタン)
                hMainWnds.Add(UIhWnds.voiceroid_playbutton, hWndWorkPtr);
            }
            private void GetVoiceEffectWindowHandle_Voiceroid_Plus_Ex()
            {
                IntPtr hWndWorkPtr = hMainWnds[UIhWnds.voiceroid_mainwindow];
 
                if (hWndWorkPtr == IntPtr.Zero)
                {
                    hMainWnds.Add(UIhWnds.voiceroid_intonation_initbutton, IntPtr.Zero);
                    hMainWnds.Add(UIhWnds.voiceroid_pitch_initbutton, IntPtr.Zero);
                    hMainWnds.Add(UIhWnds.voiceroid_speed_initbutton, IntPtr.Zero);
                    hMainWnds.Add(UIhWnds.voiceroid_volume_initbutton, IntPtr.Zero);
                    hMainWnds.Add(UIhWnds.voiceroid_intonation_textbox, IntPtr.Zero);
                    hMainWnds.Add(UIhWnds.voiceroid_pitch_textbox, IntPtr.Zero);
                    hMainWnds.Add(UIhWnds.voiceroid_speed_textbox, IntPtr.Zero);
                    hMainWnds.Add(UIhWnds.voiceroid_volume_textbox, IntPtr.Zero);
 
                    return;
                }
 
                hWndWorkPtr = GetWindow(hWndWorkPtr, GW_CHILD);    // 第1層ウインドウ
                hWndWorkPtr = GetWindow(hWndWorkPtr, GW_CHILD);    // 第2層ウインドウ
                hWndWorkPtr = GetWindow(hWndWorkPtr, GW_HWNDNEXT); // 第2層2番目ウインドウ
                hWndWorkPtr = GetWindow(hWndWorkPtr, GW_CHILD);    // 第3層ウインドウ
                hWndWorkPtr = GetWindow(hWndWorkPtr, GW_CHILD);    // 第4層ウインドウ
                hWndWorkPtr = GetWindow(hWndWorkPtr, GW_HWNDNEXT); // 第4層2番目ウインドウ
                hWndWorkPtr = GetWindow(hWndWorkPtr, GW_CHILD);    // 第5層ウインドウ
                hWndWorkPtr = GetWindow(hWndWorkPtr, GW_CHILD);    // 第6層ウインドウ
                hWndWorkPtr = GetWindow(hWndWorkPtr, GW_HWNDNEXT); // 第6層2番目ウインドウ
                hWndWorkPtr = GetWindow(hWndWorkPtr, GW_CHILD);    // 第7層ウインドウ
 
                hWndWorkPtr = GetWindow(hWndWorkPtr, GW_CHILD);    // 第8層1番目ウインドウ(抑揚初期値ボタン) 
                hMainWnds.Add(UIhWnds.voiceroid_intonation_initbutton, hWndWorkPtr);
                hWndWorkPtr = GetWindow(hWndWorkPtr, GW_HWNDNEXT); // 第8層2番目ウインドウ(高さ初期値ボタン) 
                hMainWnds.Add(UIhWnds.voiceroid_pitch_initbutton, hWndWorkPtr);
                hWndWorkPtr = GetWindow(hWndWorkPtr, GW_HWNDNEXT); // 第8層3番目ウインドウ(話速初期値ボタン) 
                hMainWnds.Add(UIhWnds.voiceroid_speed_initbutton, hWndWorkPtr);
                hWndWorkPtr = GetWindow(hWndWorkPtr, GW_HWNDNEXT); // 第8層4番目ウインドウ(音量初期値ボタン) 
                hMainWnds.Add(UIhWnds.voiceroid_volume_initbutton, hWndWorkPtr);
 
                hWndWorkPtr = GetWindow(hWndWorkPtr, GW_HWNDNEXT); // 第8層5番目ウインドウ(抑揚) 
                hMainWnds.Add(UIhWnds.voiceroid_intonation_textbox, hWndWorkPtr);
                hWndWorkPtr = GetWindow(hWndWorkPtr, GW_HWNDNEXT); // 第8層6番目ウインドウ(高さ) 
                hMainWnds.Add(UIhWnds.voiceroid_pitch_textbox, hWndWorkPtr);
                hWndWorkPtr = GetWindow(hWndWorkPtr, GW_HWNDNEXT); // 第8層7番目ウインドウ(話速) 
                hMainWnds.Add(UIhWnds.voiceroid_speed_textbox, hWndWorkPtr);
                hWndWorkPtr = GetWindow(hWndWorkPtr, GW_HWNDNEXT); // 第8層8番目ウインドウ(音量) 
                hMainWnds.Add(UIhWnds.voiceroid_volume_textbox, hWndWorkPtr);
            }
            private void GetVoiceEffectWindowHandle_Voiceroid_Plus()
            {
                IntPtr hWnd = IntPtr.Zero;
                int voiceroidProcessId = (int)hMainWnds[UIhWnds.voiceroid_processid];
 
                hWnd = FindWindow("TkTopLevel", "音声効果");
 
                if (hWnd != IntPtr.Zero)
                {
                    int processId = 0;
 
                    while (!hWnd.Equals(IntPtr.Zero))
                    {
                        GetWindowThreadProcessId(hWnd, out processId);
                        if (processId == voiceroidProcessId)
                        {
                            break;
                        }
                        else
                        {
                            hWnd = GetWindow(hWnd, GW_HWNDNEXT);
                        }
                    }
                }
 
                if (hWnd == IntPtr.Zero)
                {
                    hMainWnds.Add(UIhWnds.voiceroid_effect_window, IntPtr.Zero);
                    hMainWnds.Add(UIhWnds.voiceroid_effect_window_child, IntPtr.Zero);
                    hMainWnds.Add(UIhWnds.voiceroid_High_frequency, IntPtr.Zero);
                    hMainWnds.Add(UIhWnds.voiceroid_pitch_slider, IntPtr.Zero);
                    hMainWnds.Add(UIhWnds.voiceroid_speed_slider, IntPtr.Zero);
                    hMainWnds.Add(UIhWnds.voiceroid_volume_slider, IntPtr.Zero);
 
                    return;
                }
 
                IntPtr hWndWorkPtr = hWnd;
 
                hMainWnds.Add(UIhWnds.voiceroid_effect_window, hWndWorkPtr);
 
                hWndWorkPtr = GetWindow(hWndWorkPtr, GW_CHILD);    // 第1層ウインドウ
                hMainWnds.Add(UIhWnds.voiceroid_effect_window_child, hWndWorkPtr);
 
                hWndWorkPtr = GetWindow(hWndWorkPtr, GW_CHILD);    // 第2層1番目ウインドウ(高域強調と出荷時の設定に戻すボタン)
                hMainWnds.Add(UIhWnds.voiceroid_High_frequency, hWndWorkPtr);
 
                hWndWorkPtr = GetWindow(hWndWorkPtr, GW_HWNDNEXT); // 第2層2番目ウインドウ(エコー:ゲイン)
                hWndWorkPtr = GetWindow(hWndWorkPtr, GW_HWNDNEXT); // 第2層3番目ウインドウ(エコー:タイム)
 
                hWndWorkPtr = GetWindow(hWndWorkPtr, GW_HWNDNEXT); // 第2層4番目ウインドウ(ピッチ) 
                hMainWnds.Add(UIhWnds.voiceroid_pitch_slider, hWndWorkPtr);
 
                hWndWorkPtr = GetWindow(hWndWorkPtr, GW_HWNDNEXT); // 第2層5番目ウインドウ(速度) 
                hMainWnds.Add(UIhWnds.voiceroid_speed_slider, hWndWorkPtr);
 
                hWndWorkPtr = GetWindow(hWndWorkPtr, GW_HWNDNEXT); // 第2層6番目ウインドウ(音量) 
                hMainWnds.Add(UIhWnds.voiceroid_volume_slider, hWndWorkPtr);
            }
            private void SetVoiceEffect_init_Voiceroid_Plus_Ex()
            {
                SendMessage(hMainWnds[UIhWnds.voiceroid_intonation_initbutton], BM_CLICK, 0, 0);             // 抑揚初期化ボタンクリック
                SendMessage(hMainWnds[UIhWnds.voiceroid_pitch_initbutton], BM_CLICK, 0, 0);                  // 高さ初期化ボタンクリック
                SendMessage(hMainWnds[UIhWnds.voiceroid_speed_initbutton], BM_CLICK, 0, 0);                  // 話速初期化ボタンクリック
                SendMessage(hMainWnds[UIhWnds.voiceroid_volume_initbutton], BM_CLICK, 0, 0);                 // 音量初期化ボタンクリック
            }
            private void SetVoiceEffect_init_Voiceroid_Plus()
            {
                SendMessage(hMainWnds[UIhWnds.voiceroid_effect_window_child], WM_SETFOCUS, 0, 0);
                PostMessage(hMainWnds[UIhWnds.voiceroid_effect_window_child], WM_KEYDOWN, VK_F7, 0x00410001); // 初期化(F7押下
                PostMessage(hMainWnds[UIhWnds.voiceroid_effect_window_child], WM_KEYUP, VK_F7, 0xC0410001);
            }
            private void SetVoiceEffect_Voiceroid_Plus_Ex()
            {
                if (voiceEffectApplyMode == vRoidVoiceEffectApplyMode.resetStateAndApply)
                {
                    SetVoiceEffect_init_Voiceroid_Plus_Ex();
                }
                if ((voiceEffectApplyMode == vRoidVoiceEffectApplyMode.resetStateAndApply) ||
                    ((voiceEffectApplyMode == vRoidVoiceEffectApplyMode.keepStateAndApply) && (intonation_prev != intonation)))
                {
                    SendMessage(hMainWnds[UIhWnds.voiceroid_intonation_textbox], EM_SETSEL, 0, UInt32.MaxValue); // 抑揚を選択
                    SetClipboard(Intonation.ToString());                                                         // 抑揚の値をクリップボードに転記
                    SendMessage(hMainWnds[UIhWnds.voiceroid_intonation_textbox], WM_PASTE, 0, 0);                // 抑揚数値をペースト
                    PostMessage(hMainWnds[UIhWnds.voiceroid_intonation_textbox], WM_KEYDOWN, VK_RETURN, 0);      // 抑揚数値を確定
                    intonation_prev = intonation;
                }
                if ((voiceEffectApplyMode == vRoidVoiceEffectApplyMode.resetStateAndApply) ||
                    ((voiceEffectApplyMode == vRoidVoiceEffectApplyMode.keepStateAndApply) && (pitch_prev != pitch)))
                {
                    SendMessage(hMainWnds[UIhWnds.voiceroid_pitch_textbox], EM_SETSEL, 0, UInt32.MaxValue);      // 高さを選択
                    SetClipboard(Pitch.ToString());                                                              // 高さの値をクリップボードに転記
                    SendMessage(hMainWnds[UIhWnds.voiceroid_pitch_textbox], WM_PASTE, 0, 0);                     // 高さ数値をペースト
                    PostMessage(hMainWnds[UIhWnds.voiceroid_pitch_textbox], WM_KEYDOWN, VK_RETURN, 0);           // 高さ数値を確定
                    pitch_prev = pitch;
                }
                if ((voiceEffectApplyMode == vRoidVoiceEffectApplyMode.resetStateAndApply) ||
                    ((voiceEffectApplyMode == vRoidVoiceEffectApplyMode.keepStateAndApply) && (speed_prev != speed)))
                {
                    SendMessage(hMainWnds[UIhWnds.voiceroid_speed_textbox], EM_SETSEL, 0, UInt32.MaxValue);      // 話速を選択
                    SetClipboard(Speed.ToString());                                                              // 話速の値をクリップボードに転記
                    SendMessage(hMainWnds[UIhWnds.voiceroid_speed_textbox], WM_PASTE, 0, 0);                     // 話速数値をペースト
                    PostMessage(hMainWnds[UIhWnds.voiceroid_speed_textbox], WM_KEYDOWN, VK_RETURN, 0);           // 話速数値を確定
                    speed_prev = speed;
                }
                if ((voiceEffectApplyMode == vRoidVoiceEffectApplyMode.resetStateAndApply) ||
                    ((voiceEffectApplyMode == vRoidVoiceEffectApplyMode.keepStateAndApply) && (volume_prev != volume)))
                {
                    SendMessage(hMainWnds[UIhWnds.voiceroid_volume_textbox], EM_SETSEL, 0, UInt32.MaxValue);     // 音量を選択
                    SetClipboard(Volume.ToString());                                                             // 音量の値をクリップボードに転記
                    SendMessage(hMainWnds[UIhWnds.voiceroid_volume_textbox], WM_PASTE, 0, 0);                    // 音量数値をペースト
                    PostMessage(hMainWnds[UIhWnds.voiceroid_volume_textbox], WM_KEYDOWN, VK_RETURN, 0);          // 音量数値を確定
                    volume_prev = volume;
                }
            }
            private void SetVoiceEffect_Voiceroid_Plus()
            {
                // vRoidVoiceEffectApplyMode.keepStateAndApply を実装する方法が思いつかないでいる
 
                decimal volume = Volume;
                decimal speed = Speed;
                decimal pitch = Pitch;
 
                SetVoiceEffect_init_Voiceroid_Plus();
 
                SendMessage(hMainWnds[UIhWnds.voiceroid_effect_window_child], WM_SETFOCUS, 0, 0);
 
                // 音量を選択
                PostMessage(hMainWnds[UIhWnds.voiceroid_effect_window_child], WM_KEYDOWN, VK_TAB, 0x000F0001);
                PostMessage(hMainWnds[UIhWnds.voiceroid_effect_window_child], WM_CHAR, VK_TAB, 0x000F0001);
                PostMessage(hMainWnds[UIhWnds.voiceroid_effect_window_child], WM_KEYUP, VK_TAB, 0xC00F0001);
                if (volume != 1.0m) TuneVoiceEffectSlider_Voiceroid_Plus(0.00m, 2.00m, 0.05m, volume);
 
                // 速度を選択
                PostMessage(hMainWnds[UIhWnds.voiceroid_effect_window_child], WM_KEYDOWN, VK_TAB, 0x000F0001);
                PostMessage(hMainWnds[UIhWnds.voiceroid_effect_window_child], WM_CHAR, VK_TAB, 0x000F0001);
                PostMessage(hMainWnds[UIhWnds.voiceroid_effect_window_child], WM_KEYUP, VK_TAB, 0xC00F0001);
                if (speed != 1.0m) TuneVoiceEffectSlider_Voiceroid_Plus(0.50m, 2.00m, 0.10m, speed);
 
                // ピッチを選択
                PostMessage(hMainWnds[UIhWnds.voiceroid_effect_window_child], WM_KEYDOWN, VK_TAB, 0x000F0001);
                PostMessage(hMainWnds[UIhWnds.voiceroid_effect_window_child], WM_CHAR, VK_TAB, 0x000F0001);
                PostMessage(hMainWnds[UIhWnds.voiceroid_effect_window_child], WM_KEYUP, VK_TAB, 0xC00F0001);
                if (pitch != 1.0m) TuneVoiceEffectSlider_Voiceroid_Plus(0.50m, 2.00m, 0.10m, pitch);
 
                // エコー:タイムを選択
                PostMessage(hMainWnds[UIhWnds.voiceroid_effect_window_child], WM_KEYDOWN, VK_TAB, 0x000F0001);
                PostMessage(hMainWnds[UIhWnds.voiceroid_effect_window_child], WM_CHAR, VK_TAB, 0x000F0001);
                PostMessage(hMainWnds[UIhWnds.voiceroid_effect_window_child], WM_KEYUP, VK_TAB, 0xC00F0001);
 
                // エコー:ゲインを選択
                PostMessage(hMainWnds[UIhWnds.voiceroid_effect_window_child], WM_KEYDOWN, VK_TAB, 0x000F0001);
                PostMessage(hMainWnds[UIhWnds.voiceroid_effect_window_child], WM_CHAR, VK_TAB, 0x000F0001);
                PostMessage(hMainWnds[UIhWnds.voiceroid_effect_window_child], WM_KEYUP, VK_TAB, 0xC00F0001);
 
                // 高域強調を選択
                PostMessage(hMainWnds[UIhWnds.voiceroid_effect_window_child], WM_KEYDOWN, VK_TAB, 0x000F0001);
                PostMessage(hMainWnds[UIhWnds.voiceroid_effect_window_child], WM_CHAR, VK_TAB, 0x000F0001);
                PostMessage(hMainWnds[UIhWnds.voiceroid_effect_window_child], WM_KEYUP, VK_TAB, 0xC00F0001);
            }
            private void SetVoiceEffect_Voiceroid_Plus_2()
            {
                // vRoidVoiceEffectApplyMode.keepStateAndApply を実装する方法が思いつかないでいる
 
                decimal volume = Volume;
                decimal speed = Speed;
                decimal pitch = Pitch;
 
                SetVoiceEffect_init_Voiceroid_Plus();
 
                SendMessage(hMainWnds[UIhWnds.voiceroid_effect_window_child], WM_SETFOCUS, 0, 0);
 
                // 音量を選択
                PostMessage(hMainWnds[UIhWnds.voiceroid_effect_window_child], WM_KEYDOWN, VK_TAB, 0x000F0001);
                PostMessage(hMainWnds[UIhWnds.voiceroid_effect_window_child], WM_CHAR, VK_TAB, 0x000F0001);
                PostMessage(hMainWnds[UIhWnds.voiceroid_effect_window_child], WM_KEYUP, VK_TAB, 0xC00F0001);
                if (volume != 1.0m) TuneVoiceEffectSlider_Voiceroid_Plus(0.00m, 2.00m, 0.01m, volume);
 
                // 速度を選択
                PostMessage(hMainWnds[UIhWnds.voiceroid_effect_window_child], WM_KEYDOWN, VK_TAB, 0x000F0001);
                PostMessage(hMainWnds[UIhWnds.voiceroid_effect_window_child], WM_CHAR, VK_TAB, 0x000F0001);
                PostMessage(hMainWnds[UIhWnds.voiceroid_effect_window_child], WM_KEYUP, VK_TAB, 0xC00F0001);
                if (speed != 1.0m) TuneVoiceEffectSlider_Voiceroid_Plus(0.50m, 2.00m, 0.01m, speed);
 
                // ピッチを選択
                PostMessage(hMainWnds[UIhWnds.voiceroid_effect_window_child], WM_KEYDOWN, VK_TAB, 0x000F0001);
                PostMessage(hMainWnds[UIhWnds.voiceroid_effect_window_child], WM_CHAR, VK_TAB, 0x000F0001);
                PostMessage(hMainWnds[UIhWnds.voiceroid_effect_window_child], WM_KEYUP, VK_TAB, 0xC00F0001);
                if (pitch != 1.0m) TuneVoiceEffectSlider_Voiceroid_Plus(0.50m, 2.00m, 0.01m, pitch);
 
                // エコー:タイムを選択
                PostMessage(hMainWnds[UIhWnds.voiceroid_effect_window_child], WM_KEYDOWN, VK_TAB, 0x000F0001);
                PostMessage(hMainWnds[UIhWnds.voiceroid_effect_window_child], WM_CHAR, VK_TAB, 0x000F0001);
                PostMessage(hMainWnds[UIhWnds.voiceroid_effect_window_child], WM_KEYUP, VK_TAB, 0xC00F0001);
 
                // エコー:ゲインを選択
                PostMessage(hMainWnds[UIhWnds.voiceroid_effect_window_child], WM_KEYDOWN, VK_TAB, 0x000F0001);
                PostMessage(hMainWnds[UIhWnds.voiceroid_effect_window_child], WM_CHAR, VK_TAB, 0x000F0001);
                PostMessage(hMainWnds[UIhWnds.voiceroid_effect_window_child], WM_KEYUP, VK_TAB, 0xC00F0001);
 
                // 高域強調を選択
                PostMessage(hMainWnds[UIhWnds.voiceroid_effect_window_child], WM_KEYDOWN, VK_TAB, 0x000F0001);
                PostMessage(hMainWnds[UIhWnds.voiceroid_effect_window_child], WM_CHAR, VK_TAB, 0x000F0001);
                PostMessage(hMainWnds[UIhWnds.voiceroid_effect_window_child], WM_KEYUP, VK_TAB, 0xC00F0001);
 
                // 出荷時の設定に戻すを選択
                PostMessage(hMainWnds[UIhWnds.voiceroid_effect_window_child], WM_KEYDOWN, VK_TAB, 0x000F0001);
                PostMessage(hMainWnds[UIhWnds.voiceroid_effect_window_child], WM_CHAR, VK_TAB, 0x000F0001);
                PostMessage(hMainWnds[UIhWnds.voiceroid_effect_window_child], WM_KEYUP, VK_TAB, 0xC00F0001);
            }
            private void TuneVoiceEffectSlider_Voiceroid_Plus(decimal min, decimal max, decimal step, decimal val)
            {
                decimal value = val;
 
                if ( 1.00m < value)
                {
                    value = max < value ? max : value;
                    for (decimal count = 1.00m; count < value; count += step)
                    {
                        PostMessage(hMainWnds[UIhWnds.voiceroid_effect_window_child], WM_KEYDOWN, VK_RIGHT, 0x014D0001);
                        PostMessage(hMainWnds[UIhWnds.voiceroid_effect_window_child], WM_KEYUP, VK_RIGHT, 0xC14D0001);
                    }
                }
                else
                {
                    value = min > value ? min : value;
                    for (decimal count = 1.00m; count > value; count -= step)
                    {
                        PostMessage(hMainWnds[UIhWnds.voiceroid_effect_window_child], WM_KEYDOWN, VK_LEFT, 0x014B0001);
                        PostMessage(hMainWnds[UIhWnds.voiceroid_effect_window_child], WM_KEYUP, VK_LEFT, 0xC14B0001);
                    }
                }
            }
            private void CopyTalkText_voiceroid_Plus_Ex()
            {
                // 多分VOICEROID+EXで有効な方法
                WaitPlaying();
                SendMessage(hMainWnds[UIhWnds.voiceroid_textbox], EM_SETSEL, 0, UInt32.MaxValue); // 全テキストを選択
                SetClipboard(TalkTextSb.ToString());                                              // クリップボードに転記
                SendMessage(hMainWnds[UIhWnds.voiceroid_textbox], WM_PASTE, 0, 0);                // クリップボードの内容をペースト
            }
            private void CopyTalkText_voiceroid_Plus_2()
            {
                // 多分VOICEROID+の新しい方で有効
                SendMessage(hMainWnds[UIhWnds.voiceroid_mainwindow], WM_COMMAND, 60, 0);          // メニューの全て選択
                //SendMessage(hMainWnds[UIhWnds.voiceroid_mainwindow], WM_COMMAND, 52, 0);        // メニューの削除
                SetClipboard(TalkTextSb.ToString());                                              // クリップボードに転記
                SendMessage(hMainWnds[UIhWnds.voiceroid_mainwindow], WM_COMMAND, 56, 0);          // メニューの貼り付け
            }
            private void CopyTalkText_voiceroid_Plus()
            {
                // 多分VOICEROID+の初期型で有効
                SendMessage(hMainWnds[UIhWnds.voiceroid_mainwindow], WM_COMMAND, 46, 0);          // メニューの元に戻す
                SetClipboard(TalkTextSb.ToString());                                              // クリップボードに転記
                SendMessage(hMainWnds[UIhWnds.voiceroid_mainwindow], WM_COMMAND, 56, 0);          // メニューの貼り付け
            }
            private void GetSaveDialogWindowHandle_Type1(string dlgtitle, int retryCount, int retryWaitms)
            {
                IntPtr hWndWorkPtr = IntPtr.Zero;
                IntPtr hWndDlgWinPtr = IntPtr.Zero;
                IntPtr hWndDaddy = IntPtr.Zero;
                IntPtr hParentWnd = hMainWnds[UIhWnds.voiceroid_mainwindow];
 
                hDlgWnds.Clear();
 
                for (int i = 0; i < retryCount; i++)
                {
                    hWndWorkPtr = FindWindow("#32770", dlgtitle); // "#32770 (ダイアログ)" はダイアログのクラス名?
 
                    if (hWndWorkPtr != IntPtr.Zero)
                    {
                        while (!hWndWorkPtr.Equals(IntPtr.Zero))
                        {
                            hWndDaddy = GetParent(hWndWorkPtr);
                            if (hParentWnd.Equals(hWndDaddy))
                            {
                                break;
                            }
                            else
                            {
                                hWndWorkPtr = GetWindow(hWndWorkPtr, GW_HWNDNEXT);
                            }
                        }
                    }
 
                    if (hParentWnd.Equals(hWndDaddy)) break;
                    if (i < (retryCount - 1)) Thread.Sleep(retryWaitms);
                }
                hWndDlgWinPtr = hWndWorkPtr;
 
                if (hWndDlgWinPtr == IntPtr.Zero)
                {
                    hDlgWnds.Add(UIhWnds.savedlg_mainwindow, IntPtr.Zero);
                    hDlgWnds.Add(UIhWnds.savedlg_editbox, IntPtr.Zero);
                    hDlgWnds.Add(UIhWnds.savedlg_savebutton, IntPtr.Zero);
                    return;
                }
 
                Thread.Sleep(1000);
 
                // ダイアログウインドウハンドル
                hDlgWnds.Add(UIhWnds.savedlg_mainwindow, hWndDlgWinPtr);
 
                // テキストボックス
                hWndWorkPtr = hWndDlgWinPtr;
                hWndWorkPtr = GetWindow(hWndWorkPtr, GW_CHILD); // 第1層ウインドウ
                hWndWorkPtr = GetWindow(hWndWorkPtr, GW_CHILD); // 第2層ウインドウ
                hWndWorkPtr = GetWindow(hWndWorkPtr, GW_CHILD); // 第3層ウインドウ
                hWndWorkPtr = GetWindow(hWndWorkPtr, GW_CHILD); // 第4層ウインドウ
                hWndWorkPtr = GetWindow(hWndWorkPtr, GW_CHILD); // 第5層ウインドウ
                hDlgWnds.Add(UIhWnds.savedlg_editbox, hWndWorkPtr); // テキストボックス
 
                // 保存ボタン
                hWndWorkPtr = FindWindowEx(hWndDlgWinPtr, IntPtr.Zero, "Button", "保存(&S)"); // 配下の保存ボタン
                hDlgWnds.Add(UIhWnds.savedlg_savebutton, hWndWorkPtr);
            }
            private void GetSaveDialogWindowHandle_Type2(string dlgtitle, int retryCount, int retryWaitms)
            {
                IntPtr hWnd = IntPtr.Zero;
                IntPtr hWndWorkPtr = IntPtr.Zero;
                IntPtr hWndDlgWinPtr = IntPtr.Zero;
                int processId = 0;
                int voiceroidProcessId = (int)hMainWnds[UIhWnds.voiceroid_processid];
 
                hDlgWnds.Clear();
 
                for (int i = 0; i < retryCount; i++)
                {
                    hWnd = FindWindow("#32770", dlgtitle); // "#32770 (ダイアログ)" はダイアログのクラス名?
 
                    if (hWnd != IntPtr.Zero)
                    {
                        while (!hWnd.Equals(IntPtr.Zero))
                        {
                            GetWindowThreadProcessId(hWnd, out processId);
                            if (processId == voiceroidProcessId)
                            {
                                break;
                            }
                            else
                            {
                                hWnd = GetWindow(hWnd, GW_HWNDNEXT);
                            }
                        }
                    }
 
                    if (voiceroidProcessId == processId) break;
                    if (i < (retryCount - 1)) Thread.Sleep(retryWaitms);
                }
                hWndDlgWinPtr = hWnd;
 
                // ダイアログウインドウハンドル
                hDlgWnds.Add(UIhWnds.savedlg_mainwindow, hWndDlgWinPtr);
 
                if (hWndDlgWinPtr == IntPtr.Zero)
                {
                    hDlgWnds.Add(UIhWnds.savedlg_editbox, IntPtr.Zero);
                    hDlgWnds.Add(UIhWnds.savedlg_savebutton, IntPtr.Zero);
                    return;
                }
 
                Thread.Sleep(1000);
 
                // テキストボックス
                hWndWorkPtr = hWndDlgWinPtr;
                hWndWorkPtr = GetWindow(hWndWorkPtr, GW_CHILD); // 第1層ウインドウ
                hWndWorkPtr = GetWindow(hWndWorkPtr, GW_CHILD); // 第2層ウインドウ
                hWndWorkPtr = GetWindow(hWndWorkPtr, GW_CHILD); // 第3層ウインドウ
                hWndWorkPtr = GetWindow(hWndWorkPtr, GW_CHILD); // 第4層ウインドウ
                hWndWorkPtr = GetWindow(hWndWorkPtr, GW_CHILD); // 第5層ウインドウ
                hDlgWnds.Add(UIhWnds.savedlg_editbox, hWndWorkPtr); // テキストボックス
 
                // 保存ボタン
                hWndWorkPtr = FindWindowEx(hWndDlgWinPtr, IntPtr.Zero, "Button", "保存(&S)"); // 配下の保存ボタン
                hDlgWnds.Add(UIhWnds.savedlg_savebutton, hWndWorkPtr);
            }
            private void PlayVoice_Voiceroid_Plus_Ex()
            {
                SendMessage(hMainWnds[UIhWnds.voiceroid_playbutton], BM_CLICK, 0, 0); // 再生ボタンクリック
            }
            private void PlayVoice_Voiceroid_Plus_2()
            {
                SendMessage(hMainWnds[UIhWnds.voiceroid_playbutton], WM_NULL, 0, 0); // 再生ボタンクリック
            }
            private void PlayVoice_Voiceroid_Plus()
            {
                SendMessage(hMainWnds[UIhWnds.voiceroid_playbutton], WM_NULL, 0, 0); // 再生ボタンクリック
            }
            private void SaveVoice_voiceroid_Plus_Ex()
            {
                if (WavFilePathSb.Length == 0) return;
 
                Thread.Sleep(1000);
                PostMessage(hMainWnds[UIhWnds.voiceroid_savebutton], BM_CLICK, 0, 0); // 音声保存ボタンクリック
 
                Thread.Sleep(1000);
                GetSaveDialogWindowHandle_Type1("音声ファイルの保存", 300, 100);
 
                SaveDialogControl(WavFilePathSb.ToString());
            }
            private void SaveVoice_voiceroid_Plus_2()
            {
                if (WavFilePathSb.Length == 0) return;
 
                Thread.Sleep(1000);
                PostMessage(hMainWnds[UIhWnds.voiceroid_savebutton], BM_CLICK, 0, 0); // 音声保存ボタンクリック
 
                Thread.Sleep(1000);
                GetSaveDialogWindowHandle_Type2("音声ファイルの保存", 300, 100);
 
                SaveDialogControl(WavFilePathSb.ToString());
            }
            private void SaveVoice_voiceroid_Plus()
            {
                if (WavFilePathSb.Length == 0) return;
 
                Thread.Sleep(1000);
                PostMessage(hMainWnds[UIhWnds.voiceroid_savebutton], WM_NULL, 0, 0); // 音声保存ボタンクリック
 
                Thread.Sleep(1000);
                GetSaveDialogWindowHandle_Type1("音声ファイルの保存", 300, 100);
 
                SaveDialogControl(WavFilePathSb.ToString());
            }
            private void SaveDialogControl(string filenamePath)
            {
 
                if (!hDlgWnds[UIhWnds.savedlg_mainwindow].Equals(IntPtr.Zero))
                {
                    StringBuilder sb = new StringBuilder(filenamePath);
 
                    SendMessage(hDlgWnds[UIhWnds.savedlg_editbox], WM_SETTEXT, 0, sb);
                    SendMessage(hDlgWnds[UIhWnds.savedlg_savebutton], BM_CLICK, 0, 0);
                }
 
                Thread.Sleep(1000);
            }
            private void WaitPlaying()
            {
                int winTextLen = 0;
                int count = 0;
 
                while (true)
                {
                    winTextLen = GetWindowTextLength(hMainWnds[UIhWnds.voiceroid_playbutton]);
 
                    if (0 < winTextLen)
                    {
                        StringBuilder sb = new StringBuilder(winTextLen + 1);
                        GetWindowText(hMainWnds[UIhWnds.voiceroid_playbutton], sb, sb.Capacity);
 
                        if (sb.ToString() == " 再生")  // 文字列先頭が空白なので注意
                        {
                            break;
                        }
                        else
                        {
                            count++;
                            Thread.Sleep(100);
                            if (1800 < count) break; // 3分待ったら待つの止めるよ!
                        }
                    }
                }
            }
            private void WaitPlaying2()
            {
                int winTextLen = 0;
                int count = 0;
 
                // VOICEROID +EX はキャプションの変化が遅い模様
 
                while (true)
                {
                    winTextLen = GetWindowTextLength(hMainWnds[UIhWnds.voiceroid_playbutton]);
 
                    if (0 < winTextLen)
                    {
                        StringBuilder sb = new StringBuilder(winTextLen + 1);
                        GetWindowText(hMainWnds[UIhWnds.voiceroid_playbutton], sb, sb.Capacity);
 
                        if (sb.ToString() != " 再生")  // 文字列先頭が空白なので注意
                        {
                            break;
                        }
                        else
                        {
                            count++;
                            Thread.Sleep(100);
                            if (1800 < count) break; // 3分待ったら次のループへ移るよ!
                        }
                    }
                }
 
                winTextLen = 0;
                count = 0;
                while (true)
                {
                    winTextLen = GetWindowTextLength(hMainWnds[UIhWnds.voiceroid_playbutton]);
 
                    if (0 < winTextLen)
                    {
                        StringBuilder sb = new StringBuilder(winTextLen + 1);
                        GetWindowText(hMainWnds[UIhWnds.voiceroid_playbutton], sb, sb.Capacity);
 
                        if (sb.ToString() == " 再生")  // 文字列先頭が空白なので注意
                        {
                            break;
                        }
                        else
                        {
                            count++;
                            Thread.Sleep(100);
                            if (1800 < count) break; // 3分待ったら待つの止めるよ!
                        }
                    }
                }
            }
            private void SetClipboard(string text)
            {
                TextDataFormat tf = UnicodeText ? TextDataFormat.UnicodeText : TextDataFormat.Text;
 
                Thread t = new Thread(() => {
                    Clipboard.SetText(text, tf);
                });
                t.SetApartmentState(ApartmentState.STA);
                t.Start();
                t.Join();
            }
            private void ScanWindowHandles()
            {
                GetMainWindowHandle(voiceroid);
                switch (voiceroid)
                {
                    case vRoidAvator.YUKARI:
                    case vRoidAvator.TAMMY:
                    case vRoidAvator.YOSHIDA:
                        GetMainWindowControlHandle_Voiceroid_Plus();
                        GetVoiceEffectWindowHandle_Voiceroid_Plus();
                        break;
 
                    case vRoidAvator.ZUNKO:
                        GetMainWindowControlHandle_Voiceroid_Plus_2();
                        GetVoiceEffectWindowHandle_Voiceroid_Plus_Ex();
                        break;
 
                    default:
                        GetMainWindowControlHandle_Voiceroid_Plus_Ex();
                        GetVoiceEffectWindowHandle_Voiceroid_Plus_Ex();
                        break;
                }
            }
 
            public enum UIhWnds
            {
                voiceroid_processid,
                voiceroid_mainwindow,
                voiceroid_mainwindow_child,
                voiceroid_textbox,
                voiceroid_playbutton,
                voiceroid_savebutton,
                voiceroid_effect_window,
                voiceroid_effect_window_child,
                voiceroid_pitch_slider,
                voiceroid_speed_slider,
                voiceroid_volume_slider,
                voiceroid_High_frequency,
                voiceroid_intonation_textbox,
                voiceroid_pitch_textbox,
                voiceroid_speed_textbox,
                voiceroid_volume_textbox,
                voiceroid_intonation_initbutton,
                voiceroid_pitch_initbutton,
                voiceroid_speed_initbutton,
                voiceroid_volume_initbutton,
                savedlg_mainwindow,
                savedlg_editbox,
                savedlg_savebutton
            };
            public decimal Volume
            {
                get
                {
                    return volume;
                }
                set
                {
                    if (value < 0.00m)
                    {
                        volume = 0.00m;
                    }
                    else if (value > 2.00m)
                    {
                        volume = 2.00m;
                    }
                    else
                    {
                        volume = truncs(value, 2);
                    }
                }
            }
            public decimal Pitch
            {
                get
                {
                    return pitch;
                }
                set
                {
                    if (value < 0.50m)
                    {
                        pitch = 0.50m;
                    }
                    else if (value > 2.00m)
                    {
                        pitch = 2.00m;
                    }
                    else
                    {
                        pitch = truncs(value, 2);
                    }
                }
            }
            public decimal Intonation
            {
                get
                {
                    return intonation;
                }
                set
                {
                    if (value < 0.00m)
                    {
                        intonation = 0.00m;
                    }
                    else if (value > 2.00m)
                    {
                        intonation = 2.00m;
                    }
                    else
                    {
                        intonation = truncs(value, 2);
                    }
                }
            }
            public decimal Speed
            {
                get
                {
                    return speed;
                }
                set
                {
                    if (value < 0.50m)
                    {
                        speed = 0.50m;
                    }
                    else if (value > 4.00m)
                    {
                        speed = 4.00m;
                    }
                    else
                    {
                        speed = truncs(value, 2);
                    }
                }
            }
            public decimal Whisper
            {
                get
                {
                    return whisper;
                }
                set
                {
                    if (value < 0.00m)
                    {
                        whisper = 0.00m;
                    }
                    else if (value > 1.00m)
                    {
                        whisper = 1.00m;
                    }
                    else
                    {
                        whisper = truncs(value, 2);
                    }
                }
            }
            public decimal Emotion_happy
            {
                get
                {
                    return emotion_happy;
                }
                set
                {
                    if (value < 0.00m)
                    {
                        emotion_happy = 0.00m;
                    }
                    else if (value > 1.00m)
                    {
                        emotion_happy = 1.00m;
                    }
                    else
                    {
                        emotion_happy = truncs(value, 2);
                    }
                }
            }
            public decimal Emotion_sad
            {
                get
                {
                    return emotion_sad;
                }
                set
                {
                    if (value < 0.00m)
                    {
                        emotion_sad = 0.00m;
                    }
                    else if (value > 1.00m)
                    {
                        emotion_sad = 1.00m;
                    }
                    else
                    {
                        emotion_sad = truncs(value, 2);
                    }
                }
            }
            public decimal Emotion_anger
            {
                get
                {
                    return emotion_anger;
                }
                set
                {
                    if (value < 0.00m)
                    {
                        emotion_anger = 0.00m;
                    }
                    else if (value > 1.00m)
                    {
                        emotion_anger = 1.00m;
                    }
                    else
                    {
                        emotion_anger = truncs(value, 2);
                    }
                }
            }
            public bool WhisperEffectSwitch { get; set; }
            public int RetryCount { get; }
            public int RetryWaitms { get; }
            public string TalkText
            {
                set
                {
                    TalkTextSb.Clear();
                    TalkTextSb.Append(value);
                }
            }
            public string WavFilePath
            {
                set
                {
                    WavFilePathSb.Clear();
                    WavFilePathSb.Append(value);
                }
            }
            public string ExecutionPath
            {
                set
                {
                    ExecutionPathSb.Clear();
                    ExecutionPathSb.Append(value);
                }
            }
            public bool UnicodeText
            {
                get; set;
            }
            public vRoidVoiceEffectApplyMode VoiceEffectApplyMode { get; set; }
 
            private decimal truncs(decimal val, int digits)
            {
                decimal scale = (decimal)Math.Pow(10, digits);
                decimal ans = val > 0 ? Math.Floor(val * scale) / scale : Math.Ceiling(val * scale) / scale;
 
                return ans;
            }
            private Dictionary<UIhWnds, IntPtr> hMainWnds { get; }
 
            private Dictionary<UIhWnds, IntPtr> hDlgWnds;
            private vRoidAvator voiceroid;
            private StringBuilder ExecutionPathSb = new StringBuilder();
            private StringBuilder TalkTextSb = new StringBuilder();
            private StringBuilder WavFilePathSb = new StringBuilder();
            private decimal volume;
            private decimal volume_prev;
            private decimal pitch;
            private decimal pitch_prev;
            private decimal intonation;
            private decimal intonation_prev;
            private decimal speed;
            private decimal speed_prev;
            private decimal whisper;
            private decimal whisper_prev;
            private decimal emotion_anger;
            private decimal emotion_anger_prev;
            private decimal emotion_happy;
            private decimal emotion_happy_prev;
            private decimal emotion_sad;
            private decimal emotion_sad_prev;
 
            private vRoidVoiceEffectApplyMode voiceEffectApplyMode;
 
            const uint WM_NULL = 0x0000;
            const uint WM_ACTIVATE = 0x0006;
            const uint WM_SETFOCUS = 0x0007;
            const uint WM_SETTEXT = 0x000C;
            const uint WM_PAINT = 0x000F;
            const uint WM_SHOWWINDOW = 0x0018;
            const uint WM_SETCURSOR = 0x0020;
            const uint WM_NEXTDLGCTL = 0x0028;
            const uint WM_WINDOWPOSCHANGING = 0x0046;
            const uint WM_NOTIFY = 0x004E;
            const uint WM_NCACTIVATE = 0x0086;
            const uint WM_KEYDOWN = 0x0100;
            const uint WM_KEYUP = 0x0101;
            const uint WM_CHAR = 0x0102;
            const uint WM_COMMAND = 0x0111;
            const uint WM_HSCROLL = 0x114;
            const uint WM_VSCROLL = 0x115;
            const uint WM_IME_SETCONTEXT = 0x0281;
            const uint WM_IME_NOTIFY = 0x0282;
            const uint WM_PASTE = 0x0302;
            const uint TBM_GETPOS = 0x400;
            const uint TBM_SETPOS = 0x405;
            const uint EM_SETSEL = 0x00B1;
            const uint BM_CLICK = 0x00F5;
            const uint GW_HWNDNEXT = 0x0002;
            const uint GW_CHILD = 0x0005;
            const int VK_TAB = 0x09;
            const int VK_RETURN = 0x0D;
            const int VK_LEFT = 0x25;
            const int VK_RIGHT = 0x27;
            const int VK_F7 = 0x76;
            const int SB_LINELEFT = 0x00;
            const int SB_LINERIGHT = 0x01;
            const int IMN_SETCOMPOSITIONWINDOW = 0x0B;
            const int IMN_OPENSTATUSWINDOW = 0x02;
            const int IMN_CLOSESTATUSWINDOW = 0x01;
            const int WA_ACTIVE = 1;
 
            [DllImport("user32.dll")]
            private static extern IntPtr GetWindow(IntPtr hWnd, uint uCmd);
 
            [DllImport("user32.dll")]
            private static extern IntPtr GetParent(IntPtr hWnd);
 
            [DllImport("user32.dll")]
            private static extern int PostMessage(IntPtr hWnd, uint Msg, int wParam, uint lParam);
 
            [DllImport("user32.dll")]
            private static extern int SendMessage(IntPtr hWnd, uint Msg, int wParam, uint lParam);
 
            [DllImport("user32.dll")]
            private static extern int SendMessage(IntPtr hWnd, uint Msg, int wParam, IntPtr lParam);
 
            [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
            private static extern int SendMessage(IntPtr hWnd, uint Msg, int wParam, StringBuilder lParam);
 
            [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
            private static extern int SendMessage(IntPtr hWnd, uint Msg, int wParam, string lParam);
 
            [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
            public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
 
            [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
            private static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
 
            [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
            private static extern int GetWindowTextLength(IntPtr hWnd);
 
            [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
            private static extern IntPtr FindWindowEx(IntPtr hWndParent, IntPtr hWndChildAfter, string lpszClass, string lpString);
 
            [DllImport("user32.dll")]
            private static extern int GetWindowThreadProcessId(IntPtr hWnd, out int lpdwProcessId);
 
            [DllImport("user32.dll")]
            private static extern IntPtr SetFocus(IntPtr hWnd);
        }
    }
 
    /// <summary>
    /// ターゲットのVOICEROIDアバター
    /// </summary>
    public enum vRoidAvator
    {
        /// <summary>
        /// VOICEROID+ 京町セイカ EX
        /// </summary>
        SEIKA,
        /// <summary>
        /// VOICEROID+ 鷹の爪 吉田くん EX
        /// </summary>
        YOSHIDA_EX,
        /// <summary>
        /// VOICEROID+ 月読アイ EX
        /// </summary>
        AI_EX,
        /// <summary>
        /// VOICEROID+ 月読ショウタ EX
        /// </summary>
        SHOUTA_EX,
        /// <summary>
        /// VOICEROID+ 水奈瀬コウ EX
        /// </summary>
        MINASE,
        /// <summary>
        /// VOICEROID+ 東北きりたん EX
        /// </summary>
        KIRITAN,
        /// <summary>
        /// VOICEROID+ 東北ずん子
        /// </summary>
        ZUNKO,
        /// <summary>
        /// VOICEROID+ 東北ずん子 EX
        /// </summary>
        ZUNKO_EX,
        /// <summary>
        /// VOICEROID+ 民安ともえ EX
        /// </summary>
        TAMMY_EX,
        /// <summary>
        /// VOICEROID+ 結月ゆかり EX
        /// </summary>
        YUKARI_EX,
        /// <summary>
        /// VOICEROID+ 琴葉茜
        /// </summary>
        AKANE,
        /// <summary>
        /// VOICEROID+ 琴葉葵
        /// </summary>
        AOI,
        /// <summary>
        /// VOICEROID+ 民安ともえ
        /// </summary>
        TAMMY,
        /// <summary>
        /// VOICEROID+ 結月ゆかり
        /// </summary>
        YUKARI,
        /// <summary>
        /// VOICEROID+ 鷹の爪 吉田くん
        /// </summary>
        YOSHIDA,
        /// <summary>
        /// 音街ウナTalk Ex
        /// </summary>
        UNA,
        /// <summary>
        /// DLL内では使用しません。これで定義しても動作はしないでしょう。
        /// </summary>
        MS_TTS,
        /// <summary>
        /// DLL内では使用しません。これで定義しても動作はしないでしょう。
        /// </summary>
        VOICEROID2
    }
    /// <summary>
    /// プロダクト名サポートクラス
    /// </summary>
    public static class vRoidAvatorEx
    {
        /// <summary>
        /// プロダクト名
        /// </summary>
        /// <param name="value">アバター</param>
        /// <returns>名称文字列</returns>
        public static string ProdName(this vRoidAvator value)
        {
            string[] values =
            {
                "VOICEROID+ 京町セイカ EX",
                "VOICEROID+ 鷹の爪 吉田くん EX",
                "VOICEROID+ 月読アイ EX",
                "VOICEROID+ 月読ショウタ EX",
                "VOICEROID+ 水奈瀬コウ EX",
                "VOICEROID+ 東北きりたん EX",
                "VOICEROID+ 東北ずん子",
                "VOICEROID+ 東北ずん子 EX",
                "VOICEROID+ 民安ともえ EX",
                "VOICEROID+ 結月ゆかり EX",
                "VOICEROID+ 琴葉茜",
                "VOICEROID+ 琴葉葵",
                "VOICEROID+ 民安ともえ",
                "VOICEROID+ 結月ゆかり",
                "VOICEROID+ 鷹の爪 吉田くん",
                "音街ウナTalk Ex",
                "Microsoft 音声合成エンジン(SAPI)",
                "VOICEROID2"
            };
 
            return values[(int)value];
        }
        /// <summary>
        /// GUI構造
        /// </summary>
        /// <param name="value">アバター</param>
        /// <returns>旧式GUIならtrue</returns>
        public static bool isOldType(this vRoidAvator value)
        {
            bool ans = false;
 
            switch (value)
            {
                case vRoidAvator.TAMMY:
                case vRoidAvator.YUKARI:
                case vRoidAvator.YOSHIDA:
                    ans = true;
                    break;
 
                default:
                    ans = false;
                    break;
            }
            return ans;
        }
    }
 
    /// <summary>
    /// 音声効果パラメタ(VOICEROID+ 新型、VOICEROID+EX)
    /// </summary>
    public enum vRoidVoiceEffectParam
    {
        /// <summary>
        /// 音声効果の音量
        /// </summary>
        volume,
 
        /// <summary>
        /// 音声効果の高さ
        /// </summary>
        pitch,
 
        /// <summary>
        /// 音声効果の話速
        /// </summary>
        speed,
 
        /// <summary>
        /// 音声効果の抑揚
        /// </summary>
        intonation,
 
        /// <summary>
        /// ウィスパーボイス効果。まだこれを使う機能は実装されていません。
        /// </summary>
        whisper,
 
        /// <summary>
        /// 喜びの感情。まだこれを使う機能は実装されていません。
        /// </summary>
        emotion_happy,
 
        /// <summary>
        /// 怒りの感情。まだこれを使う機能は実装されていません。
        /// </summary>
        emotion_anger,
 
        /// <summary>
        /// 悲しみの感情。まだこれを使う機能は実装されていません。
        /// </summary>
        emotion_sad
    }
 
    /// <summary>
    /// 音声効果パラメタ適用方法
    /// </summary>
    public enum vRoidVoiceEffectApplyMode
    {
        /// <summary>
        /// 初期状態に対して適用する
        /// </summary>
        resetStateAndApply,
 
        /// <summary>
        /// 以前の状態に対して適用する
        /// </summary>
        keepStateAndApply
    }
}

その他2

説明用。

JSONで取ってきたデータをVOICEROIDに渡すと化ける、と言うので確認用に書いたコードです。
https://api.bitflyer.jp/v1/getchats?from_date=2017-12-19 の呼び出しでJSON形式のチャットデータを取り込んでゆかりさんにしゃべってもらったところ、 絵文字が化けるくらいで読み上げが困難な文字化けは発生しないようです。

Form1,cs
using System;
using System.Data;
using System.Linq;
using System.Threading;
using System.Windows.Forms;
using echoSeikaAPI;
 
namespace FlyerChatReader
{
    public partial class Form1 : Form
    {
        RestAPIAccess ra;
 
        public Form1()
        {
            InitializeComponent();
        }
 
        // GETボタン
        private void button1_Click(object sender, EventArgs e)
        {
 
            button1.Enabled = false;
 
            Thread t = new Thread(() => {
                ra = new RestAPIAccess(textBox1.Text);
            });
            t.Start();
            t.Join();
 
            listBox1.Items.AddRange( ra.messages.Select(x => x.message + " | " + x.date + " | " + x.nickname ).ToArray());
 
            vRoidController v = new vRoidController();
            v.Register_vRoid(vRoidAvator.YUKARI_EX);
 
            for (int i = 0; i < 10; i++)
            {
                v.PlaySync(vRoidAvator.YUKARI_EX, ra.messages[i].nickname + "さん " + ra.messages[i].message);
            }
 
            button1.Enabled = true;
        }
    }
}
RestAPIAccess.cs
using System;
using System.Net;
using System.Runtime.Serialization.Json;
using System.Runtime.Serialization;
using System.IO;
 
namespace FlyerChatReader
{
    [DataContract]
    class ChatData
    {
        [DataMember]
        public string nickname;
        [DataMember]
        public string message;
        [DataMember]
        public string date;
    }
 
    class RestAPIAccess
    {
        public ChatData[] messages { get; set; }
 
        public RestAPIAccess(string url)
        {
            Uri uri = new Uri(url);
 
            WebRequest req = WebRequest.Create(uri);
            req.Method = "GET";
            req.ContentType = "application/json";
 
            // JSON受信
            using (WebResponse res = req.GetResponse())
            {
                DataContractJsonSerializer js = new DataContractJsonSerializer(typeof(ChatData[]));
                using (Stream s = res.GetResponseStream())
                {
                    messages = js.ReadObject(s) as ChatData[];
                }
            }
        }
    }
 
}

コメント

コメントを入力. Wiki文法が有効です:
画像の文字が読めなければ、文字を読んだ.wavファイルをダウンロードして下さい。
 
documents/voiceroid/voiceroid-001.txt · 最終更新: 2018/01/14 12:46 by k896951

ページ用ツール