Correct a spelling mistake
[platform/core/csapi/uix-stt.git] / Tizen.Uix.Stt / Tizen.Uix.Stt / SttClient.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.Stt;
22
23 namespace Tizen.Uix.Stt
24 {
25     /// <summary>
26     /// The token event
27     /// </summary>
28     public enum ResultEvent
29     {
30         /// <summary>
31         /// Event when the recognition full or last result is ready
32         /// </summary>
33         FinalResult = 0,
34         /// <summary>
35         /// Event when the recognition partial result is ready
36         /// </summary>
37         PartialResult,
38         /// <summary>
39         /// Event when the recognition has failed
40         /// </summary>
41         Error
42     };
43
44     /// <summary>
45     /// Enumeration representing the result message
46     /// </summary>
47     public enum ResultMessage
48     {
49         /// <summary>
50         /// No Error
51         /// </summary>
52         None,
53         /// <summary>
54         /// Recognition failed  because the speech started too soon.
55         /// </summary>
56         TooSoon,
57         /// <summary>
58         /// Recognition failed  because the speech is too short.
59         /// </summary>
60         TooShort,
61         /// <summary>
62         /// Recognition failed  because the speech is too long.
63         /// </summary>
64         TooLong,
65         /// <summary>
66         /// Recognition failed  because the speech is too quiet to listen.
67         /// </summary>
68         TooQuiet,
69         /// <summary>
70         /// Recognition failed  because the speech is too loud to listen.
71         /// </summary>
72         TooLoud,
73         /// <summary>
74         /// Recognition failed  because the speech is too fast to listen.
75         /// </summary>
76         TooFast
77     };
78
79     /// <summary>
80     /// Enumeration for the Token type
81     /// </summary>
82     public enum TimeEvent
83     {
84         /// <summary>
85         /// Event when the token is beginning type
86         /// </summary>
87         Beginning = 0,
88         /// <summary>
89         /// Event when the token is middle type
90         /// </summary>
91         Middle = 1,
92         /// <summary>
93         /// Event when the token is end type
94         /// </summary>
95         End = 2
96     };
97
98     /// <summary>
99     /// Enum for Error values that can occur
100     /// </summary>
101     public enum Error
102     {
103         /// <summary>
104         /// Successful, No error
105         /// </summary>
106         None,
107         /// <summary>
108         /// Out of Memory
109         /// </summary>
110         OutOfMemory,
111         /// <summary>
112         /// I/O error
113         /// </summary>
114         IoError,
115         /// <summary>
116         /// Invalid parameter
117         /// </summary>
118         InvalidParameter,
119         /// <summary>
120         /// No answer from the STT service
121         /// </summary>
122         TimedOut,
123         /// <summary>
124         /// Device or resource busy
125         /// </summary>
126         RecorderBusy,
127         /// <summary>
128         /// Network is down
129         /// </summary>
130         OutOfNetwork,
131         /// <summary>
132         /// Permission denied
133         /// </summary>
134         PermissionDenied,
135         /// <summary>
136         /// STT NOT supported
137         /// </summary>
138         NotSupported,
139         /// <summary>
140         /// Invalid state
141         /// </summary>
142         InvalidState,
143         /// <summary>
144         /// Invalid language
145         /// </summary>
146         InvalidLanguage,
147         /// <summary>
148         /// No available engine
149         /// </summary>
150         EngineNotFound,
151         /// <summary>
152         /// Operation failed
153         /// </summary>
154         OperationFailed,
155         /// <summary>
156         /// Not supported feature of current engine
157         /// </summary>
158         NotSupportedFeature,
159         /// <summary>
160         /// Recording timed out
161         /// </summary>
162         RecordingTimedOut,
163         /// <summary>
164         /// No speech while recording
165         /// </summary>
166         NoSpeech,
167         /// <summary>
168         /// Progress to ready is not finished
169         /// </summary>
170         InProgressToReady,
171         /// <summary>
172         /// Progress to recording is not finished
173         /// </summary>
174         InProgressToRecording,
175         /// <summary>
176         /// Progress to processing is not finished
177         /// </summary>
178         InProgressToProcessing,
179         /// <summary>
180         /// Service reset
181         /// </summary>
182         ServiceReset
183     };
184
185     /// <summary>
186     /// Enumeration for Recognition Types
187     /// </summary>
188     public enum RecognitionType
189     {
190         /// <summary>
191         /// Free form dictation
192         /// </summary>
193         Free,
194         /// <summary>
195         /// Continuous free dictation.
196         /// </summary>
197         Partial,
198         /// <summary>
199         /// Search
200         /// </summary>
201         Search,
202         /// <summary>
203         /// Web Search
204         /// </summary>
205         WebSearch,
206         /// <summary>
207         /// Map
208         /// </summary>
209         Map
210     };
211
212     /// <summary>
213     /// Enumeration for the State types
214     /// </summary>
215     public enum State
216     {
217         /// <summary>
218         /// Created state
219         /// </summary>
220         Created = 0,
221         /// <summary>
222         /// Ready state
223         /// </summary>
224         Ready = 1,
225         /// <summary>
226         /// Recording state
227         /// </summary>
228         Recording = 2,
229         /// <summary>
230         /// Processing state
231         /// </summary>
232         Processing = 3,
233         /// <summary>
234         /// Unavailable
235         /// </summary>
236         Unavailable
237     };
238
239     /// <summary>
240     /// Enumeration for the Silence Detection types
241     /// </summary>
242     public enum SilenceDetection
243     {
244         /// <summary>
245         /// Silence detection type - False
246         /// </summary>
247         False = 0,
248         /// <summary>
249         /// Silence detection type - True
250         /// </summary>
251         True = 1,
252         /// <summary>
253         /// Silence detection type - Auto
254         /// </summary>
255         Auto = 2
256     };
257
258     /// <summary>
259     /// A main function of Speech-To-Text (below STT) API recognizes sound data recorded by users.
260     /// After choosing a language, applications will start recording and recognizing.
261     /// After recording, the applications will receive the recognized result.
262     /// The STT has a client-server for the service of multi-applications.
263     /// The STT service always works in the background as a server. If the service is not working, client library will invoke it and client will communicate with it.
264     /// The service has engines and the recorder so client does not have the recorder itself. Only the client request commands to the STT service for using STT.
265     /// </summary>
266     public class SttClient : IDisposable
267     {
268         private IntPtr _handle;
269         private Object thisLock = new Object();
270         private event EventHandler<RecognitionResultEventArgs> _recognitionResult;
271         private event EventHandler<StateChangedEventArgs> _stateChanged;
272         private event EventHandler<ErrorOccuredEventArgs> _errorOccured;
273         private event EventHandler<DefaultLanguageChangedEventArgs> _defaultLanguageChanged;
274         private event EventHandler<EngineChangedEventArgs> _engineChanged;
275         private bool disposedValue = false;
276         private Interop.Stt.RecognitionResultCallback _resultDelegate;
277         private Interop.Stt.StateChangedCallback _stateDelegate;
278         private Interop.Stt.ErrorCallback _errorDelegate;
279         private Interop.Stt.DefaultLanguageChangedCallback _languageDelegate;
280         private Interop.Stt.EngineChangedCallback _engineDelegate;
281         private ResultTime _result;
282         private ResultTimeCallback _resultTimeDelegate;
283
284         /// <summary>
285         /// Constructor to create a STT instance.
286         /// </summary>
287         /// <privilege>
288         /// http://tizen.org/privilege/recorder
289         /// </privilege>
290         /// <exception cref="InvalidOperationException">
291         /// This Exception can be due to the following reaons
292         /// 1. Out Of Memory
293         /// 2. Operation Failed
294         /// 3. STT Not Supported
295         /// 4. Permission Denied
296         /// </exception>
297         public SttClient()
298         {
299             IntPtr handle;
300             SttError error = SttCreate(out handle);
301             if (error != SttError.None)
302             {
303                 Log.Error(LogTag, "Create Failed with error " + error);
304                 throw ExceptionFactory.CreateException(error);
305             }
306
307             _handle = handle;
308         }
309
310         /// <summary>
311         /// Event to be invoked when the recognition is done.
312         /// </summary>
313         public event EventHandler<RecognitionResultEventArgs> RecognitionResult
314         {
315             add
316             {
317                 lock (thisLock)
318                 {
319                     _resultDelegate = (IntPtr handle, ResultEvent e, IntPtr data, int dataCount, IntPtr msg, IntPtr userData) =>
320                 {
321                     Log.Info(LogTag, "Recognition Result Event Triggered");
322                     if (data != null && msg != null)
323                     {
324                         RecognitionResultEventArgs args = new RecognitionResultEventArgs(e, data, dataCount, Marshal.PtrToStringAnsi(msg));
325                         _recognitionResult?.Invoke(this, args);
326                     }
327                     else
328                     {
329                         Log.Info(LogTag, "Recognition Result Event null received");
330                     }
331                 };
332                     SttError error = SttSetRecognitionResultCB(_handle, _resultDelegate, IntPtr.Zero);
333                     if (error != SttError.None)
334                     {
335                         Log.Error(LogTag, "Add RecognitionResult Failed with error " + error);
336                     }
337                     else
338                     {
339                         _recognitionResult += value;
340                     }
341                 }
342             }
343
344             remove
345             {
346                 lock (thisLock)
347                 {
348                     SttError error = SttUnsetRecognitionResultCB(_handle);
349                     if (error != SttError.None)
350                     {
351                         Log.Error(LogTag, "Remove RecognitionResult Failed with error " + error);
352                     }
353
354                     _recognitionResult -= value;
355                 }
356             }
357         }
358
359         /// <summary>
360         /// Event to be invoked when STT state changes.
361         /// </summary>
362         public event EventHandler<StateChangedEventArgs> StateChanged
363         {
364             add
365             {
366                 lock (thisLock)
367                 {
368                     SttClient obj = this;
369                     _stateDelegate = (IntPtr handle, State previous, State current, IntPtr userData) =>
370                     {
371                         StateChangedEventArgs args = new StateChangedEventArgs(previous, current);
372                         _stateChanged?.Invoke(obj, args);
373                     };
374                     SttError error = SttSetStateChangedCB(_handle, _stateDelegate, IntPtr.Zero);
375                     if (error != SttError.None)
376                     {
377                         Log.Error(LogTag, "Add StateChanged Failed with error " + error);
378                     }
379                     else
380                     {
381                         _stateChanged += value;
382                     }
383
384                 }
385             }
386
387             remove
388             {
389                 lock (thisLock)
390                 {
391                     SttError error = SttUnsetStateChangedCB(_handle);
392                     if (error != SttError.None)
393                     {
394                         Log.Error(LogTag, "Remove StateChanged Failed with error " + error);
395                     }
396
397                     _stateChanged -= value;
398                 }
399             }
400
401         }
402
403         /// <summary>
404         /// Event to be invoked when an error occurs.
405         /// </summary>
406         public event EventHandler<ErrorOccuredEventArgs> ErrorOccured
407         {
408             add
409             {
410                 lock (thisLock)
411                 {
412                     _errorDelegate = (IntPtr handle, SttError reason, IntPtr userData) =>
413                 {
414                     ErrorOccuredEventArgs args = new ErrorOccuredEventArgs(handle, reason);
415                     _errorOccured?.Invoke(this, args);
416                 };
417                     SttError error = SttSetErrorCB(_handle, _errorDelegate, IntPtr.Zero);
418                     if (error != SttError.None)
419                     {
420                         Log.Error(LogTag, "Add ErrorOccured Failed with error " + error);
421                     }
422
423                     else
424                     {
425                         _errorOccured += value;
426                     }
427                 }
428
429             }
430
431             remove
432             {
433                 lock (thisLock)
434                 {
435                     SttError error = SttUnsetErrorCB(_handle);
436                     if (error != SttError.None)
437                     {
438                         Log.Error(LogTag, "Remove ErrorOccured Failed with error " + error);
439                     }
440
441                     _errorOccured -= value;
442                 }
443             }
444         }
445
446         /// <summary>
447         /// Event to be invoked when default laungage change.
448         /// </summary>
449         public event EventHandler<DefaultLanguageChangedEventArgs> DefaultLanguageChanged
450         {
451             add
452             {
453                 lock (thisLock)
454                 {
455                     _languageDelegate = (IntPtr handle, IntPtr previousLanguage, IntPtr currentLanguage, IntPtr userData) =>
456                 {
457                     string previousLanguageString = Marshal.PtrToStringAnsi(previousLanguage);
458                     string currentLanguageString = Marshal.PtrToStringAnsi(currentLanguage);
459                     DefaultLanguageChangedEventArgs args = new DefaultLanguageChangedEventArgs(previousLanguageString, currentLanguageString);
460                     _defaultLanguageChanged?.Invoke(this, args);
461                 };
462                     SttError error = SttSetDefaultLanguageChangedCB(_handle, _languageDelegate, IntPtr.Zero);
463                     if (error != SttError.None)
464                     {
465                         Log.Error(LogTag, "Add DefaultLanguageChanged Failed with error " + error);
466                     }
467
468                     else
469                     {
470                         _defaultLanguageChanged += value;
471                     }
472                 }
473
474             }
475
476             remove
477             {
478                 lock (thisLock)
479                 {
480                     SttError error = SttUnsetDefaultLanguageChangedCB(_handle);
481                     if (error != SttError.None)
482                     {
483                         Log.Error(LogTag, "Remove DefaultLanguageChanged Failed with error " + error);
484                     }
485
486                     _defaultLanguageChanged -= value;
487                 }
488             }
489
490         }
491
492         /// <summary>
493         /// Event to be invoked to detect engine change.
494         /// </summary>
495         public event EventHandler<EngineChangedEventArgs> EngineChanged
496         {
497             add
498             {
499                 lock (thisLock)
500                 {
501                     _engineDelegate = (IntPtr handle, IntPtr engineId, IntPtr language, bool supportSilence, bool needCredential, IntPtr userData) =>
502                 {
503                     string engineIdString = Marshal.PtrToStringAnsi(engineId);
504                     string languageString = Marshal.PtrToStringAnsi(language);
505                     EngineChangedEventArgs args = new EngineChangedEventArgs(engineIdString, languageString, supportSilence, needCredential);
506                     _engineChanged?.Invoke(this, args);
507                 };
508                     SttError error = SttSetEngineChangedCB(_handle, _engineDelegate, IntPtr.Zero);
509                     if (error != SttError.None)
510                     {
511                         Log.Error(LogTag, "Add EngineChanged Failed with error " + error);
512                     }
513                     else
514                     {
515                         _engineChanged += value;
516                     }
517                 }
518             }
519
520             remove
521             {
522                 lock (thisLock)
523                 {
524                     SttError error = SttUnsetEngineChangedCB(_handle);
525                     if (error != SttError.None)
526                     {
527                         Log.Error(LogTag, "Remove EngineChanged Failed with error " + error);
528                     }
529
530                     _engineChanged -= value;
531                 }
532             }
533         }
534
535         /// <summary>
536         /// Gets the default language set by the user.
537         /// The language is specified as an ISO 3166 alpha-2 two letter country-code followed by ISO 639-1 for the two-letter language code.
538         /// For example, "ko_KR" for Korean, "en_US" for American English.
539         /// </summary>
540         /// <privilege>
541         /// http://tizen.org/privilege/recorder
542         /// </privilege>
543         /// <returns>
544         /// Default Lanaguage string value.
545         /// </returns>
546         public string GetDefaultLanguage
547         {
548             get
549             {
550                 string language;
551                 lock (thisLock)
552                 {
553                     SttError error = SttGetDefaultLanguage(_handle, out language);
554                     if (error != SttError.None)
555                     {
556                         Log.Error(LogTag, "DefaultLanaguage Failed with error " + error);
557                         return "";
558                     }
559                 }
560
561                 return language;
562             }
563         }
564
565         /// <summary>
566         /// Gets the microphone volume during recording.
567         /// </summary>
568         /// <privilege>
569         /// http://tizen.org/privilege/recorder
570         /// </privilege>
571         /// <precondition>
572         /// The State must be Recording.
573         /// </precondition>
574         public float GetRecordingVolume
575         {
576             get
577             {
578                 float volume;
579                 lock (thisLock)
580                 {
581                     SttError error = SttGetRecordingVolume(_handle, out volume);
582                     if (error != SttError.None)
583                     {
584                         Log.Error(LogTag, "GetRecordingVolume Failed with error " + error);
585                         return 0.0f;
586                     }
587
588                 }
589
590                 return volume;
591             }
592
593         }
594
595         /// <summary>
596         /// Gets the current STT state.
597         /// </summary>
598         /// <privilege>
599         /// http://tizen.org/privilege/recorder
600         /// </privilege>
601         /// <returns>
602         /// Current STT State value.
603         /// </returns>
604         public State GetState
605         {
606             get
607             {
608                 State state;
609                 lock (thisLock)
610                 {
611                     SttError error = SttGetState(_handle, out state);
612                     if (error != SttError.None)
613                     {
614                         Log.Error(LogTag, "GetState Failed with error " + error);
615                         return State.Unavailable;
616                     }
617                 }
618
619                 return state;
620             }
621
622         }
623
624         /// <summary>
625         /// This property can be used to get and set the current engine id.
626         /// </summary>
627         /// <exception cref="InvalidOperationException">
628         /// This Exception can occur while setting due to the following reaons
629         /// 1. Out Of Memory
630         /// 2. Operation Failed
631         /// 3. STT Not Supported
632         /// 4. Permission Denied
633         /// 5. Invalid State
634         /// </exception>
635         /// <exception cref="ArgumentException">
636         /// This can happen if Improper EngineId is provided while setting the value.
637         /// </exception>
638         /// <precondition>
639         /// The State must be Created.
640         /// </precondition>
641         public string Engine
642         {
643             get
644             {
645                 string engineId;
646                 lock (thisLock)
647                 {
648                     SttError error = SttGetEngine(_handle, out engineId);
649                     if (error != SttError.None)
650                     {
651                         Log.Error(LogTag, "Get EngineId Failed with error " + error);
652                         return "";
653                     }
654                 }
655
656                 return engineId;
657             }
658             set
659             {
660                 lock (thisLock)
661                 {
662                     SttError error = SttSetEngine(_handle, value);
663                     if (error != SttError.None)
664                     {
665                         Log.Error(LogTag, "Set EngineId Failed with error " + error);
666                         throw ExceptionFactory.CreateException(error);
667                     }
668                 }
669
670             }
671         }
672
673         /// <summary>
674         /// Retrieves the time stamp of the current recognition result
675         /// </summary>
676         /// <returns>
677         /// list of ResultTime
678         /// </returns>
679         /// <remarks>
680         /// This function should only be called in RecognitionResult Event
681         /// </remarks>
682         /// <exception cref="InvalidOperationException">
683         /// This Exception can be due to the following reaons
684         /// 1. Opearation Failed.
685         /// 2. STT Not Supported
686         /// 3. Permission Denied.
687         /// </exception>
688         public IEnumerable<ResultTime> GetDetailedResult()
689         {
690             List<ResultTime> list = new List<ResultTime>();
691             _resultTimeDelegate = (IntPtr handle, int index, TimeEvent e, IntPtr text, IntPtr startTime, IntPtr endTime, IntPtr userData) =>
692             {
693                 _result = new ResultTime(index, e, Marshal.PtrToStringAnsi(text), (long)startTime, (long)endTime);
694                 list.Add(_result);
695                 return true;
696             };
697             SttError error = SttForeachDetailedResult(_handle, _resultTimeDelegate, IntPtr.Zero);
698             if (error != SttError.None)
699             {
700                 Log.Error(LogTag, "GetDetailedResult Failed with error " + error);
701                 throw ExceptionFactory.CreateException(error);
702             }
703             return list;
704         }
705
706
707         /// <summary>
708         /// Gets the private data from stt engine.
709         /// </summary>
710         /// <param name="key">
711         /// The key string
712         /// </param>
713         /// <returns>
714         /// The Data Corresponding to the Key provided
715         /// </returns>
716         /// <exception cref="InvalidOperationException">
717         /// This Exception can be due to the following reaons
718         /// 1. No Answer from STT Service
719         /// 2. STT Not Supported
720         /// 3. Invalid State
721         /// </exception>
722         /// <precondition>
723         /// The State must be Ready.
724         /// </precondition>
725         public string GetPrivateData(string key)
726         {
727             string data;
728             lock (thisLock)
729             {
730                 SttError error = SttGetPrivateData(_handle, key, out data);
731                 if (error != SttError.None)
732                 {
733                     Log.Error(LogTag, "GetPrivateData Failed with error " + error);
734                     throw ExceptionFactory.CreateException(error);
735                 }
736             }
737
738             return data;
739         }
740
741         /// <summary>
742         /// Sets the private data to stt engine.
743         /// </summary>
744         /// <param name="key">
745         /// The key string
746         /// </param>
747         /// <param name="data">
748         /// The data string
749         /// </param>
750         /// <exception cref="InvalidOperationException">
751         /// This Exception can be due to the following reaons
752         /// 1. No Answer from STT Service
753         /// 2. STT Not Supported
754         /// 3. Invalid State
755         /// </exception>
756         /// <exception cref="ArgumentException">
757         /// This can happen if Improper value is provided while setting the value.
758         /// </exception>
759         /// <precondition>
760         /// The State must be Ready.
761         /// </precondition>
762         public void SetPrivateData(string key, string data)
763         {
764             lock (thisLock)
765             {
766                 SttError error = SttSetPrivateData(_handle, key, data);
767                 if (error != SttError.None)
768                 {
769                     Log.Error(LogTag, "SetPrivateData Failed with error " + error);
770                     throw ExceptionFactory.CreateException(error);
771                 }
772             }
773         }
774
775         /// <summary>
776         /// Gets the list of Supported Engine
777         /// </summary>
778         /// <returns>
779         /// IEnumerable<SupportedEngine> list of supported engines
780         /// </returns>
781         /// <exception cref="InvalidOperationException">
782         /// This Exception can be due to the following reaons
783         /// 1. Out Of Memory
784         /// 2. Operation Failed
785         /// 3. STT Not Supported
786         /// 4. Permission Denied
787         /// </exception>
788         public IEnumerable<SupportedEngine> GetSupportedEngines()
789         {
790             List<SupportedEngine> engineList = new List<SupportedEngine>();
791             lock (thisLock)
792             {
793                 SupportedEngineCallback supportedEngineDelegate = (IntPtr handle, IntPtr engineId, IntPtr engineName, IntPtr userData) =>
794             {
795                 string id = Marshal.PtrToStringAnsi(engineId);
796                 string name = Marshal.PtrToStringAnsi(engineName);
797                 SupportedEngine engine = new SupportedEngine(id, name);
798                 engineList.Add(engine);
799                 return true;
800             };
801                 SttError error = SttForeEachSupportedEngines(_handle, supportedEngineDelegate, IntPtr.Zero);
802                 if (error != SttError.None)
803                 {
804                     Log.Error(LogTag, "Create Failed with error " + error);
805                     throw ExceptionFactory.CreateException(error);
806                 }
807             }
808
809             return engineList;
810         }
811
812         /// <summary>
813         /// Sets the app credential
814         /// </summary>
815         /// <param name="credential">
816         /// The credential string
817         /// </param>
818         /// <exception cref="InvalidOperationException">
819         /// This Exception can be due to the following reaons
820         /// 1. Out Of Memory
821         /// 2. Operation Failed
822         /// 3. STT Not Supported
823         /// 4. Permission Denied
824         /// 5. Invalid State
825         /// </exception>
826         /// <exception cref="ArgumentException">
827         /// This can happen if Improper value is provided while setting the value.
828         /// </exception>
829         /// <precondition>
830         /// The State must be Created.
831         /// </precondition>
832         public void SetCredential(string credential)
833         {
834             lock (thisLock)
835             {
836                 SttError error = SttSetcredential(_handle, credential);
837                 if (error != SttError.None)
838                 {
839                     Log.Error(LogTag, "SetCredential Failed with error " + error);
840                     throw ExceptionFactory.CreateException(error);
841                 }
842             }
843         }
844
845         /// <summary>
846         /// Connects to the STT service asynchronously.
847         /// </summary>
848         /// <privilege>
849         /// http://tizen.org/privilege/recorder
850         /// </privilege>
851         /// <exception cref="InvalidOperationException">
852         /// This Exception can be due to the following reasons
853         /// 1. STT Not Supported
854         /// 2. Permission Denied
855         /// 3. Invalid State
856         /// </exception>
857         /// <precondition>
858         /// The State must be Created.
859         /// </precondition>
860         /// <postcondition>
861         /// If this function is successful, the STT state will be Ready
862         /// If this function is unsuccessful, ErrorOccured event will be invoked
863         /// </postcondition>
864         public void Prepare()
865         {
866             lock (thisLock)
867             {
868                 SttError error = SttPrepare(_handle);
869                 if (error != SttError.None)
870                 {
871                     Log.Error(LogTag, "SetEngine Failed with error " + error);
872                     throw ExceptionFactory.CreateException(error);
873                 }
874             }
875         }
876
877         /// <summary>
878         /// Disconnects from the STT service.
879         /// </summary>
880         /// <privilege>
881         /// http://tizen.org/privilege/recorder
882         /// </privilege>
883         /// <exception cref="InvalidOperationException">
884         /// This Exception can be due to the following reasons
885         /// 1. STT Not Supported
886         /// 2. Permission Denied
887         /// 3. Invalid State
888         /// </exception>
889         /// <precondition>
890         /// The State must be Ready.
891         /// </precondition>
892         /// <postcondition>
893         /// If this function is successful, the STT state will be Created
894         /// </postcondition>
895         public void Unprepare()
896         {
897             lock (thisLock)
898             {
899                 SttError error = SttUnprepare(_handle);
900                 if (error != SttError.None)
901                 {
902                     Log.Error(LogTag, "Unprepare Failed with error " + error);
903                     throw ExceptionFactory.CreateException(error);
904                 }
905             }
906         }
907
908         /// <summary>
909         /// Retrieves all supported languages of current engine.
910         /// The language is specified as an ISO 3166 alpha-2 two letter country-code followed by ISO 639-1 for the two-letter language code.
911         /// For example, "ko_KR" for Korean, "en_US" for American English.
912         /// </summary>
913         /// <privilege>
914         /// http://tizen.org/privilege/recorder
915         /// </privilege>
916         /// <returns>
917         /// list of strings of supported languages.
918         /// </returns>
919         /// <exception cref="InvalidOperationException">
920         /// This Exception can be due to the following reasons
921         /// 1. STT Not Supported
922         /// 2. Permission Denied
923         /// 3. Engine Not Found.
924         /// 4. Operation Failed.
925         /// </exception>
926         public IEnumerable<string> GetSupportedLangauages()
927         {
928             List<string> languageList = new List<string>();
929             lock (thisLock)
930             {
931                 SupportedLanguageCallback supportedLanguageDelegate = (IntPtr handle, IntPtr language, IntPtr userData) =>
932             {
933                 string lang = Marshal.PtrToStringAnsi(language);
934                 languageList.Add(lang);
935                 return true;
936             };
937
938                 SttError error = SttForeachSupportedLanguages(_handle, supportedLanguageDelegate, IntPtr.Zero);
939                 if (error != SttError.None)
940                 {
941                     Log.Error(LogTag, "GetSupportedLangauages Failed with error " + error);
942                     throw ExceptionFactory.CreateException(error);
943                 }
944             }
945
946             return languageList;
947         }
948
949         /// <summary>
950         /// Checks whether the recognition type is supported.
951         /// </summary>
952         /// <privilege>
953         /// http://tizen.org/privilege/recorder
954         /// </privilege>
955         /// <param name="type">
956         /// RecognitionType value.
957         /// </param>
958         /// <returns>
959         /// bool value indicating whether the recognition type is supported.
960         /// </returns>
961         /// <exception cref="InvalidOperationException">
962         /// This Exception can be due to the following reasons
963         /// 1. STT Not Supported
964         /// 2. Invalid State
965         /// 3. Engine Not Found.
966         /// 4. Operation Failed.
967         /// </exception>
968         /// <precondition>
969         /// The state should be Ready.
970         /// </precondition>
971         public bool IsRecognitionTypeSupported(RecognitionType type)
972         {
973             bool supported;
974             lock (thisLock)
975             {
976                 string recType = "stt.recognition.type.FREE";
977                 switch (type)
978                 {
979                     case RecognitionType.Free:
980                         {
981                             recType = "stt.recognition.type.FREE";
982                             break;
983                         }
984
985                     case RecognitionType.Partial:
986                         {
987                             recType = "stt.recognition.type.FREE.PARTIAL";
988                             break;
989                         }
990
991                     case RecognitionType.Search:
992                         {
993                             recType = "stt.recognition.type.SEARCH";
994                             break;
995                         }
996
997                     case RecognitionType.WebSearch:
998                         {
999                             recType = "stt.recognition.type.WEB_SEARCH";
1000                             break;
1001                         }
1002
1003                     case RecognitionType.Map:
1004                         {
1005                             recType = "stt.recognition.type.MAP";
1006                             break;
1007                         }
1008
1009                 }
1010
1011                 SttError error = SttIsRecognitionTypeSupported(_handle, recType, out supported);
1012                 if (error != SttError.None)
1013                 {
1014                     Log.Error(LogTag, "IsRecognitionTypeSupported Failed with error " + error);
1015                     throw ExceptionFactory.CreateException(error);
1016                 }
1017
1018             }
1019
1020             return supported;
1021         }
1022
1023         /// <summary>
1024         /// Sets the silence detection.
1025         /// </summary>
1026         /// <privilege>
1027         /// http://tizen.org/privilege/recorder
1028         /// </privilege>
1029         /// <param name="type">
1030         /// SilenceDetection value.
1031         /// </param>
1032         /// <exception cref="InvalidOperationException">
1033         /// This Exception can be due to the following reasons
1034         /// 1. STT Not Supported
1035         /// 2. Invalid State
1036         /// 3. Not supported feature of current engine.
1037         /// 4. Operation Failed.
1038         /// </exception>
1039         /// <precondition>
1040         /// The state should be Ready.
1041         /// </precondition>
1042         public void SetSilenceDetection(SilenceDetection type)
1043         {
1044             lock (thisLock)
1045             {
1046                 SttError error = SttSetSilenceDetection(_handle, type);
1047                 if (error != SttError.None)
1048                 {
1049                     Log.Error(LogTag, "SetSilenceDetection Failed with error " + error);
1050                     throw ExceptionFactory.CreateException(error);
1051                 }
1052             }
1053         }
1054
1055         /// <summary>
1056         /// Sets the sound to start recording.
1057         /// Sound file type should be wav type.
1058         /// </summary>
1059         /// <privilege>
1060         /// http://tizen.org/privilege/recorder
1061         /// </privilege>
1062         /// <param name="filePath">
1063         /// File Path for the sound.
1064         /// </param>
1065         /// <exception cref="InvalidOperationException">
1066         /// This Exception can be due to the following reasons
1067         /// 1. STT Not Supported.
1068         /// 2. Permission Denied.
1069         /// 3. Invalid State.
1070         /// 4. Operation Failed.
1071         /// </exception>
1072         /// <exception cref="ArgumentException">
1073         /// If an Invalid Parameter is provided.
1074         /// </exception>
1075         /// <precondition>
1076         /// The state should be Ready.
1077         /// </precondition>
1078         public void SetStartSound(string filePath)
1079         {
1080             lock (thisLock)
1081             {
1082                 SttError error = SttSetStartSound(_handle, filePath);
1083                 if (error != SttError.None)
1084                 {
1085                     Log.Error(LogTag, "SetStartSound Failed with error " + error);
1086                     throw ExceptionFactory.CreateException(error);
1087                 }
1088             }
1089         }
1090
1091         /// <summary>
1092         /// Unsets the sound to start recording.
1093         /// </summary>
1094         /// <privilege>
1095         /// http://tizen.org/privilege/recorder
1096         /// </privilege>
1097         /// <exception cref="InvalidOperationException">
1098         /// This Exception can be due to the following reasons
1099         /// 1. STT Not Supported.
1100         /// 2. Permission Denied.
1101         /// 3. Invalid State.
1102         /// 4. Operation Failed.
1103         /// </exception>
1104         /// <precondition>
1105         /// The state should be Ready.
1106         /// </precondition>
1107         public void UnsetStartSound()
1108         {
1109             lock (thisLock)
1110             {
1111                 SttError error = SttUnsetStartSound(_handle);
1112                 if (error != SttError.None)
1113                 {
1114                     Log.Error(LogTag, "UnsetStartSound Failed with error " + error);
1115                     throw ExceptionFactory.CreateException(error);
1116                 }
1117             }
1118         }
1119
1120         /// <summary>
1121         /// Sets the sound to stop recording.
1122         /// Sound file type should be wav type.
1123         /// </summary>
1124         /// <privilege>
1125         /// http://tizen.org/privilege/recorder
1126         /// </privilege>
1127         /// <param name="filePath">
1128         /// File Path for the sound.
1129         /// </param>
1130         /// <exception cref="InvalidOperationException">
1131         /// This Exception can be due to the following reasons
1132         /// 1. STT Not Supported.
1133         /// 2. Permission Denied.
1134         /// 3. Invalid State.
1135         /// 4. Operation Failed.
1136         /// </exception>
1137         /// <exception cref="ArgumentException">
1138         /// If an Invalid Parameter is provided.
1139         /// </exception>
1140         /// <precondition>
1141         /// The state should be Ready.
1142         /// </precondition>
1143         public void SetStopSound(string filePath)
1144         {
1145             lock (thisLock)
1146             {
1147                 SttError error = SttSetStopSound(_handle, filePath);
1148                 if (error != SttError.None)
1149                 {
1150                     Log.Error(LogTag, "SetStopSound Failed with error " + error);
1151                     throw ExceptionFactory.CreateException(error);
1152                 }
1153             }
1154         }
1155
1156         /// <summary>
1157         /// Unsets the sound to stop recording.
1158         /// </summary>
1159         /// <privilege>
1160         /// http://tizen.org/privilege/recorder
1161         /// </privilege>
1162         /// <exception cref="InvalidOperationException">
1163         /// This Exception can be due to the following reasons
1164         /// 1. STT Not Supported.
1165         /// 2. Permission Denied.
1166         /// 3. Invalid State.
1167         /// 4. Operation Failed.
1168         /// </exception>
1169         /// <precondition>
1170         /// The state should be Ready.
1171         /// </precondition>
1172         public void UnsetStopSound()
1173         {
1174             lock (thisLock)
1175             {
1176                 SttError error = SttUnsetStopSound(_handle);
1177                 if (error != SttError.None)
1178                 {
1179                     Log.Error(LogTag, "UnsetStopSound Failed with error " + error);
1180                     throw ExceptionFactory.CreateException(error);
1181                 }
1182             }
1183         }
1184
1185         /// <summary>
1186         /// Starts recording and recognition asynchronously.
1187         /// This function starts recording in the STT service and sending recording data to engine.
1188         /// This work continues until Stop, Cancel or silence detected by engine
1189         /// </summary>
1190         /// <privilege>
1191         /// http://tizen.org/privilege/recorder
1192         /// </privilege>
1193         /// <param name="language">
1194         /// The language selected
1195         /// </param>
1196         /// <param name="type">
1197         /// The type for recognition
1198         /// </param>
1199         /// <exception cref="InvalidOperationException">
1200         /// This Exception can be due to the following reasons
1201         /// 1. STT Not Supported.
1202         /// 2. Permission Denied.
1203         /// 3. Invalid State.
1204         /// 4. Operation Failed.
1205         /// 5. Recorder Busy.
1206         /// 6. Progress to recording is not finished
1207         /// </exception>
1208         /// <exception cref="ArgumentException">
1209         /// If an Invalid Language is provided
1210         /// </exception>
1211         /// <precondition>
1212         /// The state should be Ready.
1213         /// </precondition>
1214         /// <postcondition>
1215         /// It will invoke StateChanged Event if registerd.
1216         /// If this function succeeds, the STT state will be Recording.
1217         /// If you call this function again before state changes, you will receive ErrorINProgressToRecording.
1218         /// </postcondition>
1219         public void Start(string language, RecognitionType type)
1220         {
1221             lock (thisLock)
1222             {
1223                 string recType = "stt.recognition.type.FREE";
1224                 switch (type)
1225                 {
1226                     case RecognitionType.Free:
1227                         {
1228                             recType = "stt.recognition.type.FREE";
1229                             break;
1230                         }
1231
1232                     case RecognitionType.Partial:
1233                         {
1234                             recType = "stt.recognition.type.FREE.PARTIAL";
1235                             break;
1236                         }
1237
1238                     case RecognitionType.Search:
1239                         {
1240                             recType = "stt.recognition.type.SEARCH";
1241                             break;
1242                         }
1243
1244                     case RecognitionType.WebSearch:
1245                         {
1246                             recType = "stt.recognition.type.WEB_SEARCH";
1247                             break;
1248                         }
1249
1250                     case RecognitionType.Map:
1251                         {
1252                             recType = "stt.recognition.type.MAP";
1253                             break;
1254                         }
1255
1256                 }
1257
1258                 SttError error = SttStart(_handle, language, recType);
1259                 if (error != SttError.None)
1260                 {
1261                     Log.Error(LogTag, "Start Failed with error " + error);
1262                     throw ExceptionFactory.CreateException(error);
1263                 }
1264             }
1265         }
1266
1267         /// <summary>
1268         /// Finishes the recording and starts recognition processing in engine asynchronously.
1269         /// </summary>
1270         /// <privilege>
1271         /// http://tizen.org/privilege/recorder
1272         /// </privilege>
1273         /// <exception cref="InvalidOperationException">
1274         /// This Exception can be due to the following reasons
1275         /// 1. STT Not Supported.
1276         /// 2. Permission Denied.
1277         /// 3. Invalid State.
1278         /// 4. Operation Failed.
1279         /// 5. Progress to ready is not finished.
1280         /// 6. Progress to recording is not finished.
1281         /// 7. Progress to processing is not finished.
1282         /// </exception>
1283         /// <precondition>
1284         /// The state should be Recording.
1285         /// </precondition>
1286         /// <postcondition>
1287         /// It will invoke StateChanged Event if registerd.
1288         /// If this function succeeds, the STT state will be Processing.
1289         /// If you call this function again before state changes, you will receive ErrorINProgressToProcessing.
1290         /// After processing of engine, RecognitionResult event is invoked
1291         /// </postcondition>
1292         public void Stop()
1293         {
1294             lock (thisLock)
1295             {
1296                 SttError error = SttStop(_handle);
1297                 if (error != SttError.None)
1298                 {
1299                     Log.Error(LogTag, "Stop Failed with error " + error);
1300                     throw ExceptionFactory.CreateException(error);
1301                 }
1302             }
1303         }
1304
1305         /// <summary>
1306         /// Cancels processing recognition and recording asynchronously.
1307         /// This function cancels recording and engine cancels recognition processing.
1308         /// After successful cancel, StateChanged event is invoked otherwise if error is occurred, ErrorOccured event is invoked.
1309         /// </summary>
1310         /// <privilege>
1311         /// http://tizen.org/privilege/recorder
1312         /// </privilege>
1313         /// <exception cref="InvalidOperationException">
1314         /// This Exception can be due to the following reasons
1315         /// 1. STT Not Supported.
1316         /// 2. Permission Denied.
1317         /// 3. Invalid State.
1318         /// 4. Operation Failed.
1319         /// 5. Progress to ready is not finished.
1320         /// 6. Progress to recording is not finished.
1321         /// 7. Progress to processing is not finished.
1322         /// </exception>
1323         /// <precondition>
1324         /// The state should be Recording or Processing.
1325         /// </precondition>
1326         /// <postcondition>
1327         /// It will invoke StateChanged Event if registerd.
1328         /// If this function succeeds, the STT state will be Ready.
1329         /// If you call this function again before state changes, you will receive ErrorINProgressToReady.
1330         /// </postcondition>
1331         public void Cancel()
1332         {
1333             lock (thisLock)
1334             {
1335                 SttError error = SttCancel(_handle);
1336                 if (error != SttError.None)
1337                 {
1338                     Log.Error(LogTag, "Cancel Failed with error " + error);
1339                     throw ExceptionFactory.CreateException(error);
1340                 }
1341             }
1342         }
1343
1344         /// <summary>
1345         /// Method to release resources
1346         /// </summary>
1347         public void Dispose()
1348         {
1349             Dispose(true);
1350         }
1351
1352         protected virtual void Dispose(bool disposing)
1353         {
1354             if (!disposedValue)
1355             {
1356                 if (disposing)
1357                 {
1358                     SttError error = SttDestroy(_handle);
1359                     if (error != SttError.None)
1360                     {
1361                         Log.Error(LogTag, "Destroy Failed with error " + error);
1362                     }
1363                 }
1364
1365                 disposedValue = true;
1366             }
1367         }
1368     }
1369 }