From: manish.r Date: Fri, 26 May 2017 06:01:27 +0000 (+0530) Subject: Base Code X-Git-Tag: submit/trunk/20170823.075128~71^2~2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=296b70e43b126e0a5557db1f34abdddd563b3d76;p=platform%2Fcore%2Fcsapi%2Ftizenfx.git Base Code Change-Id: I96b20e693b27dfe09c675937ffe8e1abdc266fe9 Signed-off-by: manish.r --- diff --git a/LICENSE b/LICENSE new file mode 100755 index 0000000..d645695 --- /dev/null +++ b/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/packaging/csapi-uix-stt-engine.manifest b/packaging/csapi-uix-stt-engine.manifest new file mode 100755 index 0000000..75b0fa5 --- /dev/null +++ b/packaging/csapi-uix-stt-engine.manifest @@ -0,0 +1,5 @@ + + + + + diff --git a/packaging/csapi-uix-stt-engine.spec b/packaging/csapi-uix-stt-engine.spec new file mode 100755 index 0000000..231a016 --- /dev/null +++ b/packaging/csapi-uix-stt-engine.spec @@ -0,0 +1,44 @@ +Name: csapi-uix-stt-engine +Summary: Tizen Uix stt engine API for C# +Version: 1.0.2 +Release: 1 +Group: Development/Libraries +License: Apache-2.0 +URL: https://www.tizen.org +Source0: %{name}-%{version}.tar.gz +Source1: %{name}.manifest + +AutoReqProv: no +ExcludeArch: aarch64 + +BuildRequires: dotnet-build-tools + +# C# API Requires +BuildRequires: csapi-tizen-nuget + +%define Assemblies Tizen.Uix.SttEngine + +%description +%{summary} + +%dotnet_import_sub_packages + +%prep +%setup -q +cp %{SOURCE1} . + +%build +for ASM in %{Assemblies}; do +%dotnet_build $ASM +%dotnet_pack $ASM/$ASM.nuspec %{version} +done + +%install +for ASM in %{Assemblies}; do +%dotnet_install $ASM +done + +%files +%manifest %{name}.manifest +%license LICENSE +%attr(644,root,root) %{dotnet_assembly_files} diff --git a/src/Tizen.Uix.SttEngine/Interop/Interop.Libraries.cs b/src/Tizen.Uix.SttEngine/Interop/Interop.Libraries.cs new file mode 100755 index 0000000..83566e5 --- /dev/null +++ b/src/Tizen.Uix.SttEngine/Interop/Interop.Libraries.cs @@ -0,0 +1,30 @@ +/* +* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved +* +* Licensed under the Apache License, Version 2.0 (the License); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an AS IS BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +/// +/// Partial Interop Class +/// +internal static partial class Interop +{ + /// + /// Partial Libraries Class + /// + internal static partial class Libraries + { + internal const string SttEngine = "libstt_engine.so"; + } +} diff --git a/src/Tizen.Uix.SttEngine/Interop/Interop.SttEngine.cs b/src/Tizen.Uix.SttEngine/Interop/Interop.SttEngine.cs new file mode 100755 index 0000000..dc07ccf --- /dev/null +++ b/src/Tizen.Uix.SttEngine/Interop/Interop.SttEngine.cs @@ -0,0 +1,198 @@ +/* +* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved +* +* Licensed under the Apache License, Version 2.0 (the License); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an AS IS BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +using System; +using System.Runtime.InteropServices; +using Tizen.Uix.SttEngine; +using static Tizen.Uix.SttEngine.Engine; + +/// +/// Partial Interop Class +/// +internal static partial class Interop +{ + /// + /// SttEngine Interop Class + /// + internal static class SttEngine + { + internal static string LogTag = "Tizen.Uix.SttEngine"; + + private const int ErrorStt = -0x02F00000; + + public enum ErrorCode + { + None = Tizen.Internals.Errors.ErrorCode.None, /**< Successful */ + OutOfMemory = Tizen.Internals.Errors.ErrorCode.OutOfMemory, /**< Out of Memory */ + IoError = Tizen.Internals.Errors.ErrorCode.IoError, /**< I/O error */ + InvalidParameter = Tizen.Internals.Errors.ErrorCode.InvalidParameter, /**< Invalid parameter */ + NetworkDown = Tizen.Internals.Errors.ErrorCode.Networkdown, /**< Network down(Out of network) */ + InvalidState = ErrorStt | 0x01, /**< Invalid state */ + InvalidLanguage = ErrorStt | 0x02, /**< Invalid language */ + OperationFailed = ErrorStt | 0x04, /**< Operation failed */ + NotSupportedFeature = ErrorStt | 0x05, /**< Not supported feature of current engine */ + NotSupported = Tizen.Internals.Errors.ErrorCode.NotSupported, /**< Device or resource busy */ + PermissionDenied = Tizen.Internals.Errors.ErrorCode.PermissionDenied, /**< Permission denied */ + RecordingTimedOut = ErrorStt | 0x06, /**< Recording timed out */ + }; + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate Error InitializeCb(); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate Error DeinitializeCb(); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate Error ForEachSupportedLangsCb(SupportedLanguages cb, IntPtr userData); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate Error IsValidLanguageCb(IntPtr language, IntPtr isValid); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate bool SupportSilenceDetectionCb(); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate Error SupportRecognitionTypeCb(string type, out bool isSupported); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate Error GetRecordingFormatCb(out AudioType types, out int rate, out int channels); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate Error SetSilenceDetectionCb(bool isSet); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate Error CheckAppAgreedCb(string appid, out bool isAgreed); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate bool NeedAppCredentialCb(); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate Error ForEachResultTimeCb(IntPtr timeInfo, ResultTime callback, IntPtr userData); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate Error StartCb(IntPtr language, IntPtr type, IntPtr appid, IntPtr credential, IntPtr userData); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate Error SetRecordingDataCb(string data, uint length); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate Error StopCb(); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate Error CancelCb(); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate Error GetInfoCb(out IntPtr engineUuid, out IntPtr engineName, out IntPtr engineSetting, out IntPtr useNetwork); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate Error PrivateDataSetCb(string key, string data); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate Error PrivateDataRequestedCb(string key, out string data); + + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] + internal struct RequestCallbackStruct + { + internal int version; + [MarshalAs(UnmanagedType.FunctionPtr)] + internal GetInfoCb getInfo; + [MarshalAs(UnmanagedType.FunctionPtr)] + internal InitializeCb initialize; + [MarshalAs(UnmanagedType.FunctionPtr)] + internal DeinitializeCb deinitialize; + [MarshalAs(UnmanagedType.FunctionPtr)] + internal ForEachSupportedLangsCb supportedLanaguge; + [MarshalAs(UnmanagedType.FunctionPtr)] + internal IsValidLanguageCb validLanaguage; + [MarshalAs(UnmanagedType.FunctionPtr)] + internal SupportSilenceDetectionCb silence; + [MarshalAs(UnmanagedType.FunctionPtr)] + internal SupportRecognitionTypeCb recognitionType; + [MarshalAs(UnmanagedType.FunctionPtr)] + internal GetRecordingFormatCb recordingFormat; + [MarshalAs(UnmanagedType.FunctionPtr)] + internal ForEachResultTimeCb resultTime; + [MarshalAs(UnmanagedType.FunctionPtr)] + internal SetSilenceDetectionCb silenceDetection; + [MarshalAs(UnmanagedType.FunctionPtr)] + internal StartCb start; + [MarshalAs(UnmanagedType.FunctionPtr)] + internal SetRecordingDataCb recordingData; + [MarshalAs(UnmanagedType.FunctionPtr)] + internal StopCb stop; + [MarshalAs(UnmanagedType.FunctionPtr)] + internal CancelCb cancel; + [MarshalAs(UnmanagedType.FunctionPtr)] + internal CheckAppAgreedCb checkAppAgreed; + [MarshalAs(UnmanagedType.FunctionPtr)] + internal NeedAppCredentialCb needAppCredential; + }; + + internal sealed class CallbackStructGCHandle : IDisposable + { + internal RequestCallbackStruct CallbackStruct; + internal GCHandle CallbackStructHandle; + public CallbackStructGCHandle() + { + CallbackStruct = new RequestCallbackStruct(); + CallbackStructHandle = GCHandle.Alloc(CallbackStruct); + } + + #region IDisposable Support + private bool disposedValue = false; + + void Dispose(bool disposing) + { + Tizen.Log.Info(LogTag, "In Dispose"); + if (!disposedValue) + { + if (disposing) + { + Tizen.Log.Info(LogTag, "In Dispose free called"); + CallbackStructHandle.Free(); + } + + disposedValue = true; + } + } + + public void Dispose() + { + Dispose(true); + } + #endregion + } + + [DllImport(Libraries.SttEngine, EntryPoint = "stte_main")] + internal static extern Error STTEMain(int argc, string[] argv, IntPtr callback); + + [DllImport(Libraries.SttEngine, EntryPoint = "stte_send_result")] + internal static extern Error STTESendResult(ResultEvent resultEvent, string type, string[] result, int resultCount, string msg, IntPtr timeInfo, IntPtr userData); + + [DllImport(Libraries.SttEngine, EntryPoint = "stte_send_error")] + internal static extern Error STTESendError(Error error, string msg); + + [DllImport(Libraries.SttEngine, EntryPoint = "stte_send_speech_status")] + internal static extern Error STTESendSpeechStatus(SpeechStatus status, IntPtr userData); + + [DllImport(Libraries.SttEngine, EntryPoint = "stte_set_private_data_set_cb")] + internal static extern Error STTESetPrivateDataSetCb(PrivateDataSetCb callbackFunc); + + [DllImport(Libraries.SttEngine, EntryPoint = "stte_set_private_data_requested_cb")] + internal static extern Error STTESetPrivateDataRequestedCb(PrivateDataRequestedCb callbackFunc); + } +} diff --git a/src/Tizen.Uix.SttEngine/Tizen.Uix.SttEngine.csproj b/src/Tizen.Uix.SttEngine/Tizen.Uix.SttEngine.csproj new file mode 100755 index 0000000..184dfb2 --- /dev/null +++ b/src/Tizen.Uix.SttEngine/Tizen.Uix.SttEngine.csproj @@ -0,0 +1,16 @@ + + + + netstandard1.3 + True + True + Tizen.Uix.SttEngine.snk + true + True + + + + + + + \ No newline at end of file diff --git a/src/Tizen.Uix.SttEngine/Tizen.Uix.SttEngine.snk b/src/Tizen.Uix.SttEngine/Tizen.Uix.SttEngine.snk new file mode 100755 index 0000000..fc12d26 Binary files /dev/null and b/src/Tizen.Uix.SttEngine/Tizen.Uix.SttEngine.snk differ diff --git a/src/Tizen.Uix.SttEngine/Tizen.Uix.SttEngine/ExceptionFactory.cs b/src/Tizen.Uix.SttEngine/Tizen.Uix.SttEngine/ExceptionFactory.cs new file mode 100755 index 0000000..29db48d --- /dev/null +++ b/src/Tizen.Uix.SttEngine/Tizen.Uix.SttEngine/ExceptionFactory.cs @@ -0,0 +1,107 @@ +/* +* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved +* +* Licensed under the Apache License, Version 2.0 (the License); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an AS IS BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +using System; +using static Interop.SttEngine; + + +namespace Tizen.Uix.SttEngine +{ + internal static class ExceptionFactory + { + internal static Exception CreateException(ErrorCode err) + { + Tizen.Log.Error(LogTag, "Error " + err); + Exception exp; + switch (err) + { + case ErrorCode.OutOfMemory: + { + exp = new OutOfMemoryException("Out Of Memory"); + break; + } + + case ErrorCode.IoError: + { + exp = new InvalidOperationException("I/O Error Occured"); + break; + } + + case ErrorCode.InvalidParameter: + { + exp = new ArgumentException("Invalid Parameters Provided"); + break; + } + + case ErrorCode.NetworkDown: + { + exp = new InvalidOperationException("Network down(Out of network)"); + break; + } + + case ErrorCode.InvalidState: + { + exp = new InvalidOperationException("Invalid state"); + break; + } + + case ErrorCode.InvalidLanguage: + { + exp = new InvalidOperationException("Invalid language"); + break; + } + + case ErrorCode.OperationFailed: + { + exp = new InvalidOperationException("Operation Failed"); + break; + } + + case ErrorCode.NotSupportedFeature: + { + exp = new InvalidOperationException("Not supported feature"); + break; + } + + case ErrorCode.NotSupported: + { + exp = new NotSupportedException("Not supported"); + break; + } + + case ErrorCode.PermissionDenied: + { + exp = new UnauthorizedAccessException("Permission Denied"); + break; + } + + case ErrorCode.RecordingTimedOut: + { + exp = new TimeoutException("Recording timed out"); + break; + } + + default: + { + exp = new Exception(""); + break; + } + } + + return exp; + } + } +} diff --git a/src/Tizen.Uix.SttEngine/Tizen.Uix.SttEngine/SttEngine.cs b/src/Tizen.Uix.SttEngine/Tizen.Uix.SttEngine/SttEngine.cs new file mode 100755 index 0000000..219c3c2 --- /dev/null +++ b/src/Tizen.Uix.SttEngine/Tizen.Uix.SttEngine/SttEngine.cs @@ -0,0 +1,801 @@ +/* +* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved +* +* Licensed under the Apache License, Version 2.0 (the License); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an AS IS BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +using System; +using System.Runtime.InteropServices; +using static Interop.SttEngine; + +namespace Tizen.Uix.SttEngine +{ + /// + /// Enumeration for audio type. + /// + public enum AudioType + { + /// + /// Signed 16bit audio type, Little endian + /// + PcmS16Le = 0, + /// + /// Unsigned 8bit audio type + /// + PcmU8 + }; + + /// + /// Enumeration for result. + /// + public enum ResultEvent + { + /// + /// Event when either the full matched or the final result is delivered + /// + FinalResult = 0, + /// + /// Event when the partial matched result is delivered + /// + PartialResult, + /// + /// Event when the recognition has failed + /// + Error + }; + + /// + /// Enumeration for result time. + /// + public enum TimeEvent + { + /// + /// Event when the token is beginning type + /// + Beginning = 0, + /// + /// Event when the token is middle type + /// + Middle = 1, + /// + /// Event when the token is end type + /// + End = 2 + }; + + /// + /// Enumeration for speech status. + /// + public enum SpeechStatus + { + /// + /// Beginning point of speech is detected + /// + BeginningPointDetected = 0, + /// + /// End point of speech is detected + /// + EndPointDetected + }; + + /// + /// Enumeration representing the result message + /// + public enum ResultMessage + { + /// + /// No Error + /// + None, + /// + /// Recognition failed because the speech started too soon. + /// + TooSoon, + /// + /// Recognition failed because the speech is too short. + /// + TooShort, + /// + /// Recognition failed because the speech is too long. + /// + TooLong, + /// + /// Recognition failed because the speech is too quiet to listen. + /// + TooQuiet, + /// + /// Recognition failed because the speech is too loud to listen. + /// + TooLoud, + /// + /// Recognition failed because the speech is too fast to listen. + /// + TooFast + }; + + + /// + /// Enum for Error values that can occur + /// + public enum Error + { + /// + /// Successful, No error + /// + None = ErrorCode.None, + /// + /// Out of Memory + /// + OutOfMemory = ErrorCode.OutOfMemory, + /// + /// I/O error + /// + IoError = ErrorCode.IoError, + /// + /// Invalid parameter + /// + InvalidParameter = ErrorCode.InvalidParameter, + /// + /// Network down(Out of network) + /// + NetworkDown = ErrorCode.NetworkDown, + /// + /// Invalid state + /// + InvalidState = ErrorCode.InvalidState, + /// + /// Invalid language + /// + InvalidLanguage = ErrorCode.InvalidLanguage, + /// + /// Operation failed + /// + OperationFailed = ErrorCode.OperationFailed, + /// + /// Not supported feature of current engine + /// + NotSupportedFeature = ErrorCode.NotSupportedFeature, + /// + /// NOT supported + /// + NotSupported = ErrorCode.NotSupported, + /// + /// Permission denied + /// + PermissionDenied = ErrorCode.PermissionDenied, + /// + /// Recording timed out + /// + RecordingTimedOut = ErrorCode.RecordingTimedOut + }; + + /// + /// This Class represents the Stt Engine which has to be inherited to make the engine. + /// + public abstract class Engine + { + private CallbackStructGCHandle _callbackStructGCHandle = new CallbackStructGCHandle(); + private PrivateDataSetCb _privateDataSetCb; + private Action _privateDatacallback; + private PrivateDataRequestedCb _privateDataRequestedCb; + private OutAction _privateDataRequestedCallback; + private static Engine _engine; + private IntPtr _structIntPtrHandle; + + /// + /// An Action with 2 Input Parameter returning a Error + /// + /// Generic Type for Parameter 1 + /// The Input Parameter 1 + /// The Input Parameter 2 + /// Error Value + public delegate Error Action(T a, T b); + + /// + /// An Action with 2 Out Parameter returning a Error + /// + /// Generic Type for Parameter 1 + /// The Input Parameter 1 + /// The Input Parameter 2 + /// Error Value + public delegate Error OutAction(T a, out T b); + + /// + /// Called when Stt engine provides the time stamp of result to the engine service user. + /// This callback function is implemented by the engine service user. Therefore, the engine developer does NOT have to implement this callback function. + /// + /// The result index + /// The token event + /// The result text + /// The time started speaking the result text + /// The time finished speaking the result text + /// The User data + /// true to continue with the next iteration of the loop, false to break out of the loop + /// SendResult() should be called. + public delegate bool ResultTime(int index, TimeEvent resultEvent, string text, long startTime, long endTime, IntPtr userData); + + /// + /// Called when Stt engine informs the engine service user about whole supported language list. + /// This callback function is implemented by the engine service user. Therefore, the engine developer does NOT have to implement this callback function. + /// + /// 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 + /// for example, "ko_KR" for Korean, "en_US" for American English + /// The User data + /// true to continue with the next iteration of the loop, false to break out of the loop + /// ForEachSupportedLanguages() should be called + public delegate bool SupportedLanguages(string language, IntPtr userData); + + /// + /// Called when the engine service user requests the basic information of Stt engine. + /// + /// + /// In order to upload the engine at Tizen Appstore, both a service app and a ui app are necessary. Therefore, engineSetting must be transferred to the engine service user. + /// + /// UUID of engine + /// Name of engine + /// The engine setting application(ui app)'s app ID + /// A variable for checking whether the network is used or not + /// + /// Following Error Codes can be returned + /// 1. None + /// 2. OperationFailed + /// 3. InvalidParameter + /// + public abstract Error GetInformation(out string engineUuid, out string engineName, out string engineSetting, out bool useNetwork); + + /// + /// Called when the engine service user initializes Stt engine. + /// This callback function is called by the engine service user to request for Stt engine to be started. + /// + /// + /// Following Error Codes can be returned + /// 1. None + /// 2. InvalidParameter + /// 3. InvalidState + /// 4. OperationFailed + /// + public abstract Error Initialize(); + + /// + /// Called when the engine service user deinitializes Stt engine. + /// This callback function is called by the engine service user to request for Stt engine to be deinitialized. + /// + /// + /// Following Error Codes can be returned + /// 1. None + /// 2. InvalidState + /// + public abstract Error Deinitialize(); + + /// + /// Called when the engine service user gets the whole supported language list. + /// + /// + /// In this function, the engine service user's callback function 'SupportedLanguages' is invoked repeatedly for getting all supported languages + /// and user_data must be transferred to 'SupportedLanguages'. If 'SupportedLanguages' returns false, it should be stopped to call 'SupportedLanguages'. + /// + /// The callback function + /// The user data which must be passed to the callback delegate 'SupportedLanguages' + /// + /// Following Error Codes can be returned + /// 1. None + /// 2. InvalidState + /// 3. InvalidParameter + /// + /// + /// This callback function invokes SupportedLanguages repeatedly for getting supported languages. + /// + public abstract Error ForEachSupportedLanguages(SupportedLanguages callback, IntPtr userData); + + /// + /// Called when the engine service user checks whether the corresponding language is valid or not in Stt engine. + /// + /// 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 + /// For example, "ko_KR" for Korean, "en_US" for American English + /// A variable for checking whether the corresponding language is valid or not. true to be valid, false to be invalid + /// + /// Following Error Codes can be returned + /// 1. None + /// 2. InvalidParameter + /// + public abstract Error IsValidLanguage(string language, out bool isValid); + + /// + /// Called when the engine service user checks whether Stt engine supports silence detection. + /// + /// true to support silence detection, false not to support silence detection + public abstract bool SupportSilenceDetection(); + + /// + /// Called when the engine service user checks whether Stt engine supports the corresponding recognition type. + /// + /// The type for recognition, "stt.recognition.type.FREE" or "stt.recognition.type.FREE.PARTIAL" + /// A variable for checking whether Stt engine supports the corresponding recognition type. + /// true to support recognition type, false not to support recognition type + /// + /// Following Error Codes can be returned + /// 1. None + /// 2. InvalidParameter + /// + public abstract Error SupportRecognitionType(string type, out bool isSupported); + + /// + /// Called when the engine service user gets the proper recording format of Stt engine. + /// The recording format is used for creating the recorder. + /// + /// The format used by the recorder + /// The sample rate used by the recorder + /// The number of channels used by the recorder + /// + /// Following Error Codes can be returned + /// 1. None + /// 2. InvalidState + /// + public abstract Error GetRecordingFormat(out AudioType types, out int rate, out int channels); + + /// + /// Called when the engine service user sets the silence detection. + /// If the engine service user sets this option as 'TRUE', Stt engine will detect the silence (EPD) and send the callback event about it. + /// + /// A variable for setting the silence detection. true to detect the silence, false not to detect the silence + /// + /// Following Error Codes can be returned + /// 1. None + /// 2. InvalidState + /// 3. NotSupportedFeature + /// + public abstract Error SetSilenceDetection(bool isSet); + + /// + /// Called when the engine service user requests for Stt engine to check whether the application agreed the usage of Stt engine. + /// This callback function is called when the engine service user requests for Stt engine to check the application's agreement about using the engine. + /// According to the need, the engine developer can provide some user interfaces to check the agreement. + /// + /// The Application ID + /// A variable for checking whether the application agreed to use Stt engine or not. true to agree, false to disagree + /// + /// Following Error Codes can be returned + /// 1. None + /// 2. InvalidState + /// 3. NotSupportedFeature + /// + public abstract Error CheckAppAgreed(string appid, out bool isAgreed); + + /// + /// Called when the engine service user checks whether Stt engine needs the application's credential. + /// + /// true if Stt engine needs the application's credential, otherwise false + public abstract bool NeedAppCredential(); + + /// + /// Called when the engine service user gets the result time information(stamp). + /// + /// + /// In this function, the engine service user's callback delegate 'ResultTime' is invoked repeatedly for sending the time information to the engine service user + /// and user_data must be transferred to 'ResultTime'. If 'ResultTime' returns false, it should be stopped to call 'ResultTime'. + /// timeInfo is transferred from SendResult. The type of timeInfo is up to the Stt engine developer. + /// + /// The time information + /// The callback function + /// The user data which must be passed to the callback function ResultTime + /// + /// Following Error Codes can be returned + /// 1. None + /// 2. InvalidState + /// 3. InvalidParameter + /// + /// + /// SendResult will invoke this function + /// + /// + /// This function invokes ResultTime repeatedly for getting result time information. + /// + public abstract Error ForEachResultTime(IntPtr timeInfo, ResultTime callback, IntPtr userData); + + /// + /// Called when the engine service user starts to recognize the recording data. + /// In this callback function, Stt engine must transfer the recognition result and userData to the engine service user using SendResult(). + /// Also, if Stt engine needs the application's credential, it sets the credential granted to the application. + /// + /// 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 + /// For example, "ko_KR" for Korean, "en_US" for American English + /// The recognition type, "stt.recognition.type.FREE" or "stt.recognition.type.FREE.PARTIAL" + /// The Application ID + /// The credential granted to the application + /// The user data to be passed to the callback function + /// + /// Following Error Codes can be returned + /// 1. None + /// 2. InvalidState + /// 3. InvalidParameter + /// 4. InvalidLanguage + /// 5. OperationFailed + /// 6. NetworkDown + /// + /// + /// The engine is not in recognition processing. + /// + public abstract Error Start(string language, string type, string appid, string credential, IntPtr userData); + + /// + /// Called when the engine service user sets and sends the recording data for speech recognition. + /// This callback function is called by the engine service user to send the recording data to Stt engine.The engine receives the recording data and uses for speech recognition. + /// this function should be returned immediately after recording data copy. + /// + /// The recording data + /// The length of recording data + /// + /// Following Error Codes can be returned + /// 1. None + /// 2. InvalidState + /// 3. InvalidParameter + /// 4. OperationFailed + /// + /// + /// Start should succeed + /// + /// If the engine supports partial result, SendResult() should be invoked. + public abstract Error SetRecordingData(string data, uint length); + + /// + /// Called when the engine service user stops to recognize the recording data. + /// This callback function is called by the engine service user to stop recording and to get the recognition result. + /// + /// Following Error Codes can be returned + /// 1. None + /// 2. InvalidState + /// 3. OperationFailed + /// 4. NetworkDown + /// + /// + /// Start should succeed + /// + /// After processing of the engine, , SendResult() should be invoked. + public abstract Error Stop(); + + /// + /// Called when the engine service user cancels to recognize the recording data. + /// This callback function is called by the engine service user to cancel to recognize the recording data.Also, when starting the recorder is failed, this function is called. + /// + /// + /// Following Error Codes can be returned + /// 1. None + /// 2. InvalidState + /// + /// Stt engine is in recognition processing or recording. + public abstract Error Cancel(); + + /// + /// Public Constructor + /// + public Engine() + { + _engine = this; + } + + /// + /// Main function for Speech-To-Text (STT) engine. + /// This function is the main function for operating Stt engine. + /// + /// + /// http://tizen.org/privilege/recorder + /// + /// + /// ServiceAppMain should be used for working the engine after this function. + /// + /// The Number of Arguments + /// The Arguments Array + /// Thrown in case of Invalid Parameter + /// Thrown in case of Permission denied + /// Thrown in case of Not supported + /// thrown in case of Operation failure + public void EngineMain(int argc, string[] argv) + { + _callbackStructGCHandle.CallbackStruct.version = 1; + _callbackStructGCHandle.CallbackStruct.getInfo = _getInfoCb; + _callbackStructGCHandle.CallbackStruct.initialize = Initialize; + _callbackStructGCHandle.CallbackStruct.deinitialize = _deinitializeCb; + _callbackStructGCHandle.CallbackStruct.supportedLanaguge = ForEachSupportedLanguages; + _callbackStructGCHandle.CallbackStruct.validLanaguage = _isValidLanguageCb; + _callbackStructGCHandle.CallbackStruct.silence = SupportSilenceDetection; + _callbackStructGCHandle.CallbackStruct.recognitionType = SupportRecognitionType; + _callbackStructGCHandle.CallbackStruct.recordingFormat = GetRecordingFormat; + _callbackStructGCHandle.CallbackStruct.resultTime = ForEachResultTime; + _callbackStructGCHandle.CallbackStruct.silenceDetection = SetSilenceDetection; + _callbackStructGCHandle.CallbackStruct.start = _startCb; + _callbackStructGCHandle.CallbackStruct.recordingData = SetRecordingData; + _callbackStructGCHandle.CallbackStruct.stop = Stop; + _callbackStructGCHandle.CallbackStruct.cancel = Cancel; + _callbackStructGCHandle.CallbackStruct.checkAppAgreed = CheckAppAgreed; + _callbackStructGCHandle.CallbackStruct.needAppCredential = NeedAppCredential; + _structIntPtrHandle = Marshal.AllocHGlobal(Marshal.SizeOf(_callbackStructGCHandle.CallbackStruct)); + Marshal.StructureToPtr(_callbackStructGCHandle.CallbackStruct, _structIntPtrHandle, false); + Error error = STTEMain(argc, argv, _structIntPtrHandle); + if (error != Error.None) + { + Log.Error(LogTag, "STTEMain Failed with error " + error); + throw ExceptionFactory.CreateException((ErrorCode)error); + } + + Log.Info(LogTag, "After STTEMain"); + } + + /// + /// Sends the recognition result to the engine service user. + /// + /// + /// This API is used in SetRecordingData() and Stop(), when Stt engine sends the recognition result to the engine service user. + /// This function is called in the following situations; 1) after Stop() is called, 2) the end point of speech is detected from recording, or 3) partial result is occurred. + /// The recognition result must be transferred to the engine service user through this function. Also, timeInfo must be transferred to ForEachResultTime(). + /// The type of timeInfo is up to the Stt engine developer. + /// + /// The result event + /// The recognition type, "stt.recognition.type.FREE" or "stt.recognition.type.FREE.PARTIAL" + /// Result texts + /// Result text count + /// Engine message + /// The time information + /// Thrown in case of Invalid Parameter + /// Thrown in case of Permission denied + /// Thrown in case of Not supported + /// thrown in case of Operation failure + /// + /// EngineMain function should be invoked before this function is called. Stop will invoke this function. + /// + /// + /// This function invokes ForEachResultTime + /// + public void SendResult(ResultEvent resultEvent, string type, string[] result, int resultCount, ResultMessage msg, IntPtr timeInfo) + { + if ((result != null) && (result.Length != 0)) + { + + string message = "stt.result.message.none"; + switch (msg) + { + case ResultMessage.None: + message = "stt.result.message.none"; + break; + + case ResultMessage.TooFast: + message = "stt.result.message.error.too.fast"; + break; + + case ResultMessage.TooLong: + message = "stt.result.message.error.too.long"; + break; + + case ResultMessage.TooLoud: + message = "stt.result.message.error.too.loud"; + break; + + case ResultMessage.TooQuiet: + message = "stt.result.message.error.too.quiet"; + break; + + case ResultMessage.TooShort: + message = "stt.result.message.error.too.short"; + break; + + case ResultMessage.TooSoon: + message = "stt.result.message.error.too.soon"; + break; + } + + Error error = STTESendResult(resultEvent, type, result, resultCount, message, timeInfo, IntPtr.Zero); + if (error != Error.None) + { + Log.Error(LogTag, "STTESendResult Failed with error " + error); + throw ExceptionFactory.CreateException((ErrorCode)error); + } + + } + else + { + throw new ArgumentNullException("result", "is null or empty"); + } + } + + /// + /// Sends the error to the engine service user. + /// + /// The Error Reason + /// The error message + /// Thrown in case of Invalid Parameter + /// Thrown in case of Permission denied + /// Thrown in case of Not supported + /// thrown in case of Operation failure + /// + /// Main function should be invoked before this function is called. + /// + public void SendError(Error error, string msg) + { + Error err = STTESendError(error, msg); + if (err != Error.None) + { + Log.Error(LogTag, "SendError Failed with error " + err); + throw ExceptionFactory.CreateException((ErrorCode)error); + } + + } + + /// + /// Sends the speech status to the engine service user when Stt engine notifies the change of the speech status. + /// + /// + /// This API is invoked when Stt engine wants to notify the change of the speech status anytime. NOTE that this API can be invoked for recognizing the speech. + /// + /// SpeechStatus + /// Thrown in case of Invalid Parameter + /// Thrown in case of Permission denied + /// Thrown in case of Not supported + /// thrown in case of Operation failure + /// + /// Main function should be invoked before this function is called. Start() and SetRecordingData() will invoke this function. + /// + public void SendSpeechStatus(SpeechStatus status) + { + Error error = STTESendSpeechStatus(status, IntPtr.Zero); + if (error != Error.None) + { + Log.Error(LogTag, "SendSpeechStatus Failed with error " + error); + throw ExceptionFactory.CreateException((ErrorCode)error); + } + + } + + /// + /// Sets a callback function for setting the private data. + /// + /// + /// http://tizen.org/privilege/recorder + /// + /// + /// Called when Stt engine receives the private data from the engine service user. + /// This callback function is called when the engine service user sends the private data to Stt engine. + /// In Parameters: + /// a = Key -- The key field of private data + /// b = data -- The data field of private data + /// Following Error Codes can be returned + /// 1. None + /// 2. InvalidParameter + /// 3. OperationFailed + /// + /// Thrown in case of Invalid Parameter + /// Thrown in case of Permission denied + /// Thrown in case of Not supported + /// thrown in case of Operation failure + /// + /// Main function should be invoked before this function is called. + /// + public void SetPrivateDataSetDelegate(Action callback) + { + _privateDatacallback = callback; + _privateDataSetCb = (string key, string data) => + { + return _privateDatacallback.Invoke(key, data); + }; + Error error = STTESetPrivateDataSetCb(_privateDataSetCb); + if (error != Error.None) + { + Log.Error(LogTag, "SetPrivateDataSetDelegate Failed with error " + error); + throw ExceptionFactory.CreateException((ErrorCode)error); + } + + } + + /// + /// Sets a callback delegate for requesting the private data. + /// + /// + /// http://tizen.org/privilege/recorder + /// + /// callback function + /// Called when Stt engine provides the engine service user with the private data. + /// This callback function is called when the engine service user gets the private data from Stt engine. + /// Out Parameters: + /// a = Key -- The key field of private data + /// b = data -- The data field of private data + /// Following Error Codes can be returned + /// 1. None + /// 2. InvalidParameter + /// 3. OperationFailed + /// + /// Thrown in case of Invalid Parameter + /// Thrown in case of Permission denied + /// Thrown in case of Not supported + /// thrown in case of Operation failure + /// + /// Main function should be invoked before this function is called. + /// + public void SetPrivateDataRequestedDelegate(OutAction callback) + { + _privateDataRequestedCallback = callback; + _privateDataRequestedCb = (string key, out string data) => + { + return _privateDataRequestedCallback.Invoke(key, out data); + }; + Error error = STTESetPrivateDataRequestedCb(_privateDataRequestedCb); + if (error != Error.None) + { + Log.Error(LogTag, "SetPrivateDataRequestedDelegate Failed with error " + error); + throw ExceptionFactory.CreateException((ErrorCode)error); + } + + } + + private StartCb _startCb = (IntPtr language, IntPtr type, IntPtr appid, IntPtr credential, IntPtr userData) => + { + string lan = null; + string typ = null; + string apid = null; + string cre = null; + if (language != null) + lan = Marshal.PtrToStringAnsi(language); + if (type != null) + typ = Marshal.PtrToStringAnsi(type); + if (appid != null) + apid = Marshal.PtrToStringAnsi(appid); + if (credential != null) + cre = Marshal.PtrToStringAnsi(credential); + return _engine.Start(lan, typ, apid, cre, IntPtr.Zero); + }; + + private IsValidLanguageCb _isValidLanguageCb = (IntPtr langauge, IntPtr isValid) => + { + string langaugeStr = Marshal.PtrToStringAnsi(langauge); + bool valid; + Error err = _engine.IsValidLanguage(langaugeStr, out valid); + if (valid == true) + { + Marshal.WriteByte(isValid, 0, 1); + } + else + { + Marshal.WriteByte(isValid, 0, 0); + } + return err; + }; + + private GetInfoCb _getInfoCb = (out IntPtr engineUuid, out IntPtr engineName, out IntPtr engineSetting, out IntPtr useNetwork) => + { + string uuid; + string name; + string setting; + bool network; + Error err = _engine.GetInformation(out uuid, out name, out setting, out network); + int size = Marshal.SizeOf(); + IntPtr pBool = Marshal.AllocHGlobal(size); + if (network == true) + { + Marshal.WriteInt32(pBool, 0, 1); + } + else + { + Marshal.WriteInt32(pBool, 0, 0); + } + engineUuid = Marshal.StringToHGlobalAnsi(uuid); + engineName = Marshal.StringToHGlobalAnsi(name); + engineSetting = Marshal.StringToHGlobalAnsi(setting); + useNetwork = pBool; + return err; + }; + + private DeinitializeCb _deinitializeCb = () => + { + Marshal.FreeHGlobal(_engine._structIntPtrHandle); + return _engine.Deinitialize(); + }; + } +} \ No newline at end of file