/// <summary> /// Aquestalkに話させるやつ。 /// <see cref="byte"/>配列で帰ってくるよ。 /// </summary> /// <param name="speed">スピード</param> /// <param name="textd">テキスト</param> /// <param name="pitch">ピッチ(100で標準)</param> /// <returns>wavファイル</returns> public byte[] speak_wav(int speed, string textd, int pitch) { yukkuri_lib_interface_EventClass evc = new yukkuri_lib_interface_EventClass(textd, speed); //32bitの方に与えるパラメータを初期化。 yukkuri_lib_interface.SPEAK_RETURN spr = yukkui.Speak_to_client(evc); //32bit側を呼び出し。byte配列でwavファイルが返ってくる。 if (!spr.error.err_code.Equals(yukkuri_lib_interface.DLL_ERR_CODE.NO_ERROR)) { throw new Exception(spr.error.message); } byte[] wavd = spr.wavdata; uint samplingRate = BitConverter.ToUInt32(wavd, 24); //サンプリングレートを算出。 uint dataRate = BitConverter.ToUInt32(wavd, 28); //データレートを算出。 float pct_to = (float)pitch / 100; //ピッチの割合を計算。success float samplingRatef = samplingRate; //サンプリング周波数をfloatに。 samplingRatef *= pct_to; //サンプリング周波数をpitchで変化させる。 samplingRate = (uint)samplingRatef; //floatなサンプリング周波数をintへコンバート。 float dataRatef = dataRate; //データレートをfloatへ。 dataRatef *= pct_to; //データレートをpitchで変化させる。 dataRate = (uint)dataRatef; //データレートをfloatからintへ。 byte[] samplingRateBytes = BitConverter.GetBytes(samplingRate); byte[] dataRateBytes = BitConverter.GetBytes(dataRate); Array.Copy(samplingRateBytes, 0, wavd, 24, 4); Array.Copy(dataRateBytes, 0, wavd, 28, 4); return(wavd); //改造版wavを返す。 }
/// <summary> /// Serverが呼び出す。 /// 指定した内容でwavを生成して返す。 /// </summary> /// <param name="paramkun">指定する内容。</param> /// <returns>wavファイル</returns> public SPEAK_RETURN Speak_to_client(yukkuri_lib_interface_EventClass paramkun) { yukkuri_lib_interface_EventArgs evt = new yukkuri_lib_interface_EventArgs(paramkun); //引数を生成 foreach (SpeakDelegate listener in eventListeners_speak) { return(listener(evt)); //実行する。 } SPEAK_RETURN spr = new SPEAK_RETURN(); spr.error.err_code = DLL_ERR_CODE.OTHER_ERROR; spr.error.message = "Event listener error"; return(spr); }
static void Main(string[] args) { if (args.Length < 1) //引数がないのは丘peopleなので... { Console.Error.WriteLine("Error!"); return; } string[] argskun = args[0].Split('|'); //argsを分割。 yukkuri_lib_interface.yukkuri_lib_interface yukkuri_inter; //インタフェースを作成。 Dictionary <string, string> channelproperty = new Dictionary <string, string>(); //チャンネル作成用。 channelproperty.Add("portName", argskun[1] + "_yukkuri_lib_kokkiemouse_client_" + argskun[0]); channelproperty.Add("name", argskun[0]); IpcChannel servChannel = new IpcChannel(channelproperty, null, new BinaryServerFormatterSinkProvider //チャンネル作成。 { TypeFilterLevel = System.Runtime.Serialization.Formatters.TypeFilterLevel.Full, }); ChannelServices.RegisterChannel(servChannel, true); //チャンネル登録。 yukkuri_inter = Activator.GetObject(typeof(yukkuri_lib_interface.yukkuri_lib_interface), "ipc://" + argskun[1] + "_yukkuri_lib_kokkiemouse_" + argskun[0] + '/' + argskun[0]) as yukkuri_lib_interface.yukkuri_lib_interface; //サーバー(64bit)のインタフェースを取得。 AquesTalk aq = new AquesTalk(); //Aquestalkのクラスを取得。 CountdownEvent cekun = new CountdownEvent(1); //待機用。 yukkuri_lib_interface.EventCallbackSink ebthink = new EventCallbackSink(); //コールバック関数 ebthink.OnClose += new CloseDelegate(() => //Oncloseで呼ばれる。 { cekun.Signal(); //復帰。(終了) }); ebthink.OnSpeak += new yukkuri_lib_interface.SpeakDelegate((yukkuri_lib_interface_EventArgs yukkuargs) => //OnSpeakを定義 { int speed = yukkuargs.eventargs.speed; //speedを突っ込む。 int size = 0; //サイズが入る。 string koe = yukkuargs.eventargs.textdata; //コピー。 IntPtr wavPtr = aq.AquesTalk_Synthe(koe, speed, out size); //Aquestalk呼び出し。ポインタが返ってくる。 if (wavPtr == IntPtr.Zero) //ぬるぽなら { SPEAK_RETURN spr2 = new SPEAK_RETURN(); switch (size) { case 100: spr2.error.err_code = DLL_ERR_CODE.OTHER_ERROR; spr2.error.message = "Other error!"; break; case 101: spr2.error.err_code = DLL_ERR_CODE.out_of_memory; spr2.error.message = "OUT OF MEMORY!"; break; case 102: spr2.error.err_code = DLL_ERR_CODE.undefined_symbol; spr2.error.message = "UNDEFINED_SYMBOL"; break; case 103: spr2.error.err_code = DLL_ERR_CODE.minus_speed; spr2.error.message = "ERROR! SPEED is MINUS!"; break; case 104: spr2.error.err_code = DLL_ERR_CODE.Undefined_delimiter_code_detection; spr2.error.message = "Undefined delimiter code detection!"; break; case 105: spr2.error.err_code = DLL_ERR_CODE.undefined_symbol; spr2.error.message = "UNDEFINED_SYMBOL"; break; case 106: spr2.error.err_code = DLL_ERR_CODE.syntax_tag_error; spr2.error.message = "Syntax tag error"; break; case 107: spr2.error.err_code = DLL_ERR_CODE.tag_end_error; spr2.error.message = "TAG END OR '>' ERROR"; break; case 108: spr2.error.err_code = DLL_ERR_CODE.tag_value_invalid; spr2.error.message = "TAG VALUE INVALID ERROR"; break; case 111: spr2.error.err_code = DLL_ERR_CODE.text_not_found; spr2.error.message = "Text Not found"; break; case 200: spr2.error.err_code = DLL_ERR_CODE.too_long_text; spr2.error.message = "Too long text"; break; case 201: spr2.error.err_code = DLL_ERR_CODE.too_many_symbol; spr2.error.message = "Too many symbol"; break; case 202: spr2.error.err_code = DLL_ERR_CODE.too_long_text_buffer_over; spr2.error.message = "Too long text and buffer over"; break; case 203: spr2.error.err_code = DLL_ERR_CODE.out_of_heap_memory; spr2.error.message = "Out of heap memory"; break; case 204: spr2.error.err_code = DLL_ERR_CODE.too_long_text_buffer_over; spr2.error.message = "Too long text and buffer over"; break; default: spr2.error.err_code = DLL_ERR_CODE.OTHER_ERROR; break; } return(spr2); } byte[] wavdata = new byte[size]; //C#側で配列を確保。 Marshal.Copy(wavPtr, wavdata, 0, size); //ポインタの中身を配列にコピー。 aq.AquesTalk_FreeWave(wavPtr); //ポインタはもういらないしトラブルの元なので即開放 yukkuri_lib_interface.SPEAK_RETURN spr = new yukkuri_lib_interface.SPEAK_RETURN(); spr.error.err_code = yukkuri_lib_interface.DLL_ERR_CODE.NO_ERROR; spr.error.message = "Success!"; spr.wavdata = wavdata; return(spr);//コピーした配列を返す。 }); /* * yukkuri_inter._run_speak += new yukkuri_lib_interface.yukkuri_lib_interface.CallEventHandler((ref byte[] wav, yukkuri_lib_interface.yukkuri_lib_interface.yukkuri_lib_interface_EventArgs e) => * { * if (!loaded) return; * int speed = e.speed; * int size = 0; * string koe = e.textdata; * IntPtr wavPtr = aq.AquesTalk_Synthe(koe, speed, out size); * if(wavPtr==IntPtr.Zero ) * { * wav= new byte[] { 0 }; * return; * } * wav = new byte[size]; * Marshal.Copy(wavPtr, wav, 0, size); * aq.AquesTalk_FreeWave(wavPtr); * }); */ ebthink.OnDllLoad += new Dll_load_delegate((yukkuri_lib_interface_dllload_args eargs) => //OnDllLoadで呼ばれる。 { try { aq = new AquesTalk(eargs.dll_path); //パスをもとにAquestalkをロード。 yukkuri_inter.dll_loaded(); //ロード完了のイベント送信。 }catch (IOException e) { throw; } }); Dll_load_delegate dllldel = new Dll_load_delegate(ebthink.DllLoadtoClient); //delegateを定義。 SpeakDelegate spd = new SpeakDelegate(ebthink.SpeakCallBackToClient); //delegateを定義。 CloseDelegate cld = new CloseDelegate(ebthink.Close_toClient); //delegateを定義。 yukkuri_inter.AddEventListener_Dllload(dllldel); //delegateを突っ込む。 yukkuri_inter.AddEventListener_Speak(spd); //delegateを突っ込む。 yukkuri_inter.AddEventListener_close(cld); //delegateを突っ込む。 TimerCallback timerdelegate = new TimerCallback((Object o) => { try { yukkuri_inter.discardkun(); }catch (System.Runtime.Remoting.RemotingException e) { cekun.Signal(); } }); Timer timer; yukkuri_inter.inited();//初期化完了イベントを発行。 Task task = Task.Run(() => { timer = new Timer(timerdelegate, null, 0, 3000); }); cekun.Wait();//閉じないように。 }