summaryrefslogtreecommitdiff
path: root/Tizen.Uix.TtsEngine/Tizen.Uix.TtsEngine/TtsEngine.cs
blob: 9c3640009f6b21112cbbdbd0812b9209d76de1f9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
/*
* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
*
* Licensed under the Apache License, Version 2.0 (the License);
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

using System;
using System.Runtime.InteropServices;
using static Interop.TtsEngine;

namespace Tizen.Uix.TtsEngine
{
    /// <summary>
    /// Enumeration for audio type.
    /// </summary>
    public enum AudioType
    {
        /// <summary>
        /// Signed 16-bit audio type
        /// </summary>
        RawS16 = 0,
        /// <summary>
        /// Unsigned 8-bit audio type
        /// </summary>
        RawU8,
        /// <summary>
        /// Maximum Value
        /// </summary>
        Max
    };

    /// <summary>
    /// Enumeration for result.
    /// </summary>
    public enum ResultEvent
    {
        /// <summary>
        /// Event when the voice synthesis is failed
        /// </summary>
        Fail = -1,
        /// <summary>
        /// Event when the sound data is first data by callback function
        /// </summary>
        Start = 1,
        /// <summary>
        /// Event when the next sound data exist, not first and not last
        /// </summary>
        Continue = 2,
        /// <summary>
        /// Event when the sound data is last data or sound data is only one result
        /// </summary>
        Finish = 3
    };

    /// <summary>
    /// Enumeration for Voice Type
    /// </summary>
    public enum VoiceType
    {
        /// <summary>
        /// male voice type.
        /// </summary>
        Male = 1,
        /// <summary>
        /// female voice type.
        /// </summary>
        Female = 2,
        /// <summary>
        /// child's voice type.
        /// </summary>
        Child = 3
    }

    /// <summary>
    /// Enum for Error values that can occur
    /// </summary>
    public enum Error
    {
        /// <summary>
        /// Successful, No error
        /// </summary>
        None = ErrorCode.None,
        /// <summary>
        /// Out of Memory
        /// </summary>
        OutOfMemory = ErrorCode.OutOfMemory,
        /// <summary>
        /// I/O error
        /// </summary>
        IoError = ErrorCode.IoError,
        /// <summary>
        /// Invalid parameter
        /// </summary>
        InvalidParameter = ErrorCode.InvalidParameter,
        /// <summary>
        /// Network down(Out of network)
        /// </summary>
        NetworkDown = ErrorCode.NetworkDown,
        /// <summary>
        /// Invalid state
        /// </summary>
        InvalidState = ErrorCode.InvalidState,
        /// <summary>
        /// Invalid voice
        /// </summary>
        InvalidVoice = ErrorCode.InvalidVoice,
        /// <summary>
        /// Operation failed
        /// </summary>
        OperationFailed = ErrorCode.OperationFailed,
        /// <summary>
        /// Not supported feature of current engine
        /// </summary>
        NotSupportedFeature = ErrorCode.NotSupportedFeature,
        /// <summary>
        /// NOT supported
        /// </summary>
        NotSupported = ErrorCode.NotSupported,
        /// <summary>
        /// Permission denied
        /// </summary>
        PermissionDenied = ErrorCode.PermissionDenied
    };

    /// <summary>
    /// This Class represents the Tts Engine which has to be inherited to make the engine.
    /// </summary>
    public abstract class Engine
    {
        private CallbackStructGCHandle _callbackStructGCHandle = new CallbackStructGCHandle();
        private PrivateDataSetCb _privateDataSetCb;
        private Action<string> _privateDatacallback;
        private PrivateDataRequestedCb _privateDataRequestedCb;
        private OutAction<string> _privateDataRequestedCallback;
        private static Engine _engine;
        private IntPtr _structIntPtrHandle;

        /// <summary>
        /// An Action with 2 Input Parameter returning a Error
        /// </summary>
        /// <typeparam name="T">Generic Type for Parameter 1</typeparam>
        /// <param name="a">The Input Parameter 1</param>
        /// <param name="b">The Input Parameter 2</param>
        /// <returns>Error Value</returns>
        public delegate Error Action<T>(T a, T b);

        /// <summary>
        /// An Action with 2 Out Parameter returning a Error
        /// </summary>
        /// <typeparam name="T">Generic Type for Parameter 1</typeparam>
        /// <param name="a">The Input Parameter 1</param>
        /// <param name="b">The Input Parameter 2</param>
        /// <returns>Error Value</returns>
        public delegate Error OutAction<T>(T a, out T b);

        /// <summary>
        /// Called when TTS engine informs the engine service user about whole supported language and voice type list.
        /// This callback function is implemented by the engine service user.Therefore, the engine developer does NOT have to implement this callback function. 
        /// </summary>
        /// <remarks>
        /// This callback function is called by ForEachSupportedVoices() to inform the whole supported voice list. userData must be transferred from ForEachSupportedVoices().
        /// </remarks>
        /// <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.
        /// For example, "ko_KR" for Korean, "en_US" for American English</param>
        /// <param name="type">The voice type</param>
        /// <param name="userData">The user data passed from ForEachSupportedVoices()</param>
        /// <returns>true to continue with the next iteration of the loop false to break out of the loop</returns>
        /// <precondition>ForEachSupportedVoices() will invoke this callback function.</precondition>
        public delegate bool SupportedVoice(string language, VoiceType type, IntPtr userData);

        /// <summary>
        /// Called when the engine service user starts to synthesize a voice, asynchronously.
        /// </summary>
        /// <remarks>
        /// In this callback function, TTS engine must transfer the synthesized result to the engine service user using SendResult().
        /// Also, if TTS engine needs the application's credential, it can set the credential granted to the application.
        /// </remarks>
        /// <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.
        /// For example, "ko_KR" for Korean, "en_US" for American English</param>
        /// <param name="type">The voice type</param>
        /// <param name="text">Texts</param>
        /// <param name="speed">The speed of speaking</param>
        /// <param name="appid">The Application ID</param>
        /// <param name="credential">The credential granted to the application</param>
        /// <param name="userData">The user data which must be passed to SendResult() function</param>
        /// <returns>
        /// Following Error Codes can be returned
        /// 1. None
        /// 2. InvalidState
        /// 3. InvalidParameter
        /// 4. InvalidVoice
        /// 5. OperationFailed
        /// 6. NetworkDown
        /// 7. PermissionDenied
        /// </returns>
        /// <postcondition>This function invokes SendResult()</postcondition>
        public abstract Error StartSynthesis(string language, int type, string text, int speed, string appid, string credential, IntPtr userData);

        /// <summary>
        /// Called when the engine service user requests the basic information of TTS engine.
        /// </summary>
        /// <remarks>
        /// The allocated engineUuid, engineName, and engineSetting will be released internally.
        /// In order to upload the engine at Tizen Appstore, both a service app and a ui app are necessary.
        /// Therefore, engineSetting must be transferred to the engine service user.
        /// </remarks>
        /// <param name="engineUuid">UUID of engine</param>
        /// <param name="engineName">Name of engine</param>
        /// <param name="engineSetting">The engine setting application(ui app)'s app ID</param>
        /// <param name="useNetwork">The status for using network</param>
        /// <returns>
        /// Following Error Codes can be returned
        /// 1. None
        /// 2. InvalidState
        /// </returns>
        public abstract Error GetInformation(out string engineUuid, out string engineName, out string engineSetting, out bool useNetwork);

        /// <summary>
        /// Called when the engine service user initializes TTS engine.
        /// </summary>
        /// <returns>
        /// Following Error Codes can be returned
        /// 1. None
        /// 2. InvalidState
        /// 3. NotSupportedFeature
        /// 4. PermissionDenied
        /// </returns>
        public abstract Error Initialize();

        /// <summary>
        /// Called when the engine service user deinitializes TTS engine.
        /// </summary>
        /// <remarks>
        /// NOTE that the engine may be terminated automatically. When this callback function is invoked, the release of resources is necessary.
        /// </remarks>
        /// <returns>
        /// Following Error Codes can be returned
        /// 1. None
        /// 2. InvalidState
        /// </returns>
        public abstract Error Deinitialize();

        /// <summary>
        /// Called when the engine service user gets the whole supported voice list.
        /// </summary>
        /// <remarks>
        /// In this function, the engine service user's callback function 'SupportedVoice()' is invoked repeatedly for getting all supported voices,
        /// and userData must be transferred to 'SupportedVoice()'. If 'SupportedVoice()' returns false, it should be stopped to call 'SupportedVoice()'.</remarks>
        /// <param name="callback">The callback function</param>
        /// <param name="userData">The user data which must be passed to SupportedVoice()</param>
        /// <returns>
        /// Following Error Codes can be returned
        /// 1. None
        /// 2. OperationFailed
        /// </returns>
        /// <postcondition>This callback function invokes SupportedVoice() repeatedly for getting all supported voices.</postcondition>
        public abstract Error ForEachSupportedVoices(SupportedVoice callback, IntPtr userData);

        /// <summary>
        /// Called when the engine service user checks whether the voice is valid or not in TTS engine.
        /// </summary>
        /// <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.
        /// For example, "ko_KR" for Korean, "en_US" for American English</param>
        /// <param name="type">The voice type</param>
        /// <param name="isValid">A variable for checking whether the corresponding voice is valid or not. true to be valid, false to be invalid</param>
        /// <returns>
        /// Following Error Codes can be returned
        /// 1. None
        /// 2. InvalidParameter
        /// </returns>
        public abstract Error IsValidVoice(string language, int type, out bool isValid);

        /// <summary>
        /// Called when the engine service user sets the default pitch of TTS engine.
        /// </summary>
        /// <param name="pitch">The default pitch</param>
        /// <returns>
        /// Following Error Codes can be returned
        /// 1. None
        /// 2. InvalidState
        /// 3. OperationFailed
        /// 4. InvalidParameter
        /// </returns>
        public abstract Error SetPitch(int pitch);

        /// <summary>
        /// Called when the engine service user requests to load the corresponding voice type for the first time.
        /// </summary>
        /// <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.
        /// For example, "ko_KR" for Korean, "en_US" for American English</param>
        /// <param name="type">The voice type</param>
        /// <returns>
        /// Following Error Codes can be returned
        /// 1. None
        /// 2. InvalidState
        /// 3. OperationFailed
        /// 4. InvalidVoice
        /// 5. InvalidParameter
        /// 6. OutOfMemory
        /// </returns>
        public abstract Error LoadVoice(string language, int type);

        /// <summary>
        /// Called when the engine service user requests to unload the corresponding voice type or to stop using voice.
        /// </summary>
        /// <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.
        /// For example, "ko_KR" for Korean, "en_US" for American English</param>
        /// <param name="type">The voice type</param>
        /// <returns>
        /// Following Error Codes can be returned
        /// 1. None
        /// 2. InvalidState
        /// 3. OperationFailed
        /// 4. InvalidVoice
        /// 5. InvalidParameter
        /// </returns>
        public abstract Error UnloadVoice(string language, int type);

        /// <summary>
        /// Called when the engine service user requests for TTS engine to check whether the application agreed the usage of TTS engine.
        /// This callback function is called when the engine service user requests for TTS engine to check the application's agreement about using the engine.
        /// According to the need, the engine developer can provide some user interfaces to check the agreement.
        /// </summary>
        /// <remarks>
        /// 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.
        /// true if the developer regards that every application agreed the usage of the engine, false if the developer regards that every application disagreed.
        /// NOTE that, however, there may be any legal issue unless the developer checks the agreement.
        /// Therefore, we suggest that the engine developers should provide a function to check the agreement.
        /// </remarks>
        /// <param name="appid">The Application ID</param>
        /// <param name="isAgreed">A variable for checking whether the application agreed to use TTS engine or not. true to agree, false to disagree</param>
        /// <returns>
        /// Following Error Codes can be returned
        /// 1. None
        /// 2. InvalidState
        /// 3. NotSupportedFeature
        /// 4. InvalidParameter
        /// </returns>
        public abstract Error CheckAppAgreed(string appid, out bool isAgreed);

        /// <summary>
        /// Called when the engine service user checks whether TTS engine needs the application's credential.
        /// </summary>
        /// <returns>    true if TTS engine needs the application's credential, otherwise false </returns>
        public abstract bool NeedAppCredential();

        /// <summary>
        /// Called when the engine service user cancels to synthesize a voice.
        /// </summary>
        /// <returns>
        /// Following Error Codes can be returned
        /// 1. None
        /// 2. InvalidState
        /// </returns>
        /// <percondition>
        /// StartSynthesis should be performed
        /// </percondition>
        public abstract Error CancelSynthesis();

        /// <summary>
        /// Public Constructor
        /// </summary>
        /// <feature>
        /// http://tizen.org/feature/speech.synthesis
        /// </feature>
        public Engine()
        {
            _engine = this;
        }

        /// <summary>
        /// Main function for Text-To-Speech (TTS) engine.
        /// This function is the main function for operating TTS engine.
        /// </summary>
        /// <feature>
        /// http://tizen.org/feature/speech.synthesis
        /// </feature>
        /// <remarks>
        /// ServiceAppMain should be used for working the engine after this function.
        /// </remarks>
        /// <param name="argc">The argument count(original)</param>
        /// <param name="argv">The argument(original)</param>
        /// <exception cref="ArgumentException">Thrown in case of Invalid Parameter</exception>
        /// <exception cref="NotSupportedException">Thrown in case of Not supported</exception>
        /// <exception cref="InvalidOperationException">thrown in case of Operation failure</exception>
        public void EngineMain(int argc, string[] argv)
        {
            _callbackStructGCHandle.CallbackStruct.version = 1;
            _callbackStructGCHandle.CallbackStruct.getInfo = _getInfoCb;
            _callbackStructGCHandle.CallbackStruct.initialize = Initialize;
            _callbackStructGCHandle.CallbackStruct.deinitialize = _deinitializeCb;
            _callbackStructGCHandle.CallbackStruct.supportedVoice = ForEachSupportedVoices;
            _callbackStructGCHandle.CallbackStruct.validVoice = IsValidVoice;
            _callbackStructGCHandle.CallbackStruct.pitch = SetPitch;
            _callbackStructGCHandle.CallbackStruct.loadVoice = LoadVoice;
            _callbackStructGCHandle.CallbackStruct.unloadVoice = UnloadVoice;
            _callbackStructGCHandle.CallbackStruct.startSynthesis = _startSynthesisCb;
            _callbackStructGCHandle.CallbackStruct.cancelSynthesis = CancelSynthesis;
            _callbackStructGCHandle.CallbackStruct.checkAppAgreed = CheckAppAgreed;
            _callbackStructGCHandle.CallbackStruct.needAppCredential = NeedAppCredential;
            _structIntPtrHandle = Marshal.AllocHGlobal(Marshal.SizeOf(_callbackStructGCHandle.CallbackStruct));
            Marshal.StructureToPtr<RequestCallbackStruct>(_callbackStructGCHandle.CallbackStruct, _structIntPtrHandle, false);
            Error error = TTSEMain(argc, argv, _structIntPtrHandle);
            if (error != Error.None)
            {
                Log.Error(LogTag, "TTSEMain Failed with error " + error);
                throw ExceptionFactory.CreateException((ErrorCode)error);
            }

            Log.Info(LogTag, "After TTSEMain");
        }

        /// <summary>
        /// Gets the speed range from Tizen platform
        /// </summary>
        /// <feature>
        /// http://tizen.org/feature/speech.synthesis
        /// </feature>
        /// <remarks>
        /// This API is used when TTS engine wants to get the speed range from Tizen platform
        /// </remarks>
        /// <param name="min">The minimum speed value</param>
        /// <param name="normal">The normal speed value</param>
        /// <param name="max">The maximum speed value</param>
        /// <exception cref="NotSupportedException">Thrown in case of Not supported</exception>
        /// <exception cref="InvalidOperationException">thrown in case of Operation failure</exception>
        public void GetSpeedRange(out int min, out int normal, out int max)
        {
            Error error = TTSEGetSpeedRange(out min, out normal, out max);
            if (error != Error.None)
            {
                Log.Error(LogTag, "TTSEGetSpeedRange Failed with error " + error);
                throw ExceptionFactory.CreateException((ErrorCode)error);
            }

        }

        /// <summary>
        /// Gets the pitch range from Tizen platform.
        /// </summary>
        /// <feature>
        /// http://tizen.org/feature/speech.synthesis
        /// </feature>
        /// <remarks>
        /// This API is used when TTS engine wants to get the pitch range from Tizen platform.
        /// </remarks>
        /// <param name="min">The minimum pitch value</param>
        /// <param name="normal">The normal pitch value</param>
        /// <param name="max">The maximum pitch value</param>
        /// <exception cref="NotSupportedException">Thrown in case of Not supported</exception>
        /// <exception cref="InvalidOperationException">thrown in case of Operation failure</exception>
        public void GetPitchRange(out int min, out int normal, out int max)
        {
            Error error = TTSEGetPitchRange(out min, out normal, out max);
            if (error != Error.None)
            {
                Log.Error(LogTag, "TTSEGetPitchRange Failed with error " + error);
                throw ExceptionFactory.CreateException((ErrorCode)error);
            }

        }

        /// <summary>
        /// Sends the synthesized result to the engine service user.
        /// </summary>
        /// <feature>
        /// http://tizen.org/feature/speech.synthesis
        /// </feature>
        /// <remarks>
        /// This API is used in StartSynthesis(), when TTS engine sends the synthesized result to the engine service user.
        /// The synthesized result must be transferred to the engine service user through this function.
        /// </remarks>
        /// <param name="resultEvent">The result event</param>
        /// <param name="data">Result data</param>
        /// <param name="dataSize">Result data size</param>
        /// <param name="audioType">The audio type</param>
        /// <param name="rate">The sample rate</param>
        /// <exception cref="ArgumentException">Thrown in case of Invalid Parameter</exception>
        /// <exception cref="NotSupportedException">Thrown in case of Not supported</exception>
        /// <exception cref="InvalidOperationException">thrown in case of Operation failure</exception>
        /// <precondition>
        /// EngineMain function should be invoked before this function is called. StartSynthesis() will invoke this function.
        /// </precondition>
        public void SendResult(ResultEvent resultEvent, IntPtr data, int dataSize, AudioType audioType, int rate)
        {
            Error error = TTSESendResult(resultEvent, data, dataSize, audioType, rate, IntPtr.Zero);
            if (error != Error.None)
            {
                Log.Error(LogTag, "TTSESendResult Failed with error " + error);
                throw ExceptionFactory.CreateException((ErrorCode)error);
            }
        }

        /// <summary>
        /// Sends the error to the engine service user.
        /// </summary>
        /// <feature>
        /// http://tizen.org/feature/speech.synthesis
        /// </feature>
        /// <param name="error">The error reason</param>
        /// <param name="msg">The error message</param>
        /// <precondition>
        /// EngineMain function should be invoked before this function is called.
        /// </precondition>
        public void SendError(Error error, string msg)
        {
            Error err = TTSESendError(error, msg);
            if (err != Error.None)
            {
                Log.Error(LogTag, "SendError Failed with error " + err);
                throw ExceptionFactory.CreateException((ErrorCode)error);
            }

        }

        /// <summary>
        /// Sets a callback function for setting the private data.
        /// </summary>
        /// <feature>
        /// http://tizen.org/feature/speech.synthesis
        /// </feature>
        /// <param name="callback">
        /// Called when the engine service user gets the private data from Tts engine.
        /// In Parameters:
        /// a = Key -- The key field of private data
        /// b = data -- The data field of private data
        /// Following Error Codes can be returned
        /// 1. None
        /// 2. InvalidParameter
        /// 3. OperationFailed
        /// 4. NotSupported
        /// </param>
        /// <exception cref="ArgumentException">Thrown in case of Invalid Parameter</exception>
        /// <exception cref="UnauthorizedAccessException">Thrown in case of Permission denied</exception>
        /// <exception cref="NotSupportedException">Thrown in case of Not supported</exception>
        /// <exception cref="InvalidOperationException">thrown in case of Operation failure</exception>
        /// <precondition>
        /// Main function should be invoked before this function is called.
        /// </precondition>
        public void SetPrivateDataSetDelegate(Action<string> callback)
        {
            _privateDatacallback = callback;
            _privateDataSetCb = (string key, string data) =>
            {
                return _privateDatacallback.Invoke(key, data);
            };
            Error error = TTSESetPrivateDataSetCb(_privateDataSetCb);
            if (error != Error.None)
            {
                Log.Error(LogTag, "SetPrivateDataSetDelegate Failed with error " + error);
                throw ExceptionFactory.CreateException((ErrorCode)error);
            }

        }

        /// <summary>
        /// Sets a callback function for setting the private data.
        /// </summary>
        /// <feature>
        /// http://tizen.org/feature/speech.synthesis
        /// </feature>
        /// <param name="callback">callback function
        /// Called when TTS engine receives the private data from the engine service user.
        /// This callback function is called when the engine service user sends the private data to TTS engine.
        /// Out Parameters:
        /// a = Key -- The key field of private data
        /// b = data -- The data field of private data
        /// Following Error Codes can be returned
        /// 1. None
        /// 2. InvalidParameter
        /// 3. OperationFailed
        /// 4. NotSupported
        /// </param>
        /// <exception cref="ArgumentException">Thrown in case of Invalid Parameter</exception>
        /// <exception cref="UnauthorizedAccessException">Thrown in case of Permission denied</exception>
        /// <exception cref="NotSupportedException">Thrown in case of Not supported</exception>
        /// <exception cref="InvalidOperationException">thrown in case of Operation failure</exception>
        /// <precondition>
        /// Main function should be invoked before this function is called.
        /// </precondition>
        public void SetPrivateDataRequestedDelegate(OutAction<string> callback)
        {
            _privateDataRequestedCallback = callback;
            _privateDataRequestedCb = (string key, out string data) =>
            {
                return _privateDataRequestedCallback.Invoke(key, out data);
            };
            Error error = TTSESetPrivateDataRequestedCb(_privateDataRequestedCb);
            if (error != Error.None)
            {
                Log.Error(LogTag, "SetPrivateDataRequestedDelegate Failed with error " + error);
                throw ExceptionFactory.CreateException((ErrorCode)error);
            }

        }
        private StartSynthesisCb _startSynthesisCb = (IntPtr language, int type, IntPtr text, int speed, IntPtr appid, IntPtr credential, IntPtr userData) =>
        {
            string lan = null;
            string txt = null;
            string apid = null;
            string cre = null;
            if (language != null)
                lan = Marshal.PtrToStringAnsi(language);
            if (text != null)
                txt = Marshal.PtrToStringAnsi(text);
            if (appid != null)
                apid = Marshal.PtrToStringAnsi(appid);
            if (credential != null)
                cre = Marshal.PtrToStringAnsi(credential);
            return _engine.StartSynthesis(lan, type, txt, speed, apid, cre, IntPtr.Zero);
        };

        private GetInfoCb _getInfoCb = (out IntPtr engineUuid, out IntPtr engineName, out IntPtr engineSetting, out int useNetwork) =>
        {
            string uuid;
            string name;
            string setting;
            bool network;
            Error err = _engine.GetInformation(out uuid, out name, out setting, out network);
            if (network == true)
            {
                useNetwork = 1;
            }
            else
            {
                useNetwork = 0;
            }
            engineUuid = Marshal.StringToHGlobalAnsi(uuid);
            engineName = Marshal.StringToHGlobalAnsi(name);
            engineSetting = Marshal.StringToHGlobalAnsi(setting);
            return err;
        };

        private DeinitializeCb _deinitializeCb = () =>
        {
            Marshal.FreeHGlobal(_engine._structIntPtrHandle);
            return _engine.Deinitialize();
        };
    }
}