Release 4.0.0-preview1-00051
[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         /// Event to be invoked when TTS state changes.
244         /// </summary>
245         /// <since_tizen> 3 </since_tizen>
246         public event EventHandler<StateChangedEventArgs> StateChanged
247         {
248             add
249             {
250                 lock (thisLock)
251                 {
252                     _stateDelegate = (IntPtr handle, State previous, State current, IntPtr userData) =>
253                 {
254                     StateChangedEventArgs args = new StateChangedEventArgs(previous, current);
255                     _stateChanged?.Invoke(this, args);
256                 };
257                     TtsError error = TtsSetStateChangedCB(_handle, _stateDelegate, IntPtr.Zero);
258                     if (error != TtsError.None)
259                     {
260                         Log.Error(LogTag, "Add StateChanged Failed with error " + error);
261                     }
262                     else
263                     {
264                         _stateChanged += value;
265                     }
266                 }
267
268             }
269
270             remove
271             {
272                 lock (thisLock)
273                 {
274                     TtsError error = TtsUnsetStateChangedCB(_handle);
275                     if (error != TtsError.None)
276                     {
277                         Log.Error(LogTag, "Remove StateChanged Failed with error " + error);
278                     }
279
280                     _stateChanged -= value;
281                 }
282             }
283
284         }
285
286         /// <summary>
287         /// Event to be invoked when the utterance starts.
288         /// </summary>
289         /// <since_tizen> 3 </since_tizen>
290         public event EventHandler<UtteranceEventArgs> UtteranceStarted
291         {
292             add
293             {
294                 lock (thisLock)
295                 {
296                     _utteranceStartedResultDelegate = (IntPtr handle, int uttId, IntPtr userData) =>
297                 {
298                     UtteranceEventArgs args = new UtteranceEventArgs(uttId);
299                     _utteranceStarted?.Invoke(this, args);
300                 };
301                     TtsError error = TtsSetUtteranceStartedCB(_handle, _utteranceStartedResultDelegate, IntPtr.Zero);
302                     if (error != TtsError.None)
303                     {
304                         Log.Error(LogTag, "Add UtteranceStarted Failed with error " + error);
305                     }
306                     else
307                     {
308                         _utteranceStarted += value;
309                     }
310                 }
311             }
312
313             remove
314             {
315                 lock (thisLock)
316                 {
317                     TtsError error = TtsUnsetUtteranceStartedCB(_handle);
318                     if (error != TtsError.None)
319                     {
320                         Log.Error(LogTag, "Remove UtteranceStarted Failed with error " + error);
321                     }
322
323                     _utteranceStarted -= value;
324                 }
325             }
326         }
327
328         /// <summary>
329         /// Event to be invoked when the utterance completes.
330         /// </summary>
331         /// <since_tizen> 3 </since_tizen>
332         public event EventHandler<UtteranceEventArgs> UtteranceCompleted
333         {
334             add
335             {
336                 lock (thisLock)
337                 {
338                     _utteranceCompletedResultDelegate = (IntPtr handle, int uttId, IntPtr userData) =>
339                 {
340                     UtteranceEventArgs args = new UtteranceEventArgs(uttId);
341                     _utteranceCompleted?.Invoke(this, args);
342                 };
343                     TtsError error = TtsSetUtteranceCompletedCB(_handle, _utteranceCompletedResultDelegate, IntPtr.Zero);
344                     if (error != TtsError.None)
345                     {
346                         Log.Error(LogTag, "Add UtteranceCompleted Failed with error " + error);
347                     }
348                     else
349                     {
350                         _utteranceCompleted += value;
351                     }
352                 }
353             }
354
355             remove
356             {
357                 lock (thisLock)
358                 {
359                     TtsError error = TtsUnsetUtteranceCompletedCB(_handle);
360                     if (error != TtsError.None)
361                     {
362                         Log.Error(LogTag, "Remove UtteranceCompleted Failed with error " + error);
363                     }
364
365                     _utteranceCompleted -= value;
366                 }
367             }
368         }
369
370         /// <summary>
371         /// Event to be invoked when an error occurs.
372         /// </summary>
373         /// <since_tizen> 3 </since_tizen>
374         public event EventHandler<ErrorOccurredEventArgs> ErrorOccurred
375         {
376             add
377             {
378                 lock (thisLock)
379                 {
380                     _errorDelegate = (IntPtr handle, int uttId, TtsError reason, IntPtr userData) =>
381                 {
382                     ErrorOccurredEventArgs args = new ErrorOccurredEventArgs(handle, uttId, reason);
383                     _errorOccurred?.Invoke(this, args);
384                 };
385                     TtsError error = TtsSetErrorCB(_handle, _errorDelegate, IntPtr.Zero);
386                     if (error != TtsError.None)
387                     {
388                         Log.Error(LogTag, "Add ErrorOccurred Failed with error " + error);
389                     }
390
391                     else
392                     {
393                         _errorOccurred += value;
394                     }
395                 }
396             }
397
398             remove
399             {
400                 lock (thisLock)
401                 {
402                     TtsError error = TtsUnsetErrorCB(_handle);
403                     if (error != TtsError.None)
404                     {
405                         Log.Error(LogTag, "Remove ErrorOccurred Failed with error " + error);
406                     }
407
408                     _errorOccurred -= value;
409                 }
410             }
411         }
412
413         /// <summary>
414         /// Event to be invoked when an error occurs.
415         /// </summary>
416         /// <since_tizen> 3 </since_tizen>
417         public event EventHandler<DefaultVoiceChangedEventArgs> DefaultVoiceChanged
418         {
419             add
420             {
421                 lock (thisLock)
422                 {
423                     _voiceChangedDelegate = (IntPtr handle, IntPtr previousLanguage, int previousVoiceType, IntPtr currentLanguage, int currentVoiceType, IntPtr userData) =>
424                 {
425                     string previousLanguageString = Marshal.PtrToStringAnsi(previousLanguage);
426                     string currentLanguageString = Marshal.PtrToStringAnsi(currentLanguage);
427                     DefaultVoiceChangedEventArgs args = new DefaultVoiceChangedEventArgs(previousLanguageString, previousVoiceType, currentLanguageString, currentVoiceType);
428                     _defaultVoiceChanged?.Invoke(this, args);
429                 };
430                     TtsError error = TtsSetDefaultVoiceChangedCB(_handle, _voiceChangedDelegate, IntPtr.Zero);
431                     if (error != TtsError.None)
432                     {
433                         Log.Error(LogTag, "Add DefaultVoiceChanged Failed with error " + error);
434                     }
435
436                     else
437                     {
438                         _defaultVoiceChanged += value;
439                     }
440                 }
441
442             }
443
444             remove
445             {
446                 lock (thisLock)
447                 {
448                     TtsError error = TtsUnsetDefaultVoiceChangedCB(_handle);
449                     if (error != TtsError.None)
450                     {
451                         Log.Error(LogTag, "Remove DefaultVoiceChanged Failed with error " + error);
452                     }
453
454                     _defaultVoiceChanged -= value;
455                 }
456             }
457         }
458
459         /// <summary>
460         /// Event to be invoked to detect engine change.
461         /// </summary>
462         /// <since_tizen> 3 </since_tizen>
463         public event EventHandler<EngineChangedEventArgs> EngineChanged
464         {
465             add
466             {
467                 lock (thisLock)
468                 {
469                     _engineDelegate = (IntPtr handle, IntPtr engineId, IntPtr language, int voiceType, bool needCredential, IntPtr userData) =>
470                 {
471                     string engineIdString = Marshal.PtrToStringAnsi(engineId);
472                     string languageString = Marshal.PtrToStringAnsi(language);
473                     EngineChangedEventArgs args = new EngineChangedEventArgs(engineIdString, languageString, voiceType, needCredential);
474                     _engineChanged?.Invoke(this, args);
475                 };
476                     TtsError error = TtsSetEngineChangedCB(_handle, _engineDelegate, IntPtr.Zero);
477                     if (error != TtsError.None)
478                     {
479                         Log.Error(LogTag, "Add EngineChanged Failed with error " + error);
480                     }
481                     else
482                     {
483                         _engineChanged += value;
484                     }
485                 }
486             }
487
488             remove
489             {
490                 lock (thisLock)
491                 {
492                     TtsError error = TtsUnsetEngineChangedCB(_handle);
493                     if (error != TtsError.None)
494                     {
495                         Log.Error(LogTag, "Remove EngineChanged Failed with error " + error);
496                     }
497
498                     _engineChanged -= value;
499                 }
500             }
501         }
502
503         /// <summary>
504         /// Gets the default voice set by the user.
505         /// </summary>
506         /// <since_tizen> 3 </since_tizen>
507         /// <value>
508         /// The default voice in TTS.
509         /// </value>
510         /// <returns>
511         /// The default voice SupportedVoice value.
512         /// </returns>
513         public SupportedVoice DefaultVoice
514         {
515             get
516             {
517                 lock (thisLock)
518                 {
519                     string language;
520                     int voiceType;
521                     TtsError error = TtsGetDefaultVoice(_handle, out language, out voiceType);
522                     if (error != TtsError.None)
523                     {
524                         Log.Error(LogTag, "DefaultVoice Failed with error " + error);
525                         return new SupportedVoice();
526                     }
527
528                     return new SupportedVoice(language, voiceType);
529                 }
530             }
531         }
532
533         /// <summary>
534         /// Gets the maximum byte size for text.
535         /// </summary>
536         /// <since_tizen> 3 </since_tizen>
537         /// <value>
538         /// The Maximum byte size for text.
539         /// </value>
540         /// <returns>
541         /// The Default Voice SupportedVoice value, 0 if unable to get the value.
542         /// </returns>
543         /// <pre>
544         /// The State should be ready.
545         /// </pre>
546         public uint MaxTextSize
547         {
548             get
549             {
550                 uint maxTextSize;
551                 lock (thisLock)
552                 {
553                     TtsError error = TtsGetMaxTextSize(_handle, out maxTextSize);
554                     if (error != TtsError.None)
555                     {
556                         Log.Error(LogTag, "MaxTextSize Failed with error " + error);
557                         return 0;
558                     }
559
560                 }
561
562                 return maxTextSize;
563             }
564
565         }
566
567         /// <summary>
568         /// Gets the current TTS state.
569         /// </summary>
570         /// <since_tizen> 3 </since_tizen>
571         /// <value>
572         /// The current state of TTS.
573         /// </value>
574         /// <returns>
575         /// Current TTS State value.
576         /// </returns>
577         public State CurrentState
578         {
579             get
580             {
581                 State state;
582                 lock (thisLock)
583                 {
584                     TtsError error = TtsGetState(_handle, out state);
585                     if (error != TtsError.None)
586                     {
587                         Log.Error(LogTag, "CurrentState Failed with error " + error);
588                         return State.Unavailable;
589                     }
590
591                 }
592
593                 return state;
594             }
595
596         }
597
598         /// <summary>
599         /// The TTS Mode can be set using this property.
600         /// </summary>
601         /// <since_tizen> 3 </since_tizen>
602         /// <value>
603         /// The current TTS mode (default, screen-reader, notification).
604         /// </value>
605         /// <returns>
606         /// The Mode value.
607         /// </returns>
608         /// <exception cref="InvalidOperationException">
609         /// This exception can be due to the following reasons while setting the value:
610         /// 1. Operation Failed
611         /// 2. Engine Not Found
612         /// </exception>
613         /// <exception cref="OutOfMemoryException">This exception can be due to out Of memory.</exception>
614         /// <exception cref="NotSupportedException">This exception can be due to TTS not supported.</exception>
615         /// <pre>
616         /// The State should be created.
617         /// </pre>
618         public Mode CurrentMode
619         {
620             get
621             {
622                 Mode mode = Mode.Default;
623                 lock (thisLock)
624                 {
625                     TtsError error = TtsGetMode(_handle, out mode);
626                     if (error != TtsError.None)
627                     {
628                         Log.Error(LogTag, "Get Mode Failed with error " + error);
629                         return Mode.Default;
630                     }
631                 }
632
633                 return mode;
634             }
635             set
636             {
637                 TtsError error;
638                 lock (thisLock)
639                 {
640                     error = TtsSetMode(_handle, value);
641                 }
642
643                 if (error != TtsError.None)
644                 {
645                     Log.Error(LogTag, "Set Mode Failed with error " + error);
646                     throw ExceptionFactory.CreateException(error);
647                 }
648             }
649         }
650
651         /// <summary>
652         /// Sets the application credential.
653         /// </summary>
654         /// <since_tizen> 3 </since_tizen>
655         /// <param name="credential">.
656         /// The credential string.
657         /// </param>
658         /// <feature>
659         /// http://tizen.org/feature/speech.synthesis
660         /// </feature>
661         /// <exception cref="InvalidOperationException">This exception can be due to an invalid state.</exception>
662         /// <exception cref="NotSupportedException">This exception can be due to TTS not supported.</exception>
663         /// <exception cref="ArgumentException">This exception can be due to improper value provided while setting the value.</exception>
664         /// <pre>
665         /// The State should be created or ready.
666         /// </pre>
667         public void SetCredential(string credential)
668         {
669             lock (thisLock)
670             {
671                 TtsError error = TtsSetCredential(_handle, credential);
672                 if (error != TtsError.None)
673                 {
674                     Tizen.Log.Error(LogTag, "SetCredential Failed with error " + error);
675                     throw ExceptionFactory.CreateException(error);
676                 }
677             }
678         }
679
680         /// <summary>
681         /// Connects to the TTS service asynchronously.
682         /// </summary>
683         /// <since_tizen> 3 </since_tizen>
684         /// <feature>
685         /// http://tizen.org/feature/speech.synthesis
686         /// </feature>
687         /// <exception cref="InvalidOperationException">This exception can be due to an invalid state.</exception>
688         /// <exception cref="NotSupportedException">This exception can be due to TTS not supported.</exception>
689         /// <pre>
690         /// The State must be Created.
691         /// </pre>
692         /// <post>
693         /// If this function is successful, the TTS state will be ready.
694         /// If this function is unsuccessful, ErrorOccurred event will be invoked.
695         /// </post>
696         public void Prepare()
697         {
698             lock (thisLock)
699             {
700                 TtsError error = TtsPrepare(_handle);
701                 if (error != TtsError.None)
702                 {
703                     Log.Error(LogTag, "Prepare Failed with error " + error);
704                     throw ExceptionFactory.CreateException(error);
705                 }
706             }
707         }
708
709         /// <summary>
710         /// Disconnects from the STT service.
711         /// </summary>
712         /// <since_tizen> 3 </since_tizen>
713         /// <feature>
714         /// http://tizen.org/feature/speech.synthesis
715         /// </feature>
716         /// <exception cref="InvalidOperationException">This exception can be due to an invalid state.</exception>
717         /// <exception cref="NotSupportedException">This exception can be due to TTS not supported.</exception>
718         /// <pre>
719         /// The state must be ready.
720         /// </pre>
721         /// <post>
722         /// If this function is successful, the TTS state will be created.
723         /// </post>
724         public void Unprepare()
725         {
726             lock (thisLock)
727             {
728                 TtsError error = TtsUnprepare(_handle);
729                 if (error != TtsError.None)
730                 {
731                     Log.Error(LogTag, "Unprepare Failed with error " + error);
732                     throw ExceptionFactory.CreateException(error);
733                 }
734             }
735         }
736
737         /// <summary>
738         /// Retrieves all supported voices of the current engine.
739         /// </summary>
740         /// <since_tizen> 3 </since_tizen>
741         /// <returns>
742         /// The list of SupportedVoice.
743         /// </returns>
744         /// <feature>
745         /// http://tizen.org/feature/speech.synthesis
746         /// </feature>
747         /// <exception cref="InvalidOperationException">
748         /// This exception can be due to the following reasons:
749         /// 1. Engine Not Found
750         /// 2. Operation Failed
751         /// </exception>
752         /// <exception cref="NotSupportedException">This exception can be due to TTS not supported.</exception>
753         public IEnumerable<SupportedVoice> GetSupportedVoices()
754         {
755             List<SupportedVoice> voicesList = new List<SupportedVoice>();
756             lock (thisLock)
757             {
758                _supportedvoiceDelegate = (IntPtr handle, IntPtr language, int voiceType, IntPtr userData) =>
759             {
760                 string lang = Marshal.PtrToStringAnsi(language);
761                 SupportedVoice voice = new SupportedVoice(lang, voiceType);
762                 voicesList.Add(voice);
763                 return true;
764             };
765                 TtsError error = TtsForeachSupportedVoices(_handle, _supportedvoiceDelegate, IntPtr.Zero);
766                 if (error != TtsError.None)
767                 {
768                     Log.Error(LogTag, "GetSupportedVoices Failed with error " + error);
769                     throw ExceptionFactory.CreateException(error);
770                 }
771
772             }
773
774             return voicesList;
775         }
776
777         /// <summary>
778         /// Gets the private data from TTS engine.
779         /// </summary>
780         /// <since_tizen> 3 </since_tizen>
781         /// <param name="key">
782         /// The key string.
783         /// </param>
784         /// <returns>
785         /// The data corresponding to the provided key.
786         /// </returns>
787         /// <feature>
788         /// http://tizen.org/feature/speech.synthesis
789         /// </feature>
790         /// <exception cref="InvalidOperationException">
791         /// This exception can be due to the following reasons:
792         /// 1. Invalid State
793         /// 2. Engine Not found
794         /// 3. Operation Failure
795         /// </exception>
796         /// <exception cref="NotSupportedException">This exception can be due to TTS not supported.</exception>
797         /// <pre>
798         /// The state must be ready.
799         /// </pre>
800         public string GetPrivateData(string key)
801         {
802             string data;
803             lock (thisLock)
804             {
805                 TtsError error = TtsGetPrivateData(_handle, key, out data);
806                 if (error != TtsError.None)
807                 {
808                     Log.Error(LogTag, "GetPrivateData Failed with error " + error);
809                     throw ExceptionFactory.CreateException(error);
810                 }
811
812             }
813
814             return data;
815         }
816
817         /// <summary>
818         /// Sets the private data to tts engine.
819         /// </summary>
820         /// <since_tizen> 3 </since_tizen>
821         /// <param name="key">
822         /// The key string.
823         /// </param>
824         /// <param name="data">
825         /// The data string.
826         /// </param>
827         /// <feature>
828         /// http://tizen.org/feature/speech.synthesis
829         /// </feature>
830         /// <exception cref="InvalidOperationException">
831         /// This exception can be due to the following reasons:
832         /// 1. Invalid State
833         /// 2. Engine Not found
834         /// 3. Operation Failure
835         /// </exception>
836         /// <exception cref="NotSupportedException">This exception can be due to TTS not supported.</exception>
837         /// <exception cref="ArgumentException">This exception can be due to improper value provided while setting the value.</exception>
838         /// <pre>
839         /// The state must be ready.
840         /// </pre>
841         public void SetPrivateData(string key, string data)
842         {
843             lock (thisLock)
844             {
845                 TtsError error = TtsSetPrivateData(_handle, key, data);
846                 if (error != TtsError.None)
847                 {
848                     Log.Error(LogTag, "SetPrivateData Failed with error " + error);
849                     throw ExceptionFactory.CreateException(error);
850                 }
851             }
852         }
853
854         /// <summary>
855         /// Gets the speed range.
856         /// </summary>
857         /// <since_tizen> 3 </since_tizen>
858         /// <returns>
859         /// The SpeedRange value.
860         /// </returns>
861         /// <feature>
862         /// http://tizen.org/feature/speech.synthesis
863         /// </feature>
864         /// <exception cref="InvalidOperationException">
865         /// This exception can be due to the following reasons:
866         /// 1. Invalid State
867         /// 2. Operation Failure
868         /// </exception>
869         /// <exception cref="NotSupportedException">This exception can be due to TTS not supported.</exception>
870         /// <pre>
871         /// The state must be created.
872         /// </pre>
873         public SpeedRange GetSpeedRange()
874         {
875             int min = 0, max = 0, normal = 0;
876             lock (thisLock)
877             {
878                 TtsError error = TtsGetSpeedRange(_handle, out min, out normal, out max);
879                 if (error != TtsError.None)
880                 {
881                     Log.Error(LogTag, "GetSpeedRange Failed with error " + error);
882                     throw ExceptionFactory.CreateException(error);
883                 }
884
885             }
886
887             return new SpeedRange(min, normal, max);
888         }
889
890         /// <summary>
891         /// Adds a text to the queue.
892         /// </summary>
893         /// <since_tizen> 3 </since_tizen>
894         /// <remarks>
895         /// Locale MUST be set for UTF-8 text validation check.
896         /// </remarks>
897         /// <param name="text">
898         /// An input text based UTF-8.
899         /// </param>
900         /// <param name="language">
901         /// The language selected from the SupportedVoice.Language Property obtained from GetSupportedVoices()(e.g. 'NULL'(Automatic),'en_US').
902         /// </param>
903         /// <param name="voiceType">
904         /// The voice type selected from the SupportedVoice.VoiceType Property obtained from GetSupportedVoices().
905         /// </param>
906         /// <param name="speed">
907         /// A speaking speed (e.g.0 for Auto or the value from SpeedRange Property).
908         /// </param>
909         /// <returns>
910         /// The utterance ID.
911         /// </returns>
912         /// <feature>
913         /// http://tizen.org/feature/speech.synthesis
914         /// </feature>
915         /// <exception cref="InvalidOperationException">
916         /// This exception can be due to the following reasons:
917         /// 1. Invalid State
918         /// 2. Operation Failure
919         /// 3. Invalid Voice
920         /// </exception>
921         /// <exception cref="NotSupportedException">This exception can be due to TTS not supported.</exception>
922         /// <exception cref="UnauthorizedAccessException">This exception can be due to permission denied.</exception>
923         /// <exception cref="ArgumentException">This exception can be due to improper value provided while setting the value.</exception>
924         /// <pre>
925         /// The state must be ready or playing or paused.
926         /// </pre>
927         public int AddText(string text, string language, int voiceType, int speed)
928         {
929             int id;
930             lock (thisLock)
931             {
932                 TtsError error = TtsAddText(_handle, text, language, voiceType, speed, out id);
933                 if (error != TtsError.None)
934                 {
935                     Log.Error(LogTag, "AddText Failed with error " + error);
936                     throw ExceptionFactory.CreateException(error);
937                 }
938
939             }
940
941             return id;
942         }
943
944         /// <summary>
945         /// Starts synthesizing voice from the text and plays the synthesized audio data.
946         /// </summary>
947         /// <since_tizen> 3 </since_tizen>
948         /// <feature>
949         /// http://tizen.org/feature/speech.synthesis
950         /// </feature>
951         /// <exception cref="InvalidOperationException">
952         /// This exception can be due to the following reasons:
953         /// 1. Invalid State
954         /// 2. Operation Failure
955         /// 3. Out of Network
956         /// </exception>
957         /// <exception cref="NotSupportedException">This exception can be due to TTS not supported.</exception>
958         /// <exception cref="UnauthorizedAccessException">This exception can be due to permission denied.</exception>
959         /// <pre>
960         /// The state must be ready or paused.
961         /// </pre>
962         /// <post>
963         /// If this function succeeds, the TTS state will be playing.
964         /// </post>
965         public void Play()
966         {
967             lock (thisLock)
968             {
969                 TtsError error = TtsPlay(_handle);
970                 if (error != TtsError.None)
971                 {
972                     Log.Error(LogTag, "Play Failed with error " + error);
973                     throw ExceptionFactory.CreateException(error);
974                 }
975             }
976         }
977
978         /// <summary>
979         /// Stops playing the utterance and clears the queue.
980         /// </summary>
981         /// <since_tizen> 3 </since_tizen>
982         /// <feature>
983         /// http://tizen.org/feature/speech.synthesis
984         /// </feature>
985         /// <exception cref="InvalidOperationException">
986         /// This exception can be due to the following reasons:
987         /// 1. Invalid Stat
988         /// 2. Operation Failure
989         /// </exception>
990         /// <exception cref="NotSupportedException">This exception can be due to TTS not supported.</exception>
991         /// <pre>
992         /// The state must be ready or playing or paused.
993         /// </pre>
994         /// <post>
995         /// If this function succeeds, the TTS state will be ready.
996         /// This function will remove all text added via AddText() and synthesized sound data.
997         /// </post>
998         public void Stop()
999         {
1000             lock (thisLock)
1001             {
1002                 TtsError error = TtsStop(_handle);
1003                 if (error != TtsError.None)
1004                 {
1005                     Log.Error(LogTag, "Stop Failed with error " + error);
1006                     throw ExceptionFactory.CreateException(error);
1007                 }
1008             }
1009         }
1010
1011         /// <summary>
1012         /// Pauses the currently playing utterance.
1013         /// </summary>
1014         /// <since_tizen> 3 </since_tizen>
1015         /// <feature>
1016         /// http://tizen.org/feature/speech.synthesis
1017         /// </feature>
1018         /// <exception cref="InvalidOperationException">
1019         /// This exception can be due to the following reasons:
1020         /// 1. Invalid State
1021         /// 2. Operation Failure
1022         /// </exception>
1023         /// <exception cref="NotSupportedException">This exception can be due to TTS not supported.</exception>
1024         /// <pre>
1025         /// The state must be playing.
1026         /// </pre>
1027         /// <post>
1028         /// If this function succeeds, the TTS state will be Paused.
1029         /// </post>
1030         public void Pause()
1031         {
1032             lock (thisLock)
1033             {
1034                 TtsError error = TtsPause(_handle);
1035                 if (error != TtsError.None)
1036                 {
1037                     Log.Error(LogTag, "Pause Failed with error " + error);
1038                     throw ExceptionFactory.CreateException(error);
1039                 }
1040             }
1041         }
1042
1043         /// <summary>
1044         /// Method to release resources.
1045         /// </summary>
1046         /// <since_tizen> 3 </since_tizen>
1047         public void Dispose()
1048         {
1049             Dispose(true);
1050         }
1051
1052         protected virtual void Dispose(bool disposing)
1053         {
1054             if (!disposedValue)
1055             {
1056                 if (disposing)
1057                 {
1058                     TtsError error = TtsDestroy(_handle);
1059                     if (error != TtsError.None)
1060                     {
1061                         Log.Error(LogTag, "Destroy Failed with error " + error);
1062                     }
1063                 }
1064
1065                 disposedValue = true;
1066             }
1067         }
1068     }
1069 }