private void SetEmitterPosition(Vector3 vector3) { DspSettings dspSettings = new DspSettings(_sourceChannels, _destinationChannels); _emitter.Position = vector3; //just calculate the matrix... no doppler or anything else. _x3daudio.X3DAudioCalculate(_listener, _emitter, CalculateFlags.Matrix, dspSettings); _streamingSourceVoice.SetOutputMatrix(_masteringVoice, _sourceChannels, _destinationChannels, dspSettings.MatrixCoefficients); }
/// <summary> /// Calculates DSP settings with respect to 3D parameters. /// </summary> /// <param name="listener">Represents the point of reception.</param> /// <param name="emitter">Represents the sound source.</param> /// <param name="flags">Bitwise combination of <see cref="CalculateFlags" /> specifying which 3D parameters to calculate.</param> /// <param name="settings"> /// Instance of the <see cref="DspSettings" /> class that receives the calculation results. /// </param> public unsafe void X3DAudioCalculate(Listener listener, Emitter emitter, CalculateFlags flags, DspSettings settings) { if (settings == null) { throw new ArgumentNullException("settings"); } if (listener == null) { throw new ArgumentNullException("listener"); } if (emitter == null) { throw new ArgumentNullException("emitter"); } if ((int)flags == 0) { throw new ArgumentOutOfRangeException("flags"); } if (emitter.ChannelCount > 1 && emitter.ChannelAzimuths == null) { throw new ArgumentException("No ChannelAzimuths set for the specified emitter. The ChannelAzimuths property must not be null if the ChannelCount of the emitter is bigger than 1."); } DspSettings.DspSettingsNative nativeSettings = settings.NativeInstance; Listener.ListenerNative nativeListener = listener.NativeInstance; Emitter.EmitterNative nativeEmitter = emitter.NativeInstance; try { #region setup listener //setup listener: Cone listenerCone = listener.Cone.HasValue ? listener.Cone.Value : default(Cone); IntPtr listenerConePtr = listener.Cone.HasValue ? (IntPtr)(&listenerCone) : IntPtr.Zero; nativeListener.ConePtr = listenerConePtr; #endregion #region setup emitter //setup emitter IntPtr channelAzimuthsPtr = IntPtr.Zero; if (emitter.ChannelAzimuths != null && emitter.ChannelAzimuths.Length > 0 && emitter.ChannelCount > 0) { const int sizeOfFloat = sizeof(float); int channelAzimuthsSize = sizeOfFloat * Math.Min(emitter.ChannelCount, emitter.ChannelAzimuths.Length); channelAzimuthsPtr = Marshal.AllocHGlobal(channelAzimuthsSize); ILUtils.WriteToMemory(channelAzimuthsPtr, emitter.ChannelAzimuths, 0, channelAzimuthsSize / sizeOfFloat); } Cone emitterCone = emitter.Cone.HasValue ? emitter.Cone.Value : default(Cone); IntPtr emitterConePtr = emitter.Cone.HasValue ? (IntPtr)(&emitterCone) : IntPtr.Zero; nativeEmitter.ChannelAzimuthsPtr = channelAzimuthsPtr; nativeEmitter.ConePtr = emitterConePtr; nativeEmitter.LFECurvePtr = CurveNative.AllocMemoryAndBuildCurve(emitter.LowFrequencyEffectCurve); nativeEmitter.LPFDirectCurvePtr = CurveNative.AllocMemoryAndBuildCurve(emitter.LowPassFilterDirectCurve); nativeEmitter.LPFReverbCurvePtr = CurveNative.AllocMemoryAndBuildCurve(emitter.LowPassFilterReverbCurve); nativeEmitter.ReverbCurvePtr = CurveNative.AllocMemoryAndBuildCurve(emitter.ReverbCurve); nativeEmitter.VolumeCurvePtr = CurveNative.AllocMemoryAndBuildCurve(emitter.VolumeCurve); #endregion #region setup settings //setup settings fixed(void *pmc = settings.MatrixCoefficients, pdt = settings.DelayTimes) { nativeSettings.MatrixCoefficientsPtr = new IntPtr(pmc); nativeSettings.DelayTimesPtr = new IntPtr(pdt); #endregion fixed(void *p = &_handle) { X3DAudioCalculate(new IntPtr(p), (IntPtr)(&nativeListener), (IntPtr)(&nativeEmitter), flags, new IntPtr(&nativeSettings)); } settings.NativeInstance = nativeSettings; } } finally { nativeEmitter.FreeMemory(); } }