Release 4.0.0-preview1-00051
[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         /// <percondition>
366         /// StartSynthesis should be performed
367         /// </percondition>
368         public abstract Error CancelSynthesis();
369
370         /// <summary>
371         /// Public Constructor
372         /// </summary>
373         public Engine()
374         {
375             _engine = this;
376         }
377
378         /// <summary>
379         /// Main function for Text-To-Speech (TTS) engine.
380         /// This function is the main function for operating TTS engine.
381         /// </summary>
382         /// <remarks>
383         /// ServiceAppMain should be used for working the engine after this function.
384         /// </remarks>
385         /// <param name="argc">The argument count(original)</param>
386         /// <param name="argv">The argument(original)</param>
387         /// <exception cref="ArgumentException">Thrown in case of Invalid Parameter</exception>
388         /// <exception cref="NotSupportedException">Thrown in case of Not supported</exception>
389         /// <exception cref="InvalidOperationException">thrown in case of Operation failure</exception>
390         public void EngineMain(int argc, string[] argv)
391         {
392             _callbackStructGCHandle.CallbackStruct.version = 1;
393             _callbackStructGCHandle.CallbackStruct.getInfo = _getInfoCb;
394             _callbackStructGCHandle.CallbackStruct.initialize = Initialize;
395             _callbackStructGCHandle.CallbackStruct.deinitialize = _deinitializeCb;
396             _callbackStructGCHandle.CallbackStruct.supportedVoice = ForEachSupportedVoices;
397             _callbackStructGCHandle.CallbackStruct.validVoice = IsValidVoice;
398             _callbackStructGCHandle.CallbackStruct.pitch = SetPitch;
399             _callbackStructGCHandle.CallbackStruct.loadVoice = LoadVoice;
400             _callbackStructGCHandle.CallbackStruct.unloadVoice = UnloadVoice;
401             _callbackStructGCHandle.CallbackStruct.startSynthesis = _startSynthesisCb;
402             _callbackStructGCHandle.CallbackStruct.cancelSynthesis = CancelSynthesis;
403             _callbackStructGCHandle.CallbackStruct.checkAppAgreed = CheckAppAgreed;
404             _callbackStructGCHandle.CallbackStruct.needAppCredential = NeedAppCredential;
405             _structIntPtrHandle = Marshal.AllocHGlobal(Marshal.SizeOf(_callbackStructGCHandle.CallbackStruct));
406             Marshal.StructureToPtr<RequestCallbackStruct>(_callbackStructGCHandle.CallbackStruct, _structIntPtrHandle, false);
407             Error error = TTSEMain(argc, argv, _structIntPtrHandle);
408             if (error != Error.None)
409             {
410                 Log.Error(LogTag, "TTSEMain Failed with error " + error);
411                 throw ExceptionFactory.CreateException((ErrorCode)error);
412             }
413
414             Log.Info(LogTag, "After TTSEMain");
415         }
416
417         /// <summary>
418         /// Gets the speed range from Tizen platform
419         /// </summary>
420         /// <remarks>
421         /// This API is used when TTS engine wants to get the speed range from Tizen platform
422         /// </remarks>
423         /// <param name="min">The minimum speed value</param>
424         /// <param name="normal">The normal speed value</param>
425         /// <param name="max">The maximum speed value</param>
426         /// <exception cref="NotSupportedException">Thrown in case of Not supported</exception>
427         /// <exception cref="InvalidOperationException">thrown in case of Operation failure</exception>
428         public void GetSpeedRange(out int min, out int normal, out int max)
429         {
430             Error error = TTSEGetSpeedRange(out min, out normal, out max);
431             if (error != Error.None)
432             {
433                 Log.Error(LogTag, "TTSEGetSpeedRange Failed with error " + error);
434                 throw ExceptionFactory.CreateException((ErrorCode)error);
435             }
436
437         }
438
439         /// <summary>
440         /// Gets the pitch range from Tizen platform.
441         /// </summary>
442         /// <remarks>
443         /// This API is used when TTS engine wants to get the pitch range from Tizen platform.
444         /// </remarks>
445         /// <param name="min">The minimum pitch value</param>
446         /// <param name="normal">The normal pitch value</param>
447         /// <param name="max">The maximum pitch value</param>
448         /// <exception cref="NotSupportedException">Thrown in case of Not supported</exception>
449         /// <exception cref="InvalidOperationException">thrown in case of Operation failure</exception>
450         public void GetPitchRange(out int min, out int normal, out int max)
451         {
452             Error error = TTSEGetPitchRange(out min, out normal, out max);
453             if (error != Error.None)
454             {
455                 Log.Error(LogTag, "TTSEGetPitchRange Failed with error " + error);
456                 throw ExceptionFactory.CreateException((ErrorCode)error);
457             }
458
459         }
460
461         /// <summary>
462         /// Sends the synthesized result to the engine service user.
463         /// </summary>
464         /// <remarks>
465         /// This API is used in StartSynthesis(), when TTS engine sends the synthesized result to the engine service user.
466         /// The synthesized result must be transferred to the engine service user through this function.
467         /// </remarks>
468         /// <param name="resultEvent">The result event</param>
469         /// <param name="data">Result data</param>
470         /// <param name="dataSize">Result data size</param>
471         /// <param name="audioType">The audio type</param>
472         /// <param name="rate">The sample rate</param>
473         /// <exception cref="ArgumentException">Thrown in case of Invalid Parameter</exception>
474         /// <exception cref="NotSupportedException">Thrown in case of Not supported</exception>
475         /// <exception cref="InvalidOperationException">thrown in case of Operation failure</exception>
476         /// <precondition>
477         /// EngineMain function should be invoked before this function is called. StartSynthesis() will invoke this function.
478         /// </precondition>
479         public void SendResult(ResultEvent resultEvent, IntPtr data, int dataSize, AudioType audioType, int rate)
480         {
481             Error error = TTSESendResult(resultEvent, data, dataSize, audioType, rate, IntPtr.Zero);
482             if (error != Error.None)
483             {
484                 Log.Error(LogTag, "TTSESendResult Failed with error " + error);
485                 throw ExceptionFactory.CreateException((ErrorCode)error);
486             }
487         }
488
489         /// <summary>
490         /// Sends the error to the engine service user.
491         /// </summary>
492         /// <param name="error">The error reason</param>
493         /// <param name="msg">The error message</param>
494         /// <precondition>
495         /// EngineMain function should be invoked before this function is called.
496         /// </precondition>
497         public void SendError(Error error, string msg)
498         {
499             Error err = TTSESendError(error, msg);
500             if (err != Error.None)
501             {
502                 Log.Error(LogTag, "SendError Failed with error " + err);
503                 throw ExceptionFactory.CreateException((ErrorCode)error);
504             }
505
506         }
507
508         /// <summary>
509         /// Sets a callback function for setting the private data.
510         /// </summary>
511         /// <param name="callback">
512         /// Called when the engine service user gets the private data from Tts engine.
513         /// In Parameters:
514         /// a = Key -- The key field of private data
515         /// b = data -- The data field of private data
516         /// Following Error Codes can be returned
517         /// 1. None
518         /// 2. InvalidParameter
519         /// 3. OperationFailed
520         /// 4. NotSupported
521         /// </param>
522         /// <exception cref="ArgumentException">Thrown in case of Invalid Parameter</exception>
523         /// <exception cref="UnauthorizedAccessException">Thrown in case of Permission denied</exception>
524         /// <exception cref="NotSupportedException">Thrown in case of Not supported</exception>
525         /// <exception cref="InvalidOperationException">thrown in case of Operation failure</exception>
526         /// <precondition>
527         /// Main function should be invoked before this function is called.
528         /// </precondition>
529         public void SetPrivateDataSetDelegate(Action<string> callback)
530         {
531             _privateDatacallback = callback;
532             _privateDataSetCb = (string key, string data) =>
533             {
534                 return _privateDatacallback.Invoke(key, data);
535             };
536             Error error = TTSESetPrivateDataSetCb(_privateDataSetCb);
537             if (error != Error.None)
538             {
539                 Log.Error(LogTag, "SetPrivateDataSetDelegate Failed with error " + error);
540                 throw ExceptionFactory.CreateException((ErrorCode)error);
541             }
542
543         }
544
545         /// <summary>
546         /// Sets a callback function for setting the private data.
547         /// </summary>
548         /// <param name="callback">callback function
549         /// Called when TTS engine receives the private data from the engine service user.
550         /// This callback function is called when the engine service user sends the private data to TTS engine.
551         /// Out Parameters:
552         /// a = Key -- The key field of private data
553         /// b = data -- The data field of private data
554         /// Following Error Codes can be returned
555         /// 1. None
556         /// 2. InvalidParameter
557         /// 3. OperationFailed
558         /// 4. NotSupported
559         /// </param>
560         /// <exception cref="ArgumentException">Thrown in case of Invalid Parameter</exception>
561         /// <exception cref="UnauthorizedAccessException">Thrown in case of Permission denied</exception>
562         /// <exception cref="NotSupportedException">Thrown in case of Not supported</exception>
563         /// <exception cref="InvalidOperationException">thrown in case of Operation failure</exception>
564         /// <precondition>
565         /// Main function should be invoked before this function is called.
566         /// </precondition>
567         public void SetPrivateDataRequestedDelegate(OutAction<string> callback)
568         {
569             _privateDataRequestedCallback = callback;
570             _privateDataRequestedCb = (string key, out string data) =>
571             {
572                 return _privateDataRequestedCallback.Invoke(key, out data);
573             };
574             Error error = TTSESetPrivateDataRequestedCb(_privateDataRequestedCb);
575             if (error != Error.None)
576             {
577                 Log.Error(LogTag, "SetPrivateDataRequestedDelegate Failed with error " + error);
578                 throw ExceptionFactory.CreateException((ErrorCode)error);
579             }
580
581         }
582         private StartSynthesisCb _startSynthesisCb = (IntPtr language, int type, IntPtr text, int speed, IntPtr appid, IntPtr credential, IntPtr userData) =>
583         {
584             string lan = null;
585             string txt = null;
586             string apid = null;
587             string cre = null;
588             if (language != null)
589                 lan = Marshal.PtrToStringAnsi(language);
590             if (text != null)
591                 txt = Marshal.PtrToStringAnsi(text);
592             if (appid != null)
593                 apid = Marshal.PtrToStringAnsi(appid);
594             if (credential != null)
595                 cre = Marshal.PtrToStringAnsi(credential);
596             return _engine.StartSynthesis(lan, type, txt, speed, apid, cre, IntPtr.Zero);
597         };
598
599         private GetInfoCb _getInfoCb = (out IntPtr engineUuid, out IntPtr engineName, out IntPtr engineSetting, out int useNetwork) =>
600         {
601             string uuid;
602             string name;
603             string setting;
604             bool network;
605             Error err = _engine.GetInformation(out uuid, out name, out setting, out network);
606             if (network == true)
607             {
608                 useNetwork = 1;
609             }
610             else
611             {
612                 useNetwork = 0;
613             }
614             engineUuid = Marshal.StringToHGlobalAnsi(uuid);
615             engineName = Marshal.StringToHGlobalAnsi(name);
616             engineSetting = Marshal.StringToHGlobalAnsi(setting);
617             return err;
618         };
619
620         private DeinitializeCb _deinitializeCb = () =>
621         {
622             Marshal.FreeHGlobal(_engine._structIntPtrHandle);
623             return _engine.Deinitialize();
624         };
625     }
626 }