// Copyright (c) 2010-2014 SharpDX - Alexandre Mutel
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
using System;
using SharpDX.Multimedia;
namespace SharpDX.X3DAudio
{
public partial class X3DAudio
{
private X3DAudioHandle handle;
private readonly X3DAudioVersion version;
private readonly X3DAudioCalculateDelegate calculateDelegate;
private delegate void X3DAudioCalculateDelegate(
ref SharpDX.X3DAudio.X3DAudioHandle instance,
SharpDX.X3DAudio.Listener listenerRef,
SharpDX.X3DAudio.Emitter emitterRef,
SharpDX.X3DAudio.CalculateFlags flags,
System.IntPtr dSPSettingsRef);
///
/// Speed of sound in the air.
///
public const float SpeedOfSound = 343.5f;
///
/// Initializes a new instance of the class.
///
/// The speakers config.
/// microsoft.directx_sdk.x3daudio.x3daudioinitialize
/// void X3DAudioInitialize([In] SPEAKER_FLAGS SpeakerChannelMask,[In] float SpeedOfSound,[Out] X3DAUDIOHANDLE* Instance)
/// X3DAudioInitialize
public X3DAudio(Speakers speakers)
: this(speakers, X3DAudioVersion.Default)
{
}
///
/// Initializes a new instance of the class.
///
/// The speakers config.
/// The requestVersion.
/// microsoft.directx_sdk.x3daudio.x3daudioinitialize
/// void X3DAudioInitialize([In] SPEAKER_FLAGS SpeakerChannelMask,[In] float SpeedOfSound,[Out] X3DAUDIOHANDLE* Instance)
/// X3DAudioInitialize
public X3DAudio(Speakers speakers, X3DAudioVersion requestVersion)
: this(speakers, SpeedOfSound, requestVersion)
{
}
///
/// Initializes a new instance of the class.
///
/// The speakers config.
/// The speed of sound.
/// The request requestVersion.
///
/// microsoft.directx_sdk.x3daudio.x3daudioinitialize
///
/// void X3DAudioInitialize([In] SPEAKER_FLAGS SpeakerChannelMask,[In] float SpeedOfSound,[Out] X3DAUDIOHANDLE* Instance)
///
/// X3DAudioInitialize
public X3DAudio(Speakers speakers, float speedOfSound, X3DAudioVersion requestVersion = X3DAudioVersion.Default)
{
var tryVersions = requestVersion == X3DAudioVersion.Default
? new [] {X3DAudioVersion.Version29, X3DAudioVersion.Version28, X3DAudioVersion.Version17}
: new[] {requestVersion};
foreach(var tryVersion in tryVersions)
{
switch(tryVersion)
{
#if !WINDOWS_UWP
case X3DAudioVersion.Version17:
try
{
X3DAudio17.X3DAudioInitialize(speakers, speedOfSound, out handle);
version = X3DAudioVersion.Version17;
calculateDelegate = X3DAudio17.X3DAudioCalculate;
}
catch (DllNotFoundException) {}
break;
#endif
case X3DAudioVersion.Version28:
try
{
X3DAudio28.X3DAudioInitialize(speakers, speedOfSound, out handle);
version = X3DAudioVersion.Version28;
calculateDelegate = X3DAudio28.X3DAudioCalculate;
}
catch (DllNotFoundException) { }
break;
#if WINDOWS_UWP
case X3DAudioVersion.Version29:
try
{
X3DAudio29.X3DAudioInitialize(speakers, speedOfSound, out handle);
version = X3DAudioVersion.Version29;
calculateDelegate = X3DAudio29.X3DAudioCalculate;
}
catch (DllNotFoundException) { }
break;
#endif
}
if (version != X3DAudioVersion.Default)
{
break;
}
}
if(version == X3DAudioVersion.Default)
{
throw new DllNotFoundException(string.Format("Unable to find X3DAudio dlls for the following requested version [{0}]", string.Join(",", tryVersions)));
}
}
///
/// Gets the requestVersion of X3DAudio used.
///
/// The requestVersion.
public X3DAudioVersion Version
{
get { return version; }
}
///
/// Calculates DSP settings for the specified listener and emitter.
///
/// The listener.
/// The emitter.
/// The flags.
/// The source channel count.
/// The destination channel count.
/// DSP settings
/// ee419052
/// void X3DAudioCalculate([In] const X3DAUDIOHANDLE* Instance,[In] const X3DAUDIO_LISTENER* pListener,[In] const X3DAUDIO_EMITTER* pEmitter,[In] X3DAudioCalculateFlags Flags,[In] void* pDSPSettings)
/// X3DAudioCalculate
public DspSettings Calculate(Listener listener, Emitter emitter, CalculateFlags flags, int sourceChannelCount, int destinationChannelCount)
{
var settings = new DspSettings(sourceChannelCount, destinationChannelCount);
Calculate(listener, emitter, flags, settings);
return settings;
}
///
/// Calculates DSP settings for the specified listener and emitter. See remarks.
///
/// The listener.
/// The emitter.
/// The flags.
/// The settings.
/// The source and destination channel count must be set on before calling this method.
/// ee419052
/// void X3DAudioCalculate([In] const X3DAUDIOHANDLE* Instance,[In] const X3DAUDIO_LISTENER* pListener,[In] const X3DAUDIO_EMITTER* pEmitter,[In] X3DAudioCalculateFlags Flags,[In] void* pDSPSettings)
/// X3DAudioCalculate
public unsafe void Calculate(Listener listener, Emitter emitter, CalculateFlags flags, DspSettings settings)
{
if (settings == null) throw new ArgumentNullException("settings");
DspSettings.__Native settingsNative;
settingsNative.SrcChannelCount = settings.SourceChannelCount;
settingsNative.DstChannelCount = settings.DestinationChannelCount;
fixed (void* pMatrix = settings.MatrixCoefficients)
fixed (void* pDelays = settings.DelayTimes)
{
settingsNative.MatrixCoefficientsPointer = (IntPtr)pMatrix;
settingsNative.DelayTimesPointer = (IntPtr)pDelays;
calculateDelegate(ref handle, listener, emitter, flags, new IntPtr(&settingsNative));
}
settings.__MarshalFrom(ref settingsNative);
}
}
}