[Tts] Add new internal API for TTS synthesized PCM (#5526)
authorSuyeon Hwang <35016426+stom-hwang@users.noreply.github.com>
Thu, 7 Sep 2023 03:51:43 +0000 (12:51 +0900)
committerGitHub <noreply@github.com>
Thu, 7 Sep 2023 03:51:43 +0000 (12:51 +0900)
* Add new internal method for playing mode

Signed-off-by: Suyeon Hwang <stom.hwang@samsung.com>
* Inherit System.EventArgs class

Signed-off-by: Suyeon Hwang <stom.hwang@samsung.com>
---------

Signed-off-by: Suyeon Hwang <stom.hwang@samsung.com>
src/Tizen.Uix.Tts/Interop/Interop.Tts.cs
src/Tizen.Uix.Tts/Tizen.Uix.Tts/SynthesizedPcmEventArgs.cs [new file with mode: 0644]
src/Tizen.Uix.Tts/Tizen.Uix.Tts/TtsClient.cs

index a2afa16..7a904bd 100755 (executable)
@@ -80,6 +80,9 @@ internal static partial class Interop
         [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
         internal delegate void TtsServiceStateChangedCB(IntPtr handle, ServiceState previous, ServiceState current, IntPtr userData);
 
+        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+        internal delegate void TtsSythesizedPcmCB(IntPtr handle, int uttId, SynthesizedPcmEvent pcmEvent, IntPtr pcmData, int pcmSize, AudioType audioType, int sampleRate, IntPtr userData);
+
         [DllImport(Libraries.Tts, EntryPoint = "tts_create", CallingConvention = CallingConvention.Cdecl)]
         internal static extern TtsError TtsCreate(out IntPtr handle);
 
@@ -193,5 +196,14 @@ internal static partial class Interop
 
         [DllImport(Libraries.Tts, EntryPoint = "tts_unset_service_state_changed_cb", CallingConvention = CallingConvention.Cdecl)]
         internal static extern TtsError TtsUnsetServiceStateChangedCB(IntPtr handle);
+
+        [DllImport(Libraries.Tts, EntryPoint = "tts_set_playing_mode", CallingConvention = CallingConvention.Cdecl)]
+        internal static extern TtsError TtsSetPlayingMode(IntPtr handle, PlayingMode mode);
+
+        [DllImport(Libraries.Tts, EntryPoint = "tts_set_synthesized_pcm_cb", CallingConvention = CallingConvention.Cdecl)]
+        internal static extern TtsError TtsSetSynthesizedPcmCB(IntPtr handle, TtsSythesizedPcmCB callback, IntPtr userData);
+
+        [DllImport(Libraries.Tts, EntryPoint = "tts_unset_synthesized_pcm_cb", CallingConvention = CallingConvention.Cdecl)]
+        internal static extern TtsError TtsUnsetSynthesizedPcmCB(IntPtr handle);
     }
 }
diff --git a/src/Tizen.Uix.Tts/Tizen.Uix.Tts/SynthesizedPcmEventArgs.cs b/src/Tizen.Uix.Tts/Tizen.Uix.Tts/SynthesizedPcmEventArgs.cs
new file mode 100644 (file)
index 0000000..7751dc2
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+* Copyright (c) 2023 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.ComponentModel;
+
+namespace Tizen.Uix.Tts
+{
+    /// <summary>
+    /// This class holds information related to the TTS SynthesizedPcm event.
+    /// </summary>
+    /// <since_tizen> 11 </since_tizen>
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public class SynthesizedPcmEventArgs : EventArgs
+    {
+        internal SynthesizedPcmEventArgs(int utteranceId, SynthesizedPcmEvent synthesizedPcmEvent, byte[] data, AudioType audioType, int sampleRate)
+        {
+            UtteranceId = utteranceId;
+            EventType = synthesizedPcmEvent;
+            Data = data;
+            AudioType = audioType;
+            SampleRate = sampleRate;
+        }
+
+        /// <summary>
+        /// The utterance ID.
+        /// </summary>
+        /// <since_tizen> 11 </since_tizen>
+        public int UtteranceId
+        {
+            get;
+            internal set;
+        }
+
+        /// <summary>
+        /// The event of the PCM data.
+        /// </summary>
+        /// <since_tizen> 11 </since_tizen>
+        public SynthesizedPcmEvent EventType
+        {
+            get;
+            internal set;
+        }
+
+        /// <summary>
+        /// The syntehsized PCM data.
+        /// </summary>
+        /// <since_tizen> 11 </since_tizen>
+        public byte[] Data
+        {
+            get;
+            internal set;
+        }
+
+        /// <summary>
+        /// The audio type of the PCM data.
+        /// </summary>
+        /// <since_tizen> 11 </since_tizen>
+        public AudioType AudioType
+        {
+            get;
+            internal set;
+        }
+
+        /// <summary>
+        /// The sample rate of the PCM data.
+        /// </summary>
+        /// <since_tizen> 11 </since_tizen>
+        public int SampleRate
+        {
+            get;
+            internal set;
+        }
+    }
+}
index e5b359b..e26d071 100644 (file)
@@ -18,6 +18,7 @@
 using System;
 using System.Collections.Generic;
 using System.Runtime.InteropServices;
+using System.ComponentModel;
 using static Interop.Tts;
 
 namespace Tizen.Uix.Tts
@@ -231,6 +232,70 @@ namespace Tizen.Uix.Tts
     };
 
     /// <summary>
+    /// Enumeration for the playing modes of TTS.
+    /// </summary>
+    /// <since_tizen> 11 </since_tizen>
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public enum PlayingMode
+    {
+        /// <summary>
+        /// Mode for TTS playing on TTS service.
+        /// </summary>
+        ByService = 0,
+
+        /// <summary>
+        /// Mode for TTS playing on TTS client.
+        /// </summary>
+        ByClient = 1
+    };
+
+    /// <summary>
+    /// Enumeration for the audio types.
+    /// </summary>
+    /// <since_tizen> 11 </since_tizen>
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public enum AudioType
+    {
+        /// <summary>
+        /// Signed 16-bit audio type.
+        /// </summary>
+        RawS16 = 0,
+
+        /// <summary>
+        /// Unsigned 8-bit audio type.
+        /// </summary>
+        RawU8 = 1
+    };
+
+    /// <summary>
+    /// Enumeration for the synthesized PCM events.
+    /// </summary>
+    /// <since_tizen> 11 </since_tizen>
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public enum SynthesizedPcmEvent
+    {
+        /// <summary>
+        /// The PCM synthesis failed.
+        /// </summary>
+        Fail = -1,
+
+        /// <summary>
+        /// Received initial synthesized PCM data for an utterance.
+        /// </summary>
+        Start = 1,
+
+        /// <summary>
+        /// Received synthesized PCM data, not the first and last in the stream.
+        /// </summary>
+        Continue = 2,
+
+        /// <summary>
+        /// Received the final synthesized PCM data.
+        /// </summary>
+        Finish = 3
+    };
+
+    /// <summary>
     /// You can use Text-To-Speech (TTS) API's to read sound data transformed by the engine from input texts.
     /// Applications can add input-text to queue for reading continuously and control the player that can play, pause, and stop sound data synthesized from text.
     /// </summary>
@@ -246,6 +311,7 @@ namespace Tizen.Uix.Tts
         private event EventHandler<EngineChangedEventArgs> _engineChanged;
         private event EventHandler<ScreenReaderChangedEventArgs> _screenReaderChanged;
         private event EventHandler<ServiceStateChangedEventArgs> _serviceStateChanged;
+        private EventHandler<SynthesizedPcmEventArgs> _synthesizedPcmEventHandler;
         private bool disposedValue = false;
         private readonly Object _stateChangedLock = new Object();
         private readonly Object _utteranceStartedLock = new Object();
@@ -255,6 +321,7 @@ namespace Tizen.Uix.Tts
         private readonly Object _engineChangedLock = new Object();
         private readonly Object _screenReaderChangedLock = new Object();
         private readonly Object _serviceStateChangedLock = new Object();
+        private readonly object _synthesizedPcmLock = new object();
         private TtsStateChangedCB _stateDelegate;
         private TtsUtteranceStartedCB _utteranceStartedResultDelegate;
         private TtsUtteranceCompletedCB _utteranceCompletedResultDelegate;
@@ -263,7 +330,9 @@ namespace Tizen.Uix.Tts
         private TtsEngineChangedCB _engineDelegate;
         private TtsScreenReaderChangedCB _screenReaderDelegate;
         private TtsServiceStateChangedCB _serviceStateDelegate;
+        private TtsSythesizedPcmCB _synthesizedPcmDelegate;
         private TtsSupportedVoiceCB _supportedvoiceDelegate;
+        private PlayingMode _playingMode = PlayingMode.ByService;
 
         /// <summary>
         /// Constructor to create a TTS instance.
@@ -665,6 +734,54 @@ namespace Tizen.Uix.Tts
         }
 
         /// <summary>
+        /// Event to be invoked when the synthesized pcm data comes from the engine.
+        /// </summary>
+        /// <since_tizen> 11 </since_tizen>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public event EventHandler<SynthesizedPcmEventArgs> SynthesizedPcm
+        {
+            add
+            {
+                lock (_synthesizedPcmLock)
+                {
+                    if (_synthesizedPcmEventHandler == null)
+                    {
+                        _synthesizedPcmDelegate = (IntPtr handle, int uttId, SynthesizedPcmEvent pcmEvent, IntPtr pcmData, int pcmSize, AudioType audioType, int sampleRate, IntPtr userData) =>
+                        {
+                            var managedPcmData = new byte[pcmSize];
+                            Marshal.Copy(pcmData, managedPcmData, 0, pcmSize);
+                            SynthesizedPcmEventArgs args = new SynthesizedPcmEventArgs(uttId, pcmEvent, managedPcmData, audioType, sampleRate);
+                            _synthesizedPcmEventHandler?.Invoke(this, args);
+                        };
+
+                        TtsError error = TtsSetSynthesizedPcmCB(_handle, _synthesizedPcmDelegate, IntPtr.Zero);
+                        if (error != TtsError.None)
+                        {
+                            Log.Error(LogTag, "Add SynthesizedPcm Failed with error " + error);
+                        }
+                    }
+                    _synthesizedPcmEventHandler += value;
+                }
+            }
+
+            remove
+            {
+                lock (_synthesizedPcmLock)
+                {
+                    _synthesizedPcmEventHandler -= value;
+                    if (_synthesizedPcmEventHandler == null)
+                    {
+                        TtsError error = TtsUnsetSynthesizedPcmCB(_handle);
+                        if (error != TtsError.None)
+                        {
+                            Log.Error(LogTag, "Remove SynthesizedPcm Failed with error " + error);
+                        }
+                    }
+                }
+            }
+        }
+
+        /// <summary>
         /// Gets the default voice set by the user.
         /// </summary>
         /// <since_tizen> 3 </since_tizen>
@@ -849,6 +966,40 @@ namespace Tizen.Uix.Tts
         }
 
         /// <summary>
+        /// Sets the current playing mode.
+        /// </summary>
+        /// <since_tizen> 11 </since_tizen>
+        /// <value>
+        /// The current playing mode.
+        /// </value>
+        /// <feature>
+        /// http://tizen.org/feature/speech.synthesis
+        /// </feature>
+        /// <exception cref="InvalidOperationException">This exception can be due to an invalid state.</exception>
+        /// <exception cref="NotSupportedException">This exception can be due to TTS not supported.</exception>
+        /// <pre>
+        /// If you want to set, the Client must be in the <see cref="State.Created"/> state.
+        /// </pre>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public PlayingMode PlayingMode
+        {
+            get
+            {
+                return _playingMode;
+            }
+            set
+            {
+                TtsError error = TtsSetPlayingMode(_handle, value);
+                if (error != TtsError.None)
+                {
+                    Log.Error(LogTag, "Set Mode Failed with error " + error);
+                    throw ExceptionFactory.CreateException(error);
+                }
+                _playingMode = value;
+            }
+        }
+
+        /// <summary>
         /// Sets the application credential.
         /// </summary>
         /// <since_tizen> 3 </since_tizen>