From 6ccad8b683ce6e573015f5671e1c3ee2771b49c9 Mon Sep 17 00:00:00 2001 From: Jeongmo Yang Date: Thu, 5 Sep 2019 11:24:31 +0900 Subject: [PATCH] [AudioManager] Add new class for audio ducking (#979) * [AudioManager] Add new class for audio ducking - Added class : AudioDucking : AudioDuckingStateChangedEventArgs : AudioDuckingHandle Signed-off-by: Jeongmo Yang --- .../AudioManager/AudioDucking.cs | 182 ++++++++++++++++++ .../AudioDuckingStateChangedEventArgs.cs | 39 ++++ .../Interop/AudioDuckingHandle.cs | 42 ++++ .../Interop/Interop.Ducking.cs | 46 +++++ 4 files changed, 309 insertions(+) create mode 100644 src/Tizen.Multimedia/AudioManager/AudioDucking.cs create mode 100644 src/Tizen.Multimedia/AudioManager/AudioDuckingStateChangedEventArgs.cs create mode 100644 src/Tizen.Multimedia/Interop/AudioDuckingHandle.cs create mode 100644 src/Tizen.Multimedia/Interop/Interop.Ducking.cs diff --git a/src/Tizen.Multimedia/AudioManager/AudioDucking.cs b/src/Tizen.Multimedia/AudioManager/AudioDucking.cs new file mode 100644 index 000000000..c980084a5 --- /dev/null +++ b/src/Tizen.Multimedia/AudioManager/AudioDucking.cs @@ -0,0 +1,182 @@ +/* + * Copyright (c) 2019 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.Diagnostics; + +namespace Tizen.Multimedia +{ + /// + /// Provides the ability to control audio ducking. + /// + /// + /// 6 + public sealed class AudioDucking : IDisposable + { + private AudioDuckingHandle _handle; + private bool _disposed = false; + private Interop.AudioDucking.DuckingStateChangedCallback _duckingStateChangedCallback; + + /// + /// Initializes a new instance of the class with . + /// + /// The type of sound stream to be affected by this new instance. + /// is invalid. + /// Operation failed; internal error. + /// 6 + public AudioDucking(AudioStreamType targetType) + { + ValidationUtil.ValidateEnum(typeof(AudioStreamType), targetType, nameof(targetType)); + + _duckingStateChangedCallback = (AudioDuckingHandle ducking, bool isDucked, IntPtr _) => + { + DuckingStateChanged?.Invoke(this, + new AudioDuckingStateChangedEventArgs(IsDucked)); + }; + + Interop.AudioDucking.Create(targetType, _duckingStateChangedCallback, + IntPtr.Zero, out _handle).ThrowIfError("Unable to create stream ducking"); + + Debug.Assert(_handle != null); + } + + /// + /// Occurs when the ducking state is changed. + /// + /// 6 + public event EventHandler DuckingStateChanged; + + /// + /// Gets the ducking state of the stream. + /// + /// true if the audio stream is ducked; otherwise, false. + /// Operation failed; internal error. + /// The has already been disposed of. + /// 6 + public bool IsDucked + { + get + { + if (_disposed) + { + throw new ObjectDisposedException(nameof(AudioDucking)); + } + + Interop.AudioDucking.IsDucked(Handle, out bool isDucked). + ThrowIfError("Failed to get the running state of the device"); + + return isDucked; + } + } + + /// + /// Activate audio ducking + /// + /// The duration(milisecond) for ducking. + /// The volume ratio when ducked. + /// To activate ducking, the specified privilege is required. + /// http://tizen.org/privilege/volume.set + /// + /// is less than 0 or greater than 3000.
+ /// -or-
+ /// is less than 0.0 or greater than or equal to 1.0.
+ ///
+ /// + /// Operation failed; internal error.
+ /// -or-
+ /// The target stream is already ducked. + ///
+ /// The caller does not have required privilege to set volume. + /// The has already been disposed of. + /// 6 + public void Activate(uint duration, double ratio) + { + if (_disposed) + { + throw new ObjectDisposedException(nameof(AudioDucking)); + } + + if (duration < 0 || duration > 3000) + { + throw new ArgumentOutOfRangeException(nameof(duration), duration, "Valid range : 0 <= duration <= 3000"); + } + + if (ratio < 0.0 || ratio >= 1.0) + { + throw new ArgumentOutOfRangeException(nameof(ratio), ratio, "Valid range : 0 <= ratio < 1.0"); + } + + Interop.AudioDucking.Activate(Handle, duration, ratio). + ThrowIfError("Failed to activate ducking"); + } + + /// + /// Deactivate audio ducking + /// + /// To deactivate ducking, the specified privilege is required. + /// http://tizen.org/privilege/volume.set + /// + /// Operation failed; internal error.
+ /// -or-
+ /// The target stream is already unducked. + ///
+ /// The caller does not have required privilege to set volume. + /// The has already been disposed of. + /// 6 + public void Deactivate() + { + if (_disposed) + { + throw new ObjectDisposedException(nameof(AudioDucking)); + } + + Interop.AudioDucking.Deactivate(Handle). + ThrowIfError("Failed to deactivate ducking"); + } + + /// + /// Releases all resources used by the . + /// + /// 6 + public void Dispose() + { + if (_disposed) + { + return; + } + + if (_handle != null) + { + _handle.Dispose(); + } + + _disposed = true; + GC.SuppressFinalize(this); + } + + internal AudioDuckingHandle Handle + { + get + { + if (_disposed) + { + throw new ObjectDisposedException(nameof(AudioDucking)); + } + return _handle; + } + } + } +} \ No newline at end of file diff --git a/src/Tizen.Multimedia/AudioManager/AudioDuckingStateChangedEventArgs.cs b/src/Tizen.Multimedia/AudioManager/AudioDuckingStateChangedEventArgs.cs new file mode 100644 index 000000000..9c31bb83c --- /dev/null +++ b/src/Tizen.Multimedia/AudioManager/AudioDuckingStateChangedEventArgs.cs @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2019 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; + +namespace Tizen.Multimedia +{ + /// + /// Provides data for the event. + /// + /// 6 + public class AudioDuckingStateChangedEventArgs : EventArgs + { + internal AudioDuckingStateChangedEventArgs(bool isDucked) + { + IsDucked = isDucked; + } + + /// + /// Gets the ducking state of the stream. + /// + /// true if the state is ducked; otherwise, false. + /// 6 + public bool IsDucked { get; } + } +} diff --git a/src/Tizen.Multimedia/Interop/AudioDuckingHandle.cs b/src/Tizen.Multimedia/Interop/AudioDuckingHandle.cs new file mode 100644 index 000000000..69500b403 --- /dev/null +++ b/src/Tizen.Multimedia/Interop/AudioDuckingHandle.cs @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2019 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; + +namespace Tizen.Multimedia +{ + internal class AudioDuckingHandle : SafeHandle + { + protected AudioDuckingHandle() : base(IntPtr.Zero, true) + { + } + + public override bool IsInvalid => handle == IntPtr.Zero; + + protected override bool ReleaseHandle() + { + var ret = Interop.AudioDucking.Destroy(handle); + if (ret != AudioManagerError.None) + { + Log.Debug(GetType().FullName, $"Failed to release native {GetType()}"); + return false; + } + + return true; + } + } +} \ No newline at end of file diff --git a/src/Tizen.Multimedia/Interop/Interop.Ducking.cs b/src/Tizen.Multimedia/Interop/Interop.Ducking.cs new file mode 100644 index 000000000..7cdc82485 --- /dev/null +++ b/src/Tizen.Multimedia/Interop/Interop.Ducking.cs @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2019 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; + +namespace Tizen.Multimedia +{ + internal static partial class Interop + { + internal static partial class AudioDucking + { + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate void DuckingStateChangedCallback(AudioDuckingHandle ducking, bool isDucked, IntPtr userData); + + [DllImport(Libraries.SoundManager, EntryPoint = "sound_manager_create_stream_ducking")] + internal static extern AudioManagerError Create(AudioStreamType targetType, + DuckingStateChangedCallback callback, IntPtr userData, out AudioDuckingHandle ducking); + + [DllImport(Libraries.SoundManager, EntryPoint = "sound_manager_destroy_stream_ducking")] + internal static extern AudioManagerError Destroy(IntPtr ducking); + + [DllImport(Libraries.SoundManager, EntryPoint = "sound_manager_is_ducked")] + internal static extern AudioManagerError IsDucked(AudioDuckingHandle ducking, out bool isDucked); + + [DllImport(Libraries.SoundManager, EntryPoint = "sound_manager_activate_ducking")] + internal static extern AudioManagerError Activate(AudioDuckingHandle ducking, uint duration, double ratio); + + [DllImport(Libraries.SoundManager, EntryPoint = "sound_manager_deactivate_ducking")] + internal static extern AudioManagerError Deactivate(AudioDuckingHandle ducking); + } + } +} \ No newline at end of file -- 2.34.1