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