using System; using System.Linq; using System.Runtime.InteropServices; namespace NAudio.Dmo.Effect { internal struct DsFxWavesReverb { public float InGain; public float ReverbMix; public float ReverbTime; public float HighFreqRtRatio; } [ComImport, System.Security.SuppressUnmanagedCodeSecurity, Guid("46858c3a-0dc6-45e3-b760-d4eef16cb325"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] interface IDirectSoundFXWavesReverb { [PreserveSig] int SetAllParameters([In] ref DsFxWavesReverb param); [PreserveSig] int GetAllParameters(out DsFxWavesReverb param); } /// /// DMO Reverb Effect /// public class DmoWavesReverb : IDmoEffector { /// /// DMO Reverb Params /// public struct Params { /// /// DSFX_WAVESREVERB_INGAIN_MIN /// public const float InGainMin = -96.0f; /// /// DSFX_WAVESREVERB_INGAIN_MAX /// public const float InGainMax = 0.0f; /// /// DSFX_WAVESREVERB_INGAIN_DEFAULT /// public const float InGainDefault = 0.0f; /// /// DSFX_WAVESREVERB_REVERBMIX_MIN /// public const float ReverbMixMin = -96.0f; /// /// DSFX_WAVESREVERB_REVERBMIX_MAX /// public const float ReverbMixMax = 0.0f; /// /// DSFX_WAVESREVERB_REVERBMIX_DEFAULT /// public const float ReverbMixDefault = 0.0f; /// /// DSFX_WAVESREVERB_REVERBTIME_MIN /// public const float ReverbTimeMin = 0.001f; /// /// DSFX_WAVESREVERB_REVERBTIME_MAX /// public const float ReverbTimeMax = 3000.0f; /// /// DSFX_WAVESREVERB_REVERBTIME_DEFAULT /// public const float ReverbTimeDefault = 1000.0f; /// /// DSFX_WAVESREVERB_HIGHFREQRTRATIO_MIN /// public const float HighFreqRtRatioMin = 0.001f; /// /// DSFX_WAVESREVERB_HIGHFREQRTRATIO_MAX /// public const float HighFreqRtRatioMax = 0.999f; /// /// DSFX_WAVESREVERB_HIGHFREQRTRATIO_DEFAULT /// public const float HighFreqRtRatioDefault = 0.001f; /// /// Input gain of signal, in decibels (dB). /// public float InGain { get { var param = GetAllParameters(); return param.InGain; } set { var param = GetAllParameters(); param.InGain = Math.Max(Math.Min(InGainMax, value), InGainMin); SetAllParameters(param); } } /// /// Reverb mix, in dB. /// public float ReverbMix { get { var param = GetAllParameters(); return param.ReverbMix; } set { var param = GetAllParameters(); param.ReverbMix = Math.Max(Math.Min(ReverbMixMax, value), ReverbMixMin); SetAllParameters(param); } } /// /// Reverb time, in milliseconds. /// public float ReverbTime { get { var param = GetAllParameters(); return param.ReverbTime; } set { var param = GetAllParameters(); param.ReverbTime = Math.Max(Math.Min(ReverbTimeMax, value), ReverbTimeMin); SetAllParameters(param); } } /// /// High-frequency reverb time ratio. /// public float HighFreqRtRatio { get { var param = GetAllParameters(); return param.HighFreqRtRatio; } set { var param = GetAllParameters(); param.HighFreqRtRatio = Math.Max(Math.Min(HighFreqRtRatioMax, value), HighFreqRtRatioMin); SetAllParameters(param); } } private readonly IDirectSoundFXWavesReverb fxWavesReverb; internal Params(IDirectSoundFXWavesReverb dsFxObject) { fxWavesReverb = dsFxObject; } private void SetAllParameters(DsFxWavesReverb param) { Marshal.ThrowExceptionForHR(fxWavesReverb.SetAllParameters(ref param)); } private DsFxWavesReverb GetAllParameters() { Marshal.ThrowExceptionForHR(fxWavesReverb.GetAllParameters(out var param)); return param; } } private readonly MediaObject mediaObject; private readonly MediaObjectInPlace mediaObjectInPlace; private readonly Params effectParams; /// /// Media Object /// public MediaObject MediaObject => mediaObject; /// /// Media Object InPlace /// public MediaObjectInPlace MediaObjectInPlace => mediaObjectInPlace; /// /// Effect Parameter /// public Params EffectParams => effectParams; /// /// Create new DMO WavesReverb /// public DmoWavesReverb() { var guidWavesReverb = new Guid("87FC0268-9A55-4360-95AA-004A1D9DE26C"); var targetDescriptor = DmoEnumerator.GetAudioEffectNames().First(descriptor => Equals(descriptor.Clsid, guidWavesReverb)); if (targetDescriptor != null) { var mediaComObject = Activator.CreateInstance(Type.GetTypeFromCLSID(targetDescriptor.Clsid)); mediaObject = new MediaObject((IMediaObject) mediaComObject); mediaObjectInPlace = new MediaObjectInPlace((IMediaObjectInPlace) mediaComObject); effectParams = new Params((IDirectSoundFXWavesReverb) mediaComObject); } } /// /// Dispose code /// public void Dispose() { mediaObjectInPlace?.Dispose(); mediaObject?.Dispose(); } } }