Fix API reference
[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         /// <feature>
291         /// http://tizen.org/feature/speech.recognition
292         /// http://tizen.org/feature/microphone
293         /// </feature>
294         /// <exception cref="InvalidOperationException">
295         /// This Exception can be due to the following reaons
296         /// 1. Out Of Memory
297         /// 2. Operation Failed
298         /// 3. STT Not Supported
299         /// 4. Permission Denied
300         /// </exception>
301         public SttClient()
302         {
303             IntPtr handle;
304             SttError error = SttCreate(out handle);
305             if (error != SttError.None)
306             {
307                 Log.Error(LogTag, "Create Failed with error " + error);
308                 throw ExceptionFactory.CreateException(error);
309             }
310
311             _handle = handle;
312         }
313
314         /// <summary>
315         /// Event to be invoked when the recognition is done.
316         /// </summary>
317         public event EventHandler<RecognitionResultEventArgs> RecognitionResult
318         {
319             add
320             {
321                 lock (thisLock)
322                 {
323                     _resultDelegate = (IntPtr handle, ResultEvent e, IntPtr data, int dataCount, IntPtr msg, IntPtr userData) =>
324                 {
325                     Log.Info(LogTag, "Recognition Result Event Triggered");
326                     if (data != null && msg != null)
327                     {
328                         RecognitionResultEventArgs args = new RecognitionResultEventArgs(e, data, dataCount, Marshal.PtrToStringAnsi(msg));
329                         _recognitionResult?.Invoke(this, args);
330                     }
331                     else
332                     {
333                         Log.Info(LogTag, "Recognition Result Event null received");
334                     }
335                 };
336                     SttError error = SttSetRecognitionResultCB(_handle, _resultDelegate, IntPtr.Zero);
337                     if (error != SttError.None)
338                     {
339                         Log.Error(LogTag, "Add RecognitionResult Failed with error " + error);
340                     }
341                     else
342                     {
343                         _recognitionResult += value;
344                     }
345                 }
346             }
347
348             remove
349             {
350                 lock (thisLock)
351                 {
352                     SttError error = SttUnsetRecognitionResultCB(_handle);
353                     if (error != SttError.None)
354                     {
355                         Log.Error(LogTag, "Remove RecognitionResult Failed with error " + error);
356                     }
357
358                     _recognitionResult -= value;
359                 }
360             }
361         }
362
363         /// <summary>
364         /// Event to be invoked when STT state changes.
365         /// </summary>
366         public event EventHandler<StateChangedEventArgs> StateChanged
367         {
368             add
369             {
370                 lock (thisLock)
371                 {
372                     SttClient obj = this;
373                     _stateDelegate = (IntPtr handle, State previous, State current, IntPtr userData) =>
374                     {
375                         StateChangedEventArgs args = new StateChangedEventArgs(previous, current);
376                         _stateChanged?.Invoke(obj, args);
377                     };
378                     SttError error = SttSetStateChangedCB(_handle, _stateDelegate, IntPtr.Zero);
379                     if (error != SttError.None)
380                     {
381                         Log.Error(LogTag, "Add StateChanged Failed with error " + error);
382                     }
383                     else
384                     {
385                         _stateChanged += value;
386                     }
387
388                 }
389             }
390
391             remove
392             {
393                 lock (thisLock)
394                 {
395                     SttError error = SttUnsetStateChangedCB(_handle);
396                     if (error != SttError.None)
397                     {
398                         Log.Error(LogTag, "Remove StateChanged Failed with error " + error);
399                     }
400
401                     _stateChanged -= value;
402                 }
403             }
404
405         }
406
407         /// <summary>
408         /// Event to be invoked when an error occurs.
409         /// </summary>
410         public event EventHandler<ErrorOccuredEventArgs> ErrorOccured
411         {
412             add
413             {
414                 lock (thisLock)
415                 {
416                     _errorDelegate = (IntPtr handle, SttError reason, IntPtr userData) =>
417                 {
418                     ErrorOccuredEventArgs args = new ErrorOccuredEventArgs(handle, reason);
419                     _errorOccured?.Invoke(this, args);
420                 };
421                     SttError error = SttSetErrorCB(_handle, _errorDelegate, IntPtr.Zero);
422                     if (error != SttError.None)
423                     {
424                         Log.Error(LogTag, "Add ErrorOccured Failed with error " + error);
425                     }
426
427                     else
428                     {
429                         _errorOccured += value;
430                     }
431                 }
432
433             }
434
435             remove
436             {
437                 lock (thisLock)
438                 {
439                     SttError error = SttUnsetErrorCB(_handle);
440                     if (error != SttError.None)
441                     {
442                         Log.Error(LogTag, "Remove ErrorOccured Failed with error " + error);
443                     }
444
445                     _errorOccured -= value;
446                 }
447             }
448         }
449
450         /// <summary>
451         /// Event to be invoked when default laungage change.
452         /// </summary>
453         public event EventHandler<DefaultLanguageChangedEventArgs> DefaultLanguageChanged
454         {
455             add
456             {
457                 lock (thisLock)
458                 {
459                     _languageDelegate = (IntPtr handle, IntPtr previousLanguage, IntPtr currentLanguage, IntPtr userData) =>
460                 {
461                     string previousLanguageString = Marshal.PtrToStringAnsi(previousLanguage);
462                     string currentLanguageString = Marshal.PtrToStringAnsi(currentLanguage);
463                     DefaultLanguageChangedEventArgs args = new DefaultLanguageChangedEventArgs(previousLanguageString, currentLanguageString);
464                     _defaultLanguageChanged?.Invoke(this, args);
465                 };
466                     SttError error = SttSetDefaultLanguageChangedCB(_handle, _languageDelegate, IntPtr.Zero);
467                     if (error != SttError.None)
468                     {
469                         Log.Error(LogTag, "Add DefaultLanguageChanged Failed with error " + error);
470                     }
471
472                     else
473                     {
474                         _defaultLanguageChanged += value;
475                     }
476                 }
477
478             }
479
480             remove
481             {
482                 lock (thisLock)
483                 {
484                     SttError error = SttUnsetDefaultLanguageChangedCB(_handle);
485                     if (error != SttError.None)
486                     {
487                         Log.Error(LogTag, "Remove DefaultLanguageChanged Failed with error " + error);
488                     }
489
490                     _defaultLanguageChanged -= value;
491                 }
492             }
493
494         }
495
496         /// <summary>
497         /// Event to be invoked to detect engine change.
498         /// </summary>
499         public event EventHandler<EngineChangedEventArgs> EngineChanged
500         {
501             add
502             {
503                 lock (thisLock)
504                 {
505                     _engineDelegate = (IntPtr handle, IntPtr engineId, IntPtr language, bool supportSilence, bool needCredential, IntPtr userData) =>
506                 {
507                     string engineIdString = Marshal.PtrToStringAnsi(engineId);
508                     string languageString = Marshal.PtrToStringAnsi(language);
509                     EngineChangedEventArgs args = new EngineChangedEventArgs(engineIdString, languageString, supportSilence, needCredential);
510                     _engineChanged?.Invoke(this, args);
511                 };
512                     SttError error = SttSetEngineChangedCB(_handle, _engineDelegate, IntPtr.Zero);
513                     if (error != SttError.None)
514                     {
515                         Log.Error(LogTag, "Add EngineChanged Failed with error " + error);
516                     }
517                     else
518                     {
519                         _engineChanged += value;
520                     }
521                 }
522             }
523
524             remove
525             {
526                 lock (thisLock)
527                 {
528                     SttError error = SttUnsetEngineChangedCB(_handle);
529                     if (error != SttError.None)
530                     {
531                         Log.Error(LogTag, "Remove EngineChanged Failed with error " + error);
532                     }
533
534                     _engineChanged -= value;
535                 }
536             }
537         }
538
539         /// <summary>
540         /// Gets the default language set by the user.
541         /// 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.
542         /// For example, "ko_KR" for Korean, "en_US" for American English.
543         /// </summary>
544         /// <value>
545         /// Default language in STT.
546         /// </value>
547         /// <privilege>
548         /// http://tizen.org/privilege/recorder
549         /// </privilege>
550         /// <returns>
551         /// Default Lanaguage string value.
552         /// </returns>
553         public string GetDefaultLanguage
554         {
555             get
556             {
557                 string language;
558                 lock (thisLock)
559                 {
560                     SttError error = SttGetDefaultLanguage(_handle, out language);
561                     if (error != SttError.None)
562                     {
563                         Log.Error(LogTag, "DefaultLanaguage Failed with error " + error);
564                         return "";
565                     }
566                 }
567
568                 return language;
569             }
570         }
571
572         /// <summary>
573         /// Gets the microphone volume during recording.
574         /// </summary>
575         /// <value>
576         /// Recording volume in STT.
577         /// </value>
578         /// <privilege>
579         /// http://tizen.org/privilege/recorder
580         /// </privilege>
581         /// <pre>
582         /// The State must be Recording.
583         /// </pre>
584         public float GetRecordingVolume
585         {
586             get
587             {
588                 float volume;
589                 lock (thisLock)
590                 {
591                     SttError error = SttGetRecordingVolume(_handle, out volume);
592                     if (error != SttError.None)
593                     {
594                         Log.Error(LogTag, "GetRecordingVolume Failed with error " + error);
595                         return 0.0f;
596                     }
597
598                 }
599
600                 return volume;
601             }
602
603         }
604
605         /// <summary>
606         /// Gets the current STT state.
607         /// </summary>
608         /// <value>
609         /// Current state of STT.
610         /// </value>
611         /// <privilege>
612         /// http://tizen.org/privilege/recorder
613         /// </privilege>
614         /// <returns>
615         /// Current STT State value.
616         /// </returns>
617         public State GetState
618         {
619             get
620             {
621                 State state;
622                 lock (thisLock)
623                 {
624                     SttError error = SttGetState(_handle, out state);
625                     if (error != SttError.None)
626                     {
627                         Log.Error(LogTag, "GetState Failed with error " + error);
628                         return State.Unavailable;
629                     }
630                 }
631
632                 return state;
633             }
634
635         }
636
637         /// <summary>
638         /// This property can be used to get and set the current engine id.
639         /// </summary>
640         /// <value>
641         /// Current STT engine id.
642         /// </value>
643         /// <privilege>
644         /// http://tizen.org/privilege/recorder
645         /// </privilege>
646         /// <exception cref="InvalidOperationException">
647         /// This Exception can occur while setting due to the following reaons
648         /// 1. Out Of Memory
649         /// 2. Operation Failed
650         /// 3. STT Not Supported
651         /// 4. Permission Denied
652         /// 5. Invalid State
653         /// </exception>
654         /// <exception cref="ArgumentException">
655         /// This can happen if Improper EngineId is provided while setting the value.
656         /// </exception>
657         /// <pre>
658         /// The State must be Created.
659         /// </pre>
660         public string Engine
661         {
662             get
663             {
664                 string engineId;
665                 lock (thisLock)
666                 {
667                     SttError error = SttGetEngine(_handle, out engineId);
668                     if (error != SttError.None)
669                     {
670                         Log.Error(LogTag, "Get EngineId Failed with error " + error);
671                         return "";
672                     }
673                 }
674
675                 return engineId;
676             }
677             set
678             {
679                 lock (thisLock)
680                 {
681                     SttError error = SttSetEngine(_handle, value);
682                     if (error != SttError.None)
683                     {
684                         Log.Error(LogTag, "Set EngineId Failed with error " + error);
685                         throw ExceptionFactory.CreateException(error);
686                     }
687                 }
688
689             }
690         }
691
692         /// <summary>
693         /// Retrieves the time stamp of the current recognition result
694         /// </summary>
695         /// <returns>
696         /// list of ResultTime
697         /// </returns>
698         /// <privilege>
699         /// http://tizen.org/privilege/recorder
700         /// </privilege>
701         /// <feature>
702         /// http://tizen.org/feature/speech.recognition
703         /// http://tizen.org/feature/microphone
704         /// </feature>
705         /// <remarks>
706         /// This function should only be called in RecognitionResult Event
707         /// </remarks>
708         /// <exception cref="InvalidOperationException">
709         /// This Exception can be due to the following reaons
710         /// 1. Opearation Failed.
711         /// 2. STT Not Supported
712         /// 3. Permission Denied.
713         /// </exception>
714         public IEnumerable<ResultTime> GetDetailedResult()
715         {
716             List<ResultTime> list = new List<ResultTime>();
717             _resultTimeDelegate = (IntPtr handle, int index, TimeEvent e, IntPtr text, IntPtr startTime, IntPtr endTime, IntPtr userData) =>
718             {
719                 _result = new ResultTime(index, e, Marshal.PtrToStringAnsi(text), (long)startTime, (long)endTime);
720                 list.Add(_result);
721                 return true;
722             };
723             SttError error = SttForeachDetailedResult(_handle, _resultTimeDelegate, IntPtr.Zero);
724             if (error != SttError.None)
725             {
726                 Log.Error(LogTag, "GetDetailedResult Failed with error " + error);
727                 throw ExceptionFactory.CreateException(error);
728             }
729             return list;
730         }
731
732
733         /// <summary>
734         /// Gets the private data from stt engine.
735         /// </summary>
736         /// <param name="key">
737         /// The key string
738         /// </param>
739         /// <returns>
740         /// The Data Corresponding to the Key provided
741         /// </returns>
742         /// <privilege>
743         /// http://tizen.org/privilege/recorder
744         /// </privilege>
745         /// <feature>
746         /// http://tizen.org/feature/speech.recognition
747         /// http://tizen.org/feature/microphone
748         /// </feature>
749         /// <exception cref="InvalidOperationException">
750         /// This Exception can be due to the following reaons
751         /// 1. No Answer from STT Service
752         /// 2. STT Not Supported
753         /// 3. Invalid State
754         /// </exception>
755         /// <pre>
756         /// The State must be Ready.
757         /// </pre>
758         public string GetPrivateData(string key)
759         {
760             string data;
761             lock (thisLock)
762             {
763                 SttError error = SttGetPrivateData(_handle, key, out data);
764                 if (error != SttError.None)
765                 {
766                     Log.Error(LogTag, "GetPrivateData Failed with error " + error);
767                     throw ExceptionFactory.CreateException(error);
768                 }
769             }
770
771             return data;
772         }
773
774         /// <summary>
775         /// Sets the private data to stt engine.
776         /// </summary>
777         /// <param name="key">
778         /// The key string
779         /// </param>
780         /// <param name="data">
781         /// The data string
782         /// </param>
783         /// <privilege>
784         /// http://tizen.org/privilege/recorder
785         /// </privilege>
786         /// <feature>
787         /// http://tizen.org/feature/speech.recognition
788         /// http://tizen.org/feature/microphone
789         /// </feature>
790         /// <exception cref="InvalidOperationException">
791         /// This Exception can be due to the following reaons
792         /// 1. No Answer from STT Service
793         /// 2. STT Not Supported
794         /// 3. Invalid State
795         /// </exception>
796         /// <exception cref="ArgumentException">
797         /// This can happen if Improper value is provided while setting the value.
798         /// </exception>
799         /// <pre>
800         /// The State must be Ready.
801         /// </pre>
802         public void SetPrivateData(string key, string data)
803         {
804             lock (thisLock)
805             {
806                 SttError error = SttSetPrivateData(_handle, key, data);
807                 if (error != SttError.None)
808                 {
809                     Log.Error(LogTag, "SetPrivateData Failed with error " + error);
810                     throw ExceptionFactory.CreateException(error);
811                 }
812             }
813         }
814
815         /// <summary>
816         /// Gets the list of Supported Engine
817         /// </summary>
818         /// <returns>
819         /// IEnumerable<SupportedEngine> list of supported engines
820         /// </returns>
821         /// <privilege>
822         /// http://tizen.org/privilege/recorder
823         /// </privilege>
824         /// <feature>
825         /// http://tizen.org/feature/speech.recognition
826         /// http://tizen.org/feature/microphone
827         /// </feature>
828         /// <exception cref="InvalidOperationException">
829         /// This Exception can be due to the following reaons
830         /// 1. Out Of Memory
831         /// 2. Operation Failed
832         /// 3. STT Not Supported
833         /// 4. Permission Denied
834         /// </exception>
835         public IEnumerable<SupportedEngine> GetSupportedEngines()
836         {
837             List<SupportedEngine> engineList = new List<SupportedEngine>();
838             lock (thisLock)
839             {
840                 SupportedEngineCallback supportedEngineDelegate = (IntPtr handle, IntPtr engineId, IntPtr engineName, IntPtr userData) =>
841             {
842                 string id = Marshal.PtrToStringAnsi(engineId);
843                 string name = Marshal.PtrToStringAnsi(engineName);
844                 SupportedEngine engine = new SupportedEngine(id, name);
845                 engineList.Add(engine);
846                 return true;
847             };
848                 SttError error = SttForeEachSupportedEngines(_handle, supportedEngineDelegate, IntPtr.Zero);
849                 if (error != SttError.None)
850                 {
851                     Log.Error(LogTag, "Create Failed with error " + error);
852                     throw ExceptionFactory.CreateException(error);
853                 }
854             }
855
856             return engineList;
857         }
858
859         /// <summary>
860         /// Sets the app credential
861         /// </summary>
862         /// <param name="credential">
863         /// The credential string
864         /// </param>
865         /// <privilege>
866         /// http://tizen.org/privilege/recorder
867         /// </privilege>
868         /// <feature>
869         /// http://tizen.org/feature/speech.recognition
870         /// http://tizen.org/feature/microphone
871         /// </feature>
872         /// <exception cref="InvalidOperationException">
873         /// This Exception can be due to the following reaons
874         /// 1. Out Of Memory
875         /// 2. Operation Failed
876         /// 3. STT Not Supported
877         /// 4. Permission Denied
878         /// 5. Invalid State
879         /// </exception>
880         /// <exception cref="ArgumentException">
881         /// This can happen if Improper value is provided while setting the value.
882         /// </exception>
883         /// <pre>
884         /// The State must be Created.
885         /// </pre>
886         public void SetCredential(string credential)
887         {
888             lock (thisLock)
889             {
890                 SttError error = SttSetcredential(_handle, credential);
891                 if (error != SttError.None)
892                 {
893                     Log.Error(LogTag, "SetCredential Failed with error " + error);
894                     throw ExceptionFactory.CreateException(error);
895                 }
896             }
897         }
898
899         /// <summary>
900         /// Connects to the STT service asynchronously.
901         /// </summary>
902         /// <privilege>
903         /// http://tizen.org/privilege/recorder
904         /// </privilege>
905         /// <feature>
906         /// http://tizen.org/feature/speech.recognition
907         /// http://tizen.org/feature/microphone
908         /// </feature>
909         /// <exception cref="InvalidOperationException">
910         /// This Exception can be due to the following reasons
911         /// 1. STT Not Supported
912         /// 2. Permission Denied
913         /// 3. Invalid State
914         /// </exception>
915         /// <pre>
916         /// The State must be Created.
917         /// </pre>
918         /// <post>
919         /// If this function is successful, the STT state will be Ready
920         /// If this function is unsuccessful, ErrorOccured event will be invoked
921         /// </post>
922         public void Prepare()
923         {
924             lock (thisLock)
925             {
926                 SttError error = SttPrepare(_handle);
927                 if (error != SttError.None)
928                 {
929                     Log.Error(LogTag, "SetEngine Failed with error " + error);
930                     throw ExceptionFactory.CreateException(error);
931                 }
932             }
933         }
934
935         /// <summary>
936         /// Disconnects from the STT service.
937         /// </summary>
938         /// <privilege>
939         /// http://tizen.org/privilege/recorder
940         /// </privilege>
941         /// <feature>
942         /// http://tizen.org/feature/speech.recognition
943         /// http://tizen.org/feature/microphone
944         /// </feature>
945         /// <exception cref="InvalidOperationException">
946         /// This Exception can be due to the following reasons
947         /// 1. STT Not Supported
948         /// 2. Permission Denied
949         /// 3. Invalid State
950         /// </exception>
951         /// <pre>
952         /// The State must be Ready.
953         /// </pre>
954         /// <post>
955         /// If this function is successful, the STT state will be Created
956         /// </post>
957         public void Unprepare()
958         {
959             lock (thisLock)
960             {
961                 SttError error = SttUnprepare(_handle);
962                 if (error != SttError.None)
963                 {
964                     Log.Error(LogTag, "Unprepare Failed with error " + error);
965                     throw ExceptionFactory.CreateException(error);
966                 }
967             }
968         }
969
970         /// <summary>
971         /// Retrieves all supported languages of current engine.
972         /// 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.
973         /// For example, "ko_KR" for Korean, "en_US" for American English.
974         /// </summary>
975         /// <privilege>
976         /// http://tizen.org/privilege/recorder
977         /// </privilege>
978         /// <returns>
979         /// list of strings of supported languages.
980         /// </returns>
981         /// <feature>
982         /// http://tizen.org/feature/speech.recognition
983         /// http://tizen.org/feature/microphone
984         /// </feature>
985         /// <exception cref="InvalidOperationException">
986         /// This Exception can be due to the following reasons
987         /// 1. STT Not Supported
988         /// 2. Permission Denied
989         /// 3. Engine Not Found.
990         /// 4. Operation Failed.
991         /// </exception>
992         public IEnumerable<string> GetSupportedLangauages()
993         {
994             List<string> languageList = new List<string>();
995             lock (thisLock)
996             {
997                 SupportedLanguageCallback supportedLanguageDelegate = (IntPtr handle, IntPtr language, IntPtr userData) =>
998             {
999                 string lang = Marshal.PtrToStringAnsi(language);
1000                 languageList.Add(lang);
1001                 return true;
1002             };
1003
1004                 SttError error = SttForeachSupportedLanguages(_handle, supportedLanguageDelegate, IntPtr.Zero);
1005                 if (error != SttError.None)
1006                 {
1007                     Log.Error(LogTag, "GetSupportedLangauages Failed with error " + error);
1008                     throw ExceptionFactory.CreateException(error);
1009                 }
1010             }
1011
1012             return languageList;
1013         }
1014
1015         /// <summary>
1016         /// Checks whether the recognition type is supported.
1017         /// </summary>
1018         /// <privilege>
1019         /// http://tizen.org/privilege/recorder
1020         /// </privilege>
1021         /// <param name="type">
1022         /// RecognitionType value.
1023         /// </param>
1024         /// <returns>
1025         /// bool value indicating whether the recognition type is supported.
1026         /// </returns>
1027         /// <feature>
1028         /// http://tizen.org/feature/speech.recognition
1029         /// http://tizen.org/feature/microphone
1030         /// </feature>
1031         /// <exception cref="InvalidOperationException">
1032         /// This Exception can be due to the following reasons
1033         /// 1. STT Not Supported
1034         /// 2. Invalid State
1035         /// 3. Engine Not Found.
1036         /// 4. Operation Failed.
1037         /// </exception>
1038         /// <pre>
1039         /// The state should be Ready.
1040         /// </pre>
1041         public bool IsRecognitionTypeSupported(RecognitionType type)
1042         {
1043             bool supported;
1044             lock (thisLock)
1045             {
1046                 string recType = "stt.recognition.type.FREE";
1047                 switch (type)
1048                 {
1049                     case RecognitionType.Free:
1050                         {
1051                             recType = "stt.recognition.type.FREE";
1052                             break;
1053                         }
1054
1055                     case RecognitionType.Partial:
1056                         {
1057                             recType = "stt.recognition.type.FREE.PARTIAL";
1058                             break;
1059                         }
1060
1061                     case RecognitionType.Search:
1062                         {
1063                             recType = "stt.recognition.type.SEARCH";
1064                             break;
1065                         }
1066
1067                     case RecognitionType.WebSearch:
1068                         {
1069                             recType = "stt.recognition.type.WEB_SEARCH";
1070                             break;
1071                         }
1072
1073                     case RecognitionType.Map:
1074                         {
1075                             recType = "stt.recognition.type.MAP";
1076                             break;
1077                         }
1078
1079                 }
1080
1081                 SttError error = SttIsRecognitionTypeSupported(_handle, recType, out supported);
1082                 if (error != SttError.None)
1083                 {
1084                     Log.Error(LogTag, "IsRecognitionTypeSupported Failed with error " + error);
1085                     throw ExceptionFactory.CreateException(error);
1086                 }
1087
1088             }
1089
1090             return supported;
1091         }
1092
1093         /// <summary>
1094         /// Sets the silence detection.
1095         /// </summary>
1096         /// <privilege>
1097         /// http://tizen.org/privilege/recorder
1098         /// </privilege>
1099         /// <param name="type">
1100         /// SilenceDetection value.
1101         /// </param>
1102         /// <feature>
1103         /// http://tizen.org/feature/speech.recognition
1104         /// http://tizen.org/feature/microphone
1105         /// </feature>
1106         /// <exception cref="InvalidOperationException">
1107         /// This Exception can be due to the following reasons
1108         /// 1. STT Not Supported
1109         /// 2. Invalid State
1110         /// 3. Not supported feature of current engine.
1111         /// 4. Operation Failed.
1112         /// </exception>
1113         /// <pre>
1114         /// The state should be Ready.
1115         /// </pre>
1116         public void SetSilenceDetection(SilenceDetection type)
1117         {
1118             lock (thisLock)
1119             {
1120                 SttError error = SttSetSilenceDetection(_handle, type);
1121                 if (error != SttError.None)
1122                 {
1123                     Log.Error(LogTag, "SetSilenceDetection Failed with error " + error);
1124                     throw ExceptionFactory.CreateException(error);
1125                 }
1126             }
1127         }
1128
1129         /// <summary>
1130         /// Sets the sound to start recording.
1131         /// Sound file type should be wav type.
1132         /// </summary>
1133         /// <privilege>
1134         /// http://tizen.org/privilege/recorder
1135         /// </privilege>
1136         /// <param name="filePath">
1137         /// File Path for the sound.
1138         /// </param>
1139         /// <feature>
1140         /// http://tizen.org/feature/speech.recognition
1141         /// http://tizen.org/feature/microphone
1142         /// </feature>
1143         /// <exception cref="InvalidOperationException">
1144         /// This Exception can be due to the following reasons
1145         /// 1. STT Not Supported.
1146         /// 2. Permission Denied.
1147         /// 3. Invalid State.
1148         /// 4. Operation Failed.
1149         /// </exception>
1150         /// <exception cref="ArgumentException">
1151         /// If an Invalid Parameter is provided.
1152         /// </exception>
1153         /// <pre>
1154         /// The state should be Ready.
1155         /// </pre>
1156         public void SetStartSound(string filePath)
1157         {
1158             lock (thisLock)
1159             {
1160                 SttError error = SttSetStartSound(_handle, filePath);
1161                 if (error != SttError.None)
1162                 {
1163                     Log.Error(LogTag, "SetStartSound Failed with error " + error);
1164                     throw ExceptionFactory.CreateException(error);
1165                 }
1166             }
1167         }
1168
1169         /// <summary>
1170         /// Unsets the sound to start recording.
1171         /// </summary>
1172         /// <privilege>
1173         /// http://tizen.org/privilege/recorder
1174         /// </privilege>
1175         /// <feature>
1176         /// http://tizen.org/feature/speech.recognition
1177         /// http://tizen.org/feature/microphone
1178         /// </feature>
1179         /// <exception cref="InvalidOperationException">
1180         /// This Exception can be due to the following reasons
1181         /// 1. STT Not Supported.
1182         /// 2. Permission Denied.
1183         /// 3. Invalid State.
1184         /// 4. Operation Failed.
1185         /// </exception>
1186         /// <pre>
1187         /// The state should be Ready.
1188         /// </pre>
1189         public void UnsetStartSound()
1190         {
1191             lock (thisLock)
1192             {
1193                 SttError error = SttUnsetStartSound(_handle);
1194                 if (error != SttError.None)
1195                 {
1196                     Log.Error(LogTag, "UnsetStartSound Failed with error " + error);
1197                     throw ExceptionFactory.CreateException(error);
1198                 }
1199             }
1200         }
1201
1202         /// <summary>
1203         /// Sets the sound to stop recording.
1204         /// Sound file type should be wav type.
1205         /// </summary>
1206         /// <privilege>
1207         /// http://tizen.org/privilege/recorder
1208         /// </privilege>
1209         /// <param name="filePath">
1210         /// File Path for the sound.
1211         /// </param>
1212         /// <feature>
1213         /// http://tizen.org/feature/speech.recognition
1214         /// http://tizen.org/feature/microphone
1215         /// </feature>
1216         /// <exception cref="InvalidOperationException">
1217         /// This Exception can be due to the following reasons
1218         /// 1. STT Not Supported.
1219         /// 2. Permission Denied.
1220         /// 3. Invalid State.
1221         /// 4. Operation Failed.
1222         /// </exception>
1223         /// <exception cref="ArgumentException">
1224         /// If an Invalid Parameter is provided.
1225         /// </exception>
1226         /// <pre>
1227         /// The state should be Ready.
1228         /// </pre>
1229         public void SetStopSound(string filePath)
1230         {
1231             lock (thisLock)
1232             {
1233                 SttError error = SttSetStopSound(_handle, filePath);
1234                 if (error != SttError.None)
1235                 {
1236                     Log.Error(LogTag, "SetStopSound Failed with error " + error);
1237                     throw ExceptionFactory.CreateException(error);
1238                 }
1239             }
1240         }
1241
1242         /// <summary>
1243         /// Unsets the sound to stop recording.
1244         /// </summary>
1245         /// <privilege>
1246         /// http://tizen.org/privilege/recorder
1247         /// </privilege>
1248         /// <feature>
1249         /// http://tizen.org/feature/speech.recognition
1250         /// http://tizen.org/feature/microphone
1251         /// </feature>
1252         /// <exception cref="InvalidOperationException">
1253         /// This Exception can be due to the following reasons
1254         /// 1. STT Not Supported.
1255         /// 2. Permission Denied.
1256         /// 3. Invalid State.
1257         /// 4. Operation Failed.
1258         /// </exception>
1259         /// <pre>
1260         /// The state should be Ready.
1261         /// </pre>
1262         public void UnsetStopSound()
1263         {
1264             lock (thisLock)
1265             {
1266                 SttError error = SttUnsetStopSound(_handle);
1267                 if (error != SttError.None)
1268                 {
1269                     Log.Error(LogTag, "UnsetStopSound Failed with error " + error);
1270                     throw ExceptionFactory.CreateException(error);
1271                 }
1272             }
1273         }
1274
1275         /// <summary>
1276         /// Starts recording and recognition asynchronously.
1277         /// This function starts recording in the STT service and sending recording data to engine.
1278         /// This work continues until Stop, Cancel or silence detected by engine
1279         /// </summary>
1280         /// <privilege>
1281         /// http://tizen.org/privilege/recorder
1282         /// </privilege>
1283         /// <param name="language">
1284         /// The language selected
1285         /// </param>
1286         /// <param name="type">
1287         /// The type for recognition
1288         /// </param>
1289         /// <feature>
1290         /// http://tizen.org/feature/speech.recognition
1291         /// http://tizen.org/feature/microphone
1292         /// </feature>
1293         /// <exception cref="InvalidOperationException">
1294         /// This Exception can be due to the following reasons
1295         /// 1. STT Not Supported.
1296         /// 2. Permission Denied.
1297         /// 3. Invalid State.
1298         /// 4. Operation Failed.
1299         /// 5. Recorder Busy.
1300         /// 6. Progress to recording is not finished
1301         /// </exception>
1302         /// <exception cref="ArgumentException">
1303         /// If an Invalid Language is provided
1304         /// </exception>
1305         /// <pre>
1306         /// The state should be Ready.
1307         /// </pre>
1308         /// <post>
1309         /// It will invoke StateChanged Event if registerd.
1310         /// If this function succeeds, the STT state will be Recording.
1311         /// If you call this function again before state changes, you will receive ErrorINProgressToRecording.
1312         /// </post>
1313         public void Start(string language, RecognitionType type)
1314         {
1315             lock (thisLock)
1316             {
1317                 string recType = "stt.recognition.type.FREE";
1318                 switch (type)
1319                 {
1320                     case RecognitionType.Free:
1321                         {
1322                             recType = "stt.recognition.type.FREE";
1323                             break;
1324                         }
1325
1326                     case RecognitionType.Partial:
1327                         {
1328                             recType = "stt.recognition.type.FREE.PARTIAL";
1329                             break;
1330                         }
1331
1332                     case RecognitionType.Search:
1333                         {
1334                             recType = "stt.recognition.type.SEARCH";
1335                             break;
1336                         }
1337
1338                     case RecognitionType.WebSearch:
1339                         {
1340                             recType = "stt.recognition.type.WEB_SEARCH";
1341                             break;
1342                         }
1343
1344                     case RecognitionType.Map:
1345                         {
1346                             recType = "stt.recognition.type.MAP";
1347                             break;
1348                         }
1349
1350                 }
1351
1352                 SttError error = SttStart(_handle, language, recType);
1353                 if (error != SttError.None)
1354                 {
1355                     Log.Error(LogTag, "Start Failed with error " + error);
1356                     throw ExceptionFactory.CreateException(error);
1357                 }
1358             }
1359         }
1360
1361         /// <summary>
1362         /// Finishes the recording and starts recognition processing in engine asynchronously.
1363         /// </summary>
1364         /// <privilege>
1365         /// http://tizen.org/privilege/recorder
1366         /// </privilege>
1367         /// <feature>
1368         /// http://tizen.org/feature/speech.recognition
1369         /// http://tizen.org/feature/microphone
1370         /// </feature>
1371         /// <exception cref="InvalidOperationException">
1372         /// This Exception can be due to the following reasons
1373         /// 1. STT Not Supported.
1374         /// 2. Permission Denied.
1375         /// 3. Invalid State.
1376         /// 4. Operation Failed.
1377         /// 5. Progress to ready is not finished.
1378         /// 6. Progress to recording is not finished.
1379         /// 7. Progress to processing is not finished.
1380         /// </exception>
1381         /// <pre>
1382         /// The state should be Recording.
1383         /// </pre>
1384         /// <post>
1385         /// It will invoke StateChanged Event if registerd.
1386         /// If this function succeeds, the STT state will be Processing.
1387         /// If you call this function again before state changes, you will receive ErrorINProgressToProcessing.
1388         /// After processing of engine, RecognitionResult event is invoked
1389         /// </post>
1390         public void Stop()
1391         {
1392             lock (thisLock)
1393             {
1394                 SttError error = SttStop(_handle);
1395                 if (error != SttError.None)
1396                 {
1397                     Log.Error(LogTag, "Stop Failed with error " + error);
1398                     throw ExceptionFactory.CreateException(error);
1399                 }
1400             }
1401         }
1402
1403         /// <summary>
1404         /// Cancels processing recognition and recording asynchronously.
1405         /// This function cancels recording and engine cancels recognition processing.
1406         /// After successful cancel, StateChanged event is invoked otherwise if error is occurred, ErrorOccured event is invoked.
1407         /// </summary>
1408         /// <privilege>
1409         /// http://tizen.org/privilege/recorder
1410         /// </privilege>
1411         /// <feature>
1412         /// http://tizen.org/feature/speech.recognition
1413         /// http://tizen.org/feature/microphone
1414         /// </feature>
1415         /// <exception cref="InvalidOperationException">
1416         /// This Exception can be due to the following reasons
1417         /// 1. STT Not Supported.
1418         /// 2. Permission Denied.
1419         /// 3. Invalid State.
1420         /// 4. Operation Failed.
1421         /// 5. Progress to ready is not finished.
1422         /// 6. Progress to recording is not finished.
1423         /// 7. Progress to processing is not finished.
1424         /// </exception>
1425         /// <pre>
1426         /// The state should be Recording or Processing.
1427         /// </pre>
1428         /// <post>
1429         /// It will invoke StateChanged Event if registerd.
1430         /// If this function succeeds, the STT state will be Ready.
1431         /// If you call this function again before state changes, you will receive ErrorINProgressToReady.
1432         /// </post>
1433         public void Cancel()
1434         {
1435             lock (thisLock)
1436             {
1437                 SttError error = SttCancel(_handle);
1438                 if (error != SttError.None)
1439                 {
1440                     Log.Error(LogTag, "Cancel Failed with error " + error);
1441                     throw ExceptionFactory.CreateException(error);
1442                 }
1443             }
1444         }
1445
1446         /// <summary>
1447         /// Method to release resources
1448         /// </summary>
1449         public void Dispose()
1450         {
1451             Dispose(true);
1452         }
1453
1454         protected virtual void Dispose(bool disposing)
1455         {
1456             if (!disposedValue)
1457             {
1458                 if (disposing)
1459                 {
1460                     SttError error = SttDestroy(_handle);
1461                     if (error != SttError.None)
1462                     {
1463                         Log.Error(LogTag, "Destroy Failed with error " + error);
1464                     }
1465                 }
1466
1467                 disposedValue = true;
1468             }
1469         }
1470     }
1471 }