[NUI] TCSACR-226 code change (#1032)
[platform/core/csapi/tizenfx.git] / src / Tizen.Uix.Tts / Tizen.Uix.Tts / TtsClient.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
18 using System;
19 using System.Collections.Generic;
20 using System.Runtime.InteropServices;
21 using static Interop.Tts;
22
23 namespace Tizen.Uix.Tts
24 {
25     /// <summary>
26     /// Enumeration for the states.
27     /// </summary>
28     /// <since_tizen> 3 </since_tizen>
29     public enum State
30     {
31         /// <summary>
32         ///  Created state.
33         /// </summary>
34         /// <since_tizen> 3 </since_tizen>
35         Created = 0,
36
37         /// <summary>
38         /// Ready state.
39         /// </summary>
40         /// <since_tizen> 3 </since_tizen>
41         Ready = 1,
42
43         /// <summary>
44         /// Playing state.
45         /// </summary>
46         /// <since_tizen> 3 </since_tizen>
47         Playing = 2,
48
49         /// <summary>
50         /// Paused state.
51         /// </summary>
52         /// <since_tizen> 3 </since_tizen>
53         Paused = 3,
54
55         /// <summary>
56         /// Unavailable state.
57         /// </summary>
58         /// <since_tizen> 3 </since_tizen>
59         Unavailable
60     };
61
62     /// <summary>
63     /// Enumeration for TTS mode.
64     /// </summary>
65     /// <since_tizen> 3 </since_tizen>
66     public enum Mode
67     {
68         /// <summary>
69         /// Default mode for normal application.
70         /// </summary>
71         /// <since_tizen> 3 </since_tizen>
72         Default = 0,
73
74         /// <summary>
75         /// Notification mode.
76         /// </summary>
77         /// <since_tizen> 3 </since_tizen>
78         Notification = 1,
79
80         /// <summary>
81         /// Accessibility mode.
82         /// </summary>
83         /// <since_tizen> 3 </since_tizen>
84         ScreenReader = 2
85     };
86
87     /// <summary>
88     /// Enumeration for error values that can occur.
89     /// </summary>
90     /// <since_tizen> 3 </since_tizen>
91     public enum Error
92     {
93         /// <summary>
94         /// Successful, no error.
95         /// </summary>
96         /// <since_tizen> 3 </since_tizen>
97         None,
98         /// <summary>
99         /// Out of memory.
100         /// </summary>
101         /// <since_tizen> 3 </since_tizen>
102         OutOfMemory,
103         /// <summary>
104         /// I/O error.
105         /// </summary>
106         /// <since_tizen> 3 </since_tizen>
107         IoError,
108         /// <summary>
109         /// Invalid parameter.
110         /// </summary>
111         /// <since_tizen> 3 </since_tizen>
112         InvalidParameter,
113         /// <summary>
114         /// No answer from the STT service.
115         /// </summary>
116         /// <since_tizen> 3 </since_tizen>
117         TimedOut,
118         /// <summary>
119         /// Network is down.
120         /// </summary>
121         /// <since_tizen> 3 </since_tizen>
122         OutOfNetwork,
123         /// <summary>
124         /// Permission denied.
125         /// </summary>
126         /// <since_tizen> 3 </since_tizen>
127         PermissionDenied,
128         /// <summary>
129         /// STT not supported.
130         /// </summary>
131         /// <since_tizen> 3 </since_tizen>
132         NotSupported,
133         /// <summary>
134         /// Invalid state.
135         /// </summary>
136         /// <since_tizen> 3 </since_tizen>
137         InvalidState,
138         /// <summary>
139         /// Invalid voice.
140         /// </summary>
141         /// <since_tizen> 3 </since_tizen>
142         InvalidVoice,
143         /// <summary>
144         /// No available engine.
145         /// </summary>
146         /// <since_tizen> 3 </since_tizen>
147         EngineNotFound,
148         /// <summary>
149         /// Operation failed.
150         /// </summary>
151         /// <since_tizen> 3 </since_tizen>
152         OperationFailed,
153         /// <summary>
154         /// Audio policy blocked.
155         /// </summary>
156         /// <since_tizen> 3 </since_tizen>
157         AudioPolicyBlocked
158     };
159
160     /// <summary>
161     /// Enumeration for the voice types.
162     /// </summary>
163     /// <since_tizen> 3 </since_tizen>
164     public enum Voice
165     {
166         /// <summary>
167         /// The automatic voice type.
168         /// </summary>
169         /// <since_tizen> 3 </since_tizen>
170         Auto,
171
172         /// <summary>
173         /// The male voice type.
174         /// </summary>
175         /// <since_tizen> 3 </since_tizen>
176         Male,
177
178         /// <summary>
179         /// The female voice type.
180         /// </summary>
181         /// <since_tizen> 3 </since_tizen>
182         Female,
183
184         /// <summary>
185         /// The child voice type.
186         /// </summary>
187         /// <since_tizen> 3 </since_tizen>
188         Child
189     };
190
191     /// <summary>
192     /// You can use Text-To-Speech (TTS) API's to read sound data transformed by the engine from input texts.
193     /// Applications can add input-text to queue for reading continuously and control the player that can play, pause, and stop sound data synthesized from text.
194     /// </summary>
195     /// <since_tizen> 3 </since_tizen>
196     public class TtsClient : IDisposable
197     {
198         private IntPtr _handle;
199         private event EventHandler<StateChangedEventArgs> _stateChanged;
200         private event EventHandler<UtteranceEventArgs> _utteranceStarted;
201         private event EventHandler<UtteranceEventArgs> _utteranceCompleted;
202         private event EventHandler<ErrorOccurredEventArgs> _errorOccurred;
203         private event EventHandler<DefaultVoiceChangedEventArgs> _defaultVoiceChanged;
204         private event EventHandler<EngineChangedEventArgs> _engineChanged;
205         private bool disposedValue = false;
206         private Object thisLock = new Object();
207         private TtsStateChangedCB _stateDelegate;
208         private TtsUtteranceStartedCB _utteranceStartedResultDelegate;
209         private TtsUtteranceCompletedCB _utteranceCompletedResultDelegate;
210         private TtsErrorCB _errorDelegate;
211         private TtsDefaultVoiceChangedCB _voiceChangedDelegate;
212         private TtsEngineChangedCB _engineDelegate;
213         private TtsSupportedVoiceCB _supportedvoiceDelegate;
214
215         /// <summary>
216         /// Constructor to create a TTS instance.
217         /// </summary>
218         /// <since_tizen> 3 </since_tizen>
219         /// <feature>
220         /// http://tizen.org/feature/speech.synthesis
221         /// </feature>
222         /// <exception cref="InvalidOperationException">
223         /// This exception can be due to the following reasons:
224         /// 1. Operation Failed
225         /// 2. Engine Not Found
226         /// </exception>
227         /// <exception cref="OutOfMemoryException">This exception can be due to out Of memory.</exception>
228         /// <exception cref="NotSupportedException">This exception can be due to TTS not supported.</exception>
229         public TtsClient()
230         {
231             IntPtr handle;
232             TtsError error = TtsCreate(out handle);
233             if (error != TtsError.None)
234             {
235                 Log.Error(LogTag, "Create Failed with error " + error);
236                 throw ExceptionFactory.CreateException(error);
237             }
238
239             _handle = handle;
240         }
241
242         /// <summary>
243         /// Destructor to destroy TtsClient handle.
244         /// </summary>
245         ~TtsClient()
246         {
247             Dispose(false);
248         }
249
250         /// <summary>
251         /// Event to be invoked when TTS state changes.
252         /// </summary>
253         /// <since_tizen> 3 </since_tizen>
254         public event EventHandler<StateChangedEventArgs> StateChanged
255         {
256             add
257             {
258                 lock (thisLock)
259                 {
260                     if (_stateChanged == null)
261                     {
262                         _stateDelegate = (IntPtr handle, State previous, State current, IntPtr userData) =>
263                         {
264                             StateChangedEventArgs args = new StateChangedEventArgs(previous, current);
265                             _stateChanged?.Invoke(this, args);
266                         };
267
268                         TtsError error = TtsSetStateChangedCB(_handle, _stateDelegate, IntPtr.Zero);
269                         if (error != TtsError.None)
270                         {
271                             Log.Error(LogTag, "Add StateChanged Failed with error " + error);
272                         }
273                     }
274                     _stateChanged += value;
275                 }
276
277             }
278
279             remove
280             {
281                 lock (thisLock)
282                 {
283                     _stateChanged -= value;
284                     if (_stateChanged == null)
285                     {
286                         TtsError error = TtsUnsetStateChangedCB(_handle);
287                         if (error != TtsError.None)
288                         {
289                             Log.Error(LogTag, "Remove StateChanged Failed with error " + error);
290                         }
291                     }
292                 }
293             }
294
295         }
296
297         /// <summary>
298         /// Event to be invoked when the utterance starts.
299         /// </summary>
300         /// <since_tizen> 3 </since_tizen>
301         public event EventHandler<UtteranceEventArgs> UtteranceStarted
302         {
303             add
304             {
305                 lock (thisLock)
306                 {
307                     if (_utteranceStarted == null)
308                     {
309                         _utteranceStartedResultDelegate = (IntPtr handle, int uttId, IntPtr userData) =>
310                         {
311                             UtteranceEventArgs args = new UtteranceEventArgs(uttId);
312                             _utteranceStarted?.Invoke(this, args);
313                         };
314
315                         TtsError error = TtsSetUtteranceStartedCB(_handle, _utteranceStartedResultDelegate, IntPtr.Zero);
316                         if (error != TtsError.None)
317                         {
318                             Log.Error(LogTag, "Add UtteranceStarted Failed with error " + error);
319                         }
320                     }
321                     _utteranceStarted += value;
322                 }
323             }
324
325             remove
326             {
327                 lock (thisLock)
328                 {
329                     _utteranceStarted -= value;
330                     if (_utteranceStarted == null)
331                     {
332                         TtsError error = TtsUnsetUtteranceStartedCB(_handle);
333                         if (error != TtsError.None)
334                         {
335                             Log.Error(LogTag, "Remove UtteranceStarted Failed with error " + error);
336                         }
337                     }
338                 }
339             }
340         }
341
342         /// <summary>
343         /// Event to be invoked when the utterance completes.
344         /// </summary>
345         /// <since_tizen> 3 </since_tizen>
346         public event EventHandler<UtteranceEventArgs> UtteranceCompleted
347         {
348             add
349             {
350                 lock (thisLock)
351                 {
352                     if (_utteranceCompleted == null)
353                     {
354                         _utteranceCompletedResultDelegate = (IntPtr handle, int uttId, IntPtr userData) =>
355                         {
356                             UtteranceEventArgs args = new UtteranceEventArgs(uttId);
357                             _utteranceCompleted?.Invoke(this, args);
358                         };
359
360                         TtsError error = TtsSetUtteranceCompletedCB(_handle, _utteranceCompletedResultDelegate, IntPtr.Zero);
361                         if (error != TtsError.None)
362                         {
363                             Log.Error(LogTag, "Add UtteranceCompleted Failed with error " + error);
364                         }
365                     }
366                     _utteranceCompleted += value;
367                 }
368             }
369
370             remove
371             {
372                 lock (thisLock)
373                 {
374                     _utteranceCompleted -= value;
375                     if (_utteranceCompleted == null)
376                     {
377                         TtsError error = TtsUnsetUtteranceCompletedCB(_handle);
378                         if (error != TtsError.None)
379                         {
380                             Log.Error(LogTag, "Remove UtteranceCompleted Failed with error " + error);
381                         }
382                     }
383                 }
384             }
385         }
386
387         /// <summary>
388         /// Event to be invoked when an error occurs.
389         /// </summary>
390         /// <since_tizen> 4 </since_tizen>
391         public event EventHandler<ErrorOccurredEventArgs> ErrorOccurred
392         {
393             add
394             {
395                 lock (thisLock)
396                 {
397                     if (_errorOccurred == null)
398                     {
399                         _errorDelegate = (IntPtr handle, int uttId, TtsError reason, IntPtr userData) =>
400                         {
401                             ErrorOccurredEventArgs args = new ErrorOccurredEventArgs(handle, uttId, reason);
402                             _errorOccurred?.Invoke(this, args);
403                         };
404
405                         TtsError error = TtsSetErrorCB(_handle, _errorDelegate, IntPtr.Zero);
406                         if (error != TtsError.None)
407                         {
408                             Log.Error(LogTag, "Add ErrorOccurred Failed with error " + error);
409                         }
410                     }
411                     _errorOccurred += value;
412                 }
413             }
414
415             remove
416             {
417                 lock (thisLock)
418                 {
419                     _errorOccurred -= value;
420                     if (_errorOccurred == null)
421                     {
422                         TtsError error = TtsUnsetErrorCB(_handle);
423                         if (error != TtsError.None)
424                         {
425                             Log.Error(LogTag, "Remove ErrorOccurred Failed with error " + error);
426                         }
427                     }
428                 }
429             }
430         }
431
432         /// <summary>
433         /// Event to be invoked when an error occurs.
434         /// </summary>
435         /// <since_tizen> 3 </since_tizen>
436         public event EventHandler<DefaultVoiceChangedEventArgs> DefaultVoiceChanged
437         {
438             add
439             {
440                 lock (thisLock)
441                 {
442                     if (_defaultVoiceChanged == null)
443                     {
444                         _voiceChangedDelegate = (IntPtr handle, IntPtr previousLanguage, int previousVoiceType, IntPtr currentLanguage, int currentVoiceType, IntPtr userData) =>
445                         {
446                             string previousLanguageString = Marshal.PtrToStringAnsi(previousLanguage);
447                             string currentLanguageString = Marshal.PtrToStringAnsi(currentLanguage);
448                             DefaultVoiceChangedEventArgs args = new DefaultVoiceChangedEventArgs(previousLanguageString, previousVoiceType, currentLanguageString, currentVoiceType);
449                             _defaultVoiceChanged?.Invoke(this, args);
450                         };
451
452                         TtsError error = TtsSetDefaultVoiceChangedCB(_handle, _voiceChangedDelegate, IntPtr.Zero);
453                         if (error != TtsError.None)
454                         {
455                             Log.Error(LogTag, "Add DefaultVoiceChanged Failed with error " + error);
456                         }
457                     }
458                     _defaultVoiceChanged += value;
459                 }
460
461             }
462
463             remove
464             {
465                 lock (thisLock)
466                 {
467                     _defaultVoiceChanged -= value;
468                     if (_defaultVoiceChanged == null)
469                                         {
470                         TtsError error = TtsUnsetDefaultVoiceChangedCB(_handle);
471                         if (error != TtsError.None)
472                         {
473                             Log.Error(LogTag, "Remove DefaultVoiceChanged Failed with error " + error);
474                         }
475                     }
476                 }
477             }
478         }
479
480         /// <summary>
481         /// Event to be invoked to detect engine change.
482         /// </summary>
483         /// <since_tizen> 3 </since_tizen>
484         public event EventHandler<EngineChangedEventArgs> EngineChanged
485         {
486             add
487             {
488                 lock (thisLock)
489                 {
490                     if (_engineChanged == null)
491                     {
492                         _engineDelegate = (IntPtr handle, IntPtr engineId, IntPtr language, int voiceType, bool needCredential, IntPtr userData) =>
493                         {
494                             string engineIdString = Marshal.PtrToStringAnsi(engineId);
495                             string languageString = Marshal.PtrToStringAnsi(language);
496                             EngineChangedEventArgs args = new EngineChangedEventArgs(engineIdString, languageString, voiceType, needCredential);
497                             _engineChanged?.Invoke(this, args);
498                         };
499                         TtsError error = TtsSetEngineChangedCB(_handle, _engineDelegate, IntPtr.Zero);
500                         if (error != TtsError.None)
501                         {
502                             Log.Error(LogTag, "Add EngineChanged Failed with error " + error);
503                         }
504                     }
505                     _engineChanged += value;
506                 }
507             }
508
509             remove
510             {
511                 lock (thisLock)
512                 {
513                     _engineChanged -= value;
514                     if (_engineChanged == null)
515                     {
516                         TtsError error = TtsUnsetEngineChangedCB(_handle);
517                         if (error != TtsError.None)
518                         {
519                             Log.Error(LogTag, "Remove EngineChanged Failed with error " + error);
520                         }
521                     }
522                 }
523             }
524         }
525
526         /// <summary>
527         /// Gets the default voice set by the user.
528         /// </summary>
529         /// <since_tizen> 3 </since_tizen>
530         /// <value>
531         /// The default voice in TTS.
532         /// </value>
533         /// <returns>
534         /// The default voice SupportedVoice value.
535         /// </returns>
536         public SupportedVoice DefaultVoice
537         {
538             get
539             {
540                 lock (thisLock)
541                 {
542                     string language;
543                     int voiceType;
544                     TtsError error = TtsGetDefaultVoice(_handle, out language, out voiceType);
545                     if (error != TtsError.None)
546                     {
547                         Log.Error(LogTag, "DefaultVoice Failed with error " + error);
548                         return new SupportedVoice();
549                     }
550
551                     return new SupportedVoice(language, voiceType);
552                 }
553             }
554         }
555
556         /// <summary>
557         /// Gets the maximum byte size for text.
558         /// </summary>
559         /// <since_tizen> 3 </since_tizen>
560         /// <value>
561         /// The Maximum byte size for text.
562         /// </value>
563         /// <returns>
564         /// The Default Voice SupportedVoice value, 0 if unable to get the value.
565         /// </returns>
566         /// <pre>
567         /// The State should be ready.
568         /// </pre>
569         public uint MaxTextSize
570         {
571             get
572             {
573                 uint maxTextSize;
574                 lock (thisLock)
575                 {
576                     TtsError error = TtsGetMaxTextSize(_handle, out maxTextSize);
577                     if (error != TtsError.None)
578                     {
579                         Log.Error(LogTag, "MaxTextSize Failed with error " + error);
580                         return 0;
581                     }
582                 }
583
584                 return maxTextSize;
585             }
586
587         }
588
589         /// <summary>
590         /// Gets the current TTS state.
591         /// </summary>
592         /// <since_tizen> 3 </since_tizen>
593         /// <value>
594         /// The current state of TTS.
595         /// </value>
596         /// <returns>
597         /// Current TTS State value.
598         /// </returns>
599         public State CurrentState
600         {
601             get
602             {
603                 State state;
604                 lock (thisLock)
605                 {
606                     TtsError error = TtsGetState(_handle, out state);
607                     if (error != TtsError.None)
608                     {
609                         Log.Error(LogTag, "CurrentState Failed with error " + error);
610                         return State.Unavailable;
611                     }
612                 }
613
614                 return state;
615             }
616
617         }
618
619         /// <summary>
620         /// The TTS Mode can be set using this property.
621         /// </summary>
622         /// <since_tizen> 3 </since_tizen>
623         /// <value>
624         /// The current TTS mode (default, screen-reader, notification).
625         /// </value>
626         /// <returns>
627         /// The Mode value.
628         /// </returns>
629         /// <exception cref="InvalidOperationException">
630         /// This exception can be due to the following reasons while setting the value:
631         /// 1. Operation Failed
632         /// 2. Engine Not Found
633         /// </exception>
634         /// <exception cref="OutOfMemoryException">This exception can be due to out Of memory.</exception>
635         /// <exception cref="NotSupportedException">This exception can be due to TTS not supported.</exception>
636         /// <pre>
637         /// The State should be created.
638         /// </pre>
639         public Mode CurrentMode
640         {
641             get
642             {
643                 Mode mode = Mode.Default;
644                 lock (thisLock)
645                 {
646                     TtsError error = TtsGetMode(_handle, out mode);
647                     if (error != TtsError.None)
648                     {
649                         Log.Error(LogTag, "Get Mode Failed with error " + error);
650                         return Mode.Default;
651                     }
652                 }
653
654                 return mode;
655             }
656             set
657             {
658                 TtsError error;
659                 lock (thisLock)
660                 {
661                     error = TtsSetMode(_handle, value);
662                 }
663
664                 if (error != TtsError.None)
665                 {
666                     Log.Error(LogTag, "Set Mode Failed with error " + error);
667                     throw ExceptionFactory.CreateException(error);
668                 }
669             }
670         }
671
672         /// <summary>
673         /// Sets the application credential.
674         /// </summary>
675         /// <since_tizen> 3 </since_tizen>
676         /// <param name="credential">.
677         /// The credential string.
678         /// </param>
679         /// <feature>
680         /// http://tizen.org/feature/speech.synthesis
681         /// </feature>
682         /// <exception cref="InvalidOperationException">This exception can be due to an invalid state.</exception>
683         /// <exception cref="NotSupportedException">This exception can be due to TTS not supported.</exception>
684         /// <exception cref="ArgumentException">This exception can be due to improper value provided while setting the value.</exception>
685         /// <pre>
686         /// The State should be created or ready.
687         /// </pre>
688         public void SetCredential(string credential)
689         {
690             lock (thisLock)
691             {
692                 TtsError error = TtsSetCredential(_handle, credential);
693                 if (error != TtsError.None)
694                 {
695                     Tizen.Log.Error(LogTag, "SetCredential Failed with error " + error);
696                     throw ExceptionFactory.CreateException(error);
697                 }
698             }
699         }
700
701         /// <summary>
702         /// Connects to the TTS service asynchronously.
703         /// </summary>
704         /// <since_tizen> 3 </since_tizen>
705         /// <feature>
706         /// http://tizen.org/feature/speech.synthesis
707         /// </feature>
708         /// <exception cref="InvalidOperationException">This exception can be due to an invalid state.</exception>
709         /// <exception cref="NotSupportedException">This exception can be due to TTS not supported.</exception>
710         /// <pre>
711         /// The State must be Created.
712         /// </pre>
713         /// <post>
714         /// If this function is successful, the TTS state will be ready.
715         /// If this function is unsuccessful, ErrorOccurred event will be invoked.
716         /// </post>
717         public void Prepare()
718         {
719             lock (thisLock)
720             {
721                 TtsError error = TtsPrepare(_handle);
722                 if (error != TtsError.None)
723                 {
724                     Log.Error(LogTag, "Prepare Failed with error " + error);
725                     throw ExceptionFactory.CreateException(error);
726                 }
727             }
728         }
729
730         /// <summary>
731         /// Disconnects from the STT service.
732         /// </summary>
733         /// <since_tizen> 3 </since_tizen>
734         /// <feature>
735         /// http://tizen.org/feature/speech.synthesis
736         /// </feature>
737         /// <exception cref="InvalidOperationException">This exception can be due to an invalid state.</exception>
738         /// <exception cref="NotSupportedException">This exception can be due to TTS not supported.</exception>
739         /// <pre>
740         /// The state must be ready.
741         /// </pre>
742         /// <post>
743         /// If this function is successful, the TTS state will be created.
744         /// </post>
745         public void Unprepare()
746         {
747             lock (thisLock)
748             {
749                 TtsError error = TtsUnprepare(_handle);
750                 if (error != TtsError.None)
751                 {
752                     Log.Error(LogTag, "Unprepare Failed with error " + error);
753                     throw ExceptionFactory.CreateException(error);
754                 }
755             }
756         }
757
758         /// <summary>
759         /// Retrieves all supported voices of the current engine.
760         /// </summary>
761         /// <since_tizen> 3 </since_tizen>
762         /// <returns>
763         /// The list of SupportedVoice.
764         /// </returns>
765         /// <feature>
766         /// http://tizen.org/feature/speech.synthesis
767         /// </feature>
768         /// <exception cref="InvalidOperationException">
769         /// This exception can be due to the following reasons:
770         /// 1. Engine Not Found
771         /// 2. Operation Failed
772         /// </exception>
773         /// <exception cref="NotSupportedException">This exception can be due to TTS not supported.</exception>
774         public IEnumerable<SupportedVoice> GetSupportedVoices()
775         {
776             List<SupportedVoice> voicesList = new List<SupportedVoice>();
777             lock (thisLock)
778             {
779                _supportedvoiceDelegate = (IntPtr handle, IntPtr language, int voiceType, IntPtr userData) =>
780                 {
781                     string lang = Marshal.PtrToStringAnsi(language);
782                     SupportedVoice voice = new SupportedVoice(lang, voiceType);
783                     voicesList.Add(voice);
784                     return true;
785                 };
786                 TtsError error = TtsForeachSupportedVoices(_handle, _supportedvoiceDelegate, IntPtr.Zero);
787                 if (error != TtsError.None)
788                 {
789                     Log.Error(LogTag, "GetSupportedVoices Failed with error " + error);
790                     throw ExceptionFactory.CreateException(error);
791                 }
792             }
793
794             return voicesList;
795         }
796
797         /// <summary>
798         /// Gets the private data from TTS engine.
799         /// </summary>
800         /// <since_tizen> 3 </since_tizen>
801         /// <param name="key">
802         /// The key string.
803         /// </param>
804         /// <returns>
805         /// The data corresponding to the provided key.
806         /// </returns>
807         /// <feature>
808         /// http://tizen.org/feature/speech.synthesis
809         /// </feature>
810         /// <exception cref="InvalidOperationException">
811         /// This exception can be due to the following reasons:
812         /// 1. Invalid State
813         /// 2. Engine Not found
814         /// 3. Operation Failure
815         /// </exception>
816         /// <exception cref="NotSupportedException">This exception can be due to TTS not supported.</exception>
817         /// <pre>
818         /// The state must be ready.
819         /// </pre>
820         public string GetPrivateData(string key)
821         {
822             string data;
823             lock (thisLock)
824             {
825                 TtsError error = TtsGetPrivateData(_handle, key, out data);
826                 if (error != TtsError.None)
827                 {
828                     Log.Error(LogTag, "GetPrivateData Failed with error " + error);
829                     throw ExceptionFactory.CreateException(error);
830                 }
831             }
832
833             return data;
834         }
835
836         /// <summary>
837         /// Sets the private data to tts engine.
838         /// </summary>
839         /// <since_tizen> 3 </since_tizen>
840         /// <param name="key">
841         /// The key string.
842         /// </param>
843         /// <param name="data">
844         /// The data string.
845         /// </param>
846         /// <feature>
847         /// http://tizen.org/feature/speech.synthesis
848         /// </feature>
849         /// <exception cref="InvalidOperationException">
850         /// This exception can be due to the following reasons:
851         /// 1. Invalid State
852         /// 2. Engine Not found
853         /// 3. Operation Failure
854         /// </exception>
855         /// <exception cref="NotSupportedException">This exception can be due to TTS not supported.</exception>
856         /// <exception cref="ArgumentException">This exception can be due to improper value provided while setting the value.</exception>
857         /// <pre>
858         /// The state must be ready.
859         /// </pre>
860         public void SetPrivateData(string key, string data)
861         {
862             lock (thisLock)
863             {
864                 TtsError error = TtsSetPrivateData(_handle, key, data);
865                 if (error != TtsError.None)
866                 {
867                     Log.Error(LogTag, "SetPrivateData Failed with error " + error);
868                     throw ExceptionFactory.CreateException(error);
869                 }
870             }
871         }
872
873         /// <summary>
874         /// Gets the speed range.
875         /// </summary>
876         /// <since_tizen> 3 </since_tizen>
877         /// <returns>
878         /// The SpeedRange value.
879         /// </returns>
880         /// <feature>
881         /// http://tizen.org/feature/speech.synthesis
882         /// </feature>
883         /// <exception cref="InvalidOperationException">
884         /// This exception can be due to the following reasons:
885         /// 1. Invalid State
886         /// 2. Operation Failure
887         /// </exception>
888         /// <exception cref="NotSupportedException">This exception can be due to TTS not supported.</exception>
889         /// <pre>
890         /// The state must be created.
891         /// </pre>
892         public SpeedRange GetSpeedRange()
893         {
894             int min = 0, max = 0, normal = 0;
895             lock (thisLock)
896             {
897                 TtsError error = TtsGetSpeedRange(_handle, out min, out normal, out max);
898                 if (error != TtsError.None)
899                 {
900                     Log.Error(LogTag, "GetSpeedRange Failed with error " + error);
901                     throw ExceptionFactory.CreateException(error);
902                 }
903             }
904
905             return new SpeedRange(min, normal, max);
906         }
907
908         /// <summary>
909         /// Adds a text to the queue.
910         /// </summary>
911         /// <since_tizen> 3 </since_tizen>
912         /// <remarks>
913         /// Locale MUST be set for UTF-8 text validation check.
914         /// </remarks>
915         /// <param name="text">
916         /// An input text based UTF-8.
917         /// </param>
918         /// <param name="language">
919         /// The language selected from the SupportedVoice.Language Property obtained from GetSupportedVoices()(e.g. 'NULL'(Automatic),'en_US').
920         /// </param>
921         /// <param name="voiceType">
922         /// The voice type selected from the SupportedVoice.VoiceType Property obtained from GetSupportedVoices().
923         /// </param>
924         /// <param name="speed">
925         /// A speaking speed (e.g.0 for Auto or the value from SpeedRange Property).
926         /// </param>
927         /// <returns>
928         /// The utterance ID.
929         /// </returns>
930         /// <feature>
931         /// http://tizen.org/feature/speech.synthesis
932         /// </feature>
933         /// <exception cref="InvalidOperationException">
934         /// This exception can be due to the following reasons:
935         /// 1. Invalid State
936         /// 2. Operation Failure
937         /// 3. Invalid Voice
938         /// </exception>
939         /// <exception cref="NotSupportedException">This exception can be due to TTS not supported.</exception>
940         /// <exception cref="UnauthorizedAccessException">This exception can be due to permission denied.</exception>
941         /// <exception cref="ArgumentException">This exception can be due to improper value provided while setting the value.</exception>
942         /// <pre>
943         /// The state must be ready or playing or paused.
944         /// </pre>
945         public int AddText(string text, string language, int voiceType, int speed)
946         {
947             int id;
948             lock (thisLock)
949             {
950                 TtsError error = TtsAddText(_handle, text, language, voiceType, speed, out id);
951                 if (error != TtsError.None)
952                 {
953                     Log.Error(LogTag, "AddText Failed with error " + error);
954                     throw ExceptionFactory.CreateException(error);
955                 }
956             }
957
958             return id;
959         }
960
961         /// <summary>
962         /// Starts synthesizing voice from the text and plays the synthesized audio data.
963         /// </summary>
964         /// <since_tizen> 3 </since_tizen>
965         /// <feature>
966         /// http://tizen.org/feature/speech.synthesis
967         /// </feature>
968         /// <exception cref="InvalidOperationException">
969         /// This exception can be due to the following reasons:
970         /// 1. Invalid State
971         /// 2. Operation Failure
972         /// 3. Out of Network
973         /// </exception>
974         /// <exception cref="NotSupportedException">This exception can be due to TTS not supported.</exception>
975         /// <exception cref="UnauthorizedAccessException">This exception can be due to permission denied.</exception>
976         /// <pre>
977         /// The state must be ready or paused.
978         /// </pre>
979         /// <post>
980         /// If this function succeeds, the TTS state will be playing.
981         /// </post>
982         public void Play()
983         {
984             lock (thisLock)
985             {
986                 TtsError error = TtsPlay(_handle);
987                 if (error != TtsError.None)
988                 {
989                     Log.Error(LogTag, "Play Failed with error " + error);
990                     throw ExceptionFactory.CreateException(error);
991                 }
992             }
993         }
994
995         /// <summary>
996         /// Stops playing the utterance and clears the queue.
997         /// </summary>
998         /// <since_tizen> 3 </since_tizen>
999         /// <feature>
1000         /// http://tizen.org/feature/speech.synthesis
1001         /// </feature>
1002         /// <exception cref="InvalidOperationException">
1003         /// This exception can be due to the following reasons:
1004         /// 1. Invalid Stat
1005         /// 2. Operation Failure
1006         /// </exception>
1007         /// <exception cref="NotSupportedException">This exception can be due to TTS not supported.</exception>
1008         /// <pre>
1009         /// The state must be ready or playing or paused.
1010         /// </pre>
1011         /// <post>
1012         /// If this function succeeds, the TTS state will be ready.
1013         /// This function will remove all text added via AddText() and synthesized sound data.
1014         /// </post>
1015         public void Stop()
1016         {
1017             lock (thisLock)
1018             {
1019                 TtsError error = TtsStop(_handle);
1020                 if (error != TtsError.None)
1021                 {
1022                     Log.Error(LogTag, "Stop Failed with error " + error);
1023                     throw ExceptionFactory.CreateException(error);
1024                 }
1025             }
1026         }
1027
1028         /// <summary>
1029         /// Pauses the currently playing utterance.
1030         /// </summary>
1031         /// <since_tizen> 3 </since_tizen>
1032         /// <feature>
1033         /// http://tizen.org/feature/speech.synthesis
1034         /// </feature>
1035         /// <exception cref="InvalidOperationException">
1036         /// This exception can be due to the following reasons:
1037         /// 1. Invalid State
1038         /// 2. Operation Failure
1039         /// </exception>
1040         /// <exception cref="NotSupportedException">This exception can be due to TTS not supported.</exception>
1041         /// <pre>
1042         /// The state must be playing.
1043         /// </pre>
1044         /// <post>
1045         /// If this function succeeds, the TTS state will be Paused.
1046         /// </post>
1047         public void Pause()
1048         {
1049             lock (thisLock)
1050             {
1051                 TtsError error = TtsPause(_handle);
1052                 if (error != TtsError.None)
1053                 {
1054                     Log.Error(LogTag, "Pause Failed with error " + error);
1055                     throw ExceptionFactory.CreateException(error);
1056                 }
1057             }
1058         }
1059
1060         /// <summary>
1061         /// Method to release resources.
1062         /// </summary>
1063         /// <since_tizen> 3 </since_tizen>
1064         public void Dispose()
1065         {
1066             Dispose(true);
1067             GC.SuppressFinalize(this);
1068         }
1069
1070         /// <summary>
1071         /// Method to release resources.
1072         /// </summary>
1073         /// <since_tizen> 3 </since_tizen>
1074         /// <param name="disposing">
1075         /// The boolean value for destoying tts handle.
1076         /// </param>
1077         protected virtual void Dispose(bool disposing)
1078         {
1079             if (!disposedValue)
1080                         {
1081                                 lock (thisLock)
1082                                 {
1083                                         if (_handle != IntPtr.Zero)
1084                                         {
1085                                                 TtsError error = TtsDestroy(_handle);
1086                                                 if (error != TtsError.None)
1087                                                 {
1088                                                         Log.Error(LogTag, "Destroy Failed with error " + error);
1089                                                 }
1090                                                 _handle = IntPtr.Zero;
1091                                         }
1092                                 }
1093
1094                                 disposedValue = true;
1095             }
1096         }
1097     }
1098 }