e957b7452b2119e2d0f3627bd505cc08f545d6c2
[platform/core/csapi/tizenfx.git] / src / Tizen.Uix.TtsEngine / Tizen.Uix.TtsEngine / TtsEngine.cs
1 /*
2 * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
3 *
4 * Licensed under the Apache License, Version 2.0 (the License);
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an AS IS BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 using System;
18 using System.Runtime.InteropServices;
19 using static Interop.TtsEngine;
20
21 namespace Tizen.Uix.TtsEngine
22 {
23     /// <summary>
24     /// Enumeration for audio type.
25     /// </summary>
26     public enum AudioType
27     {
28         /// <summary>
29         /// Signed 16-bit audio type
30         /// </summary>
31         RawS16 = 0,
32         /// <summary>
33         /// Unsigned 8-bit audio type
34         /// </summary>
35         RawU8,
36         /// <summary>
37         /// Maximum Value
38         /// </summary>
39         Max
40     };
41
42     /// <summary>
43     /// Enumeration for result.
44     /// </summary>
45     public enum ResultEvent
46     {
47         /// <summary>
48         /// Event when the voice synthesis is failed
49         /// </summary>
50         Fail = -1,
51         /// <summary>
52         /// Event when the sound data is first data by callback function
53         /// </summary>
54         Start = 1,
55         /// <summary>
56         /// Event when the next sound data exist, not first and not last
57         /// </summary>
58         Continue = 2,
59         /// <summary>
60         /// Event when the sound data is last data or sound data is only one result
61         /// </summary>
62         Finish = 3
63     };
64
65     /// <summary>
66     /// Enumeration for Voice Type
67     /// </summary>
68     public enum VoiceType
69     {
70         /// <summary>
71         /// male voice type.
72         /// </summary>
73         Male = 1,
74         /// <summary>
75         /// female voice type.
76         /// </summary>
77         Female = 2,
78         /// <summary>
79         /// child's voice type.
80         /// </summary>
81         Child = 3
82     }
83
84     /// <summary>
85     /// Enum for Error values that can occur
86     /// </summary>
87     public enum Error
88     {
89         /// <summary>
90         /// Successful, No error
91         /// </summary>
92         None = ErrorCode.None,
93         /// <summary>
94         /// Out of Memory
95         /// </summary>
96         OutOfMemory = ErrorCode.OutOfMemory,
97         /// <summary>
98         /// I/O error
99         /// </summary>
100         IoError = ErrorCode.IoError,
101         /// <summary>
102         /// Invalid parameter
103         /// </summary>
104         InvalidParameter = ErrorCode.InvalidParameter,
105         /// <summary>
106         /// Network down(Out of network)
107         /// </summary>
108         NetworkDown = ErrorCode.NetworkDown,
109         /// <summary>
110         /// Invalid state
111         /// </summary>
112         InvalidState = ErrorCode.InvalidState,
113         /// <summary>
114         /// Invalid voice
115         /// </summary>
116         InvalidVoice = ErrorCode.InvalidVoice,
117         /// <summary>
118         /// Operation failed
119         /// </summary>
120         OperationFailed = ErrorCode.OperationFailed,
121         /// <summary>
122         /// Not supported feature of current engine
123         /// </summary>
124         NotSupportedFeature = ErrorCode.NotSupportedFeature,
125         /// <summary>
126         /// NOT supported
127         /// </summary>
128         NotSupported = ErrorCode.NotSupported,
129         /// <summary>
130         /// Permission denied
131         /// </summary>
132         PermissionDenied = ErrorCode.PermissionDenied
133     };
134
135     /// <summary>
136     /// This Class represents the Tts Engine which has to be inherited to make the engine.
137     /// </summary>
138     public abstract class Engine
139     {
140         private CallbackStructGCHandle _callbackStructGCHandle = new CallbackStructGCHandle();
141         private PrivateDataSetCb _privateDataSetCb;
142         private Action<string> _privateDatacallback;
143         private PrivateDataRequestedCb _privateDataRequestedCb;
144         private OutAction<string> _privateDataRequestedCallback;
145         private static Engine _engine;
146         private IntPtr _structIntPtrHandle;
147
148         /// <summary>
149         /// An Action with 2 Input Parameter returning a Error
150         /// </summary>
151         /// <typeparam name="T">Generic Type for Parameter 1</typeparam>
152         /// <param name="a">The Input Parameter 1</param>
153         /// <param name="b">The Input Parameter 2</param>
154         /// <returns>Error Value</returns>
155         public delegate Error Action<T>(T a, T b);
156
157         /// <summary>
158         /// An Action with 2 Out Parameter returning a Error
159         /// </summary>
160         /// <typeparam name="T">Generic Type for Parameter 1</typeparam>
161         /// <param name="a">The Input Parameter 1</param>
162         /// <param name="b">The Input Parameter 2</param>
163         /// <returns>Error Value</returns>
164         public delegate Error OutAction<T>(T a, out T b);
165
166         /// <summary>
167         /// Called when TTS engine informs the engine service user about whole supported language and voice type list.
168         /// This callback function is implemented by the engine service user.Therefore, the engine developer does NOT have to implement this callback function. 
169         /// </summary>
170         /// <remarks>
171         /// This callback function is called by ForEachSupportedVoices() to inform the whole supported voice list. userData must be transferred from ForEachSupportedVoices().
172         /// </remarks>
173         /// <param name="language">The language is specified as an ISO 3166 alpha-2 two-letter country code followed by ISO 639-1 for the two-letter language code.
174         /// For example, "ko_KR" for Korean, "en_US" for American English</param>
175         /// <param name="type">The voice type</param>
176         /// <param name="userData">The user data passed from ForEachSupportedVoices()</param>
177         /// <returns>true to continue with the next iteration of the loop false to break out of the loop</returns>
178         /// <precondition>ForEachSupportedVoices() will invoke this callback function.</precondition>
179         public delegate bool SupportedVoice(string language, VoiceType type, IntPtr userData);
180
181         /// <summary>
182         /// Called when the engine service user starts to synthesize a voice, asynchronously.
183         /// </summary>
184         /// <remarks>
185         /// In this callback function, TTS engine must transfer the synthesized result to the engine service user using SendResult().
186         /// Also, if TTS engine needs the application's credential, it can set the credential granted to the application.
187         /// </remarks>
188         /// <param name="language">The language is specified as an ISO 3166 alpha-2 two-letter country code followed by ISO 639-1 for the two-letter language code.
189         /// For example, "ko_KR" for Korean, "en_US" for American English</param>
190         /// <param name="type">The voice type</param>
191         /// <param name="text">Texts</param>
192         /// <param name="speed">The speed of speaking</param>
193         /// <param name="appid">The Application ID</param>
194         /// <param name="credential">The credential granted to the application</param>
195         /// <param name="userData">The user data which must be passed to SendResult() function</param>
196         /// <returns>
197         /// Following Error Codes can be returned
198         /// 1. None
199         /// 2. InvalidState
200         /// 3. InvalidParameter
201         /// 4. InvalidVoice
202         /// 5. OperationFailed
203         /// 6. NetworkDown
204         /// 7. PermissionDenied
205         /// </returns>
206         /// <postcondition>This function invokes SendResult()</postcondition>
207         public abstract Error StartSynthesis(string language, int type, string text, int speed, string appid, string credential, IntPtr userData);
208
209         /// <summary>
210         /// Called when the engine service user requests the basic information of TTS engine.
211         /// </summary>
212         /// <remarks>
213         /// The allocated engineUuid, engineName, and engineSetting will be released internally.
214         /// In order to upload the engine at Tizen Appstore, both a service app and a ui app are necessary.
215         /// Therefore, engineSetting must be transferred to the engine service user.
216         /// </remarks>
217         /// <param name="engineUuid">UUID of engine</param>
218         /// <param name="engineName">Name of engine</param>
219         /// <param name="engineSetting">The engine setting application(ui app)'s app ID</param>
220         /// <param name="useNetwork">The status for using network</param>
221         /// <returns>
222         /// Following Error Codes can be returned
223         /// 1. None
224         /// 2. InvalidState
225         /// </returns>
226         public abstract Error GetInformation(out string engineUuid, out string engineName, out string engineSetting, out bool useNetwork);
227
228         /// <summary>
229         /// Called when the engine service user initializes TTS engine.
230         /// </summary>
231         /// <returns>
232         /// Following Error Codes can be returned
233         /// 1. None
234         /// 2. InvalidState
235         /// 3. NotSupportedFeature
236         /// 4. PermissionDenied
237         /// </returns>
238         public abstract Error Initialize();
239
240         /// <summary>
241         /// Called when the engine service user deinitializes TTS engine.
242         /// </summary>
243         /// <remarks>
244         /// NOTE that the engine may be terminated automatically. When this callback function is invoked, the release of resources is necessary.
245         /// </remarks>
246         /// <returns>
247         /// Following Error Codes can be returned
248         /// 1. None
249         /// 2. InvalidState
250         /// </returns>
251         public abstract Error Deinitialize();
252
253         /// <summary>
254         /// Called when the engine service user gets the whole supported voice list.
255         /// </summary>
256         /// <remarks>
257         /// In this function, the engine service user's callback function 'SupportedVoice()' is invoked repeatedly for getting all supported voices,
258         /// and userData must be transferred to 'SupportedVoice()'. If 'SupportedVoice()' returns false, it should be stopped to call 'SupportedVoice()'.</remarks>
259         /// <param name="callback">The callback function</param>
260         /// <param name="userData">The user data which must be passed to SupportedVoice()</param>
261         /// <returns>
262         /// Following Error Codes can be returned
263         /// 1. None
264         /// 2. OperationFailed
265         /// </returns>
266         /// <postcondition>This callback function invokes SupportedVoice() repeatedly for getting all supported voices.</postcondition>
267         public abstract Error ForEachSupportedVoices(SupportedVoice callback, IntPtr userData);
268
269         /// <summary>
270         /// Called when the engine service user checks whether the voice is valid or not in TTS engine.
271         /// </summary>
272         /// <param name="language">The language is specified as an ISO 3166 alpha-2 two-letter country code followed by ISO 639-1 for the two-letter language code.
273         /// For example, "ko_KR" for Korean, "en_US" for American English</param>
274         /// <param name="type">The voice type</param>
275         /// <param name="isValid">A variable for checking whether the corresponding voice is valid or not. true to be valid, false to be invalid</param>
276         /// <returns>
277         /// Following Error Codes can be returned
278         /// 1. None
279         /// 2. InvalidParameter
280         /// </returns>
281         public abstract Error IsValidVoice(string language, int type, out bool isValid);
282
283         /// <summary>
284         /// Called when the engine service user sets the default pitch of TTS engine.
285         /// </summary>
286         /// <param name="pitch">The default pitch</param>
287         /// <returns>
288         /// Following Error Codes can be returned
289         /// 1. None
290         /// 2. InvalidState
291         /// 3. OperationFailed
292         /// 4. InvalidParameter
293         /// </returns>
294         public abstract Error SetPitch(int pitch);
295
296         /// <summary>
297         /// Called when the engine service user requests to load the corresponding voice type for the first time.
298         /// </summary>
299         /// <param name="language">The language is specified as an ISO 3166 alpha-2 two-letter country code followed by ISO 639-1 for the two-letter language code.
300         /// For example, "ko_KR" for Korean, "en_US" for American English</param>
301         /// <param name="type">The voice type</param>
302         /// <returns>
303         /// Following Error Codes can be returned
304         /// 1. None
305         /// 2. InvalidState
306         /// 3. OperationFailed
307         /// 4. InvalidVoice
308         /// 5. InvalidParameter
309         /// 6. OutOfMemory
310         /// </returns>
311         public abstract Error LoadVoice(string language, int type);
312
313         /// <summary>
314         /// Called when the engine service user requests to unload the corresponding voice type or to stop using voice.
315         /// </summary>
316         /// <param name="language">The language is specified as an ISO 3166 alpha-2 two-letter country code followed by ISO 639-1 for the two-letter language code.
317         /// For example, "ko_KR" for Korean, "en_US" for American English</param>
318         /// <param name="type">The voice type</param>
319         /// <returns>
320         /// Following Error Codes can be returned
321         /// 1. None
322         /// 2. InvalidState
323         /// 3. OperationFailed
324         /// 4. InvalidVoice
325         /// 5. InvalidParameter
326         /// </returns>
327         public abstract Error UnloadVoice(string language, int type);
328
329         /// <summary>
330         /// Called when the engine service user requests for TTS engine to check whether the application agreed the usage of TTS engine.
331         /// This callback function is called when the engine service user requests for TTS engine to check the application's agreement about using the engine.
332         /// According to the need, the engine developer can provide some user interfaces to check the agreement.
333         /// </summary>
334         /// <remarks>
335         /// If the TTS engine developer wants not to check the agreement, the developer has need to return proper values as isAgreed in accordance with the intention.
336         /// true if the developer regards that every application agreed the usage of the engine, false if the developer regards that every application disagreed.
337         /// NOTE that, however, there may be any legal issue unless the developer checks the agreement.
338         /// Therefore, we suggest that the engine developers should provide a function to check the agreement.
339         /// </remarks>
340         /// <param name="appid">The Application ID</param>
341         /// <param name="isAgreed">A variable for checking whether the application agreed to use TTS engine or not. true to agree, false to disagree</param>
342         /// <returns>
343         /// Following Error Codes can be returned
344         /// 1. None
345         /// 2. InvalidState
346         /// 3. NotSupportedFeature
347         /// 4. InvalidParameter
348         /// </returns>
349         public abstract Error CheckAppAgreed(string appid, out bool isAgreed);
350
351         /// <summary>
352         /// Called when the engine service user checks whether TTS engine needs the application's credential.
353         /// </summary>
354         /// <returns>    true if TTS engine needs the application's credential, otherwise false </returns>
355         public abstract bool NeedAppCredential();
356
357         /// <summary>
358         /// Called when the engine service user cancels to synthesize a voice.
359         /// </summary>
360         /// <returns>
361         /// Following Error Codes can be returned
362         /// 1. None
363         /// 2. InvalidState
364         /// </returns>
365         /// <precondition>
366         /// StartSynthesis should be performed
367         /// </precondition>
368         public abstract Error CancelSynthesis();
369
370         /// <summary>
371         /// Public Constructor
372         /// </summary>
373         /// <feature>
374         /// http://tizen.org/feature/speech.synthesis
375         /// </feature>
376         public Engine()
377         {
378             _engine = this;
379         }
380
381         /// <summary>
382         /// Main function for Text-To-Speech (TTS) engine.
383         /// This function is the main function for operating TTS engine.
384         /// </summary>
385         /// <feature>
386         /// http://tizen.org/feature/speech.synthesis
387         /// </feature>
388         /// <remarks>
389         /// ServiceAppMain should be used for working the engine after this function.
390         /// </remarks>
391         /// <param name="argc">The argument count(original)</param>
392         /// <param name="argv">The argument(original)</param>
393         /// <exception cref="ArgumentException">Thrown in case of Invalid Parameter</exception>
394         /// <exception cref="NotSupportedException">Thrown in case of Not supported</exception>
395         /// <exception cref="InvalidOperationException">thrown in case of Operation failure</exception>
396         public void EngineMain(int argc, string[] argv)
397         {
398             _callbackStructGCHandle.CallbackStruct.version = 1;
399             _callbackStructGCHandle.CallbackStruct.getInfo = _getInfoCb;
400             _callbackStructGCHandle.CallbackStruct.initialize = Initialize;
401             _callbackStructGCHandle.CallbackStruct.deinitialize = _deinitializeCb;
402             _callbackStructGCHandle.CallbackStruct.supportedVoice = ForEachSupportedVoices;
403             _callbackStructGCHandle.CallbackStruct.validVoice = IsValidVoice;
404             _callbackStructGCHandle.CallbackStruct.pitch = SetPitch;
405             _callbackStructGCHandle.CallbackStruct.loadVoice = LoadVoice;
406             _callbackStructGCHandle.CallbackStruct.unloadVoice = UnloadVoice;
407             _callbackStructGCHandle.CallbackStruct.startSynthesis = _startSynthesisCb;
408             _callbackStructGCHandle.CallbackStruct.cancelSynthesis = CancelSynthesis;
409             _callbackStructGCHandle.CallbackStruct.checkAppAgreed = CheckAppAgreed;
410             _callbackStructGCHandle.CallbackStruct.needAppCredential = NeedAppCredential;
411             _structIntPtrHandle = Marshal.AllocHGlobal(Marshal.SizeOf(_callbackStructGCHandle.CallbackStruct));
412             Marshal.StructureToPtr<RequestCallbackStruct>(_callbackStructGCHandle.CallbackStruct, _structIntPtrHandle, false);
413             Error error = TTSEMain(argc, argv, _structIntPtrHandle);
414             if (error != Error.None)
415             {
416                 Log.Error(LogTag, "TTSEMain Failed with error " + error);
417                 throw ExceptionFactory.CreateException((ErrorCode)error);
418             }
419
420             Log.Info(LogTag, "After TTSEMain");
421         }
422
423         /// <summary>
424         /// Gets the speed range from Tizen platform
425         /// </summary>
426         /// <feature>
427         /// http://tizen.org/feature/speech.synthesis
428         /// </feature>
429         /// <remarks>
430         /// This API is used when TTS engine wants to get the speed range from Tizen platform
431         /// </remarks>
432         /// <param name="min">The minimum speed value</param>
433         /// <param name="normal">The normal speed value</param>
434         /// <param name="max">The maximum speed value</param>
435         /// <exception cref="NotSupportedException">Thrown in case of Not supported</exception>
436         /// <exception cref="InvalidOperationException">thrown in case of Operation failure</exception>
437         public void GetSpeedRange(out int min, out int normal, out int max)
438         {
439             Error error = TTSEGetSpeedRange(out min, out normal, out max);
440             if (error != Error.None)
441             {
442                 Log.Error(LogTag, "TTSEGetSpeedRange Failed with error " + error);
443                 throw ExceptionFactory.CreateException((ErrorCode)error);
444             }
445
446         }
447
448         /// <summary>
449         /// Gets the pitch range from Tizen platform.
450         /// </summary>
451         /// <feature>
452         /// http://tizen.org/feature/speech.synthesis
453         /// </feature>
454         /// <remarks>
455         /// This API is used when TTS engine wants to get the pitch range from Tizen platform.
456         /// </remarks>
457         /// <param name="min">The minimum pitch value</param>
458         /// <param name="normal">The normal pitch value</param>
459         /// <param name="max">The maximum pitch value</param>
460         /// <exception cref="NotSupportedException">Thrown in case of Not supported</exception>
461         /// <exception cref="InvalidOperationException">thrown in case of Operation failure</exception>
462         public void GetPitchRange(out int min, out int normal, out int max)
463         {
464             Error error = TTSEGetPitchRange(out min, out normal, out max);
465             if (error != Error.None)
466             {
467                 Log.Error(LogTag, "TTSEGetPitchRange Failed with error " + error);
468                 throw ExceptionFactory.CreateException((ErrorCode)error);
469             }
470
471         }
472
473         /// <summary>
474         /// Sends the synthesized result to the engine service user.
475         /// </summary>
476         /// <feature>
477         /// http://tizen.org/feature/speech.synthesis
478         /// </feature>
479         /// <remarks>
480         /// This API is used in StartSynthesis(), when TTS engine sends the synthesized result to the engine service user.
481         /// The synthesized result must be transferred to the engine service user through this function.
482         /// </remarks>
483         /// <param name="resultEvent">The result event</param>
484         /// <param name="data">Result data</param>
485         /// <param name="dataSize">Result data size</param>
486         /// <param name="audioType">The audio type</param>
487         /// <param name="rate">The sample rate</param>
488         /// <exception cref="ArgumentException">Thrown in case of Invalid Parameter</exception>
489         /// <exception cref="NotSupportedException">Thrown in case of Not supported</exception>
490         /// <exception cref="InvalidOperationException">thrown in case of Operation failure</exception>
491         /// <precondition>
492         /// EngineMain function should be invoked before this function is called. StartSynthesis() will invoke this function.
493         /// </precondition>
494         public void SendResult(ResultEvent resultEvent, IntPtr data, int dataSize, AudioType audioType, int rate)
495         {
496             Error error = TTSESendResult(resultEvent, data, dataSize, audioType, rate, IntPtr.Zero);
497             if (error != Error.None)
498             {
499                 Log.Error(LogTag, "TTSESendResult Failed with error " + error);
500                 throw ExceptionFactory.CreateException((ErrorCode)error);
501             }
502         }
503
504         /// <summary>
505         /// Sends the error to the engine service user.
506         /// </summary>
507         /// <feature>
508         /// http://tizen.org/feature/speech.synthesis
509         /// </feature>
510         /// <param name="error">The error reason</param>
511         /// <param name="msg">The error message</param>
512         /// <precondition>
513         /// EngineMain function should be invoked before this function is called.
514         /// </precondition>
515         public void SendError(Error error, string msg)
516         {
517             Error err = TTSESendError(error, msg);
518             if (err != Error.None)
519             {
520                 Log.Error(LogTag, "SendError Failed with error " + err);
521                 throw ExceptionFactory.CreateException((ErrorCode)error);
522             }
523
524         }
525
526         /// <summary>
527         /// Sets a callback function for setting the private data.
528         /// </summary>
529         /// <feature>
530         /// http://tizen.org/feature/speech.synthesis
531         /// </feature>
532         /// <param name="callback">
533         /// Called when the engine service user gets the private data from Tts engine.
534         /// In Parameters:
535         /// a = Key -- The key field of private data
536         /// b = data -- The data field of private data
537         /// Following Error Codes can be returned
538         /// 1. None
539         /// 2. InvalidParameter
540         /// 3. OperationFailed
541         /// 4. NotSupported
542         /// </param>
543         /// <exception cref="ArgumentException">Thrown in case of Invalid Parameter</exception>
544         /// <exception cref="UnauthorizedAccessException">Thrown in case of Permission denied</exception>
545         /// <exception cref="NotSupportedException">Thrown in case of Not supported</exception>
546         /// <exception cref="InvalidOperationException">thrown in case of Operation failure</exception>
547         /// <precondition>
548         /// Main function should be invoked before this function is called.
549         /// </precondition>
550         public void SetPrivateDataSetDelegate(Action<string> callback)
551         {
552             _privateDatacallback = callback;
553             _privateDataSetCb = (string key, string data) =>
554             {
555                 return _privateDatacallback.Invoke(key, data);
556             };
557             Error error = TTSESetPrivateDataSetCb(_privateDataSetCb);
558             if (error != Error.None)
559             {
560                 Log.Error(LogTag, "SetPrivateDataSetDelegate Failed with error " + error);
561                 throw ExceptionFactory.CreateException((ErrorCode)error);
562             }
563
564         }
565
566         /// <summary>
567         /// Sets a callback function for setting the private data.
568         /// </summary>
569         /// <feature>
570         /// http://tizen.org/feature/speech.synthesis
571         /// </feature>
572         /// <param name="callback">callback function
573         /// Called when TTS engine receives the private data from the engine service user.
574         /// This callback function is called when the engine service user sends the private data to TTS engine.
575         /// Out Parameters:
576         /// a = Key -- The key field of private data
577         /// b = data -- The data field of private data
578         /// Following Error Codes can be returned
579         /// 1. None
580         /// 2. InvalidParameter
581         /// 3. OperationFailed
582         /// 4. NotSupported
583         /// </param>
584         /// <exception cref="ArgumentException">Thrown in case of Invalid Parameter</exception>
585         /// <exception cref="UnauthorizedAccessException">Thrown in case of Permission denied</exception>
586         /// <exception cref="NotSupportedException">Thrown in case of Not supported</exception>
587         /// <exception cref="InvalidOperationException">thrown in case of Operation failure</exception>
588         /// <precondition>
589         /// Main function should be invoked before this function is called.
590         /// </precondition>
591         public void SetPrivateDataRequestedDelegate(OutAction<string> callback)
592         {
593             _privateDataRequestedCallback = callback;
594             _privateDataRequestedCb = (string key, out string data) =>
595             {
596                 return _privateDataRequestedCallback.Invoke(key, out data);
597             };
598             Error error = TTSESetPrivateDataRequestedCb(_privateDataRequestedCb);
599             if (error != Error.None)
600             {
601                 Log.Error(LogTag, "SetPrivateDataRequestedDelegate Failed with error " + error);
602                 throw ExceptionFactory.CreateException((ErrorCode)error);
603             }
604
605         }
606         private StartSynthesisCb _startSynthesisCb = (IntPtr language, int type, IntPtr text, int speed, IntPtr appid, IntPtr credential, IntPtr userData) =>
607         {
608             string lan = null;
609             string txt = null;
610             string apid = null;
611             string cre = null;
612             if (language != null)
613                 lan = Marshal.PtrToStringAnsi(language);
614             if (text != null)
615                 txt = Marshal.PtrToStringAnsi(text);
616             if (appid != null)
617                 apid = Marshal.PtrToStringAnsi(appid);
618             if (credential != null)
619                 cre = Marshal.PtrToStringAnsi(credential);
620             return _engine.StartSynthesis(lan, type, txt, speed, apid, cre, IntPtr.Zero);
621         };
622
623         private GetInfoCb _getInfoCb = (out IntPtr engineUuid, out IntPtr engineName, out IntPtr engineSetting, out int useNetwork) =>
624         {
625             string uuid;
626             string name;
627             string setting;
628             bool network;
629             Error err = _engine.GetInformation(out uuid, out name, out setting, out network);
630             if (network == true)
631             {
632                 useNetwork = 1;
633             }
634             else
635             {
636                 useNetwork = 0;
637             }
638             engineUuid = Marshal.StringToHGlobalAnsi(uuid);
639             engineName = Marshal.StringToHGlobalAnsi(name);
640             engineSetting = Marshal.StringToHGlobalAnsi(setting);
641             return err;
642         };
643
644         private DeinitializeCb _deinitializeCb = () =>
645         {
646             Marshal.FreeHGlobal(_engine._structIntPtrHandle);
647             return _engine.Deinitialize();
648         };
649     }
650 }