diff --git a/src/Tizen.Multimedia/AudioManager/AudioStreamPolicy.cs b/src/Tizen.Multimedia/AudioManager/AudioStreamPolicy.cs
index 9d450f638bb..0d8ada32706 100644
--- a/src/Tizen.Multimedia/AudioManager/AudioStreamPolicy.cs
+++ b/src/Tizen.Multimedia/AudioManager/AudioStreamPolicy.cs
@@ -15,7 +15,9 @@
*/
using System;
+using System.Collections.Generic;
using System.Diagnostics;
+using System.Linq;
namespace Tizen.Multimedia
{
@@ -421,6 +423,104 @@ public bool HasStreamOnDevice(AudioDevice device)
return isOn;
}
+ ///
+ /// Sets the sound effect.
+ ///
+ ///
+ /// If is true, must be or
+ /// or .
+ /// And must not be null.
+ /// If is false, must be or
+ /// or .
+ ///
+ /// See .
+ /// A reference device for sound effect.
+ /// When is true, A reference device is null.
+ /// The current is not supported for sound effect with reference.
+ /// The has already been disposed.
+ /// 12
+ public void SetSoundEffect(SoundEffectInfo info, bool withReference)
+ {
+ if (withReference)
+ {
+ var set = new SoundEffectType[] { SoundEffectType.ReferenceCopy, SoundEffectType.AecSpeex, SoundEffectType.AecWebrtc };
+ if (!set.Contains(info.Type))
+ {
+ Log.Error(Tag, $"Type={info.Type} is not supported for setting with reference.");
+ throw new ArgumentException($"{info.Type} is not supported for setting with reference.");
+ }
+ if (info.ReferenceDevice == null)
+ {
+ throw new ArgumentNullException(nameof(info.ReferenceDevice));
+ }
+
+ Log.Info(Tag, $"{info.ReferenceDevice}");
+
+ Interop.AudioStreamPolicy.SetSoundEffectWithReference(Handle, (SoundEffectWithReferenceNative)info.Type.ToNative(),
+ info.ReferenceDevice.Id).ThrowIfError("Failed to set audio effect with reference");
+ }
+ else
+ {
+ var set = new SoundEffectType[] { SoundEffectType.NoiseSuppression, SoundEffectType.AutoGainControl, SoundEffectType.NsWithAgc };
+ if (!set.Contains(info.Type))
+ {
+ throw new ArgumentException($"{info.Type} is not supported for setting without reference.");
+ }
+
+ Interop.AudioStreamPolicy.SetSoundEffect(Handle, info.Type.ToNative()).
+ ThrowIfError("Failed to set sound effect with reference");
+ }
+ }
+
+ ///
+ /// Gets the sound effect.
+ ///
+ ///
+ /// If is false, of returned value will be null.
+ ///
+ ///
+ /// The sound effect is not set yet.
+ /// - or -
+ /// There's no matched AudioDevice.
+ ///
+ /// Sound effect is not set yet.
+ /// The has already been disposed.
+ /// 12
+ public SoundEffectInfo GetSoundEffect(bool withReference)
+ {
+ AudioManagerError ret = AudioManagerError.None;
+ SoundEffectInfo soundEffectInfo;
+ int deviceId = 0;
+
+ if (withReference)
+ {
+ ret = Interop.AudioStreamPolicy.GetSoundEffectWithReference(Handle, out SoundEffectWithReferenceNative nativeEffect, out deviceId);
+ if (ret == AudioManagerError.InvalidParameter)
+ {
+ throw new InvalidOperationException("There's no sound effect with reference");
+ }
+ ret.ThrowIfError("Failed to get sound effect with reference");
+
+ Log.Info(Tag, $"Device ID : {deviceId}");
+
+ soundEffectInfo = new SoundEffectInfo(nativeEffect.ToPublic(),
+ AudioManager.GetConnectedDevices().Where(d => d.Id == deviceId).Single());
+ }
+ else
+ {
+ ret = Interop.AudioStreamPolicy.GetSoundEffect(Handle, out int nativeEffect);
+ if (ret == AudioManagerError.InvalidParameter)
+ {
+ throw new InvalidOperationException("There's no sound effect");
+ }
+ ret.ThrowIfError("Failed to get sound effect");
+
+ soundEffectInfo = new SoundEffectInfo(((SoundEffectNative)nativeEffect).ToPublic());
+ }
+
+ return soundEffectInfo;
+ }
+
///
/// Releases all resources used by the .
///
diff --git a/src/Tizen.Multimedia/AudioManager/SoundEffect.cs b/src/Tizen.Multimedia/AudioManager/SoundEffect.cs
new file mode 100644
index 00000000000..25f6277eb02
--- /dev/null
+++ b/src/Tizen.Multimedia/AudioManager/SoundEffect.cs
@@ -0,0 +1,236 @@
+/*
+ * Copyright (c) 2024 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
+{
+ ///
+ /// Specifies the sound effect types.
+ ///
+ /// 12
+ public enum SoundEffectType
+ {
+ ///
+ /// Noise suppression for voice call.
+ ///
+ NoiseSuppression,
+
+ ///
+ /// Auto Gain Control for normal capturing.
+ ///
+ AutoGainControl,
+
+ ///
+ /// Noise suppression + Auto Gain Control.
+ ///
+ NsWithAgc,
+
+ ///
+ /// Includes the output sound from the reference device in the recorded audio.
+ ///
+ ///
+ /// This effect should be used with .
+ ///
+ ReferenceCopy = 0x1001,
+
+ ///
+ /// AEC (Acoustic Echo Cancellation) with Speex.
+ ///
+ ///
+ /// This effect should be used with .
+ ///
+ AecSpeex,
+
+ ///
+ /// AEC (Acoustic Echo Cancellation) with WebRTC.
+ ///
+ ///
+ /// This effect should be used with .
+ ///
+ AecWebrtc
+ }
+
+ ///
+ /// Specifies the sound effect information.
+ ///
+ /// 12
+ public struct SoundEffectInfo
+ {
+ ///
+ /// Initializes a new instance of .
+ ///
+ /// The SoundEffectType.
+ /// Invalid input enum type.
+ /// 12
+ public SoundEffectInfo(SoundEffectType type)
+ {
+ ValidationUtil.ValidateEnum(typeof(SoundEffectType), type, nameof(type));
+
+ Type = type;
+ ReferenceDevice = null;
+ }
+
+ ///
+ /// Initializes a new instance of with a reference audio device.
+ ///
+ /// The SoundEffectType.
+ /// The AudioDevice to be refered.
+ /// 12
+ public SoundEffectInfo(SoundEffectType type, AudioDevice device)
+ {
+ ValidationUtil.ValidateEnum(typeof(SoundEffectType), type, nameof(type));
+
+ Type = type;
+ ReferenceDevice = device;
+ }
+
+ ///
+ /// The SoundEffectType.
+ ///
+ /// 12
+ public SoundEffectType Type { get; }
+
+ ///
+ /// The AudioDevice used by the SoundEffect as additional source of audio data.
+ ///
+ /// 12
+ public AudioDevice ReferenceDevice { get; }
+ }
+
+ [Flags]
+ internal enum SoundEffectNative
+ {
+ NoiseSuppression = 1,
+ AutoGainControl = 2
+ }
+
+ internal enum SoundEffectWithReferenceNative
+ {
+ ReferenceCopy = 1,
+ AecSpeex = 2,
+ AecWebrtc = 4
+ }
+
+ internal static class EnumExtensions
+ {
+ private const string Tag = "Tizen.Multimedia.AudioManager";
+
+ internal static int ToNative(this SoundEffectType effect)
+ {
+ int ret = 0;
+
+ /* Native enum values are defined as below:
+ typedef enum {
+ SOUND_EFFECT_REFERENCE_COPY = 0x0001, //< Including reference source
+ SOUND_EFFECT_ACOUSTIC_ECHO_CANCEL_SPEEX = 0x0002, //< Acoustic echo cancel with speex
+ SOUND_EFFECT_ACOUSTIC_ECHO_CANCEL_WEBRTC = 0x0004, //< Acoustic echo cancel with webrtc
+ } sound_effect_method_with_reference_e;
+
+ typedef enum {
+ SOUND_EFFECT_NOISE_SUPPRESSION_VOIP = 0x0001, //< Noise suppression for voice call
+ SOUND_EFFECT_AUTOMATIC_GAIN_CONTROL_CAPTURE = 0x0002, //< Auto Gain Control for normal capturing
+ } sound_effect_method_e;
+ */
+ switch (effect)
+ {
+ case SoundEffectType.NoiseSuppression:
+ ret = 1;
+ break;
+ case SoundEffectType.AutoGainControl:
+ ret = 2;
+ break;
+ case SoundEffectType.NsWithAgc:
+ ret = 3;
+ break;
+ case SoundEffectType.ReferenceCopy:
+ ret = 1;
+ break;
+ case SoundEffectType.AecSpeex:
+ ret = 2;
+ break;
+ case SoundEffectType.AecWebrtc:
+ ret = 4;
+ break;
+ default:
+ Log.Error(Tag, "Invalid sound effect type.");
+ break;
+ }
+
+ return ret;
+ }
+
+ internal static SoundEffectType ToPublic(this SoundEffectNative effect)
+ {
+ SoundEffectType ret = SoundEffectType.NoiseSuppression;
+
+ /* Native enum values are defined as below. And these can be set together.
+ typedef enum {
+ SOUND_EFFECT_NOISE_SUPPRESSION_VOIP = 0x0001, //< Noise suppression for voice call
+ SOUND_EFFECT_AUTOMATIC_GAIN_CONTROL_CAPTURE = 0x0002, //< Auto Gain Control for normal capturing
+ } sound_effect_method_e;
+ */
+ switch (effect)
+ {
+ case SoundEffectNative.NoiseSuppression:
+ ret = SoundEffectType.NoiseSuppression;
+ break;
+ case SoundEffectNative.AutoGainControl:
+ ret = SoundEffectType.AutoGainControl;
+ break;
+ case SoundEffectNative.NoiseSuppression | SoundEffectNative.AutoGainControl:
+ ret = SoundEffectType.NsWithAgc;
+ break;
+ default:
+ Log.Error(Tag, "Invalid sound effect type.");
+ break;
+ }
+
+ return ret;
+ }
+
+ internal static SoundEffectType ToPublic(this SoundEffectWithReferenceNative effect)
+ {
+ SoundEffectType ret = SoundEffectType.ReferenceCopy;
+
+ /* Native enum values are defined as below. And these cannot be set together.
+ typedef enum {
+ SOUND_EFFECT_REFERENCE_COPY = 0x0001, //< Including reference source
+ SOUND_EFFECT_ACOUSTIC_ECHO_CANCEL_SPEEX = 0x0002, //< Acoustic echo cancel with speex
+ SOUND_EFFECT_ACOUSTIC_ECHO_CANCEL_WEBRTC = 0x0004, //< Acoustic echo cancel with webrtc
+ } sound_effect_method_with_reference_e;
+ */
+ switch (effect)
+ {
+ case SoundEffectWithReferenceNative.ReferenceCopy:
+ ret = SoundEffectType.ReferenceCopy;
+ break;
+ case SoundEffectWithReferenceNative.AecSpeex:
+ ret = SoundEffectType.AecSpeex;
+ break;
+ case SoundEffectWithReferenceNative.AecWebrtc:
+ ret = SoundEffectType.AecWebrtc;
+ break;
+ default:
+ Log.Error(Tag, "Invalid sound effect type.");
+ break;
+ }
+
+ return ret;
+ }
+ }
+
+}
diff --git a/src/Tizen.Multimedia/Interop/Interop.StreamPolicy.cs b/src/Tizen.Multimedia/Interop/Interop.StreamPolicy.cs
index ede35629858..1c8f91b97a9 100644
--- a/src/Tizen.Multimedia/Interop/Interop.StreamPolicy.cs
+++ b/src/Tizen.Multimedia/Interop/Interop.StreamPolicy.cs
@@ -91,6 +91,20 @@ internal static extern AudioManagerError AddFocusStateWatchCallback(AudioStreamF
[DllImport(Libraries.SoundManager, EntryPoint = "sound_manager_is_stream_on_device_by_id")]
internal static extern AudioManagerError IsStreamOnDevice(AudioStreamPolicyHandle streamInfo, int deviceId,
out bool isOn);
+
+ [DllImport(Libraries.SoundManager, EntryPoint = "sound_manager_set_effect_method_with_reference_by_id")]
+ internal static extern AudioManagerError SetSoundEffectWithReference(AudioStreamPolicyHandle streamInfo,
+ SoundEffectWithReferenceNative effect, int deviceId);
+
+ [DllImport(Libraries.SoundManager, EntryPoint = "sound_manager_get_effect_method_with_reference")]
+ internal static extern AudioManagerError GetSoundEffectWithReference(AudioStreamPolicyHandle streamInfo,
+ out SoundEffectWithReferenceNative effect, out int deviceId);
+
+ [DllImport(Libraries.SoundManager, EntryPoint = "sound_manager_set_effect_method")]
+ internal static extern AudioManagerError SetSoundEffect(AudioStreamPolicyHandle streamInfo, int effect);
+
+ [DllImport(Libraries.SoundManager, EntryPoint = "sound_manager_get_effect_method")]
+ internal static extern AudioManagerError GetSoundEffect(AudioStreamPolicyHandle streamInfo, out int effect);
}
}
}
\ No newline at end of file