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