/* FAudio# - C# Wrapper for FAudio * * Copyright (c) 2020 Ethan Lee. * * This software is provided 'as-is', without any express or implied warranty. * In no event will the authors be held liable for any damages arising from * the use of this software. * * Permission is granted to anyone to use this software for any purpose, * including commercial applications, and to alter it and redistribute it * freely, subject to the following restrictions: * * 1. The origin of this software must not be misrepresented; you must not * claim that you wrote the original software. If you use this software in a * product, an acknowledgment in the product documentation would be * appreciated but is not required. * * 2. Altered source versions must be plainly marked as such, and must not be * misrepresented as being the original software. * * 3. This notice may not be removed or altered from any source distribution. * * Ethan "flibitijibibo" Lee * */ #region Using Statements using System; using System.Runtime.InteropServices; using System.Text; #endregion public static class FAudio { #region Native Library Name const string nativeLibName = "FAudio"; #endregion #region UTF8 Marshaling /* Used for stack allocated string marshaling. */ private static int Utf8Size(string str) { return (str.Length * 4) + 1; } private static unsafe byte* Utf8Encode(string str, byte* buffer, int bufferSize) { fixed (char* strPtr = str) { Encoding.UTF8.GetBytes(strPtr, str.Length + 1, buffer, bufferSize); } return buffer; } /* Used for heap allocated string marshaling * Returned byte* must be free'd with FreeHGlobal. */ private static unsafe byte* Utf8Encode(string str) { int bufferSize = (str.Length * 4) + 1; byte* buffer = (byte*)Marshal.AllocHGlobal(bufferSize); fixed (char* strPtr = str) { Encoding.UTF8.GetBytes(strPtr, str.Length + 1, buffer, bufferSize); } return buffer; } #endregion #region FAudio API /* Version */ public const uint FAUDIO_TARGET_VERSION = 8; public const uint FAUDIO_ABI_VERSION = 0; public const uint FAUDIO_MAJOR_VERSION = 20; public const uint FAUDIO_MINOR_VERSION = 6; public const uint FAUDIO_PATCH_VERSION = 0; public const uint FAUDIO_COMPILED_VERSION = ( (FAUDIO_ABI_VERSION * 100 * 100 * 100) + (FAUDIO_MAJOR_VERSION * 100 * 100) + (FAUDIO_MINOR_VERSION * 100) + (FAUDIO_PATCH_VERSION) ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FAudioLinkedVersion(); /* Enumerations */ [Flags] public enum FAudioDeviceRole { FAudioNotDefaultDevice = 0x0, FAudioDefaultConsoleDevice = 0x1, FAudioDefaultMultimediaDevice = 0x2, FAudioDefaultCommunicationsDevice = 0x4, FAudioDefaultGameDevice = 0x8, FAudioGlobalDefaultDevice = 0xF, FAudioInvalidDeviceRole = ~FAudioGlobalDefaultDevice } public enum FAudioFilterType { FAudioLowPassFilter, FAudioBandPassFilter, FAudioHighPassFilter, FAudioNotchFilter } /* FIXME: The original enum violates ISO C and is platform specific anyway... */ public const uint FAUDIO_DEFAULT_PROCESSOR = 0xFFFFFFFF; /* Structures */ [StructLayout(LayoutKind.Sequential, Pack = 1)] public unsafe struct FAudioGUID { public uint Data1; public ushort Data2; public ushort Data3; public fixed byte Data4[8]; } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct FAudioWaveFormatEx { public ushort wFormatTag; public ushort nChannels; public uint nSamplesPerSec; public uint nAvgBytesPerSec; public ushort nBlockAlign; public ushort wBitsPerSample; public ushort cbSize; } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct FAudioWaveFormatExtensible { public FAudioWaveFormatEx Format; public ushort Samples; /* FIXME: union! */ public uint dwChannelMask; public FAudioGUID SubFormat; } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct FAudioADPCMCoefSet { public short iCoef1; public short iCoef2; } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct FAudioADPCMWaveFormat { public FAudioWaveFormatEx wfx; public ushort wSamplesPerBlock; public ushort wNumCoef; public IntPtr aCoef; /* FAudioADPCMCoefSet[] */ /* MSADPCM has 7 coefficient pairs: * { * { 256, 0 }, * { 512, -256 }, * { 0, 0 }, * { 192, 64 }, * { 240, 0 }, * { 460, -208 }, * { 392, -232 } * } */ } [StructLayout(LayoutKind.Sequential, Pack = 1)] public unsafe struct FAudioDeviceDetails { public fixed short DeviceID[256]; /* Win32 wchar_t */ public fixed short DisplayName[256]; /* Win32 wchar_t */ public FAudioDeviceRole Role; public FAudioWaveFormatExtensible OutputFormat; } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct FAudioVoiceDetails { public uint CreationFlags; public uint ActiveFlags; public uint InputChannels; public uint InputSampleRate; } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct FAudioSendDescriptor { public uint Flags; public IntPtr pOutputVoice; /* FAudioVoice* */ } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct FAudioVoiceSends { public uint SendCount; public IntPtr pSends; /* FAudioSendDescriptor* */ } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct FAudioEffectDescriptor { public IntPtr pEffect; /* void* */ public int InitialState; public uint OutputChannels; } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct FAudioEffectChain { public uint EffectCount; public IntPtr pEffectDescriptors; /* FAudioEffectDescriptor* */ } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct FAudioFilterParameters { public FAudioFilterType Type; public float Frequency; public float OneOverQ; } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct FAudioBuffer { public uint Flags; public uint AudioBytes; public IntPtr pAudioData; /* const uint8_t* */ public uint PlayBegin; public uint PlayLength; public uint LoopBegin; public uint LoopLength; public uint LoopCount; public IntPtr pContext; /* void* */ } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct FAudioBufferWMA { public IntPtr pDecodedPacketCumulativeBytes; /* const uint32_t* */ public uint PacketCount; } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct FAudioVoiceState { public IntPtr pCurrentBufferContext; /* void* */ public uint BuffersQueued; public ulong SamplesPlayed; } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct FAudioPerformanceData { public ulong AudioCyclesSinceLastQuery; public ulong TotalCyclesSinceLastQuery; public uint MinimumCyclesPerQuantum; public uint MaximumCyclesPerQuantum; public uint MemoryUsageInBytes; public uint CurrentLatencyInSamples; public uint GlitchesSinceEngineStarted; public uint ActiveSourceVoiceCount; public uint TotalSourceVoiceCount; public uint ActiveSubmixVoiceCount; public uint ActiveResamplerCount; public uint ActiveMatrixMixCount; public uint ActiveXmaSourceVoices; public uint ActiveXmaStreams; } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct FAudioDebugConfiguration { public uint TraceMask; public uint BreakMask; public int LogThreadID; public int LogFileline; public int LogFunctionName; public int LogTiming; } /* Constants */ public const uint FAUDIO_MAX_BUFFER_BYTES = 0x80000000; public const uint FAUDIO_MAX_QUEUED_BUFFERS = 64; public const uint FAUDIO_MAX_AUDIO_CHANNELS = 64; public const uint FAUDIO_MIN_SAMPLE_RATE = 1000; public const uint FAUDIO_MAX_SAMPLE_RATE = 200000; public const float FAUDIO_MAX_VOLUME_LEVEL = 16777216.0f; public const float FAUDIO_MIN_FREQ_RATIO = (1.0f / 1024.0f); public const float FAUDIO_MAX_FREQ_RATIO = 1024.0f; public const float FAUDIO_DEFAULT_FREQ_RATIO = 2.0f; public const float FAUDIO_MAX_FILTER_ONEOVERQ = 1.5f; public const float FAUDIO_MAX_FILTER_FREQUENCY = 1.0f; public const uint FAUDIO_MAX_LOOP_COUNT = 254; public const uint FAUDIO_COMMIT_NOW = 0; public const uint FAUDIO_COMMIT_ALL = 0; public const uint FAUDIO_INVALID_OPSET = unchecked((uint) -1); public const uint FAUDIO_NO_LOOP_REGION = 0; public const uint FAUDIO_LOOP_INFINITE = 255; public const uint FAUDIO_DEFAULT_CHANNELS = 0; public const uint FAUDIO_DEFAULT_SAMPLERATE = 0; public const uint FAUDIO_DEBUG_ENGINE = 0x0001; public const uint FAUDIO_VOICE_NOPITCH = 0x0002; public const uint FAUDIO_VOICE_NOSRC = 0x0004; public const uint FAUDIO_VOICE_USEFILTER = 0x0008; public const uint FAUDIO_VOICE_MUSIC = 0x0010; public const uint FAUDIO_PLAY_TAILS = 0x0020; public const uint FAUDIO_END_OF_STREAM = 0x0040; public const uint FAUDIO_SEND_USEFILTER = 0x0080; public const uint FAUDIO_VOICE_NOSAMPLESPLAYED = 0x0100; public const uint FAUDIO_1024_QUANTUM = 0x8000; public const FAudioFilterType FAUDIO_DEFAULT_FILTER_TYPE = FAudioFilterType.FAudioLowPassFilter; public const float FAUDIO_DEFAULT_FILTER_FREQUENCY = FAUDIO_MAX_FILTER_FREQUENCY; public const float FAUDIO_DEFAULT_FILTER_ONEOVERQ = 1.0f; public const ushort FAUDIO_LOG_ERRORS = 0x0001; public const ushort FAUDIO_LOG_WARNINGS = 0x0002; public const ushort FAUDIO_LOG_INFO = 0x0004; public const ushort FAUDIO_LOG_DETAIL = 0x0008; public const ushort FAUDIO_LOG_API_CALLS = 0x0010; public const ushort FAUDIO_LOG_FUNC_CALLS = 0x0020; public const ushort FAUDIO_LOG_TIMING = 0x0040; public const ushort FAUDIO_LOG_LOCKS = 0x0080; public const ushort FAUDIO_LOG_MEMORY = 0x0100; public const ushort FAUDIO_LOG_STREAMING = 0x1000; /* FAudio Interface */ /* FIXME: Do we want to actually reproduce the COM stuff or what...? -flibit */ [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FAudioCreate( out IntPtr ppFAudio, /* FAudio** */ uint Flags, uint XAudio2Processor /* FAudioProcessor */ ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FAudio_AddRef( IntPtr audio /* FAudio */ ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FAudio_Release( IntPtr audio /* FAudio* */ ); /* FIXME: QueryInterface? Or just ignore COM garbage... -flibit */ [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FAudio_GetDeviceCount( IntPtr audio, /* FAudio* */ out uint pCount ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FAudio_GetDeviceDetails( IntPtr audio, /* FAudio* */ uint Index, out FAudioDeviceDetails pDeviceDetails ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FAudio_Initialize( IntPtr audio, /* FAudio* */ uint Flags, uint XAudio2Processor /* FAudioProcessor */ ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FAudio_RegisterForCallbacks( IntPtr audio, /* FAudio* */ IntPtr pCallback /* FAudioEngineCallback* */ ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern void FAudio_UnregisterForCallbacks( IntPtr audio, /* FAudio* */ IntPtr pCallback /* FAudioEngineCallback* */ ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FAudio_CreateSourceVoice( IntPtr audio, /* FAudio* */ out IntPtr ppSourceVoice, /* FAudioSourceVoice** */ ref FAudioWaveFormatEx pSourceFormat, uint Flags, float MaxFrequencyRatio, IntPtr pCallback, /* FAudioVoiceCallback* */ IntPtr pSendList, /* FAudioVoiceSends* */ IntPtr pEffectChain /* FAudioEffectChain* */ ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FAudio_CreateSubmixVoice( IntPtr audio, /* FAudio* */ out IntPtr ppSubmixVoice, /* FAudioSubmixVoice** */ uint InputChannels, uint InputSampleRate, uint Flags, uint ProcessingStage, IntPtr pSendList, /* FAudioVoiceSends* */ IntPtr pEffectChain /* FAudioEffectChain* */ ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FAudio_CreateMasteringVoice( IntPtr audio, /* FAudio* */ out IntPtr ppMasteringVoice, /* FAudioMasteringVoice** */ uint InputChannels, uint InputSampleRate, uint Flags, uint DeviceIndex, IntPtr pEffectChain /* FAudioEffectChain* */ ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FAudio_StartEngine( IntPtr audio /* FAudio* */ ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern void FAudio_StopEngine( IntPtr audio /* FAudio* */ ); [DllImport(nativeLibName, EntryPoint = "FAudio_CommitOperationSet", CallingConvention = CallingConvention.Cdecl)] public static extern uint FAudio_CommitChanges( IntPtr audio /* FAudio* */, uint OperationSet ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern void FAudio_GetPerformanceData( IntPtr audio, /* FAudio* */ out FAudioPerformanceData pPerfData ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern void FAudio_SetDebugConfiguration( IntPtr audio, /* FAudio* */ ref FAudioDebugConfiguration pDebugConfiguration, IntPtr pReserved /* void* */ ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern void FAudio_GetProcessingQuantum( IntPtr audio, /* FAudio */ out uint quantumNumerator, out uint quantumDenominator ); /* FAudioVoice Interface */ [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern void FAudioVoice_GetVoiceDetails( IntPtr voice, /* FAudioVoice* */ out FAudioVoiceDetails pVoiceDetails ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FAudioVoice_SetOutputVoices( IntPtr voice, /* FAudioVoice* */ ref FAudioVoiceSends pSendList ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FAudioVoice_SetEffectChain( IntPtr voice, /* FAudioVoice* */ ref FAudioEffectChain pEffectChain ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FAudioVoice_EnableEffect( IntPtr voice, /* FAudioVoice* */ uint EffectIndex, uint OperationSet ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FAudioVoice_DisableEffect( IntPtr voice, /* FAudioVoice* */ uint EffectIndex, uint OperationSet ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern void FAudioVoice_GetEffectState( IntPtr voice, /* FAudioVoice* */ uint EffectIndex, out int pEnabled ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FAudioVoice_SetEffectParameters( IntPtr voice, /* FAudioVoice* */ uint EffectIndex, IntPtr pParameters, /* const void* */ uint ParametersByteSize, uint OperationSet ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FAudioVoice_GetEffectParameters( IntPtr voice, /* FAudioVoice* */ uint EffectIndex, IntPtr pParameters, /* void* */ uint ParametersByteSize ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FAudioVoice_SetFilterParameters( IntPtr voice, /* FAudioVoice* */ ref FAudioFilterParameters pParameters, uint OperationSet ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern void FAudioVoice_GetFilterParameters( IntPtr voice, /* FAudioVoice* */ out FAudioFilterParameters pParameters ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FAudioVoice_SetOutputFilterParameters( IntPtr voice, /* FAudioVoice* */ IntPtr pDestinationVoice, /* FAudioVoice */ ref FAudioFilterParameters pParameters, uint OperationSet ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern void FAudioVoice_GetOutputFilterParameters( IntPtr voice, /* FAudioVoice* */ IntPtr pDestinationVoice, /* FAudioVoice */ out FAudioFilterParameters pParameters ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FAudioVoice_SetVolume( IntPtr voice, /* FAudioVoice* */ float Volume, uint OperationSet ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern void FAudioVoice_GetVolume( IntPtr voice, /* FAudioVoice* */ out float pVolume ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FAudioVoice_SetChannelVolumes( IntPtr voice, /* FAudioVoice* */ uint Channels, float[] pVolumes, uint OperationSet ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern void FAudioVoice_GetChannelVolumes( IntPtr voice, /* FAudioVoice* */ uint Channels, float[] pVolumes ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FAudioVoice_SetOutputMatrix( IntPtr voice, /* FAudioVoice* */ IntPtr pDestinationVoice, /* FAudioVoice* */ uint SourceChannels, uint DestinationChannels, IntPtr pLevelMatrix, /* float* */ uint OperationSet ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern void FAudioVoice_GetOutputMatrix( IntPtr voice, /* FAudioVoice* */ IntPtr pDestinationVoice, /* FAudioVoice* */ uint SourceChannels, uint DestinationChannels, float[] pLevelMatrix ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern void FAudioVoice_DestroyVoice( IntPtr voice /* FAudioVoice* */ ); /* FAudioSourceVoice Interface */ [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FAudioSourceVoice_Start( IntPtr voice, /* FAudioSourceVoice* */ uint Flags, uint OperationSet ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FAudioSourceVoice_Stop( IntPtr voice, /* FAudioSourceVoice* */ uint Flags, uint OperationSet ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FAudioSourceVoice_SubmitSourceBuffer( IntPtr voice, /* FAudioSourceVoice* */ ref FAudioBuffer pBuffer, IntPtr pBufferWMA /* const FAudioBufferWMA* */ ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FAudioSourceVoice_FlushSourceBuffers( IntPtr voice /* FAudioSourceVoice* */ ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FAudioSourceVoice_Discontinuity( IntPtr voice /* FAudioSourceVoice* */ ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FAudioSourceVoice_ExitLoop( IntPtr voice, /* FAudioSourceVoice* */ uint OperationSet ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern void FAudioSourceVoice_GetState( IntPtr voice, /* FAudioSourceVoice* */ out FAudioVoiceState pVoiceState, uint Flags ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FAudioSourceVoice_SetFrequencyRatio( IntPtr voice, /* FAudioSourceVoice* */ float Ratio, uint OperationSet ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern void FAudioSourceVoice_GetFrequencyRatio( IntPtr voice, /* FAudioSourceVoice* */ out float pRatio ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FAudioSourceVoice_SetSourceSampleRate( IntPtr voice, /* FAudioSourceVoice* */ uint NewSourceSampleRate ); /* FAudioEngineCallback Interface */ [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate void OnCriticalErrorFunc( IntPtr engineCallback, /* FAudioEngineCallback* */ uint Error ); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate void OnProcessingPassEndFunc( IntPtr engineCallback /* FAudioEngineCallback* */ ); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate void OnProcessingPassStartFunc( IntPtr engineCallback /* FAudioEngineCallback* */ ); [StructLayout(LayoutKind.Sequential)] public struct FAudioEngineCallback { public IntPtr OnCriticalError; /* OnCriticalErrorFunc */ public IntPtr OnProcessingPassEnd; /* OnProcessingPassEndFunc */ public IntPtr OnProcessingPassStart; /* OnProcessingPassStartFunc */ } /* FAudioVoiceCallback Interface */ [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate void OnBufferEndFunc( IntPtr voiceCallback, /* FAudioVoiceCallback* */ IntPtr pBufferContext /* void* */ ); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate void OnBufferStartFunc( IntPtr voiceCallback, /* FAudioVoiceCallback* */ IntPtr pBufferContext /* void* */ ); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate void OnLoopEndFunc( IntPtr voiceCallback, /* FAudioVoiceCallback* */ IntPtr pBufferContext /* void* */ ); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate void OnStreamEndFunc( IntPtr voiceCallback /* FAudioVoiceCallback* */ ); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate void OnVoiceErrorFunc( IntPtr voiceCallback, /* FAudioVoiceCallback* */ IntPtr pBufferContext, /* void* */ uint Error ); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate void OnVoiceProcessingPassEndFunc( IntPtr voiceCallback /* FAudioVoiceCallback* */ ); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate void OnVoiceProcessingPassStartFunc( IntPtr voiceCallback, /* FAudioVoiceCallback* */ uint BytesRequired ); [StructLayout(LayoutKind.Sequential)] public struct FAudioVoiceCallback { public IntPtr OnBufferEnd; /* OnBufferEndFunc */ public IntPtr OnBufferStart; /* OnBufferStartFunc */ public IntPtr OnLoopEnd; /* OnLoopEndFunc */ public IntPtr OnStreamEnd; /* OnStreamEndFunc */ public IntPtr OnVoiceError; /* OnVoiceErrorFunc */ public IntPtr OnVoiceProcessingPassEnd; /* OnVoiceProcessingPassEndFunc */ public IntPtr OnVoiceProcessingPassStart; /* OnVoiceProcessingPassStartFunc */ } #endregion #region FAudioFX API /* TODO */ /* Structures */ [StructLayout(LayoutKind.Sequential)] public struct FAudioFXReverbParameters { public float WetDryMix; public uint ReflectionsDelay; public byte ReverbDelay; public byte RearDelay; public byte PositionLeft; public byte PositionRight; public byte PositionMatrixLeft; public byte PositionMatrixRight; public byte EarlyDiffusion; public byte LateDiffusion; public byte LowEQGain; public byte LowEQCutoff; public byte HighEQGain; public byte HighEQCutoff; public float RoomFilterFreq; public float RoomFilterMain; public float RoomFilterHF; public float ReflectionsGain; public float ReverbGain; public float DecayTime; public float Density; public float RoomSize; } /* Constants */ public const float FAUDIOFX_REVERB_DEFAULT_WET_DRY_MIX = 100.0f; public const uint FAUDIOFX_REVERB_DEFAULT_REFLECTIONS_DELAY = 5; public const byte FAUDIOFX_REVERB_DEFAULT_REVERB_DELAY = 5; public const byte FAUDIOFX_REVERB_DEFAULT_REAR_DELAY = 5; public const byte FAUDIOFX_REVERB_DEFAULT_POSITION = 6; public const byte FAUDIOFX_REVERB_DEFAULT_POSITION_MATRIX = 27; public const byte FAUDIOFX_REVERB_DEFAULT_EARLY_DIFFUSION = 8; public const byte FAUDIOFX_REVERB_DEFAULT_LATE_DIFFUSION = 8; public const byte FAUDIOFX_REVERB_DEFAULT_LOW_EQ_GAIN = 8; public const byte FAUDIOFX_REVERB_DEFAULT_LOW_EQ_CUTOFF = 4; public const byte FAUDIOFX_REVERB_DEFAULT_HIGH_EQ_GAIN = 8; public const byte FAUDIOFX_REVERB_DEFAULT_HIGH_EQ_CUTOFF = 4; public const float FAUDIOFX_REVERB_DEFAULT_ROOM_FILTER_FREQ = 5000.0f; public const float FAUDIOFX_REVERB_DEFAULT_ROOM_FILTER_MAIN = 0.0f; public const float FAUDIOFX_REVERB_DEFAULT_ROOM_FILTER_HF = 0.0f; public const float FAUDIOFX_REVERB_DEFAULT_REFLECTIONS_GAIN = 0.0f; public const float FAUDIOFX_REVERB_DEFAULT_REVERB_GAIN = 0.0f; public const float FAUDIOFX_REVERB_DEFAULT_DECAY_TIME = 1.0f; public const float FAUDIOFX_REVERB_DEFAULT_DENSITY = 100.0f; public const float FAUDIOFX_REVERB_DEFAULT_ROOM_SIZE = 100.0f; /* Functions */ [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FAudioCreateReverb(out IntPtr ppApo, uint Flags); #endregion #region FAPO API /* TODO */ #endregion #region FAPOBase API /* TODO */ [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FAPOBase_Release(IntPtr fapo); #endregion #region FACT API /* Delegates */ [UnmanagedFunctionPointer(CallingConvention.StdCall)] public delegate int FACTReadFileCallback( IntPtr hFile, IntPtr buffer, uint nNumberOfBytesToRead, IntPtr lpOverlapped /* FACTOverlapped* */ ); [UnmanagedFunctionPointer(CallingConvention.StdCall)] public delegate int FACTGetOverlappedResultCallback( IntPtr hFile, IntPtr lpOverlapped, /* FACTOverlapped* */ out uint lpNumberOfBytesTransferred, int bWait ); [UnmanagedFunctionPointer(CallingConvention.StdCall)] public delegate void FACTNotificationCallback( IntPtr pNotification /* const FACTNotification* */ ); /* Enumerations */ public enum FACTWaveBankSegIdx { FACT_WAVEBANK_SEGIDX_BANKDATA = 0, FACT_WAVEBANK_SEGIDX_ENTRYMETADATA, FACT_WAVEBANK_SEGIDX_SEEKTABLES, FACT_WAVEBANK_SEGIDX_ENTRYNAMES, FACT_WAVEBANK_SEGIDX_ENTRYWAVEDATA, FACT_WAVEBANK_SEGIDX_COUNT } /* Structures */ [StructLayout(LayoutKind.Sequential)] public unsafe struct FACTRendererDetails { public fixed short rendererID[0xFF]; // Win32 wchar_t public fixed short displayName[0xFF]; // Win32 wchar_t public int defaultDevice; } [StructLayout(LayoutKind.Sequential)] public struct FACTOverlapped { public IntPtr Internal; /* ULONG_PTR */ public IntPtr InternalHigh; /* ULONG_PTR */ public uint Offset; /* FIXME: union! */ public uint OffsetHigh; /* FIXME: union! */ public IntPtr hEvent; } [StructLayout(LayoutKind.Sequential)] public struct FACTFileIOCallbacks { public IntPtr readFileCallback; /* FACTReadCallback */ public IntPtr getOverlappedResultCallback; /* FACTGetOverlappedResultCallback */ } [StructLayout(LayoutKind.Sequential)] public struct FACTRuntimeParameters { public uint lookAheadTime; public IntPtr pGlobalSettingsBuffer; public uint globalSettingsBufferSize; public uint globalSettingsFlags; public uint globalSettingsAllocAttributes; public FACTFileIOCallbacks fileIOCallbacks; public IntPtr fnNotificationCallback; /* FACTNotificationCallback */ public IntPtr pRendererID; /* Win32 wchar_t* */ public IntPtr pXAudio2; public IntPtr pMasteringVoice; } [StructLayout(LayoutKind.Sequential)] public struct FACTStreamingParameters { public IntPtr file; public uint offset; public uint flags; public ushort packetSize; } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct FACTWaveBankRegion { public uint dwOffset; public uint dwLength; } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct FACTWaveBankSampleRegion { public uint dwStartSample; public uint dwTotalSamples; } /* TODO [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct FACTWaveBankHeader { public uint dwSignature; public uint dwVersion; public uint dwHeaderVersion; public fixed FACTWaveBankRegion Segments[FACT_WAVEBANK_SEGIDX_COUNT]; } */ [StructLayout(LayoutKind.Sequential, Pack = 1)] /* FIXME: union! */ public struct FACTWaveBankMiniWaveFormat { /*struct { public uint wFormatTag : 2; public uint nChannels : 3; public uint nSamplesPerSec : 18; public uint wBlockAlign : 8; public uint wBitsPerSample : 1; };*/ public uint dwValue; } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct FACTWaveBankEntry { public uint dwFlagsAndDuration; /* FIXME: union! */ public FACTWaveBankMiniWaveFormat Format; public FACTWaveBankRegion PlayRegion; public FACTWaveBankSampleRegion LoopRegion; } /* TODO [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct FACTWaveBankEntryCompact { public uint dwOffset : 21; public uint dwLengthDeviation : 11; } */ [StructLayout(LayoutKind.Sequential, Pack = 1)] public unsafe struct FACTWaveBankData { public uint dwFlags; public uint dwEntryCount; public fixed char szBankName[64]; public uint dwEntryMetaDataElementSize; public uint dwEntryNameElementSize; public uint dwAlignment; public FACTWaveBankMiniWaveFormat CompactFormat; public ulong BuildTime; } [StructLayout(LayoutKind.Sequential)] public unsafe struct FACTWaveProperties { public fixed byte friendlyName[64]; public FACTWaveBankMiniWaveFormat format; public uint durationInSamples; public FACTWaveBankSampleRegion loopRegion; public int streaming; } [StructLayout(LayoutKind.Sequential)] public struct FACTWaveInstanceProperties { public FACTWaveProperties properties; public int backgroundMusic; } [StructLayout(LayoutKind.Sequential)] public unsafe struct FACTCueProperties { public fixed char friendlyName[0xFF]; public int interactive; public ushort iaVariableIndex; public ushort numVariations; public byte maxInstances; public byte currentInstances; } [StructLayout(LayoutKind.Sequential)] public struct FACTTrackProperties { public uint duration; public ushort numVariations; public byte numChannels; public ushort waveVariation; public byte loopCount; } [StructLayout(LayoutKind.Sequential)] public struct FACTVariationProperties { public ushort index; public byte weight; public float iaVariableMin; public float iaVariableMax; public int linger; } [StructLayout(LayoutKind.Sequential)] public struct FACTSoundProperties { public ushort category; public byte priority; public short pitch; public float volume; public ushort numTracks; public FACTTrackProperties arrTrackProperties; /* FIXME: [1] */ } [StructLayout(LayoutKind.Sequential)] public struct FACTSoundVariationProperties { public FACTVariationProperties variationProperties; public FACTSoundProperties soundProperties; } [StructLayout(LayoutKind.Sequential)] public struct FACTCueInstanceProperties { public uint allocAttributes; public FACTCueProperties cueProperties; public FACTSoundVariationProperties activeVariationProperties; } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct FACTNotificationDescription { public byte type; public byte flags; public IntPtr pSoundBank; /* FACTSoundBank* */ public IntPtr pWaveBank; /* FACTWaveBank* */ public IntPtr pCue; /* FACTCue* */ public IntPtr pWave; /* FACTWave* */ public ushort cueIndex; public ushort waveIndex; public IntPtr pvContext; } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct FACTNotificationCue { public ushort cueIndex; public IntPtr pSoundBank; /* FACTSoundBank* */ public IntPtr pCue; /* FACTCue* */ } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct FACTNotificationMarker { public ushort cueIndex; public IntPtr pSoundBank; /* FACTSoundBank* */ public IntPtr pCue; /* FACTCue* */ public uint marker; } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct FACTNotificationSoundBank { public IntPtr pSoundBank; /* FACTSoundBank* */ } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct FACTNotificationWaveBank { public IntPtr pWaveBank; /* FACTWaveBank* */ } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct FACTNotificationVariable { public ushort cueIndex; public IntPtr pSoundBank; /* FACTSoundBank* */ public IntPtr pCue; /* FACTCue* */ public ushort variableIndex; public float variableValue; public int local; } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct FACTNotificationGUI { public uint reserved; } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct FACTNotificationWave { public IntPtr pWaveBank; /* FACTWaveBank* */ public ushort waveIndex; public ushort cueIndex; public IntPtr pSoundBank; /* FACTSoundBank* */ public IntPtr pCue; /* FACTCue* */ public IntPtr pWave; /* FACTWave* */ } [StructLayout(LayoutKind.Explicit)] public struct FACTNotification_union { [FieldOffset(0)] public FACTNotificationCue cue; [FieldOffset(0)] public FACTNotificationMarker marker; [FieldOffset(0)] public FACTNotificationSoundBank soundBank; [FieldOffset(0)] public FACTNotificationWaveBank waveBank; [FieldOffset(0)] public FACTNotificationVariable variable; [FieldOffset(0)] public FACTNotificationGUI gui; [FieldOffset(0)] public FACTNotificationWave wave; } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct FACTNotification { public byte type; public int timeStamp; public IntPtr pvContext; public FACTNotification_union anon; } /* Constants */ public const int FACT_CONTENT_VERSION = 46; public const uint FACT_FLAG_MANAGEDATA = 0x00000001; public const uint FACT_FLAG_STOP_RELEASE = 0x00000000; public const uint FACT_FLAG_STOP_IMMEDIATE = 0x00000001; public const uint FACT_FLAG_BACKGROUND_MUSIC = 0x00000002; public const uint FACT_FLAG_UNITS_MS = 0x00000004; public const uint FACT_FLAG_UNITS_SAMPLES = 0x00000008; public const uint FACT_STATE_CREATED = 0x00000001; public const uint FACT_STATE_PREPARING = 0x00000002; public const uint FACT_STATE_PREPARED = 0x00000004; public const uint FACT_STATE_PLAYING = 0x00000008; public const uint FACT_STATE_STOPPING = 0x00000010; public const uint FACT_STATE_STOPPED = 0x00000020; public const uint FACT_STATE_PAUSED = 0x00000040; public const uint FACT_STATE_INUSE = 0x00000080; public const uint FACT_STATE_PREPAREFAILED = 0x80000000; public const short FACTPITCH_MIN = -1200; public const short FACTPITCH_MAX = 1200; public const short FACTPITCH_MIN_TOTAL = -2400; public const short FACTPITCH_MAX_TOTAL = 2400; public const float FACTVOLUME_MIN = 0.0f; public const float FACTVOLUME_MAX = 16777216.0f; public const ushort FACTINDEX_INVALID = 0xFFFF; public const ushort FACTVARIABLEINDEX_INVALID = 0xFFFF; public const ushort FACTCATEGORY_INVALID = 0xFFFF; public const uint FACT_ENGINE_LOOKAHEAD_DEFAULT = 250; public const byte FACTNOTIFICATIONTYPE_CUEPREPARED = 1; public const byte FACTNOTIFICATIONTYPE_CUEPLAY = 2; public const byte FACTNOTIFICATIONTYPE_CUESTOP = 3; public const byte FACTNOTIFICATIONTYPE_CUEDESTROYED = 4; public const byte FACTNOTIFICATIONTYPE_MARKER = 5; public const byte FACTNOTIFICATIONTYPE_SOUNDBANKDESTROYED = 6; public const byte FACTNOTIFICATIONTYPE_WAVEBANKDESTROYED = 7; public const byte FACTNOTIFICATIONTYPE_LOCALVARIABLECHANGED = 8; public const byte FACTNOTIFICATIONTYPE_GLOBALVARIABLECHANGED = 9; public const byte FACTNOTIFICATIONTYPE_GUICONNECTED = 10; public const byte FACTNOTIFICATIONTYPE_GUIDISCONNECTED = 11; public const byte FACTNOTIFICATIONTYPE_WAVEPREPARED = 12; public const byte FACTNOTIFICATIONTYPE_WAVEPLAY = 13; public const byte FACTNOTIFICATIONTYPE_WAVESTOP = 14; public const byte FACTNOTIFICATIONTYPE_WAVELOOPED = 15; public const byte FACTNOTIFICATIONTYPE_WAVEDESTROYED = 16; public const byte FACTNOTIFICATIONTYPE_WAVEBANKPREPARED = 17; public const byte FACTNOTIFICATIONTYPE_WAVEBANKSTREAMING_INVALIDCONTENT = 18; public const byte FACT_FLAG_NOTIFICATION_PERSIST = 0x01; public const uint FACT_WAVEBANK_TYPE_BUFFER = 0x00000000; public const uint FACT_WAVEBANK_TYPE_STREAMING = 0x00000001; public const uint FACT_WAVEBANK_TYPE_MASK = 0x00000001; public const uint FACT_WAVEBANK_FLAGS_ENTRYNAMES = 0x00010000; public const uint FACT_WAVEBANK_FLAGS_COMPACT = 0x00020000; public const uint FACT_WAVEBANK_FLAGS_SYNC_DISABLED = 0x00040000; public const uint FACT_WAVEBANK_FLAGS_SEEKTABLES = 0x00080000; public const uint FACT_WAVEBANK_FLAGS_MASK = 0x000F0000; /* AudioEngine Interface */ /* FIXME: Do we want to actually reproduce the COM stuff or what...? -flibit */ [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FACTCreateEngine( uint dwCreationFlags, out IntPtr ppEngine /* FACTAudioEngine** */ ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FACTAudioEngine_AddRef( IntPtr pEngine /* FACTAudioEngine* */ ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FACTAudioEngine_Release( IntPtr pEngine /* FACTAudioEngine* */ ); /* FIXME: QueryInterface? Or just ignore COM garbage... -flibit */ [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FACTAudioEngine_GetRendererCount( IntPtr pEngine, /* FACTAudioEngine* */ out ushort pnRendererCount ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FACTAudioEngine_GetRendererDetails( IntPtr pEngine, /* FACTAudioEngine* */ ushort nRendererIndex, out FACTRendererDetails pRendererDetails ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FACTAudioEngine_GetFinalMixFormat( IntPtr pEngine, /* FACTAudioEngine* */ out FAudioWaveFormatExtensible pFinalMixFormat ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FACTAudioEngine_Initialize( IntPtr pEngine, /* FACTAudioEngine* */ ref FACTRuntimeParameters pParams ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FACTAudioEngine_ShutDown( IntPtr pEngine /* FACTAudioEngine* */ ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FACTAudioEngine_DoWork( IntPtr pEngine /* FACTAudioEngine* */ ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FACTAudioEngine_CreateSoundBank( IntPtr pEngine, /* FACTAudioEngine* */ IntPtr pvBuffer, uint dwSize, uint dwFlags, uint dwAllocAttributes, out IntPtr ppSoundBank /* FACTSoundBank** */ ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FACTAudioEngine_CreateInMemoryWaveBank( IntPtr pEngine, /* FACTAudioEngine* */ IntPtr pvBuffer, uint dwSize, uint dwFlags, uint dwAllocAttributes, out IntPtr ppWaveBank /* FACTWaveBank** */ ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FACTAudioEngine_CreateStreamingWaveBank( IntPtr pEngine, /* FACTAudioEngine* */ ref FACTStreamingParameters pParms, out IntPtr ppWaveBank /* FACTWaveBank** */ ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] private static extern unsafe uint FACTAudioEngine_PrepareWave( IntPtr pEngine, /* FACTAudioEngine* */ uint dwFlags, byte* szWavePath, uint wStreamingPacketSize, uint dwAlignment, uint dwPlayOffset, byte nLoopCount, out IntPtr ppWave /* FACTWave** */ ); public static unsafe uint FACTAudioEngine_PrepareWave( IntPtr pEngine, /* FACTAudioEngine* */ uint dwFlags, string szWavePath, uint wStreamingPacketSize, uint dwAlignment, uint dwPlayOffset, byte nLoopCount, out IntPtr ppWave /* FACTWave** */ ) { byte* utf8WavePath = Utf8Encode(szWavePath); uint result = FACTAudioEngine_PrepareWave( pEngine, dwFlags, utf8WavePath, wStreamingPacketSize, dwAlignment, dwPlayOffset, nLoopCount, out ppWave ); Marshal.FreeHGlobal((IntPtr) utf8WavePath); return result; } [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FACTAudioEngine_PrepareInMemoryWave( IntPtr pEngine, /* FACTAudioEngine* */ uint dwFlags, FACTWaveBankEntry entry, uint[] pdwSeekTable, /* Optional! */ byte[] pbWaveData, uint dwPlayOffset, byte nLoopCount, out IntPtr ppWave /* FACTWave** */ ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FACTAudioEngine_PrepareStreamingWave( IntPtr pEngine, /* FACTAudioEngine* */ uint dwFlags, FACTWaveBankEntry entry, FACTStreamingParameters streamingParams, uint dwAlignment, uint[] pdwSeekTable, /* Optional! */ byte[] pbWaveData, uint dwPlayOffset, byte nLoopCount, out IntPtr ppWave /* FACTWave** */ ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FACTAudioEngine_RegisterNotification( IntPtr pEngine, /* FACTAudioEngine* */ ref FACTNotificationDescription pNotificationDescription ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FACTAudioEngine_UnRegisterNotification( IntPtr pEngine, /* FACTAudioEngine* */ ref FACTNotificationDescription pNotificationDescription ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] private static extern unsafe ushort FACTAudioEngine_GetCategory( IntPtr pEngine, /* FACTAudioEngine* */ byte* szFriendlyName ); public static unsafe ushort FACTAudioEngine_GetCategory( IntPtr pEngine, /* FACTAudioEngine* */ string szFriendlyName ) { int utf8BufSize = Utf8Size(szFriendlyName); byte* utf8Buf = stackalloc byte[utf8BufSize]; return FACTAudioEngine_GetCategory( pEngine, Utf8Encode(szFriendlyName, utf8Buf, utf8BufSize) ); } [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FACTAudioEngine_Stop( IntPtr pEngine, /* FACTAudioEngine* */ ushort nCategory, uint dwFlags ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FACTAudioEngine_SetVolume( IntPtr pEngine, /* FACTAudioEngine* */ ushort nCategory, float volume ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FACTAudioEngine_Pause( IntPtr pEngine, /* FACTAudioEngine* */ ushort nCategory, int fPause ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] private static extern unsafe ushort FACTAudioEngine_GetGlobalVariableIndex( IntPtr pEngine, /* FACTAudioEngine* */ byte* szFriendlyName ); public static unsafe ushort FACTAudioEngine_GetGlobalVariableIndex( IntPtr pEngine, /* FACTAudioEngine* */ string szFriendlyName ) { int utf8BufSize = Utf8Size(szFriendlyName); byte* utf8Buf = stackalloc byte[utf8BufSize]; return FACTAudioEngine_GetGlobalVariableIndex( pEngine, Utf8Encode(szFriendlyName, utf8Buf, utf8BufSize) ); } [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FACTAudioEngine_SetGlobalVariable( IntPtr pEngine, /* FACTAudioEngine* */ ushort nIndex, float nValue ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FACTAudioEngine_GetGlobalVariable( IntPtr pEngine, /* FACTAudioEngine* */ ushort nIndex, out float pnValue ); /* SoundBank Interface */ [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] private static extern unsafe ushort FACTSoundBank_GetCueIndex( IntPtr pSoundBank, /* FACTSoundBank* */ byte* szFriendlyName ); public static unsafe ushort FACTSoundBank_GetCueIndex( IntPtr pSoundBank, /* FACTSoundBank* */ string szFriendlyName ) { int utf8BufSize = Utf8Size(szFriendlyName); byte* utf8Buf = stackalloc byte[utf8BufSize]; return FACTSoundBank_GetCueIndex( pSoundBank, Utf8Encode(szFriendlyName, utf8Buf, utf8BufSize) ); } [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FACTSoundBank_GetNumCues( IntPtr pSoundBank, /* FACTSoundBank* */ out ushort pnNumCues ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FACTSoundBank_GetCueProperties( IntPtr pSoundBank, /* FACTSoundBank* */ ushort nCueIndex, out FACTCueProperties pProperties ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FACTSoundBank_Prepare( IntPtr pSoundBank, /* FACTSoundBank* */ ushort nCueIndex, uint dwFlags, int timeOffset, out IntPtr ppCue /* FACTCue** */ ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FACTSoundBank_Play( IntPtr pSoundBank, /* FACTSoundBank* */ ushort nCueIndex, uint dwFlags, int timeOffset, out IntPtr ppCue /* FACTCue** */ ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FACTSoundBank_Play( IntPtr pSoundBank, /* FACTSoundBank* */ ushort nCueIndex, uint dwFlags, int timeOffset, IntPtr ppCue /* Pass IntPtr.Zero! */ ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FACTSoundBank_Play3D( IntPtr pSoundBank, /* FACTSoundBank* */ ushort nCueIndex, uint dwFlags, int timeOffset, ref F3DAUDIO_DSP_SETTINGS pDSPSettings, IntPtr ppCue /* Pass IntPtr.Zero! */ ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FACTSoundBank_Stop( IntPtr pSoundBank, /* FACTSoundBank* */ ushort nCueIndex, uint dwFlags ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FACTSoundBank_Destroy( IntPtr pSoundBank /* FACTSoundBank* */ ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FACTSoundBank_GetState( IntPtr pSoundBank, /* FACTSoundBank* */ out uint pdwState ); /* WaveBank Interface */ [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FACTWaveBank_Destroy( IntPtr pWaveBank /* FACTWaveBank* */ ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FACTWaveBank_GetState( IntPtr pWaveBank, /* FACTWaveBank* */ out uint pdwState ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FACTWaveBank_GetNumWaves( IntPtr pWaveBank, /* FACTWaveBank* */ out ushort pnNumWaves ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] private static extern unsafe ushort FACTWaveBank_GetWaveIndex( IntPtr pWaveBank, /* FACTWaveBank* */ byte* szFriendlyName ); public static unsafe ushort FACTWaveBank_GetWaveIndex( IntPtr pWaveBank, /* FACTWaveBank* */ string szFriendlyName ) { int utf8BufSize = Utf8Size(szFriendlyName); byte* utf8Buf = stackalloc byte[utf8BufSize]; return FACTWaveBank_GetWaveIndex( pWaveBank, Utf8Encode(szFriendlyName, utf8Buf, utf8BufSize) ); } [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FACTWaveBank_GetWaveProperties( IntPtr pWaveBank, /* FACTWaveBank* */ ushort nWaveIndex, out FACTWaveProperties pWaveProperties ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FACTWaveBank_Prepare( IntPtr pWaveBank, /* FACTWaveBank* */ ushort nWaveIndex, uint dwFlags, uint dwPlayOffset, byte nLoopCount, out IntPtr ppWave /* FACTWave** */ ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FACTWaveBank_Play( IntPtr pWaveBank, /* FACTWaveBank* */ ushort nWaveIndex, uint dwFlags, uint dwPlayOffset, byte nLoopCount, out IntPtr ppWave /* FACTWave** */ ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FACTWaveBank_Stop( IntPtr pWaveBank, /* FACTWaveBank* */ ushort nWaveIndex, uint dwFlags ); /* Wave Interface */ [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FACTWave_Destroy( IntPtr pWave /* FACTWave* */ ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FACTWave_Play( IntPtr pWave /* FACTWave* */ ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FACTWave_Stop( IntPtr pWave, /* FACTWave* */ uint dwFlags ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FACTWave_Pause( IntPtr pWave, /* FACTWave* */ int fPause ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FACTWave_GetState( IntPtr pWave, /* FACTWave* */ out uint pdwState ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FACTWave_SetPitch( IntPtr pWave, /* FACTWave* */ short pitch ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FACTWave_SetVolume( IntPtr pWave, /* FACTWave* */ float volume ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FACTWave_SetMatrixCoefficients( IntPtr pWave, /* FACTWave* */ uint uSrcChannelCount, uint uDstChannelCount, float[] pMatrixCoefficients ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FACTWave_GetProperties( IntPtr pWave, /* FACTWave* */ out FACTWaveInstanceProperties pProperties ); /* Cue Interface */ [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FACTCue_Destroy( IntPtr pCue /* FACTCue* */ ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FACTCue_Play( IntPtr pCue /* FACTCue* */ ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FACTCue_Stop( IntPtr pCue, /* FACTCue* */ uint dwFlags ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FACTCue_GetState( IntPtr pCue, /* FACTCue* */ out uint pdwState ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FACTCue_SetMatrixCoefficients( IntPtr pCue, /* FACTCue* */ uint uSrcChannelCount, uint uDstChannelCount, float[] pMatrixCoefficients ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] private static extern unsafe ushort FACTCue_GetVariableIndex( IntPtr pCue, /* FACTCue* */ byte* szFriendlyName ); public static unsafe ushort FACTCue_GetVariableIndex( IntPtr pCue, /* FACTCue* */ string szFriendlyName ) { int utf8BufSize = Utf8Size(szFriendlyName); byte* utf8Buf = stackalloc byte[utf8BufSize]; return FACTCue_GetVariableIndex( pCue, Utf8Encode(szFriendlyName, utf8Buf, utf8BufSize) ); } [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FACTCue_SetVariable( IntPtr pCue, /* FACTCue* */ ushort nIndex, float nValue ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FACTCue_GetVariable( IntPtr pCue, /* FACTCue* */ ushort nIndex, out float nValue ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FACTCue_Pause( IntPtr pCue, /* FACTCue* */ int fPause ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FACTCue_GetProperties( IntPtr pCue, /* FACTCue* */ out IntPtr ppProperties /* FACTCueInstanceProperties** */ ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FACTCue_SetOutputVoices( IntPtr pCue, /* FACTCue* */ IntPtr pSendList /* Optional FAudioVoiceSends* */ ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FACTCue_SetOutputVoiceMatrix( IntPtr pCue, /* FACTCue* */ IntPtr pDestinationVoice, /* Optional FAudioVoice* */ uint SourceChannels, uint DestinationChannels, float[] pLevelMatrix /* SourceChannels * DestinationChannels */ ); #endregion #region F3DAudio API /* Constants */ public const uint SPEAKER_FRONT_LEFT = 0x00000001; public const uint SPEAKER_FRONT_RIGHT = 0x00000002; public const uint SPEAKER_FRONT_CENTER = 0x00000004; public const uint SPEAKER_LOW_FREQUENCY = 0x00000008; public const uint SPEAKER_BACK_LEFT = 0x00000010; public const uint SPEAKER_BACK_RIGHT = 0x00000020; public const uint SPEAKER_FRONT_LEFT_OF_CENTER = 0x00000040; public const uint SPEAKER_FRONT_RIGHT_OF_CENTER = 0x00000080; public const uint SPEAKER_BACK_CENTER = 0x00000100; public const uint SPEAKER_SIDE_LEFT = 0x00000200; public const uint SPEAKER_SIDE_RIGHT = 0x00000400; public const uint SPEAKER_TOP_CENTER = 0x00000800; public const uint SPEAKER_TOP_FRONT_LEFT = 0x00001000; public const uint SPEAKER_TOP_FRONT_CENTER = 0x00002000; public const uint SPEAKER_TOP_FRONT_RIGHT = 0x00004000; public const uint SPEAKER_TOP_BACK_LEFT = 0x00008000; public const uint SPEAKER_TOP_BACK_CENTER = 0x00010000; public const uint SPEAKER_TOP_BACK_RIGHT = 0x00020000; public const uint SPEAKER_MONO = SPEAKER_FRONT_CENTER; public const uint SPEAKER_STEREO = (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT); public const uint SPEAKER_2POINT1 = ( SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_LOW_FREQUENCY ); public const uint SPEAKER_SURROUND = ( SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_BACK_CENTER ); public const uint SPEAKER_QUAD = ( SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT ); public const uint SPEAKER_4POINT1 = ( SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_LOW_FREQUENCY | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT ); public const uint SPEAKER_5POINT1 = ( SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT ); public const uint SPEAKER_7POINT1 = ( SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT | SPEAKER_FRONT_LEFT_OF_CENTER | SPEAKER_FRONT_RIGHT_OF_CENTER ); public const uint SPEAKER_5POINT1_SURROUND = ( SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY | SPEAKER_SIDE_LEFT | SPEAKER_SIDE_RIGHT ); public const uint SPEAKER_7POINT1_SURROUND = ( SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT | SPEAKER_SIDE_LEFT | SPEAKER_SIDE_RIGHT ); /* FIXME: Hmmmm */ public const uint SPEAKER_XBOX = SPEAKER_5POINT1; public const float F3DAUDIO_PI = 3.141592654f; public const float F3DAUDIO_2PI = 6.283185307f; public const uint F3DAUDIO_CALCULATE_MATRIX = 0x00000001; public const uint F3DAUDIO_CALCULATE_DELAY = 0x00000002; public const uint F3DAUDIO_CALCULATE_LPF_DIRECT = 0x00000004; public const uint F3DAUDIO_CALCULATE_LPF_REVERB = 0x00000008; public const uint F3DAUDIO_CALCULATE_REVERB = 0x00000010; public const uint F3DAUDIO_CALCULATE_DOPPLER = 0x00000020; public const uint F3DAUDIO_CALCULATE_EMITTER_ANGLE = 0x00000040; public const uint F3DAUDIO_CALCULATE_ZEROCENTER = 0x00010000; public const uint F3DAUDIO_CALCULATE_REDIRECT_TO_LFE = 0x00020000; /* Type Declarations */ /* FIXME: Everything about this type blows */ public const int F3DAUDIO_HANDLE_BYTESIZE = 20; // Alloc a byte[] of size F3DAUDIO_HANDLE_BYTESIZE! /* Structures */ [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct F3DAUDIO_VECTOR { public float x; public float y; public float z; } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct F3DAUDIO_DISTANCE_CURVE_POINT { public float Distance; public float DSPSetting; } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct F3DAUDIO_DISTANCE_CURVE { IntPtr pPoints; /* F3DAUDIO_DISTANCE_CURVE_POINT* */ public uint PointCount; } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct F3DAUDIO_CONE { public float InnerAngle; public float OuterAngle; public float InnerVolume; public float OuterVolume; public float InnerLPF; public float OuterLPF; public float InnerReverb; public float OuterReverb; } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct F3DAUDIO_LISTENER { public F3DAUDIO_VECTOR OrientFront; public F3DAUDIO_VECTOR OrientTop; public F3DAUDIO_VECTOR Position; public F3DAUDIO_VECTOR Velocity; public IntPtr pCone; /* F3DAUDIO_CONE* */ } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct F3DAUDIO_EMITTER { public IntPtr pCone; /* F3DAUDIO_CONE* */ public F3DAUDIO_VECTOR OrientFront; public F3DAUDIO_VECTOR OrientTop; public F3DAUDIO_VECTOR Position; public F3DAUDIO_VECTOR Velocity; public float InnerRadius; public float InnerRadiusAngle; public uint ChannelCount; public float ChannelRadius; public IntPtr pChannelAzimuths; /* float */ public IntPtr pVolumeCurve; public IntPtr pLFECurve; /* F3DAUDIO_DISTANCE_CURVE* */ public IntPtr pLPFDirectCurve; /* F3DAUDIO_DISTANCE_CURVE* */ public IntPtr pLPFReverbCurve; /* F3DAUDIO_DISTANCE_CURVE* */ public IntPtr pReverbCurve; /* F3DAUDIO_DISTANCE_CURVE* */ public float CurveDistanceScaler; public float DopplerScaler; } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct F3DAUDIO_DSP_SETTINGS { public IntPtr pMatrixCoefficients; /* float* */ public IntPtr pDelayTimes; /* float* */ public uint SrcChannelCount; public uint DstChannelCount; public float LPFDirectCoefficient; public float LPFReverbCoefficient; public float ReverbLevel; public float DopplerFactor; public float EmitterToListenerAngle; public float EmitterToListenerDistance; public float EmitterVelocityComponent; public float ListenerVelocityComponent; } /* Functions */ [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern void F3DAudioInitialize( uint SpeakerChannelMask, float SpeedOfSound, byte[] Instance // F3DAUDIO_HANDLE ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint F3DAudioInitialize8( uint SpeakerChannelMask, float SpeedOfSound, byte[] Instance // F3DAUDIO_HANDLE ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern void F3DAudioCalculate( byte[] Instance, // F3DAUDIO_HANDLE ref F3DAUDIO_LISTENER pListener, ref F3DAUDIO_EMITTER pEmitter, uint Flags, ref F3DAUDIO_DSP_SETTINGS pDSPSettings ); #endregion #region FACT3D API /* Constants */ public const float LEFT_AZIMUTH = (3.0f * F3DAUDIO_PI / 2.0f); public const float RIGHT_AZIMUTH = (F3DAUDIO_PI / 2.0f); public const float FRONT_LEFT_AZIMUTH = (7.0f * F3DAUDIO_PI / 4.0f); public const float FRONT_RIGHT_AZIMUTH = (F3DAUDIO_PI / 4.0f); public const float FRONT_CENTER_AZIMUTH = 0.0f; public const float LOW_FREQUENCY_AZIMUTH = F3DAUDIO_2PI; public const float BACK_LEFT_AZIMUTH = (5.0f * F3DAUDIO_PI / 4.0f); public const float BACK_RIGHT_AZIMUTH = (3.0f * F3DAUDIO_PI / 4.0f); public const float BACK_CENTER_AZIMUTH = F3DAUDIO_PI; public const float FRONT_LEFT_OF_CENTER_AZIMUTH = (15.0f * F3DAUDIO_PI / 8.0f); public const float FRONT_RIGHT_OF_CENTER_AZIMUTH = (F3DAUDIO_PI / 8.0f); public static readonly float[] aStereoLayout = new float[] { LEFT_AZIMUTH, RIGHT_AZIMUTH }; public static readonly float[] a2Point1Layout = new float[] { LEFT_AZIMUTH, RIGHT_AZIMUTH, LOW_FREQUENCY_AZIMUTH }; public static readonly float[] aQuadLayout = new float[] { FRONT_LEFT_AZIMUTH, FRONT_RIGHT_AZIMUTH, BACK_LEFT_AZIMUTH, BACK_RIGHT_AZIMUTH }; public static readonly float[] a4Point1Layout = new float[] { FRONT_LEFT_AZIMUTH, FRONT_RIGHT_AZIMUTH, LOW_FREQUENCY_AZIMUTH, BACK_LEFT_AZIMUTH, BACK_RIGHT_AZIMUTH }; public static readonly float[] a5Point1Layout = new float[] { FRONT_LEFT_AZIMUTH, FRONT_RIGHT_AZIMUTH, FRONT_CENTER_AZIMUTH, LOW_FREQUENCY_AZIMUTH, BACK_LEFT_AZIMUTH, BACK_RIGHT_AZIMUTH }; public static readonly float[] a7Point1Layout = new float[] { FRONT_LEFT_AZIMUTH, FRONT_RIGHT_AZIMUTH, FRONT_CENTER_AZIMUTH, LOW_FREQUENCY_AZIMUTH, BACK_LEFT_AZIMUTH, BACK_RIGHT_AZIMUTH, LEFT_AZIMUTH, RIGHT_AZIMUTH }; /* Functions */ [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FACT3DInitialize( IntPtr pEngine, /* FACTAudioEngine* */ byte[] D3FInstance // F3DAUDIO_HANDLE ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FACT3DCalculate( byte[] F3DInstance, // F3DAUDIO_HANDLE ref F3DAUDIO_LISTENER pListener, ref F3DAUDIO_EMITTER pEmitter, ref F3DAUDIO_DSP_SETTINGS pDSPSettings ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint FACT3DApply( ref F3DAUDIO_DSP_SETTINGS pDSPSettings, IntPtr pCue /* FACTCue* */ ); #endregion #region XNA Song API [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern void XNA_SongInit(); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern void XNA_SongQuit(); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] private static extern unsafe float XNA_PlaySong(byte* name); public static unsafe float XNA_PlaySong(string name) { int utf8BufSize = Utf8Size(name); byte* utf8Buf = stackalloc byte[utf8BufSize]; return XNA_PlaySong(Utf8Encode(name, utf8Buf, utf8BufSize)); } [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern void XNA_PauseSong(); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern void XNA_ResumeSong(); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern void XNA_StopSong(); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern void XNA_SetSongVolume(float volume); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint XNA_GetSongEnded(); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern void XNA_EnableVisualization(uint enable); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint XNA_VisualizationEnabled(); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern void XNA_GetSongVisualizationData( float[] frequencies, float[] samples, uint count ); #endregion #region FAudio I/O API /* Delegates */ /* IntPtr refers to a size_t */ [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate IntPtr FAudio_readfunc( IntPtr data, /* void* */ IntPtr dst, /* void* */ IntPtr size, /* size_t */ IntPtr count /* size_t */ ); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate long FAudio_seekfunc( IntPtr data, /* void* */ long offset, int whence ); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate int FAudio_closefunc(IntPtr data); /* Structures */ [StructLayout(LayoutKind.Sequential)] public struct FAudioIOStream { public IntPtr data; public IntPtr read; /* FAudio_readfunc */ public IntPtr seek; /* FAudio_seekfunc */ public IntPtr close; /* FAudio_closefunc */ public IntPtr ioLock; /* lock, lolC# */ } /* Functions */ /* IntPtr refers to an FAudioIOStream* */ [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] private static extern unsafe IntPtr FAudio_fopen(byte* path); public static unsafe IntPtr FAudio_fopen(string path) { int utf8BufSize = Utf8Size(path); byte* utf8Buf = stackalloc byte[utf8BufSize]; return FAudio_fopen(Utf8Encode(path, utf8Buf, utf8BufSize)); } /* IntPtr refers to an FAudioIOStream* */ [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern IntPtr FAudio_memopen(IntPtr mem, int len); /* IntPtr refers to a uint8_t* */ [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern IntPtr FAudio_memptr(IntPtr io, IntPtr offset); /* io refers to an FAudioIOStream* */ [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern void FAudio_close(IntPtr io); #endregion #region stb_vorbis /* Because why not? */ [StructLayout(LayoutKind.Sequential)] public struct stb_vorbis_alloc { public IntPtr alloc_buffer; public int alloc_buffer_length_in_bytes; } [StructLayout(LayoutKind.Sequential)] public struct stb_vorbis_info { public uint sample_rate; public int channels; public uint setup_memory_required; public uint setup_temp_memory_required; public uint temp_memory_required; public int max_frame_size; } [StructLayout(LayoutKind.Sequential)] public struct stb_vorbis_comment { public IntPtr vendor; public int comment_list_length; public IntPtr comment_list; } [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern stb_vorbis_info stb_vorbis_get_info(IntPtr f); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern stb_vorbis_comment stb_vorbis_get_comment(IntPtr f); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern int stb_vorbis_get_error(IntPtr f); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern void stb_vorbis_close(IntPtr f); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern int stb_vorbis_get_sample_offset(IntPtr f); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint stb_vorbis_get_file_offset(IntPtr f); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern IntPtr stb_vorbis_open_memory( IntPtr data, int len, out int error, IntPtr alloc_buffer /* stb_vorbis_alloc* */ ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] private static extern unsafe IntPtr stb_vorbis_open_filename( byte* filename, out int error, IntPtr alloc_buffer /* stb_vorbis_alloc* */ ); public static unsafe IntPtr stb_vorbis_open_filename( string filename, out int error, IntPtr alloc_buffer /* stb_vorbis_alloc* */ ) { int utf8BufSize = Utf8Size(filename); byte* utf8Buf = stackalloc byte[utf8BufSize]; return stb_vorbis_open_filename( Utf8Encode(filename, utf8Buf, utf8BufSize), out error, alloc_buffer ); } [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern IntPtr stb_vorbis_open_file( IntPtr f, /* FAudioIOStream* */ int close_handle_on_close, out int error, IntPtr alloc_buffer /* stb_vorbis_alloc* */ ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern IntPtr stb_vorbis_open_file_section( IntPtr f, /* FAudioIOStream* */ int close_handle_on_close, out int error, IntPtr alloc_buffer, /* stb_vorbis_alloc* */ uint len ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern int stb_vorbis_seek_frame(IntPtr f, uint sample_number); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern int stb_vorbis_seek(IntPtr f, uint sample_number); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern int stb_vorbis_seek_start(IntPtr f); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern uint stb_vorbis_stream_length_in_samples(IntPtr f); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern float stb_vorbis_stream_length_in_seconds(IntPtr f); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern int stb_vorbis_get_frame_float( IntPtr f, out int channels, ref float[][] output ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern int stb_vorbis_get_frame_float( IntPtr f, IntPtr channels, /* IntPtr.Zero */ ref float[][] output ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern int stb_vorbis_get_samples_float_interleaved( IntPtr f, int channels, float[] buffer, int num_floats ); [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern int stb_vorbis_get_samples_float( IntPtr f, int channels, float[][] buffer, int num_samples ); #endregion }