[AudioManager] Add new APIs for USB Audio output device (#447)
authorSangchul Lee <sangchul1011@gmail.com>
Tue, 2 Oct 2018 00:49:46 +0000 (09:49 +0900)
committerGitHub <noreply@github.com>
Tue, 2 Oct 2018 00:49:46 +0000 (09:49 +0900)
* [AudioManager] Add new APIs regarding sample format and rate for USB audio output device

Added in AudioDevice class as below:
 - method
  : GetSupportedSampleFormats()
  : GetSupportedSampleRates()
 - member
  : SampleFormat
  : SampleRate

Signed-off-by: Sangchul Lee <sc11.lee@samsung.com>
* [AudioManager] Add new APIs regarding USB audio output device setting

'AvoidResampling' and 'MediaStreamOnly' properties are added in AudioDevice class

Signed-off-by: Sangchul Lee <sc11.lee@samsung.com>
* [AudioManager] Export methods instead of properties that can throw exceptions

Enumeration of AudioSampleFormat.cs is also revised.

Signed-off-by: Sangchul Lee <sc11.lee@samsung.com>
* [AudioManager] Convert rate enum value from core to uint and fix bug

Signed-off-by: Sangchul Lee <sc11.lee@samsung.com>
* [AudioManager] Fix documentation

Signed-off-by: Sangchul Lee <sc11.lee@samsung.com>
src/Tizen.Multimedia/AudioManager/AudioDevice.cs [changed mode: 0755->0644]
src/Tizen.Multimedia/AudioManager/AudioDeviceRunningChangedEventArgs.cs [changed mode: 0644->0755]
src/Tizen.Multimedia/AudioManager/AudioSampleFormat.cs [new file with mode: 0755]
src/Tizen.Multimedia/Interop/Interop.Device.cs

old mode 100755 (executable)
new mode 100644 (file)
index 9e71c10..987f0d3
@@ -16,6 +16,8 @@
 
 using System;
 using System.Runtime.InteropServices;
+using System.Collections.Generic;
+using System.Linq;
 
 namespace Tizen.Multimedia
 {
@@ -28,6 +30,7 @@ namespace Tizen.Multimedia
         private readonly int _id;
         private readonly AudioDeviceType _type;
         private readonly AudioDeviceIoDirection _ioDirection;
+        private const string Tag = "Tizen.Multimedia.AudioDevice";
 
         internal AudioDevice(IntPtr deviceHandle)
         {
@@ -104,10 +107,249 @@ namespace Tizen.Multimedia
                     ThrowIfError("Failed to get the running state of the device");
 
                 return isRunning;
+                       }
+        }
+
+        /// <summary>
+        /// Gets the device's supported sample formats.
+        /// </summary>
+        /// <returns>An IEnumerable&lt;AudioSampleFormat&gt; that contains supported sample formats.</returns>
+        /// <remarks>
+        /// This device should be <see cref="AudioDeviceType.UsbAudio"/> type and <see cref="AudioDeviceIoDirection.Output"/> direction.
+        /// </remarks>
+        /// <exception cref="InvalidOperationException">This device is not valid or is disconnected.</exception>
+        /// <since_tizen> 5 </since_tizen>
+        public IEnumerable<AudioSampleFormat> GetSupportedSampleFormats()
+        {
+            Interop.AudioDevice.GetSupportedSampleFormats(_id, out IntPtr formats, out uint numberOfElements).
+                ThrowIfError("Failed to get supported sample formats");
+
+            return RetrieveFormats();
+
+            IEnumerable<AudioSampleFormat> RetrieveFormats()
+            {
+                int[] formatsResult = new int[numberOfElements];
+
+                Marshal.Copy(formats, formatsResult, 0, (int)numberOfElements);
+                Interop.Libc.Free(formats);
+
+                foreach (int f in formatsResult)
+                {
+                    Log.Debug(Tag, $"supported sample format:{f}");
+                }
+
+                return formatsResult.Cast<AudioSampleFormat>();
+            }
+        }
+
+        /// <summary>
+        /// Sets the device's sample format.
+        /// </summary>
+        /// <param name="format">The <see cref="AudioSampleFormat"/> to set to the device.</param>
+        /// <remarks>
+        /// This device should be <see cref="AudioDeviceType.UsbAudio"/> type and <see cref="AudioDeviceIoDirection.Output"/> direction.
+        /// </remarks>
+        /// <exception cref="InvalidOperationException">This device is not valid or is disconnected.</exception>
+        /// <since_tizen> 5 </since_tizen>
+        public void SetSampleFormat(AudioSampleFormat format)
+        {
+            Interop.AudioDevice.SetSampleFormat(_id, format).
+                    ThrowIfError("Failed to set sample format of the device");
+        }
+
+        /// <summary>
+        /// Gets the device's sample format.
+        /// </summary>
+        /// <returns>The <see cref="AudioSampleFormat"/> of the device.</returns>
+        /// <remarks>
+        /// This device should be <see cref="AudioDeviceType.UsbAudio"/> type and <see cref="AudioDeviceIoDirection.Output"/> direction.
+        /// </remarks>
+        /// <exception cref="InvalidOperationException">This device is not valid or is disconnected.</exception>
+        /// <since_tizen> 5 </since_tizen>
+        public AudioSampleFormat GetSampleFormat()
+        {
+            Interop.AudioDevice.GetSampleFormat(_id, out AudioSampleFormat format).
+                ThrowIfError("Failed to get sample format of the device");
+
+            return format;
+        }
+
+        private uint ConvertCoreRateValToUint(int value)
+        {
+            switch (value)
+            {
+                case 0: return 8000;
+                case 1: return 16000;
+                case 2: return 22050;
+                case 3: return 44100;
+                case 4: return 48000;
+                case 5: return 88200;
+                case 6: return 96000;
+                case 7: return 192000;
+                default:
+                    Log.Error(Tag, $"unknown value from core:{value}");
+                    return 0;
+            }
+        }
+
+        private uint ConvertRateToCoreValue(uint rate)
+        {
+            switch (rate)
+            {
+                case 8000: return 0;
+                case 16000: return 1;
+                case 22050: return 2;
+                case 44100: return 3;
+                case 48000: return 4;
+                case 88200: return 5;
+                case 96000: return 6;
+                case 192000: return 7;
+                default:
+                    Log.Error(Tag, $"not supported rate:{rate}");
+                    return 0;
+            }
+        }
+
+        /// <summary>
+        /// Gets the device's supported sample rates.
+        /// </summary>
+        /// <returns>An IEnumerable&lt;uint&gt; that contains supported sample rates.</returns>
+        /// <remarks>
+        /// This device should be <see cref="AudioDeviceType.UsbAudio"/> type and <see cref="AudioDeviceIoDirection.Output"/> direction.
+        /// </remarks>
+        /// <exception cref="InvalidOperationException">This device is not valid or is disconnected.</exception>
+        /// <since_tizen> 5 </since_tizen>
+        public IEnumerable<uint> GetSupportedSampleRates()
+        {
+            Interop.AudioDevice.GetSupportedSampleRates(_id, out IntPtr rates, out uint numberOfElements).
+                ThrowIfError("Failed to get supported sample formats");
+
+            return RetrieveRates();
+
+            IEnumerable<uint> RetrieveRates()
+            {
+                int[] ratesResult = new int[numberOfElements];
+                uint[] convertedRates = new uint[numberOfElements];
+
+                Marshal.Copy(rates, ratesResult, 0, (int)numberOfElements);
+                Interop.Libc.Free(rates);
+
+                for (int i = 0; i < ratesResult.Length; i++)
+                {
+                    convertedRates[i] = ConvertCoreRateValToUint(ratesResult[i]);
+                    Log.Debug(Tag, $"supported sample rate:{convertedRates[i]}");
+                }
+
+                return convertedRates;
             }
         }
 
         /// <summary>
+        /// Sets the device's sample rate.
+        /// </summary>
+        /// <param name="rate">The sample rate to set to the device.</param>
+        /// <remarks>
+        /// This device should be <see cref="AudioDeviceType.UsbAudio"/> type and <see cref="AudioDeviceIoDirection.Output"/> direction.
+        /// </remarks>
+        /// <exception cref="InvalidOperationException">This device is not valid or is disconnected.</exception>
+        /// <since_tizen> 5 </since_tizen>
+        public void SetSampleRate(uint rate)
+        {
+            Interop.AudioDevice.SetSampleRate(_id, ConvertRateToCoreValue(rate)).
+                ThrowIfError("Failed to set sample rate of the device");
+        }
+
+        /// <summary>
+        /// Gets the device's sample rate.
+        /// </summary>
+        /// <returns>The sample rate of the device.</returns>
+        /// <remarks>
+        /// This device should be <see cref="AudioDeviceType.UsbAudio"/> type and <see cref="AudioDeviceIoDirection.Output"/> direction.
+        /// </remarks>
+        /// <exception cref="InvalidOperationException">This device is not valid or is disconnected.</exception>
+        /// <since_tizen> 5 </since_tizen>
+        public uint GetSampleRate()
+        {
+            Interop.AudioDevice.GetSampleRate(_id, out uint rate).
+                ThrowIfError("Failed to get sample rate of the device");
+
+            return ConvertCoreRateValToUint((int)rate);
+        }
+
+        /// <summary>
+        /// Sets the device's 'avoid resampling' property.
+        /// </summary>
+        /// <param name="enable">The 'avoid resampling' value to set to the device.</param>
+        /// <remarks>
+        /// This device should be <see cref="AudioDeviceType.UsbAudio"/> type and <see cref="AudioDeviceIoDirection.Output"/> direction.
+        /// This property is not enabled as default. With this enabled, this device will use the first stream's original sample format
+        /// and rate without resampling if supported.
+        /// </remarks>
+        /// <exception cref="InvalidOperationException">This device is not valid or is disconnected.</exception>
+        /// <since_tizen> 5 </since_tizen>
+        public void SetAvoidResampling(bool enable)
+        {
+            Interop.AudioDevice.SetAvoidResampling(_id, enable).
+                ThrowIfError("Failed to set avoid-resampling property of the device");
+
+        }
+
+        /// <summary>
+        /// Gets the device's 'avoid resampling' property.
+        /// </summary>
+        /// <returns>The 'avoid resampling' property of the device.</returns>
+        /// <remarks>
+        /// This device should be <see cref="AudioDeviceType.UsbAudio"/> type and <see cref="AudioDeviceIoDirection.Output"/> direction.
+        /// This property is not enabled as default. With this enabled, this device will use the first stream's original sample format
+        /// and rate without resampling if supported.
+        /// </remarks>
+        /// <exception cref="InvalidOperationException">This device is not valid or is disconnected.</exception>
+        /// <since_tizen> 5 </since_tizen>
+        public bool GetAvoidResampling()
+        {
+            Interop.AudioDevice.GetAvoidResampling(_id, out bool enabled).
+                ThrowIfError("Failed to get avoid-resampling property of the device");
+
+            return enabled;
+        }
+
+        /// <summary>
+        /// Sets the restriction of stream type only for media.
+        /// </summary>
+        /// <param name="enable">The 'media stream only' value to set to the device.</param>
+        /// <remarks>
+        /// This device should be <see cref="AudioDeviceType.UsbAudio"/> type and <see cref="AudioDeviceIoDirection.Output"/> direction.
+        ///    This property is not enabled as default. With this enabled, no other stream types except <see cref="AudioStreamType.Media"/>
+        ///    are not allowed to this device.
+        /// </remarks>
+        /// <exception cref="InvalidOperationException">This device is not valid or is disconnected.</exception>
+        /// <since_tizen> 5 </since_tizen>
+        public void SetMediaStreamOnly(bool enable)
+        {
+            Interop.AudioDevice.SetMediaStreamOnly(_id, enable).
+                ThrowIfError("Failed to set media-stream-only property of the device");
+        }
+
+        /// <summary>
+        /// Gets the restriction of stream type only for media.
+        /// </summary>
+        /// <returns>The 'media stream only' property of the device.</returns>
+        /// <remarks>
+        /// This device should be <see cref="AudioDeviceType.UsbAudio"/> type and <see cref="AudioDeviceIoDirection.Output"/> direction.
+        ///    This property is not enabled as default. With this enabled, no other stream types except <see cref="AudioStreamType.Media"/>
+        ///    are not allowed to this device.
+        /// </remarks>
+        /// <exception cref="InvalidOperationException">This device is not valid or is disconnected.</exception>
+        /// <since_tizen> 5 </since_tizen>
+        public bool GetMediaStreamOnly()
+        {
+            Interop.AudioDevice.GetMediaStreamOnly(_id, out bool enabled).
+                ThrowIfError("Failed to get media-stream-only property of the device");
+
+            return enabled;
+        }
+
+        /// <summary>
         /// Returns a string that represents the current object.
         /// </summary>
         /// <returns>A string that represents the current object.</returns>
diff --git a/src/Tizen.Multimedia/AudioManager/AudioSampleFormat.cs b/src/Tizen.Multimedia/AudioManager/AudioSampleFormat.cs
new file mode 100755 (executable)
index 0000000..c679adc
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2018 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.
+ */
+
+namespace Tizen.Multimedia
+{
+    /// <summary>
+    /// Specifies the audio sample formats.
+    /// </summary>
+    /// <since_tizen> 5 </since_tizen>
+    public enum AudioSampleFormat
+    {
+        /// <summary>
+        /// Unsigned 8 bit samples.
+        /// </summary>
+        U8,
+
+        /// <summary>
+        /// Signed 16 bit samples.
+        /// </summary>
+        S16LE,
+
+        /// <summary>
+        /// Signed 24 bit samples.
+        /// </summary>
+        S24LE,
+
+        /// <summary>
+        /// Signed 24 bit(packed in 32 bit) samples.
+        /// </summary>
+        S24PackedIn32LE,
+    }
+}
index 98f0d71..100c3f9 100755 (executable)
@@ -60,6 +60,36 @@ namespace Tizen.Multimedia
             [DllImport(Libraries.SoundManager, EntryPoint = "sound_manager_is_device_running_by_id")]
             internal static extern AudioManagerError IsDeviceRunning(int deviceId, out bool isRunning);
 
+            [DllImport(Libraries.SoundManager, EntryPoint = "sound_manager_get_supported_sample_formats_by_id")]
+            internal static extern AudioManagerError GetSupportedSampleFormats(int deviceId, out IntPtr formats, out uint numberOfElements);
+
+            [DllImport(Libraries.SoundManager, EntryPoint = "sound_manager_set_sample_format_by_id")]
+            internal static extern AudioManagerError SetSampleFormat(int deviceId, AudioSampleFormat format);
+
+            [DllImport(Libraries.SoundManager, EntryPoint = "sound_manager_get_sample_format_by_id")]
+            internal static extern AudioManagerError GetSampleFormat(int deviceId, out AudioSampleFormat format);
+
+            [DllImport(Libraries.SoundManager, EntryPoint = "sound_manager_get_supported_sample_rates_by_id")]
+            internal static extern AudioManagerError GetSupportedSampleRates(int deviceId, out IntPtr rates, out uint numberOfElements);
+
+            [DllImport(Libraries.SoundManager, EntryPoint = "sound_manager_set_sample_rate_by_id")]
+            internal static extern AudioManagerError SetSampleRate(int deviceId, uint rate);
+
+            [DllImport(Libraries.SoundManager, EntryPoint = "sound_manager_get_sample_rate_by_id")]
+            internal static extern AudioManagerError GetSampleRate(int deviceId, out uint rate);
+
+            [DllImport(Libraries.SoundManager, EntryPoint = "sound_manager_set_avoid_resampling_by_id")]
+            internal static extern AudioManagerError SetAvoidResampling(int deviceId, bool enable);
+
+            [DllImport(Libraries.SoundManager, EntryPoint = "sound_manager_get_avoid_resampling_by_id")]
+            internal static extern AudioManagerError GetAvoidResampling(int deviceId, out bool enabled);
+
+            [DllImport(Libraries.SoundManager, EntryPoint = "sound_manager_set_media_stream_only_by_id")]
+            internal static extern AudioManagerError SetMediaStreamOnly(int deviceId, bool enable);
+
+            [DllImport(Libraries.SoundManager, EntryPoint = "sound_manager_get_media_stream_only_by_id")]
+            internal static extern AudioManagerError GetMediaStreamOnly(int deviceId, out bool enabled);
+
             [DllImport(Libraries.SoundManager, EntryPoint = "sound_manager_add_device_connection_changed_cb")]
             internal static extern AudioManagerError AddDeviceConnectionChangedCallback(
                 AudioDeviceOptions deviceMask, ConnectionChangedCallback callback, IntPtr userData, out int id);