1 /* FAudio# - C# Wrapper for FAudio
2  *
3  * Copyright (c) 2018-2021 Ethan Lee.
4  *
5  * This software is provided 'as-is', without any express or implied warranty.
6  * In no event will the authors be held liable for any damages arising from
7  * the use of this software.
8  *
9  * Permission is granted to anyone to use this software for any purpose,
10  * including commercial applications, and to alter it and redistribute it
11  * freely, subject to the following restrictions:
12  *
13  * 1. The origin of this software must not be misrepresented; you must not
14  * claim that you wrote the original software. If you use this software in a
15  * product, an acknowledgment in the product documentation would be
16  * appreciated but is not required.
17  *
18  * 2. Altered source versions must be plainly marked as such, and must not be
19  * misrepresented as being the original software.
20  *
21  * 3. This notice may not be removed or altered from any source distribution.
22  *
23  * Ethan "flibitijibibo" Lee <flibitijibibo@flibitijibibo.com>
24  *
25  */
26 
27 #region Using Statements
28 using System;
29 using System.Runtime.InteropServices;
30 using System.Text;
31 #endregion
32 
33 public static class FAudio
34 {
35 	#region Native Library Name
36 
37 	const string nativeLibName = "FAudio";
38 
39 	#endregion
40 
41 	#region UTF8 Marshaling
42 
43 	/* Used for stack allocated string marshaling. */
Utf8Size(string str)44 	private static int Utf8Size(string str)
45 	{
46 		return (str.Length * 4) + 1;
47 	}
Utf8Encode(string str, byte* buffer, int bufferSize)48 	private static unsafe byte* Utf8Encode(string str, byte* buffer, int bufferSize)
49 	{
50 		fixed (char* strPtr = str)
51 		{
52 			Encoding.UTF8.GetBytes(strPtr, str.Length + 1, buffer, bufferSize);
53 		}
54 
55 		return buffer;
56 	}
57 
58 	/* Used for heap allocated string marshaling
59 	 * Returned byte* must be free'd with FreeHGlobal.
60 	 */
Utf8Encode(string str)61 	private static unsafe byte* Utf8Encode(string str)
62 	{
63 		int bufferSize = (str.Length * 4) + 1;
64 		byte* buffer = (byte*)Marshal.AllocHGlobal(bufferSize);
65 		fixed (char* strPtr = str)
66 		{
67 			Encoding.UTF8.GetBytes(strPtr, str.Length + 1, buffer, bufferSize);
68 		}
69 		return buffer;
70 	}
71 
72 	#endregion
73 
74 	#region FAudio API
75 
76 	/* Version */
77 
78 	public const uint FAUDIO_TARGET_VERSION = 8;
79 
80 	public const uint FAUDIO_ABI_VERSION =		 0;
81 	public const uint FAUDIO_MAJOR_VERSION =	21;
82 	public const uint FAUDIO_MINOR_VERSION =	 1;
83 	public const uint FAUDIO_PATCH_VERSION =	 0;
84 
85 	public const uint FAUDIO_COMPILED_VERSION = (
86 		(FAUDIO_ABI_VERSION * 100 * 100 * 100) +
87 		(FAUDIO_MAJOR_VERSION * 100 * 100) +
88 		(FAUDIO_MINOR_VERSION * 100) +
89 		(FAUDIO_PATCH_VERSION)
90 	);
91 
92 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FAudioLinkedVersion()93 	public static extern uint FAudioLinkedVersion();
94 
95 	/* Enumerations */
96 
97 	[Flags]
98 	public enum FAudioDeviceRole
99 	{
100 		FAudioNotDefaultDevice =		0x0,
101 		FAudioDefaultConsoleDevice =		0x1,
102 		FAudioDefaultMultimediaDevice =		0x2,
103 		FAudioDefaultCommunicationsDevice =	0x4,
104 		FAudioDefaultGameDevice =		0x8,
105 		FAudioGlobalDefaultDevice =		0xF,
106 		FAudioInvalidDeviceRole = ~FAudioGlobalDefaultDevice
107 	}
108 
109 	public enum FAudioFilterType
110 	{
111 		FAudioLowPassFilter,
112 		FAudioBandPassFilter,
113 		FAudioHighPassFilter,
114 		FAudioNotchFilter
115 	}
116 
117 	/* FIXME: The original enum violates ISO C and is platform specific anyway... */
118 	public const uint FAUDIO_DEFAULT_PROCESSOR = 0xFFFFFFFF;
119 
120 	/* Structures */
121 
122 	[StructLayout(LayoutKind.Sequential, Pack = 1)]
123 	public unsafe struct FAudioGUID
124 	{
125 		public uint Data1;
126 		public ushort Data2;
127 		public ushort Data3;
128 		public fixed byte Data4[8];
129 	}
130 
131 	[StructLayout(LayoutKind.Sequential, Pack = 1)]
132 	public struct FAudioWaveFormatEx
133 	{
134 		public ushort wFormatTag;
135 		public ushort nChannels;
136 		public uint nSamplesPerSec;
137 		public uint nAvgBytesPerSec;
138 		public ushort nBlockAlign;
139 		public ushort wBitsPerSample;
140 		public ushort cbSize;
141 	}
142 
143 	[StructLayout(LayoutKind.Sequential, Pack = 1)]
144 	public struct FAudioWaveFormatExtensible
145 	{
146 		public FAudioWaveFormatEx Format;
147 		public ushort Samples; /* FIXME: union! */
148 		public uint dwChannelMask;
149 		public FAudioGUID SubFormat;
150 	}
151 
152 	[StructLayout(LayoutKind.Sequential, Pack = 1)]
153 	public struct FAudioADPCMCoefSet
154 	{
155 		public short iCoef1;
156 		public short iCoef2;
157 	}
158 
159 	[StructLayout(LayoutKind.Sequential, Pack = 1)]
160 	public struct FAudioADPCMWaveFormat
161 	{
162 		public FAudioWaveFormatEx wfx;
163 		public ushort wSamplesPerBlock;
164 		public ushort wNumCoef;
165 		public IntPtr aCoef; /* FAudioADPCMCoefSet[] */
166 		/* MSADPCM has 7 coefficient pairs:
167 		 * {
168 		 *	{ 256,    0 },
169 		 *	{ 512, -256 },
170 		 *	{   0,    0 },
171 		 *	{ 192,   64 },
172 		 *	{ 240,    0 },
173 		 *	{ 460, -208 },
174 		 *	{ 392, -232 }
175 		 * }
176 		 */
177 	}
178 
179 	[StructLayout(LayoutKind.Sequential, Pack = 1)]
180 	public unsafe struct FAudioDeviceDetails
181 	{
182 		public fixed short DeviceID[256]; /* Win32 wchar_t */
183 		public fixed short DisplayName[256]; /* Win32 wchar_t */
184 		public FAudioDeviceRole Role;
185 		public FAudioWaveFormatExtensible OutputFormat;
186 	}
187 
188 	[StructLayout(LayoutKind.Sequential, Pack = 1)]
189 	public struct FAudioVoiceDetails
190 	{
191 		public uint CreationFlags;
192 		public uint ActiveFlags;
193 		public uint InputChannels;
194 		public uint InputSampleRate;
195 	}
196 
197 	[StructLayout(LayoutKind.Sequential, Pack = 1)]
198 	public struct FAudioSendDescriptor
199 	{
200 		public uint Flags;
201 		public IntPtr pOutputVoice; /* FAudioVoice* */
202 	}
203 
204 	[StructLayout(LayoutKind.Sequential, Pack = 1)]
205 	public struct FAudioVoiceSends
206 	{
207 		public uint SendCount;
208 		public IntPtr pSends; /* FAudioSendDescriptor* */
209 	}
210 
211 	[StructLayout(LayoutKind.Sequential, Pack = 1)]
212 	public struct FAudioEffectDescriptor
213 	{
214 		public IntPtr pEffect; /* void* */
215 		public int InitialState;
216 		public uint OutputChannels;
217 	}
218 
219 	[StructLayout(LayoutKind.Sequential, Pack = 1)]
220 	public struct FAudioEffectChain
221 	{
222 		public uint EffectCount;
223 		public IntPtr pEffectDescriptors; /* FAudioEffectDescriptor* */
224 	}
225 
226 	[StructLayout(LayoutKind.Sequential, Pack = 1)]
227 	public struct FAudioFilterParameters
228 	{
229 		public FAudioFilterType Type;
230 		public float Frequency;
231 		public float OneOverQ;
232 	}
233 
234 	[StructLayout(LayoutKind.Sequential, Pack = 1)]
235 	public struct FAudioBuffer
236 	{
237 		public uint Flags;
238 		public uint AudioBytes;
239 		public IntPtr pAudioData; /* const uint8_t* */
240 		public uint PlayBegin;
241 		public uint PlayLength;
242 		public uint LoopBegin;
243 		public uint LoopLength;
244 		public uint LoopCount;
245 		public IntPtr pContext; /* void* */
246 	}
247 
248 	[StructLayout(LayoutKind.Sequential, Pack = 1)]
249 	public struct FAudioBufferWMA
250 	{
251 		public IntPtr pDecodedPacketCumulativeBytes; /* const uint32_t* */
252 		public uint PacketCount;
253 	}
254 
255 	[StructLayout(LayoutKind.Sequential, Pack = 1)]
256 	public struct FAudioVoiceState
257 	{
258 		public IntPtr pCurrentBufferContext; /* void* */
259 		public uint BuffersQueued;
260 		public ulong SamplesPlayed;
261 	}
262 
263 	[StructLayout(LayoutKind.Sequential, Pack = 1)]
264 	public struct FAudioPerformanceData
265 	{
266 		public ulong AudioCyclesSinceLastQuery;
267 		public ulong TotalCyclesSinceLastQuery;
268 		public uint MinimumCyclesPerQuantum;
269 		public uint MaximumCyclesPerQuantum;
270 		public uint MemoryUsageInBytes;
271 		public uint CurrentLatencyInSamples;
272 		public uint GlitchesSinceEngineStarted;
273 		public uint ActiveSourceVoiceCount;
274 		public uint TotalSourceVoiceCount;
275 		public uint ActiveSubmixVoiceCount;
276 		public uint ActiveResamplerCount;
277 		public uint ActiveMatrixMixCount;
278 		public uint ActiveXmaSourceVoices;
279 		public uint ActiveXmaStreams;
280 	}
281 
282 	[StructLayout(LayoutKind.Sequential, Pack = 1)]
283 	public struct FAudioDebugConfiguration
284 	{
285 		public uint TraceMask;
286 		public uint BreakMask;
287 		public int LogThreadID;
288 		public int LogFileline;
289 		public int LogFunctionName;
290 		public int LogTiming;
291 	}
292 
293 	/* Constants */
294 
295 	public const uint FAUDIO_MAX_BUFFER_BYTES =		0x80000000;
296 	public const uint FAUDIO_MAX_QUEUED_BUFFERS =		64;
297 	public const uint FAUDIO_MAX_AUDIO_CHANNELS =		64;
298 	public const uint FAUDIO_MIN_SAMPLE_RATE =		1000;
299 	public const uint FAUDIO_MAX_SAMPLE_RATE =		200000;
300 	public const float FAUDIO_MAX_VOLUME_LEVEL =		16777216.0f;
301 	public const float FAUDIO_MIN_FREQ_RATIO =		(1.0f / 1024.0f);
302 	public const float FAUDIO_MAX_FREQ_RATIO =		1024.0f;
303 	public const float FAUDIO_DEFAULT_FREQ_RATIO =		2.0f;
304 	public const float FAUDIO_MAX_FILTER_ONEOVERQ =		1.5f;
305 	public const float FAUDIO_MAX_FILTER_FREQUENCY =	1.0f;
306 	public const uint FAUDIO_MAX_LOOP_COUNT =		254;
307 
308 	public const uint FAUDIO_COMMIT_NOW =		0;
309 	public const uint FAUDIO_COMMIT_ALL =		0;
310 	public const uint FAUDIO_INVALID_OPSET =	unchecked((uint) -1);
311 	public const uint FAUDIO_NO_LOOP_REGION =	0;
312 	public const uint FAUDIO_LOOP_INFINITE =	255;
313 	public const uint FAUDIO_DEFAULT_CHANNELS =	0;
314 	public const uint FAUDIO_DEFAULT_SAMPLERATE =	0;
315 
316 	public const uint FAUDIO_DEBUG_ENGINE =			0x0001;
317 	public const uint FAUDIO_VOICE_NOPITCH =		0x0002;
318 	public const uint FAUDIO_VOICE_NOSRC =			0x0004;
319 	public const uint FAUDIO_VOICE_USEFILTER =		0x0008;
320 	public const uint FAUDIO_VOICE_MUSIC =			0x0010;
321 	public const uint FAUDIO_PLAY_TAILS =			0x0020;
322 	public const uint FAUDIO_END_OF_STREAM =		0x0040;
323 	public const uint FAUDIO_SEND_USEFILTER =		0x0080;
324 	public const uint FAUDIO_VOICE_NOSAMPLESPLAYED =	0x0100;
325 	public const uint FAUDIO_1024_QUANTUM =			0x8000;
326 
327 	public const FAudioFilterType FAUDIO_DEFAULT_FILTER_TYPE =	FAudioFilterType.FAudioLowPassFilter;
328 	public const float FAUDIO_DEFAULT_FILTER_FREQUENCY =		FAUDIO_MAX_FILTER_FREQUENCY;
329 	public const float FAUDIO_DEFAULT_FILTER_ONEOVERQ =		1.0f;
330 
331 	public const ushort FAUDIO_LOG_ERRORS =		0x0001;
332 	public const ushort FAUDIO_LOG_WARNINGS =	0x0002;
333 	public const ushort FAUDIO_LOG_INFO =		0x0004;
334 	public const ushort FAUDIO_LOG_DETAIL =		0x0008;
335 	public const ushort FAUDIO_LOG_API_CALLS =	0x0010;
336 	public const ushort FAUDIO_LOG_FUNC_CALLS =	0x0020;
337 	public const ushort FAUDIO_LOG_TIMING =		0x0040;
338 	public const ushort FAUDIO_LOG_LOCKS =		0x0080;
339 	public const ushort FAUDIO_LOG_MEMORY =		0x0100;
340 	public const ushort FAUDIO_LOG_STREAMING =	0x1000;
341 
342 	/* FAudio Interface */
343 
344 	/* FIXME: Do we want to actually reproduce the COM stuff or what...? -flibit */
345 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FAudioCreate( out IntPtr ppFAudio, uint Flags, uint XAudio2Processor )346 	public static extern uint FAudioCreate(
347 		out IntPtr ppFAudio, /* FAudio** */
348 		uint Flags,
349 		uint XAudio2Processor /* FAudioProcessor */
350 	);
351 
352 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FAudio_AddRef( IntPtr audio )353 	public static extern uint FAudio_AddRef(
354 		IntPtr audio /* FAudio */
355 	);
356 
357 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FAudio_Release( IntPtr audio )358 	public static extern uint FAudio_Release(
359 		IntPtr audio /* FAudio* */
360 	);
361 
362 	/* FIXME: QueryInterface? Or just ignore COM garbage... -flibit */
363 
364 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FAudio_GetDeviceCount( IntPtr audio, out uint pCount )365 	public static extern uint FAudio_GetDeviceCount(
366 		IntPtr audio, /* FAudio* */
367 		out uint pCount
368 	);
369 
370 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FAudio_GetDeviceDetails( IntPtr audio, uint Index, out FAudioDeviceDetails pDeviceDetails )371 	public static extern uint FAudio_GetDeviceDetails(
372 		IntPtr audio, /* FAudio* */
373 		uint Index,
374 		out FAudioDeviceDetails pDeviceDetails
375 	);
376 
377 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FAudio_Initialize( IntPtr audio, uint Flags, uint XAudio2Processor )378 	public static extern uint FAudio_Initialize(
379 		IntPtr audio, /* FAudio* */
380 		uint Flags,
381 		uint XAudio2Processor /* FAudioProcessor */
382 	);
383 
384 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FAudio_RegisterForCallbacks( IntPtr audio, IntPtr pCallback )385 	public static extern uint FAudio_RegisterForCallbacks(
386 		IntPtr audio, /* FAudio* */
387 		IntPtr pCallback /* FAudioEngineCallback* */
388 	);
389 
390 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FAudio_UnregisterForCallbacks( IntPtr audio, IntPtr pCallback )391 	public static extern void FAudio_UnregisterForCallbacks(
392 		IntPtr audio, /* FAudio* */
393 		IntPtr pCallback /* FAudioEngineCallback* */
394 	);
395 
396 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FAudio_CreateSourceVoice( IntPtr audio, out IntPtr ppSourceVoice, ref FAudioWaveFormatEx pSourceFormat, uint Flags, float MaxFrequencyRatio, IntPtr pCallback, IntPtr pSendList, IntPtr pEffectChain )397 	public static extern uint FAudio_CreateSourceVoice(
398 		IntPtr audio, /* FAudio* */
399 		out IntPtr ppSourceVoice, /* FAudioSourceVoice** */
400 		ref FAudioWaveFormatEx pSourceFormat,
401 		uint Flags,
402 		float MaxFrequencyRatio,
403 		IntPtr pCallback, /* FAudioVoiceCallback* */
404 		IntPtr pSendList, /* FAudioVoiceSends* */
405 		IntPtr pEffectChain /* FAudioEffectChain* */
406 	);
407 
408 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FAudio_CreateSubmixVoice( IntPtr audio, out IntPtr ppSubmixVoice, uint InputChannels, uint InputSampleRate, uint Flags, uint ProcessingStage, IntPtr pSendList, IntPtr pEffectChain )409 	public static extern uint FAudio_CreateSubmixVoice(
410 		IntPtr audio, /* FAudio* */
411 		out IntPtr ppSubmixVoice, /* FAudioSubmixVoice** */
412 		uint InputChannels,
413 		uint InputSampleRate,
414 		uint Flags,
415 		uint ProcessingStage,
416 		IntPtr pSendList, /* FAudioVoiceSends* */
417 		IntPtr pEffectChain /* FAudioEffectChain* */
418 	);
419 
420 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FAudio_CreateMasteringVoice( IntPtr audio, out IntPtr ppMasteringVoice, uint InputChannels, uint InputSampleRate, uint Flags, uint DeviceIndex, IntPtr pEffectChain )421 	public static extern uint FAudio_CreateMasteringVoice(
422 		IntPtr audio, /* FAudio* */
423 		out IntPtr ppMasteringVoice, /* FAudioMasteringVoice** */
424 		uint InputChannels,
425 		uint InputSampleRate,
426 		uint Flags,
427 		uint DeviceIndex,
428 		IntPtr pEffectChain /* FAudioEffectChain* */
429 	);
430 
431 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FAudio_StartEngine( IntPtr audio )432 	public static extern uint FAudio_StartEngine(
433 		IntPtr audio /* FAudio* */
434 	);
435 
436 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FAudio_StopEngine( IntPtr audio )437 	public static extern void FAudio_StopEngine(
438 		IntPtr audio /* FAudio* */
439 	);
440 
441 	[DllImport(nativeLibName, EntryPoint = "FAudio_CommitOperationSet", CallingConvention = CallingConvention.Cdecl)]
FAudio_CommitChanges( IntPtr audio , uint OperationSet )442 	public static extern uint FAudio_CommitChanges(
443 		IntPtr audio /* FAudio* */,
444 		uint OperationSet
445 	);
446 
447 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FAudio_GetPerformanceData( IntPtr audio, out FAudioPerformanceData pPerfData )448 	public static extern void FAudio_GetPerformanceData(
449 		IntPtr audio, /* FAudio* */
450 		out FAudioPerformanceData pPerfData
451 	);
452 
453 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FAudio_SetDebugConfiguration( IntPtr audio, ref FAudioDebugConfiguration pDebugConfiguration, IntPtr pReserved )454 	public static extern void FAudio_SetDebugConfiguration(
455 		IntPtr audio, /* FAudio* */
456 		ref FAudioDebugConfiguration pDebugConfiguration,
457 		IntPtr pReserved /* void* */
458 	);
459 
460 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FAudio_GetProcessingQuantum( IntPtr audio, out uint quantumNumerator, out uint quantumDenominator )461 	public static extern void FAudio_GetProcessingQuantum(
462 		IntPtr audio, /* FAudio */
463 		out uint quantumNumerator,
464 		out uint quantumDenominator
465 	);
466 
467 	/* FAudioVoice Interface */
468 
469 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FAudioVoice_GetVoiceDetails( IntPtr voice, out FAudioVoiceDetails pVoiceDetails )470 	public static extern void FAudioVoice_GetVoiceDetails(
471 		IntPtr voice, /* FAudioVoice* */
472 		out FAudioVoiceDetails pVoiceDetails
473 	);
474 
475 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FAudioVoice_SetOutputVoices( IntPtr voice, ref FAudioVoiceSends pSendList )476 	public static extern uint FAudioVoice_SetOutputVoices(
477 		IntPtr voice, /* FAudioVoice* */
478 		ref FAudioVoiceSends pSendList
479 	);
480 
481 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FAudioVoice_SetEffectChain( IntPtr voice, ref FAudioEffectChain pEffectChain )482 	public static extern uint FAudioVoice_SetEffectChain(
483 		IntPtr voice, /* FAudioVoice* */
484 		ref FAudioEffectChain pEffectChain
485 	);
486 
487 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FAudioVoice_EnableEffect( IntPtr voice, uint EffectIndex, uint OperationSet )488 	public static extern uint FAudioVoice_EnableEffect(
489 		IntPtr voice, /* FAudioVoice* */
490 		uint EffectIndex,
491 		uint OperationSet
492 	);
493 
494 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FAudioVoice_DisableEffect( IntPtr voice, uint EffectIndex, uint OperationSet )495 	public static extern uint FAudioVoice_DisableEffect(
496 		IntPtr voice, /* FAudioVoice* */
497 		uint EffectIndex,
498 		uint OperationSet
499 	);
500 
501 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FAudioVoice_GetEffectState( IntPtr voice, uint EffectIndex, out int pEnabled )502 	public static extern void FAudioVoice_GetEffectState(
503 		IntPtr voice, /* FAudioVoice* */
504 		uint EffectIndex,
505 		out int pEnabled
506 	);
507 
508 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FAudioVoice_SetEffectParameters( IntPtr voice, uint EffectIndex, IntPtr pParameters, uint ParametersByteSize, uint OperationSet )509 	public static extern uint FAudioVoice_SetEffectParameters(
510 		IntPtr voice, /* FAudioVoice* */
511 		uint EffectIndex,
512 		IntPtr pParameters, /* const void* */
513 		uint ParametersByteSize,
514 		uint OperationSet
515 	);
516 
517 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FAudioVoice_GetEffectParameters( IntPtr voice, uint EffectIndex, IntPtr pParameters, uint ParametersByteSize )518 	public static extern uint FAudioVoice_GetEffectParameters(
519 		IntPtr voice, /* FAudioVoice* */
520 		uint EffectIndex,
521 		IntPtr pParameters, /* void* */
522 		uint ParametersByteSize
523 	);
524 
525 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FAudioVoice_SetFilterParameters( IntPtr voice, ref FAudioFilterParameters pParameters, uint OperationSet )526 	public static extern uint FAudioVoice_SetFilterParameters(
527 		IntPtr voice, /* FAudioVoice* */
528 		ref FAudioFilterParameters pParameters,
529 		uint OperationSet
530 	);
531 
532 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FAudioVoice_GetFilterParameters( IntPtr voice, out FAudioFilterParameters pParameters )533 	public static extern void FAudioVoice_GetFilterParameters(
534 		IntPtr voice, /* FAudioVoice* */
535 		out FAudioFilterParameters pParameters
536 	);
537 
538 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FAudioVoice_SetOutputFilterParameters( IntPtr voice, IntPtr pDestinationVoice, ref FAudioFilterParameters pParameters, uint OperationSet )539 	public static extern uint FAudioVoice_SetOutputFilterParameters(
540 		IntPtr voice, /* FAudioVoice* */
541 		IntPtr pDestinationVoice, /* FAudioVoice */
542 		ref FAudioFilterParameters pParameters,
543 		uint OperationSet
544 	);
545 
546 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FAudioVoice_GetOutputFilterParameters( IntPtr voice, IntPtr pDestinationVoice, out FAudioFilterParameters pParameters )547 	public static extern void FAudioVoice_GetOutputFilterParameters(
548 		IntPtr voice, /* FAudioVoice* */
549 		IntPtr pDestinationVoice, /* FAudioVoice */
550 		out FAudioFilterParameters pParameters
551 	);
552 
553 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FAudioVoice_SetVolume( IntPtr voice, float Volume, uint OperationSet )554 	public static extern uint FAudioVoice_SetVolume(
555 		IntPtr voice, /* FAudioVoice* */
556 		float Volume,
557 		uint OperationSet
558 	);
559 
560 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FAudioVoice_GetVolume( IntPtr voice, out float pVolume )561 	public static extern void FAudioVoice_GetVolume(
562 		IntPtr voice, /* FAudioVoice* */
563 		out float pVolume
564 	);
565 
566 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FAudioVoice_SetChannelVolumes( IntPtr voice, uint Channels, float[] pVolumes, uint OperationSet )567 	public static extern uint FAudioVoice_SetChannelVolumes(
568 		IntPtr voice, /* FAudioVoice* */
569 		uint Channels,
570 		float[] pVolumes,
571 		uint OperationSet
572 	);
573 
574 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FAudioVoice_GetChannelVolumes( IntPtr voice, uint Channels, float[] pVolumes )575 	public static extern void FAudioVoice_GetChannelVolumes(
576 		IntPtr voice, /* FAudioVoice* */
577 		uint Channels,
578 		float[] pVolumes
579 	);
580 
581 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FAudioVoice_SetOutputMatrix( IntPtr voice, IntPtr pDestinationVoice, uint SourceChannels, uint DestinationChannels, IntPtr pLevelMatrix, uint OperationSet )582 	public static extern uint FAudioVoice_SetOutputMatrix(
583 		IntPtr voice, /* FAudioVoice* */
584 		IntPtr pDestinationVoice, /* FAudioVoice* */
585 		uint SourceChannels,
586 		uint DestinationChannels,
587 		IntPtr pLevelMatrix, /* float* */
588 		uint OperationSet
589 	);
590 
591 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FAudioVoice_GetOutputMatrix( IntPtr voice, IntPtr pDestinationVoice, uint SourceChannels, uint DestinationChannels, float[] pLevelMatrix )592 	public static extern void FAudioVoice_GetOutputMatrix(
593 		IntPtr voice, /* FAudioVoice* */
594 		IntPtr pDestinationVoice, /* FAudioVoice* */
595 		uint SourceChannels,
596 		uint DestinationChannels,
597 		float[] pLevelMatrix
598 	);
599 
600 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FAudioVoice_DestroyVoice( IntPtr voice )601 	public static extern void FAudioVoice_DestroyVoice(
602 		IntPtr voice /* FAudioVoice* */
603 	);
604 
605 	/* FAudioSourceVoice Interface */
606 
607 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FAudioSourceVoice_Start( IntPtr voice, uint Flags, uint OperationSet )608 	public static extern uint FAudioSourceVoice_Start(
609 		IntPtr voice, /* FAudioSourceVoice* */
610 		uint Flags,
611 		uint OperationSet
612 	);
613 
614 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FAudioSourceVoice_Stop( IntPtr voice, uint Flags, uint OperationSet )615 	public static extern uint FAudioSourceVoice_Stop(
616 		IntPtr voice, /* FAudioSourceVoice* */
617 		uint Flags,
618 		uint OperationSet
619 	);
620 
621 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FAudioSourceVoice_SubmitSourceBuffer( IntPtr voice, ref FAudioBuffer pBuffer, IntPtr pBufferWMA )622 	public static extern uint FAudioSourceVoice_SubmitSourceBuffer(
623 		IntPtr voice, /* FAudioSourceVoice* */
624 		ref FAudioBuffer pBuffer,
625 		IntPtr pBufferWMA /* const FAudioBufferWMA* */
626 	);
627 
628 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FAudioSourceVoice_FlushSourceBuffers( IntPtr voice )629 	public static extern uint FAudioSourceVoice_FlushSourceBuffers(
630 		IntPtr voice /* FAudioSourceVoice* */
631 	);
632 
633 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FAudioSourceVoice_Discontinuity( IntPtr voice )634 	public static extern uint FAudioSourceVoice_Discontinuity(
635 		IntPtr voice /* FAudioSourceVoice* */
636 	);
637 
638 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FAudioSourceVoice_ExitLoop( IntPtr voice, uint OperationSet )639 	public static extern uint FAudioSourceVoice_ExitLoop(
640 		IntPtr voice, /* FAudioSourceVoice* */
641 		uint OperationSet
642 	);
643 
644 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FAudioSourceVoice_GetState( IntPtr voice, out FAudioVoiceState pVoiceState, uint Flags )645 	public static extern void FAudioSourceVoice_GetState(
646 		IntPtr voice, /* FAudioSourceVoice* */
647 		out FAudioVoiceState pVoiceState,
648 		uint Flags
649 	);
650 
651 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FAudioSourceVoice_SetFrequencyRatio( IntPtr voice, float Ratio, uint OperationSet )652 	public static extern uint FAudioSourceVoice_SetFrequencyRatio(
653 		IntPtr voice, /* FAudioSourceVoice* */
654 		float Ratio,
655 		uint OperationSet
656 	);
657 
658 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FAudioSourceVoice_GetFrequencyRatio( IntPtr voice, out float pRatio )659 	public static extern void FAudioSourceVoice_GetFrequencyRatio(
660 		IntPtr voice, /* FAudioSourceVoice* */
661 		out float pRatio
662 	);
663 
664 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FAudioSourceVoice_SetSourceSampleRate( IntPtr voice, uint NewSourceSampleRate )665 	public static extern uint FAudioSourceVoice_SetSourceSampleRate(
666 		IntPtr voice, /* FAudioSourceVoice* */
667 		uint NewSourceSampleRate
668 	);
669 
670 	/* FAudioEngineCallback Interface */
671 
672 	[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
OnCriticalErrorFunc( IntPtr engineCallback, uint Error )673 	public delegate void OnCriticalErrorFunc(
674 		IntPtr engineCallback, /* FAudioEngineCallback* */
675 		uint Error
676 	);
677 
678 	[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
OnProcessingPassEndFunc( IntPtr engineCallback )679 	public delegate void OnProcessingPassEndFunc(
680 		IntPtr engineCallback /* FAudioEngineCallback* */
681 	);
682 
683 	[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
OnProcessingPassStartFunc( IntPtr engineCallback )684 	public delegate void OnProcessingPassStartFunc(
685 		IntPtr engineCallback /* FAudioEngineCallback* */
686 	);
687 
688 	[StructLayout(LayoutKind.Sequential)]
689 	public struct FAudioEngineCallback
690 	{
691 		public IntPtr OnCriticalError; /* OnCriticalErrorFunc */
692 		public IntPtr OnProcessingPassEnd; /* OnProcessingPassEndFunc */
693 		public IntPtr OnProcessingPassStart; /* OnProcessingPassStartFunc */
694 	}
695 
696 	/* FAudioVoiceCallback Interface */
697 
698 	[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
OnBufferEndFunc( IntPtr voiceCallback, IntPtr pBufferContext )699 	public delegate void OnBufferEndFunc(
700 		IntPtr voiceCallback, /* FAudioVoiceCallback* */
701 		IntPtr pBufferContext /* void* */
702 	);
703 
704 	[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
OnBufferStartFunc( IntPtr voiceCallback, IntPtr pBufferContext )705 	public delegate void OnBufferStartFunc(
706 		IntPtr voiceCallback, /* FAudioVoiceCallback* */
707 		IntPtr pBufferContext /* void* */
708 	);
709 
710 	[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
OnLoopEndFunc( IntPtr voiceCallback, IntPtr pBufferContext )711 	public delegate void OnLoopEndFunc(
712 		IntPtr voiceCallback, /* FAudioVoiceCallback* */
713 		IntPtr pBufferContext /* void* */
714 	);
715 
716 	[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
OnStreamEndFunc( IntPtr voiceCallback )717 	public delegate void OnStreamEndFunc(
718 		IntPtr voiceCallback /* FAudioVoiceCallback* */
719 	);
720 
721 	[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
OnVoiceErrorFunc( IntPtr voiceCallback, IntPtr pBufferContext, uint Error )722 	public delegate void OnVoiceErrorFunc(
723 		IntPtr voiceCallback, /* FAudioVoiceCallback* */
724 		IntPtr pBufferContext, /* void* */
725 		uint Error
726 	);
727 
728 	[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
OnVoiceProcessingPassEndFunc( IntPtr voiceCallback )729 	public delegate void OnVoiceProcessingPassEndFunc(
730 		IntPtr voiceCallback /* FAudioVoiceCallback* */
731 	);
732 
733 	[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
OnVoiceProcessingPassStartFunc( IntPtr voiceCallback, uint BytesRequired )734 	public delegate void OnVoiceProcessingPassStartFunc(
735 		IntPtr voiceCallback, /* FAudioVoiceCallback* */
736 		uint BytesRequired
737 	);
738 
739 	[StructLayout(LayoutKind.Sequential)]
740 	public struct FAudioVoiceCallback
741 	{
742 		public IntPtr OnBufferEnd; /* OnBufferEndFunc */
743 		public IntPtr OnBufferStart; /* OnBufferStartFunc */
744 		public IntPtr OnLoopEnd; /* OnLoopEndFunc */
745 		public IntPtr OnStreamEnd; /* OnStreamEndFunc */
746 		public IntPtr OnVoiceError; /* OnVoiceErrorFunc */
747 		public IntPtr OnVoiceProcessingPassEnd; /* OnVoiceProcessingPassEndFunc */
748 		public IntPtr OnVoiceProcessingPassStart; /* OnVoiceProcessingPassStartFunc */
749 	}
750 
751 	#endregion
752 
753 	#region FAudioFX API
754 
755 	/* TODO */
756 
757 	/* Structures */
758 
759 	[StructLayout(LayoutKind.Sequential)]
760 	public struct FAudioFXReverbParameters
761 	{
762 		public float WetDryMix;
763 		public uint ReflectionsDelay;
764 		public byte ReverbDelay;
765 		public byte RearDelay;
766 		public byte PositionLeft;
767 		public byte PositionRight;
768 		public byte PositionMatrixLeft;
769 		public byte PositionMatrixRight;
770 		public byte EarlyDiffusion;
771 		public byte LateDiffusion;
772 		public byte LowEQGain;
773 		public byte LowEQCutoff;
774 		public byte HighEQGain;
775 		public byte HighEQCutoff;
776 		public float RoomFilterFreq;
777 		public float RoomFilterMain;
778 		public float RoomFilterHF;
779 		public float ReflectionsGain;
780 		public float ReverbGain;
781 		public float DecayTime;
782 		public float Density;
783 		public float RoomSize;
784 	}
785 
786 	[StructLayout(LayoutKind.Sequential)]
787 	public struct FAudioFXReverbParameters9
788 	{
789 		public float WetDryMix;
790 		public uint ReflectionsDelay;
791 		public byte ReverbDelay;
792 		public byte RearDelay;
793 		public byte SideDelay;
794 		public byte PositionLeft;
795 		public byte PositionRight;
796 		public byte PositionMatrixLeft;
797 		public byte PositionMatrixRight;
798 		public byte EarlyDiffusion;
799 		public byte LateDiffusion;
800 		public byte LowEQGain;
801 		public byte LowEQCutoff;
802 		public byte HighEQGain;
803 		public byte HighEQCutoff;
804 		public float RoomFilterFreq;
805 		public float RoomFilterMain;
806 		public float RoomFilterHF;
807 		public float ReflectionsGain;
808 		public float ReverbGain;
809 		public float DecayTime;
810 		public float Density;
811 		public float RoomSize;
812 	}
813 
814 	/* Constants */
815 
816 	public const float FAUDIOFX_REVERB_DEFAULT_WET_DRY_MIX =	100.0f;
817 	public const uint FAUDIOFX_REVERB_DEFAULT_REFLECTIONS_DELAY =	5;
818 	public const byte FAUDIOFX_REVERB_DEFAULT_REVERB_DELAY =	5;
819 	public const byte FAUDIOFX_REVERB_DEFAULT_REAR_DELAY =		5;
820 	public const byte FAUDIOFX_REVERB_DEFAULT_7POINT1_SIDE_DELAY =	5;
821 	public const byte FAUDIOFX_REVERB_DEFAULT_7POINT1_REAR_DELAY =	20;
822 	public const byte FAUDIOFX_REVERB_DEFAULT_POSITION =		6;
823 	public const byte FAUDIOFX_REVERB_DEFAULT_POSITION_MATRIX =	27;
824 	public const byte FAUDIOFX_REVERB_DEFAULT_EARLY_DIFFUSION =	8;
825 	public const byte FAUDIOFX_REVERB_DEFAULT_LATE_DIFFUSION =	8;
826 	public const byte FAUDIOFX_REVERB_DEFAULT_LOW_EQ_GAIN =		8;
827 	public const byte FAUDIOFX_REVERB_DEFAULT_LOW_EQ_CUTOFF =	4;
828 	public const byte FAUDIOFX_REVERB_DEFAULT_HIGH_EQ_GAIN =	8;
829 	public const byte FAUDIOFX_REVERB_DEFAULT_HIGH_EQ_CUTOFF =	4;
830 	public const float FAUDIOFX_REVERB_DEFAULT_ROOM_FILTER_FREQ =	5000.0f;
831 	public const float FAUDIOFX_REVERB_DEFAULT_ROOM_FILTER_MAIN =	0.0f;
832 	public const float FAUDIOFX_REVERB_DEFAULT_ROOM_FILTER_HF =	0.0f;
833 	public const float FAUDIOFX_REVERB_DEFAULT_REFLECTIONS_GAIN =	0.0f;
834 	public const float FAUDIOFX_REVERB_DEFAULT_REVERB_GAIN =	0.0f;
835 	public const float FAUDIOFX_REVERB_DEFAULT_DECAY_TIME =		1.0f;
836 	public const float FAUDIOFX_REVERB_DEFAULT_DENSITY =		100.0f;
837 	public const float FAUDIOFX_REVERB_DEFAULT_ROOM_SIZE =		100.0f;
838 
839 	/* Functions */
840 
841 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FAudioCreateReverb(out IntPtr ppApo, uint Flags)842 	public static extern uint FAudioCreateReverb(out IntPtr ppApo, uint Flags);
843 
844 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FAudioCreateReverb9(out IntPtr ppApo, uint Flags)845 	public static extern uint FAudioCreateReverb9(out IntPtr ppApo, uint Flags);
846 
847 	#endregion
848 
849 	#region FAPO API
850 
851 	/* TODO */
852 
853 	#endregion
854 
855 	#region FAPOBase API
856 
857 	/* TODO */
858 
859 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FAPOBase_Release(IntPtr fapo)860 	public static extern uint FAPOBase_Release(IntPtr fapo);
861 
862 	#endregion
863 
864 	#region FACT API
865 
866 	/* Delegates */
867 
868 	[UnmanagedFunctionPointer(CallingConvention.StdCall)]
FACTReadFileCallback( IntPtr hFile, IntPtr buffer, uint nNumberOfBytesToRead, IntPtr lpOverlapped )869 	public delegate int FACTReadFileCallback(
870 		IntPtr hFile,
871 		IntPtr buffer,
872 		uint nNumberOfBytesToRead,
873 		IntPtr lpOverlapped /* FACTOverlapped* */
874 	);
875 
876 	[UnmanagedFunctionPointer(CallingConvention.StdCall)]
FACTGetOverlappedResultCallback( IntPtr hFile, IntPtr lpOverlapped, out uint lpNumberOfBytesTransferred, int bWait )877 	public delegate int FACTGetOverlappedResultCallback(
878 		IntPtr hFile,
879 		IntPtr lpOverlapped, /* FACTOverlapped* */
880 		out uint lpNumberOfBytesTransferred,
881 		int bWait
882 	);
883 
884 	[UnmanagedFunctionPointer(CallingConvention.StdCall)]
FACTNotificationCallback( IntPtr pNotification )885 	public delegate void FACTNotificationCallback(
886 		IntPtr pNotification /* const FACTNotification* */
887 	);
888 
889 	/* Enumerations */
890 
891 	public enum FACTWaveBankSegIdx
892 	{
893 		FACT_WAVEBANK_SEGIDX_BANKDATA = 0,
894 		FACT_WAVEBANK_SEGIDX_ENTRYMETADATA,
895 		FACT_WAVEBANK_SEGIDX_SEEKTABLES,
896 		FACT_WAVEBANK_SEGIDX_ENTRYNAMES,
897 		FACT_WAVEBANK_SEGIDX_ENTRYWAVEDATA,
898 		FACT_WAVEBANK_SEGIDX_COUNT
899 	}
900 
901 	/* Structures */
902 
903 	[StructLayout(LayoutKind.Sequential)]
904 	public unsafe struct FACTRendererDetails
905 	{
906 		public fixed short rendererID[0xFF]; // Win32 wchar_t
907 		public fixed short displayName[0xFF]; // Win32 wchar_t
908 		public int defaultDevice;
909 	}
910 
911 	[StructLayout(LayoutKind.Sequential)]
912 	public struct FACTOverlapped
913 	{
914 		public IntPtr Internal; /* ULONG_PTR */
915 		public IntPtr InternalHigh; /* ULONG_PTR */
916 		public uint Offset; /* FIXME: union! */
917 		public uint OffsetHigh; /* FIXME: union! */
918 		public IntPtr hEvent;
919 	}
920 
921 	[StructLayout(LayoutKind.Sequential)]
922 	public struct FACTFileIOCallbacks
923 	{
924 		public IntPtr readFileCallback; /* FACTReadCallback */
925 		public IntPtr getOverlappedResultCallback; /* FACTGetOverlappedResultCallback */
926 	}
927 
928 	[StructLayout(LayoutKind.Sequential)]
929 	public struct FACTRuntimeParameters
930 	{
931 		public uint lookAheadTime;
932 		public IntPtr pGlobalSettingsBuffer;
933 		public uint globalSettingsBufferSize;
934 		public uint globalSettingsFlags;
935 		public uint globalSettingsAllocAttributes;
936 		public FACTFileIOCallbacks fileIOCallbacks;
937 		public IntPtr fnNotificationCallback; /* FACTNotificationCallback */
938 		public IntPtr pRendererID; /* Win32 wchar_t* */
939 		public IntPtr pXAudio2;
940 		public IntPtr pMasteringVoice;
941 	}
942 
943 	[StructLayout(LayoutKind.Sequential)]
944 	public struct FACTStreamingParameters
945 	{
946 		public IntPtr file;
947 		public uint offset;
948 		public uint flags;
949 		public ushort packetSize;
950 	}
951 
952 	[StructLayout(LayoutKind.Sequential, Pack = 1)]
953 	public struct FACTWaveBankRegion
954 	{
955 		public uint dwOffset;
956 		public uint dwLength;
957 	}
958 
959 	[StructLayout(LayoutKind.Sequential, Pack = 1)]
960 	public struct FACTWaveBankSampleRegion
961 	{
962 		public uint dwStartSample;
963 		public uint dwTotalSamples;
964 	}
965 
966 	/* TODO
967 	[StructLayout(LayoutKind.Sequential, Pack = 1)]
968 	public struct FACTWaveBankHeader
969 	{
970 		public uint dwSignature;
971 		public uint dwVersion;
972 		public uint dwHeaderVersion;
973 		public fixed FACTWaveBankRegion Segments[FACT_WAVEBANK_SEGIDX_COUNT];
974 	}
975 	*/
976 
977 	[StructLayout(LayoutKind.Sequential, Pack = 1)] /* FIXME: union! */
978 	public struct FACTWaveBankMiniWaveFormat
979 	{
980 		/*struct
981 		{
982 			public uint wFormatTag : 2;
983 			public uint nChannels : 3;
984 			public uint nSamplesPerSec : 18;
985 			public uint wBlockAlign : 8;
986 			public uint wBitsPerSample : 1;
987 		};*/
988 		public uint dwValue;
989 	}
990 
991 	[StructLayout(LayoutKind.Sequential, Pack = 1)]
992 	public struct FACTWaveBankEntry
993 	{
994 		public uint dwFlagsAndDuration; /* FIXME: union! */
995 		public FACTWaveBankMiniWaveFormat Format;
996 		public FACTWaveBankRegion PlayRegion;
997 		public FACTWaveBankSampleRegion LoopRegion;
998 	}
999 
1000 	/* TODO
1001 	[StructLayout(LayoutKind.Sequential, Pack = 1)]
1002 	public struct FACTWaveBankEntryCompact
1003 	{
1004 		public uint dwOffset : 21;
1005 		public uint dwLengthDeviation : 11;
1006 	}
1007 	*/
1008 
1009 	[StructLayout(LayoutKind.Sequential, Pack = 1)]
1010 	public unsafe struct FACTWaveBankData
1011 	{
1012 		public uint dwFlags;
1013 		public uint dwEntryCount;
1014 		public fixed char szBankName[64];
1015 		public uint dwEntryMetaDataElementSize;
1016 		public uint dwEntryNameElementSize;
1017 		public uint dwAlignment;
1018 		public FACTWaveBankMiniWaveFormat CompactFormat;
1019 		public ulong BuildTime;
1020 	}
1021 
1022 	[StructLayout(LayoutKind.Sequential)]
1023 	public unsafe struct FACTWaveProperties
1024 	{
1025 		public fixed byte friendlyName[64];
1026 		public FACTWaveBankMiniWaveFormat format;
1027 		public uint durationInSamples;
1028 		public FACTWaveBankSampleRegion loopRegion;
1029 		public int streaming;
1030 	}
1031 
1032 	[StructLayout(LayoutKind.Sequential)]
1033 	public struct FACTWaveInstanceProperties
1034 	{
1035 		public FACTWaveProperties properties;
1036 		public int backgroundMusic;
1037 	}
1038 
1039 	[StructLayout(LayoutKind.Sequential)]
1040 	public unsafe struct FACTCueProperties
1041 	{
1042 		public fixed char friendlyName[0xFF];
1043 		public int interactive;
1044 		public ushort iaVariableIndex;
1045 		public ushort numVariations;
1046 		public byte maxInstances;
1047 		public byte currentInstances;
1048 	}
1049 
1050 	[StructLayout(LayoutKind.Sequential)]
1051 	public struct FACTTrackProperties
1052 	{
1053 		public uint duration;
1054 		public ushort numVariations;
1055 		public byte numChannels;
1056 		public ushort waveVariation;
1057 		public byte loopCount;
1058 	}
1059 
1060 	[StructLayout(LayoutKind.Sequential)]
1061 	public struct FACTVariationProperties
1062 	{
1063 		public ushort index;
1064 		public byte weight;
1065 		public float iaVariableMin;
1066 		public float iaVariableMax;
1067 		public int linger;
1068 	}
1069 
1070 	[StructLayout(LayoutKind.Sequential)]
1071 	public struct FACTSoundProperties
1072 	{
1073 		public ushort category;
1074 		public byte priority;
1075 		public short pitch;
1076 		public float volume;
1077 		public ushort numTracks;
1078 		public FACTTrackProperties arrTrackProperties; /* FIXME: [1] */
1079 	}
1080 
1081 	[StructLayout(LayoutKind.Sequential)]
1082 	public struct FACTSoundVariationProperties
1083 	{
1084 		public FACTVariationProperties variationProperties;
1085 		public FACTSoundProperties soundProperties;
1086 	}
1087 
1088 	[StructLayout(LayoutKind.Sequential)]
1089 	public struct FACTCueInstanceProperties
1090 	{
1091 		public uint allocAttributes;
1092 		public FACTCueProperties cueProperties;
1093 		public FACTSoundVariationProperties activeVariationProperties;
1094 	}
1095 
1096 	[StructLayout(LayoutKind.Sequential, Pack = 1)]
1097 	public struct FACTNotificationDescription
1098 	{
1099 		public byte type;
1100 		public byte flags;
1101 		public IntPtr pSoundBank; /* FACTSoundBank* */
1102 		public IntPtr pWaveBank; /* FACTWaveBank* */
1103 		public IntPtr pCue; /* FACTCue* */
1104 		public IntPtr pWave; /* FACTWave* */
1105 		public ushort cueIndex;
1106 		public ushort waveIndex;
1107 		public IntPtr pvContext;
1108 	}
1109 
1110 	[StructLayout(LayoutKind.Sequential, Pack = 1)]
1111 	public struct FACTNotificationCue
1112 	{
1113 		public ushort cueIndex;
1114 		public IntPtr pSoundBank; /* FACTSoundBank* */
1115 		public IntPtr pCue; /* FACTCue* */
1116 	}
1117 
1118 	[StructLayout(LayoutKind.Sequential, Pack = 1)]
1119 	public struct FACTNotificationMarker
1120 	{
1121 		public ushort cueIndex;
1122 		public IntPtr pSoundBank; /* FACTSoundBank* */
1123 		public IntPtr pCue; /* FACTCue* */
1124 		public uint marker;
1125 	}
1126 
1127 	[StructLayout(LayoutKind.Sequential, Pack = 1)]
1128 	public struct FACTNotificationSoundBank
1129 	{
1130 		public IntPtr pSoundBank; /* FACTSoundBank* */
1131 	}
1132 
1133 	[StructLayout(LayoutKind.Sequential, Pack = 1)]
1134 	public struct FACTNotificationWaveBank
1135 	{
1136 		public IntPtr pWaveBank; /* FACTWaveBank* */
1137 	}
1138 
1139 	[StructLayout(LayoutKind.Sequential, Pack = 1)]
1140 	public struct FACTNotificationVariable
1141 	{
1142 		public ushort cueIndex;
1143 		public IntPtr pSoundBank; /* FACTSoundBank* */
1144 		public IntPtr pCue; /* FACTCue* */
1145 		public ushort variableIndex;
1146 		public float variableValue;
1147 		public int local;
1148 	}
1149 
1150 	[StructLayout(LayoutKind.Sequential, Pack = 1)]
1151 	public struct FACTNotificationGUI
1152 	{
1153 		public uint reserved;
1154 	}
1155 
1156 	[StructLayout(LayoutKind.Sequential, Pack = 1)]
1157 	public struct FACTNotificationWave
1158 	{
1159 		public IntPtr pWaveBank; /* FACTWaveBank* */
1160 		public ushort waveIndex;
1161 		public ushort cueIndex;
1162 		public IntPtr pSoundBank; /* FACTSoundBank* */
1163 		public IntPtr pCue; /* FACTCue* */
1164 		public IntPtr pWave; /* FACTWave* */
1165 	}
1166 
1167 	[StructLayout(LayoutKind.Explicit)]
1168 	public struct FACTNotification_union
1169 	{
1170 		[FieldOffset(0)]
1171 		public FACTNotificationCue cue;
1172 		[FieldOffset(0)]
1173 		public FACTNotificationMarker marker;
1174 		[FieldOffset(0)]
1175 		public FACTNotificationSoundBank soundBank;
1176 		[FieldOffset(0)]
1177 		public FACTNotificationWaveBank waveBank;
1178 		[FieldOffset(0)]
1179 		public FACTNotificationVariable variable;
1180 		[FieldOffset(0)]
1181 		public FACTNotificationGUI gui;
1182 		[FieldOffset(0)]
1183 		public FACTNotificationWave wave;
1184 	}
1185 
1186 	[StructLayout(LayoutKind.Sequential, Pack = 1)]
1187 	public struct FACTNotification
1188 	{
1189 		public byte type;
1190 		public int timeStamp;
1191 		public IntPtr pvContext;
1192 		public FACTNotification_union anon;
1193 	}
1194 
1195 	/* Constants */
1196 
1197 	public const int FACT_CONTENT_VERSION = 46;
1198 
1199 	public const uint FACT_FLAG_MANAGEDATA =	0x00000001;
1200 
1201 	public const uint FACT_FLAG_STOP_RELEASE =	0x00000000;
1202 	public const uint FACT_FLAG_STOP_IMMEDIATE =	0x00000001;
1203 
1204 	public const uint FACT_FLAG_BACKGROUND_MUSIC =	0x00000002;
1205 	public const uint FACT_FLAG_UNITS_MS =		0x00000004;
1206 	public const uint FACT_FLAG_UNITS_SAMPLES =	0x00000008;
1207 
1208 	public const uint FACT_STATE_CREATED =		0x00000001;
1209 	public const uint FACT_STATE_PREPARING =	0x00000002;
1210 	public const uint FACT_STATE_PREPARED =		0x00000004;
1211 	public const uint FACT_STATE_PLAYING =		0x00000008;
1212 	public const uint FACT_STATE_STOPPING =		0x00000010;
1213 	public const uint FACT_STATE_STOPPED =		0x00000020;
1214 	public const uint FACT_STATE_PAUSED =		0x00000040;
1215 	public const uint FACT_STATE_INUSE =		0x00000080;
1216 	public const uint FACT_STATE_PREPAREFAILED =	0x80000000;
1217 
1218 	public const short FACTPITCH_MIN =		-1200;
1219 	public const short FACTPITCH_MAX =		 1200;
1220 	public const short FACTPITCH_MIN_TOTAL =	-2400;
1221 	public const short FACTPITCH_MAX_TOTAL =	 2400;
1222 
1223 	public const float FACTVOLUME_MIN = 0.0f;
1224 	public const float FACTVOLUME_MAX = 16777216.0f;
1225 
1226 	public const ushort FACTINDEX_INVALID =		0xFFFF;
1227 	public const ushort FACTVARIABLEINDEX_INVALID =	0xFFFF;
1228 	public const ushort FACTCATEGORY_INVALID =	0xFFFF;
1229 
1230 	public const uint FACT_ENGINE_LOOKAHEAD_DEFAULT = 250;
1231 
1232 	public const byte FACTNOTIFICATIONTYPE_CUEPREPARED =				1;
1233 	public const byte FACTNOTIFICATIONTYPE_CUEPLAY =				2;
1234 	public const byte FACTNOTIFICATIONTYPE_CUESTOP =				3;
1235 	public const byte FACTNOTIFICATIONTYPE_CUEDESTROYED =				4;
1236 	public const byte FACTNOTIFICATIONTYPE_MARKER =					5;
1237 	public const byte FACTNOTIFICATIONTYPE_SOUNDBANKDESTROYED =			6;
1238 	public const byte FACTNOTIFICATIONTYPE_WAVEBANKDESTROYED =			7;
1239 	public const byte FACTNOTIFICATIONTYPE_LOCALVARIABLECHANGED =			8;
1240 	public const byte FACTNOTIFICATIONTYPE_GLOBALVARIABLECHANGED =			9;
1241 	public const byte FACTNOTIFICATIONTYPE_GUICONNECTED =				10;
1242 	public const byte FACTNOTIFICATIONTYPE_GUIDISCONNECTED =			11;
1243 	public const byte FACTNOTIFICATIONTYPE_WAVEPREPARED =				12;
1244 	public const byte FACTNOTIFICATIONTYPE_WAVEPLAY =				13;
1245 	public const byte FACTNOTIFICATIONTYPE_WAVESTOP =				14;
1246 	public const byte FACTNOTIFICATIONTYPE_WAVELOOPED =				15;
1247 	public const byte FACTNOTIFICATIONTYPE_WAVEDESTROYED =				16;
1248 	public const byte FACTNOTIFICATIONTYPE_WAVEBANKPREPARED =			17;
1249 	public const byte FACTNOTIFICATIONTYPE_WAVEBANKSTREAMING_INVALIDCONTENT =	18;
1250 
1251 	public const byte FACT_FLAG_NOTIFICATION_PERSIST = 0x01;
1252 
1253 	public const uint FACT_WAVEBANK_TYPE_BUFFER =		0x00000000;
1254 	public const uint FACT_WAVEBANK_TYPE_STREAMING =	0x00000001;
1255 	public const uint FACT_WAVEBANK_TYPE_MASK =		0x00000001;
1256 
1257 	public const uint FACT_WAVEBANK_FLAGS_ENTRYNAMES =	0x00010000;
1258 	public const uint FACT_WAVEBANK_FLAGS_COMPACT =		0x00020000;
1259 	public const uint FACT_WAVEBANK_FLAGS_SYNC_DISABLED =	0x00040000;
1260 	public const uint FACT_WAVEBANK_FLAGS_SEEKTABLES =	0x00080000;
1261 	public const uint FACT_WAVEBANK_FLAGS_MASK =		0x000F0000;
1262 
1263 	/* AudioEngine Interface */
1264 
1265 	/* FIXME: Do we want to actually reproduce the COM stuff or what...? -flibit */
1266 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FACTCreateEngine( uint dwCreationFlags, out IntPtr ppEngine )1267 	public static extern uint FACTCreateEngine(
1268 		uint dwCreationFlags,
1269 		out IntPtr ppEngine /* FACTAudioEngine** */
1270 	);
1271 
1272 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FACTAudioEngine_AddRef( IntPtr pEngine )1273 	public static extern uint FACTAudioEngine_AddRef(
1274 		IntPtr pEngine /* FACTAudioEngine* */
1275 	);
1276 
1277 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FACTAudioEngine_Release( IntPtr pEngine )1278 	public static extern uint FACTAudioEngine_Release(
1279 		IntPtr pEngine /* FACTAudioEngine* */
1280 	);
1281 
1282 	/* FIXME: QueryInterface? Or just ignore COM garbage... -flibit */
1283 
1284 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FACTAudioEngine_GetRendererCount( IntPtr pEngine, out ushort pnRendererCount )1285 	public static extern uint FACTAudioEngine_GetRendererCount(
1286 		IntPtr pEngine, /* FACTAudioEngine* */
1287 		out ushort pnRendererCount
1288 	);
1289 
1290 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FACTAudioEngine_GetRendererDetails( IntPtr pEngine, ushort nRendererIndex, out FACTRendererDetails pRendererDetails )1291 	public static extern uint FACTAudioEngine_GetRendererDetails(
1292 		IntPtr pEngine, /* FACTAudioEngine* */
1293 		ushort nRendererIndex,
1294 		out FACTRendererDetails pRendererDetails
1295 	);
1296 
1297 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FACTAudioEngine_GetFinalMixFormat( IntPtr pEngine, out FAudioWaveFormatExtensible pFinalMixFormat )1298 	public static extern uint FACTAudioEngine_GetFinalMixFormat(
1299 		IntPtr pEngine, /* FACTAudioEngine* */
1300 		out FAudioWaveFormatExtensible pFinalMixFormat
1301 	);
1302 
1303 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FACTAudioEngine_Initialize( IntPtr pEngine, ref FACTRuntimeParameters pParams )1304 	public static extern uint FACTAudioEngine_Initialize(
1305 		IntPtr pEngine, /* FACTAudioEngine* */
1306 		ref FACTRuntimeParameters pParams
1307 	);
1308 
1309 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FACTAudioEngine_ShutDown( IntPtr pEngine )1310 	public static extern uint FACTAudioEngine_ShutDown(
1311 		IntPtr pEngine /* FACTAudioEngine* */
1312 	);
1313 
1314 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FACTAudioEngine_DoWork( IntPtr pEngine )1315 	public static extern uint FACTAudioEngine_DoWork(
1316 		IntPtr pEngine /* FACTAudioEngine* */
1317 	);
1318 
1319 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FACTAudioEngine_CreateSoundBank( IntPtr pEngine, IntPtr pvBuffer, uint dwSize, uint dwFlags, uint dwAllocAttributes, out IntPtr ppSoundBank )1320 	public static extern uint FACTAudioEngine_CreateSoundBank(
1321 		IntPtr pEngine, /* FACTAudioEngine* */
1322 		IntPtr pvBuffer,
1323 		uint dwSize,
1324 		uint dwFlags,
1325 		uint dwAllocAttributes,
1326 		out IntPtr ppSoundBank /* FACTSoundBank** */
1327 	);
1328 
1329 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FACTAudioEngine_CreateInMemoryWaveBank( IntPtr pEngine, IntPtr pvBuffer, uint dwSize, uint dwFlags, uint dwAllocAttributes, out IntPtr ppWaveBank )1330 	public static extern uint FACTAudioEngine_CreateInMemoryWaveBank(
1331 		IntPtr pEngine, /* FACTAudioEngine* */
1332 		IntPtr pvBuffer,
1333 		uint dwSize,
1334 		uint dwFlags,
1335 		uint dwAllocAttributes,
1336 		out IntPtr ppWaveBank /* FACTWaveBank** */
1337 	);
1338 
1339 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FACTAudioEngine_CreateStreamingWaveBank( IntPtr pEngine, ref FACTStreamingParameters pParms, out IntPtr ppWaveBank )1340 	public static extern uint FACTAudioEngine_CreateStreamingWaveBank(
1341 		IntPtr pEngine, /* FACTAudioEngine* */
1342 		ref FACTStreamingParameters pParms,
1343 		out IntPtr ppWaveBank /* FACTWaveBank** */
1344 	);
1345 
1346 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FACTAudioEngine_PrepareWave( IntPtr pEngine, uint dwFlags, byte* szWavePath, uint wStreamingPacketSize, uint dwAlignment, uint dwPlayOffset, byte nLoopCount, out IntPtr ppWave )1347 	private static extern unsafe uint FACTAudioEngine_PrepareWave(
1348 		IntPtr pEngine, /* FACTAudioEngine* */
1349 		uint dwFlags,
1350 		byte* szWavePath,
1351 		uint wStreamingPacketSize,
1352 		uint dwAlignment,
1353 		uint dwPlayOffset,
1354 		byte nLoopCount,
1355 		out IntPtr ppWave /* FACTWave** */
1356 	);
FACTAudioEngine_PrepareWave( IntPtr pEngine, uint dwFlags, string szWavePath, uint wStreamingPacketSize, uint dwAlignment, uint dwPlayOffset, byte nLoopCount, out IntPtr ppWave )1357 	public static unsafe uint FACTAudioEngine_PrepareWave(
1358 		IntPtr pEngine, /* FACTAudioEngine* */
1359 		uint dwFlags,
1360 		string szWavePath,
1361 		uint wStreamingPacketSize,
1362 		uint dwAlignment,
1363 		uint dwPlayOffset,
1364 		byte nLoopCount,
1365 		out IntPtr ppWave /* FACTWave** */
1366 	) {
1367 		byte* utf8WavePath = Utf8Encode(szWavePath);
1368 		uint result = FACTAudioEngine_PrepareWave(
1369 			pEngine,
1370 			dwFlags,
1371 			utf8WavePath,
1372 			wStreamingPacketSize,
1373 			dwAlignment,
1374 			dwPlayOffset,
1375 			nLoopCount,
1376 			out ppWave
1377 		);
1378 		Marshal.FreeHGlobal((IntPtr) utf8WavePath);
1379 		return result;
1380 	}
1381 
1382 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FACTAudioEngine_PrepareInMemoryWave( IntPtr pEngine, uint dwFlags, FACTWaveBankEntry entry, uint[] pdwSeekTable, byte[] pbWaveData, uint dwPlayOffset, byte nLoopCount, out IntPtr ppWave )1383 	public static extern uint FACTAudioEngine_PrepareInMemoryWave(
1384 		IntPtr pEngine, /* FACTAudioEngine* */
1385 		uint dwFlags,
1386 		FACTWaveBankEntry entry,
1387 		uint[] pdwSeekTable, /* Optional! */
1388 		byte[] pbWaveData,
1389 		uint dwPlayOffset,
1390 		byte nLoopCount,
1391 		out IntPtr ppWave /* FACTWave** */
1392 	);
1393 
1394 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FACTAudioEngine_PrepareStreamingWave( IntPtr pEngine, uint dwFlags, FACTWaveBankEntry entry, FACTStreamingParameters streamingParams, uint dwAlignment, uint[] pdwSeekTable, byte[] pbWaveData, uint dwPlayOffset, byte nLoopCount, out IntPtr ppWave )1395 	public static extern uint FACTAudioEngine_PrepareStreamingWave(
1396 		IntPtr pEngine, /* FACTAudioEngine* */
1397 		uint dwFlags,
1398 		FACTWaveBankEntry entry,
1399 		FACTStreamingParameters streamingParams,
1400 		uint dwAlignment,
1401 		uint[] pdwSeekTable, /* Optional! */
1402 		byte[] pbWaveData,
1403 		uint dwPlayOffset,
1404 		byte nLoopCount,
1405 		out IntPtr ppWave /* FACTWave** */
1406 	);
1407 
1408 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FACTAudioEngine_RegisterNotification( IntPtr pEngine, ref FACTNotificationDescription pNotificationDescription )1409 	public static extern uint FACTAudioEngine_RegisterNotification(
1410 		IntPtr pEngine, /* FACTAudioEngine* */
1411 		ref FACTNotificationDescription pNotificationDescription
1412 	);
1413 
1414 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FACTAudioEngine_UnRegisterNotification( IntPtr pEngine, ref FACTNotificationDescription pNotificationDescription )1415 	public static extern uint FACTAudioEngine_UnRegisterNotification(
1416 		IntPtr pEngine, /* FACTAudioEngine* */
1417 		ref FACTNotificationDescription pNotificationDescription
1418 	);
1419 
1420 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FACTAudioEngine_GetCategory( IntPtr pEngine, byte* szFriendlyName )1421 	private static extern unsafe ushort FACTAudioEngine_GetCategory(
1422 		IntPtr pEngine, /* FACTAudioEngine* */
1423 		byte* szFriendlyName
1424 	);
FACTAudioEngine_GetCategory( IntPtr pEngine, string szFriendlyName )1425 	public static unsafe ushort FACTAudioEngine_GetCategory(
1426 		IntPtr pEngine, /* FACTAudioEngine* */
1427 		string szFriendlyName
1428 	) {
1429 		int utf8BufSize = Utf8Size(szFriendlyName);
1430 		byte* utf8Buf = stackalloc byte[utf8BufSize];
1431 		return FACTAudioEngine_GetCategory(
1432 			pEngine,
1433 			Utf8Encode(szFriendlyName, utf8Buf, utf8BufSize)
1434 		);
1435 	}
1436 
1437 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FACTAudioEngine_Stop( IntPtr pEngine, ushort nCategory, uint dwFlags )1438 	public static extern uint FACTAudioEngine_Stop(
1439 		IntPtr pEngine, /* FACTAudioEngine* */
1440 		ushort nCategory,
1441 		uint dwFlags
1442 	);
1443 
1444 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FACTAudioEngine_SetVolume( IntPtr pEngine, ushort nCategory, float volume )1445 	public static extern uint FACTAudioEngine_SetVolume(
1446 		IntPtr pEngine, /* FACTAudioEngine* */
1447 		ushort nCategory,
1448 		float volume
1449 	);
1450 
1451 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FACTAudioEngine_Pause( IntPtr pEngine, ushort nCategory, int fPause )1452 	public static extern uint FACTAudioEngine_Pause(
1453 		IntPtr pEngine, /* FACTAudioEngine* */
1454 		ushort nCategory,
1455 		int fPause
1456 	);
1457 
1458 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FACTAudioEngine_GetGlobalVariableIndex( IntPtr pEngine, byte* szFriendlyName )1459 	private static extern unsafe ushort FACTAudioEngine_GetGlobalVariableIndex(
1460 		IntPtr pEngine, /* FACTAudioEngine* */
1461 		byte* szFriendlyName
1462 	);
FACTAudioEngine_GetGlobalVariableIndex( IntPtr pEngine, string szFriendlyName )1463 	public static unsafe ushort FACTAudioEngine_GetGlobalVariableIndex(
1464 		IntPtr pEngine, /* FACTAudioEngine* */
1465 		string szFriendlyName
1466 	) {
1467 		int utf8BufSize = Utf8Size(szFriendlyName);
1468 		byte* utf8Buf = stackalloc byte[utf8BufSize];
1469 		return FACTAudioEngine_GetGlobalVariableIndex(
1470 			pEngine,
1471 			Utf8Encode(szFriendlyName, utf8Buf, utf8BufSize)
1472 		);
1473 	}
1474 
1475 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FACTAudioEngine_SetGlobalVariable( IntPtr pEngine, ushort nIndex, float nValue )1476 	public static extern uint FACTAudioEngine_SetGlobalVariable(
1477 		IntPtr pEngine, /* FACTAudioEngine* */
1478 		ushort nIndex,
1479 		float nValue
1480 	);
1481 
1482 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FACTAudioEngine_GetGlobalVariable( IntPtr pEngine, ushort nIndex, out float pnValue )1483 	public static extern uint FACTAudioEngine_GetGlobalVariable(
1484 		IntPtr pEngine, /* FACTAudioEngine* */
1485 		ushort nIndex,
1486 		out float pnValue
1487 	);
1488 
1489 	/* SoundBank Interface */
1490 
1491 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FACTSoundBank_GetCueIndex( IntPtr pSoundBank, byte* szFriendlyName )1492 	private static extern unsafe ushort FACTSoundBank_GetCueIndex(
1493 		IntPtr pSoundBank, /* FACTSoundBank* */
1494 		byte* szFriendlyName
1495 	);
FACTSoundBank_GetCueIndex( IntPtr pSoundBank, string szFriendlyName )1496 	public static unsafe ushort FACTSoundBank_GetCueIndex(
1497 		IntPtr pSoundBank, /* FACTSoundBank* */
1498 		string szFriendlyName
1499 	)
1500 	{
1501 		int utf8BufSize = Utf8Size(szFriendlyName);
1502 		byte* utf8Buf = stackalloc byte[utf8BufSize];
1503 		return FACTSoundBank_GetCueIndex(
1504 			pSoundBank,
1505 			Utf8Encode(szFriendlyName, utf8Buf, utf8BufSize)
1506 		);
1507 	}
1508 
1509 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FACTSoundBank_GetNumCues( IntPtr pSoundBank, out ushort pnNumCues )1510 	public static extern uint FACTSoundBank_GetNumCues(
1511 		IntPtr pSoundBank, /* FACTSoundBank* */
1512 		out ushort pnNumCues
1513 	);
1514 
1515 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FACTSoundBank_GetCueProperties( IntPtr pSoundBank, ushort nCueIndex, out FACTCueProperties pProperties )1516 	public static extern uint FACTSoundBank_GetCueProperties(
1517 		IntPtr pSoundBank, /* FACTSoundBank* */
1518 		ushort nCueIndex,
1519 		out FACTCueProperties pProperties
1520 	);
1521 
1522 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FACTSoundBank_Prepare( IntPtr pSoundBank, ushort nCueIndex, uint dwFlags, int timeOffset, out IntPtr ppCue )1523 	public static extern uint FACTSoundBank_Prepare(
1524 		IntPtr pSoundBank, /* FACTSoundBank* */
1525 		ushort nCueIndex,
1526 		uint dwFlags,
1527 		int timeOffset,
1528 		out IntPtr ppCue /* FACTCue** */
1529 	);
1530 
1531 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FACTSoundBank_Play( IntPtr pSoundBank, ushort nCueIndex, uint dwFlags, int timeOffset, out IntPtr ppCue )1532 	public static extern uint FACTSoundBank_Play(
1533 		IntPtr pSoundBank, /* FACTSoundBank* */
1534 		ushort nCueIndex,
1535 		uint dwFlags,
1536 		int timeOffset,
1537 		out IntPtr ppCue /* FACTCue** */
1538 	);
1539 
1540 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FACTSoundBank_Play( IntPtr pSoundBank, ushort nCueIndex, uint dwFlags, int timeOffset, IntPtr ppCue )1541 	public static extern uint FACTSoundBank_Play(
1542 		IntPtr pSoundBank, /* FACTSoundBank* */
1543 		ushort nCueIndex,
1544 		uint dwFlags,
1545 		int timeOffset,
1546 		IntPtr ppCue /* Pass IntPtr.Zero! */
1547 	);
1548 
1549 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FACTSoundBank_Play3D( IntPtr pSoundBank, ushort nCueIndex, uint dwFlags, int timeOffset, ref F3DAUDIO_DSP_SETTINGS pDSPSettings, IntPtr ppCue )1550 	public static extern uint FACTSoundBank_Play3D(
1551 		IntPtr pSoundBank, /* FACTSoundBank* */
1552 		ushort nCueIndex,
1553 		uint dwFlags,
1554 		int timeOffset,
1555 		ref F3DAUDIO_DSP_SETTINGS pDSPSettings,
1556 		IntPtr ppCue /* Pass IntPtr.Zero! */
1557 	);
1558 
1559 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FACTSoundBank_Stop( IntPtr pSoundBank, ushort nCueIndex, uint dwFlags )1560 	public static extern uint FACTSoundBank_Stop(
1561 		IntPtr pSoundBank, /* FACTSoundBank* */
1562 		ushort nCueIndex,
1563 		uint dwFlags
1564 	);
1565 
1566 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FACTSoundBank_Destroy( IntPtr pSoundBank )1567 	public static extern uint FACTSoundBank_Destroy(
1568 		IntPtr pSoundBank /* FACTSoundBank* */
1569 	);
1570 
1571 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FACTSoundBank_GetState( IntPtr pSoundBank, out uint pdwState )1572 	public static extern uint FACTSoundBank_GetState(
1573 		IntPtr pSoundBank, /* FACTSoundBank* */
1574 		out uint pdwState
1575 	);
1576 
1577 	/* WaveBank Interface */
1578 
1579 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FACTWaveBank_Destroy( IntPtr pWaveBank )1580 	public static extern uint FACTWaveBank_Destroy(
1581 		IntPtr pWaveBank /* FACTWaveBank* */
1582 	);
1583 
1584 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FACTWaveBank_GetState( IntPtr pWaveBank, out uint pdwState )1585 	public static extern uint FACTWaveBank_GetState(
1586 		IntPtr pWaveBank, /* FACTWaveBank* */
1587 		out uint pdwState
1588 	);
1589 
1590 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FACTWaveBank_GetNumWaves( IntPtr pWaveBank, out ushort pnNumWaves )1591 	public static extern uint FACTWaveBank_GetNumWaves(
1592 		IntPtr pWaveBank, /* FACTWaveBank* */
1593 		out ushort pnNumWaves
1594 	);
1595 
1596 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FACTWaveBank_GetWaveIndex( IntPtr pWaveBank, byte* szFriendlyName )1597 	private static extern unsafe ushort FACTWaveBank_GetWaveIndex(
1598 		IntPtr pWaveBank, /* FACTWaveBank* */
1599 		byte* szFriendlyName
1600 	);
FACTWaveBank_GetWaveIndex( IntPtr pWaveBank, string szFriendlyName )1601 	public static unsafe ushort FACTWaveBank_GetWaveIndex(
1602 		IntPtr pWaveBank, /* FACTWaveBank* */
1603 		string szFriendlyName
1604 	) {
1605 		int utf8BufSize = Utf8Size(szFriendlyName);
1606 		byte* utf8Buf = stackalloc byte[utf8BufSize];
1607 		return FACTWaveBank_GetWaveIndex(
1608 			pWaveBank,
1609 			Utf8Encode(szFriendlyName, utf8Buf, utf8BufSize)
1610 		);
1611 	}
1612 
1613 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FACTWaveBank_GetWaveProperties( IntPtr pWaveBank, ushort nWaveIndex, out FACTWaveProperties pWaveProperties )1614 	public static extern uint FACTWaveBank_GetWaveProperties(
1615 		IntPtr pWaveBank, /* FACTWaveBank* */
1616 		ushort nWaveIndex,
1617 		out FACTWaveProperties pWaveProperties
1618 	);
1619 
1620 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FACTWaveBank_Prepare( IntPtr pWaveBank, ushort nWaveIndex, uint dwFlags, uint dwPlayOffset, byte nLoopCount, out IntPtr ppWave )1621 	public static extern uint FACTWaveBank_Prepare(
1622 		IntPtr pWaveBank, /* FACTWaveBank* */
1623 		ushort nWaveIndex,
1624 		uint dwFlags,
1625 		uint dwPlayOffset,
1626 		byte nLoopCount,
1627 		out IntPtr ppWave /* FACTWave** */
1628 	);
1629 
1630 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FACTWaveBank_Play( IntPtr pWaveBank, ushort nWaveIndex, uint dwFlags, uint dwPlayOffset, byte nLoopCount, out IntPtr ppWave )1631 	public static extern uint FACTWaveBank_Play(
1632 		IntPtr pWaveBank, /* FACTWaveBank* */
1633 		ushort nWaveIndex,
1634 		uint dwFlags,
1635 		uint dwPlayOffset,
1636 		byte nLoopCount,
1637 		out IntPtr ppWave /* FACTWave** */
1638 	);
1639 
1640 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FACTWaveBank_Stop( IntPtr pWaveBank, ushort nWaveIndex, uint dwFlags )1641 	public static extern uint FACTWaveBank_Stop(
1642 		IntPtr pWaveBank, /* FACTWaveBank* */
1643 		ushort nWaveIndex,
1644 		uint dwFlags
1645 	);
1646 
1647 	/* Wave Interface */
1648 
1649 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FACTWave_Destroy( IntPtr pWave )1650 	public static extern uint FACTWave_Destroy(
1651 		IntPtr pWave /* FACTWave* */
1652 	);
1653 
1654 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FACTWave_Play( IntPtr pWave )1655 	public static extern uint FACTWave_Play(
1656 		IntPtr pWave /* FACTWave* */
1657 	);
1658 
1659 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FACTWave_Stop( IntPtr pWave, uint dwFlags )1660 	public static extern uint FACTWave_Stop(
1661 		IntPtr pWave, /* FACTWave* */
1662 		uint dwFlags
1663 	);
1664 
1665 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FACTWave_Pause( IntPtr pWave, int fPause )1666 	public static extern uint FACTWave_Pause(
1667 		IntPtr pWave, /* FACTWave* */
1668 		int fPause
1669 	);
1670 
1671 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FACTWave_GetState( IntPtr pWave, out uint pdwState )1672 	public static extern uint FACTWave_GetState(
1673 		IntPtr pWave, /* FACTWave* */
1674 		out uint pdwState
1675 	);
1676 
1677 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FACTWave_SetPitch( IntPtr pWave, short pitch )1678 	public static extern uint FACTWave_SetPitch(
1679 		IntPtr pWave, /* FACTWave* */
1680 		short pitch
1681 	);
1682 
1683 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FACTWave_SetVolume( IntPtr pWave, float volume )1684 	public static extern uint FACTWave_SetVolume(
1685 		IntPtr pWave, /* FACTWave* */
1686 		float volume
1687 	);
1688 
1689 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FACTWave_SetMatrixCoefficients( IntPtr pWave, uint uSrcChannelCount, uint uDstChannelCount, float[] pMatrixCoefficients )1690 	public static extern uint FACTWave_SetMatrixCoefficients(
1691 		IntPtr pWave, /* FACTWave* */
1692 		uint uSrcChannelCount,
1693 		uint uDstChannelCount,
1694 		float[] pMatrixCoefficients
1695 	);
1696 
1697 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FACTWave_GetProperties( IntPtr pWave, out FACTWaveInstanceProperties pProperties )1698 	public static extern uint FACTWave_GetProperties(
1699 		IntPtr pWave, /* FACTWave* */
1700 		out FACTWaveInstanceProperties pProperties
1701 	);
1702 
1703 	/* Cue Interface */
1704 
1705 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FACTCue_Destroy( IntPtr pCue )1706 	public static extern uint FACTCue_Destroy(
1707 		IntPtr pCue /* FACTCue* */
1708 	);
1709 
1710 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FACTCue_Play( IntPtr pCue )1711 	public static extern uint FACTCue_Play(
1712 		IntPtr pCue /* FACTCue* */
1713 	);
1714 
1715 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FACTCue_Stop( IntPtr pCue, uint dwFlags )1716 	public static extern uint FACTCue_Stop(
1717 		IntPtr pCue, /* FACTCue* */
1718 		uint dwFlags
1719 	);
1720 
1721 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FACTCue_GetState( IntPtr pCue, out uint pdwState )1722 	public static extern uint FACTCue_GetState(
1723 		IntPtr pCue, /* FACTCue* */
1724 		out uint pdwState
1725 	);
1726 
1727 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FACTCue_SetMatrixCoefficients( IntPtr pCue, uint uSrcChannelCount, uint uDstChannelCount, float[] pMatrixCoefficients )1728 	public static extern uint FACTCue_SetMatrixCoefficients(
1729 		IntPtr pCue, /* FACTCue* */
1730 		uint uSrcChannelCount,
1731 		uint uDstChannelCount,
1732 		float[] pMatrixCoefficients
1733 	);
1734 
1735 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FACTCue_GetVariableIndex( IntPtr pCue, byte* szFriendlyName )1736 	private static extern unsafe ushort FACTCue_GetVariableIndex(
1737 		IntPtr pCue, /* FACTCue* */
1738 		byte* szFriendlyName
1739 	);
FACTCue_GetVariableIndex( IntPtr pCue, string szFriendlyName )1740 	public static unsafe ushort FACTCue_GetVariableIndex(
1741 		IntPtr pCue, /* FACTCue* */
1742 		string szFriendlyName
1743 	) {
1744 		int utf8BufSize = Utf8Size(szFriendlyName);
1745 		byte* utf8Buf = stackalloc byte[utf8BufSize];
1746 		return FACTCue_GetVariableIndex(
1747 			pCue,
1748 			Utf8Encode(szFriendlyName, utf8Buf, utf8BufSize)
1749 		);
1750 	}
1751 
1752 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FACTCue_SetVariable( IntPtr pCue, ushort nIndex, float nValue )1753 	public static extern uint FACTCue_SetVariable(
1754 		IntPtr pCue, /* FACTCue* */
1755 		ushort nIndex,
1756 		float nValue
1757 	);
1758 
1759 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FACTCue_GetVariable( IntPtr pCue, ushort nIndex, out float nValue )1760 	public static extern uint FACTCue_GetVariable(
1761 		IntPtr pCue, /* FACTCue* */
1762 		ushort nIndex,
1763 		out float nValue
1764 	);
1765 
1766 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FACTCue_Pause( IntPtr pCue, int fPause )1767 	public static extern uint FACTCue_Pause(
1768 		IntPtr pCue, /* FACTCue* */
1769 		int fPause
1770 	);
1771 
1772 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FACTCue_GetProperties( IntPtr pCue, out IntPtr ppProperties )1773 	public static extern uint FACTCue_GetProperties(
1774 		IntPtr pCue, /* FACTCue* */
1775 		out IntPtr ppProperties /* FACTCueInstanceProperties** */
1776 	);
1777 
1778 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FACTCue_SetOutputVoices( IntPtr pCue, IntPtr pSendList )1779 	public static extern uint FACTCue_SetOutputVoices(
1780 		IntPtr pCue, /* FACTCue* */
1781 		IntPtr pSendList /* Optional FAudioVoiceSends* */
1782 	);
1783 
1784 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FACTCue_SetOutputVoiceMatrix( IntPtr pCue, IntPtr pDestinationVoice, uint SourceChannels, uint DestinationChannels, float[] pLevelMatrix )1785 	public static extern uint FACTCue_SetOutputVoiceMatrix(
1786 		IntPtr pCue, /* FACTCue* */
1787 		IntPtr pDestinationVoice, /* Optional FAudioVoice* */
1788 		uint SourceChannels,
1789 		uint DestinationChannels,
1790 		float[] pLevelMatrix /* SourceChannels * DestinationChannels */
1791 	);
1792 
1793 	#endregion
1794 
1795 	#region F3DAudio API
1796 
1797 	/* Constants */
1798 
1799 	public const uint SPEAKER_FRONT_LEFT =			0x00000001;
1800 	public const uint SPEAKER_FRONT_RIGHT =			0x00000002;
1801 	public const uint SPEAKER_FRONT_CENTER =		0x00000004;
1802 	public const uint SPEAKER_LOW_FREQUENCY =		0x00000008;
1803 	public const uint SPEAKER_BACK_LEFT =			0x00000010;
1804 	public const uint SPEAKER_BACK_RIGHT =			0x00000020;
1805 	public const uint SPEAKER_FRONT_LEFT_OF_CENTER =	0x00000040;
1806 	public const uint SPEAKER_FRONT_RIGHT_OF_CENTER =	0x00000080;
1807 	public const uint SPEAKER_BACK_CENTER =			0x00000100;
1808 	public const uint SPEAKER_SIDE_LEFT =			0x00000200;
1809 	public const uint SPEAKER_SIDE_RIGHT =			0x00000400;
1810 	public const uint SPEAKER_TOP_CENTER =			0x00000800;
1811 	public const uint SPEAKER_TOP_FRONT_LEFT =		0x00001000;
1812 	public const uint SPEAKER_TOP_FRONT_CENTER =		0x00002000;
1813 	public const uint SPEAKER_TOP_FRONT_RIGHT =		0x00004000;
1814 	public const uint SPEAKER_TOP_BACK_LEFT =		0x00008000;
1815 	public const uint SPEAKER_TOP_BACK_CENTER =		0x00010000;
1816 	public const uint SPEAKER_TOP_BACK_RIGHT =		0x00020000;
1817 
1818 	public const uint SPEAKER_MONO =	SPEAKER_FRONT_CENTER;
1819 	public const uint SPEAKER_STEREO =	(SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT);
1820 	public const uint SPEAKER_2POINT1 =
1821 		(	SPEAKER_FRONT_LEFT	|
1822 			SPEAKER_FRONT_RIGHT	|
1823 			SPEAKER_LOW_FREQUENCY	);
1824 	public const uint SPEAKER_SURROUND =
1825 		(	SPEAKER_FRONT_LEFT	|
1826 			SPEAKER_FRONT_RIGHT	|
1827 			SPEAKER_FRONT_CENTER	|
1828 			SPEAKER_BACK_CENTER	);
1829 	public const uint SPEAKER_QUAD =
1830 		(	SPEAKER_FRONT_LEFT	|
1831 			SPEAKER_FRONT_RIGHT	|
1832 			SPEAKER_BACK_LEFT	|
1833 			SPEAKER_BACK_RIGHT	);
1834 	public const uint SPEAKER_4POINT1 =
1835 		(	SPEAKER_FRONT_LEFT	|
1836 			SPEAKER_FRONT_RIGHT	|
1837 			SPEAKER_LOW_FREQUENCY	|
1838 			SPEAKER_BACK_LEFT	|
1839 			SPEAKER_BACK_RIGHT	);
1840 	public const uint SPEAKER_5POINT1 =
1841 		(	SPEAKER_FRONT_LEFT	|
1842 			SPEAKER_FRONT_RIGHT	|
1843 			SPEAKER_FRONT_CENTER	|
1844 			SPEAKER_LOW_FREQUENCY	|
1845 			SPEAKER_BACK_LEFT	|
1846 			SPEAKER_BACK_RIGHT	);
1847 	public const uint SPEAKER_7POINT1 =
1848 		(	SPEAKER_FRONT_LEFT		|
1849 			SPEAKER_FRONT_RIGHT		|
1850 			SPEAKER_FRONT_CENTER		|
1851 			SPEAKER_LOW_FREQUENCY		|
1852 			SPEAKER_BACK_LEFT		|
1853 			SPEAKER_BACK_RIGHT		|
1854 			SPEAKER_FRONT_LEFT_OF_CENTER	|
1855 			SPEAKER_FRONT_RIGHT_OF_CENTER	);
1856 	public const uint SPEAKER_5POINT1_SURROUND =
1857 		(	SPEAKER_FRONT_LEFT	|
1858 			SPEAKER_FRONT_RIGHT	|
1859 			SPEAKER_FRONT_CENTER	|
1860 			SPEAKER_LOW_FREQUENCY	|
1861 			SPEAKER_SIDE_LEFT	|
1862 			SPEAKER_SIDE_RIGHT	);
1863 	public const uint SPEAKER_7POINT1_SURROUND =
1864 		(	SPEAKER_FRONT_LEFT	|
1865 			SPEAKER_FRONT_RIGHT	|
1866 			SPEAKER_FRONT_CENTER	|
1867 			SPEAKER_LOW_FREQUENCY	|
1868 			SPEAKER_BACK_LEFT	|
1869 			SPEAKER_BACK_RIGHT	|
1870 			SPEAKER_SIDE_LEFT	|
1871 			SPEAKER_SIDE_RIGHT	);
1872 
1873 	/* FIXME: Hmmmm */
1874 	public const uint SPEAKER_XBOX = SPEAKER_5POINT1;
1875 
1876 	public const float F3DAUDIO_PI =	3.141592654f;
1877 	public const float F3DAUDIO_2PI =	6.283185307f;
1878 
1879 	public const uint F3DAUDIO_CALCULATE_MATRIX =		0x00000001;
1880 	public const uint F3DAUDIO_CALCULATE_DELAY =		0x00000002;
1881 	public const uint F3DAUDIO_CALCULATE_LPF_DIRECT =	0x00000004;
1882 	public const uint F3DAUDIO_CALCULATE_LPF_REVERB =	0x00000008;
1883 	public const uint F3DAUDIO_CALCULATE_REVERB =		0x00000010;
1884 	public const uint F3DAUDIO_CALCULATE_DOPPLER =		0x00000020;
1885 	public const uint F3DAUDIO_CALCULATE_EMITTER_ANGLE =	0x00000040;
1886 	public const uint F3DAUDIO_CALCULATE_ZEROCENTER =	0x00010000;
1887 	public const uint F3DAUDIO_CALCULATE_REDIRECT_TO_LFE =	0x00020000;
1888 
1889 	/* Type Declarations */
1890 
1891 	/* FIXME: Everything about this type blows */
1892 	public const int F3DAUDIO_HANDLE_BYTESIZE = 20;
1893 	// Alloc a byte[] of size F3DAUDIO_HANDLE_BYTESIZE!
1894 
1895 	/* Structures */
1896 
1897 	[StructLayout(LayoutKind.Sequential, Pack = 1)]
1898 	public struct F3DAUDIO_VECTOR
1899 	{
1900 		public float x;
1901 		public float y;
1902 		public float z;
1903 	}
1904 
1905 	[StructLayout(LayoutKind.Sequential, Pack = 1)]
1906 	public struct F3DAUDIO_DISTANCE_CURVE_POINT
1907 	{
1908 		public float Distance;
1909 		public float DSPSetting;
1910 	}
1911 
1912 	[StructLayout(LayoutKind.Sequential, Pack = 1)]
1913 	public struct F3DAUDIO_DISTANCE_CURVE
1914 	{
1915 		IntPtr pPoints; /* F3DAUDIO_DISTANCE_CURVE_POINT* */
1916 		public uint PointCount;
1917 	}
1918 
1919 	[StructLayout(LayoutKind.Sequential, Pack = 1)]
1920 	public struct F3DAUDIO_CONE
1921 	{
1922 		public float InnerAngle;
1923 		public float OuterAngle;
1924 		public float InnerVolume;
1925 		public float OuterVolume;
1926 		public float InnerLPF;
1927 		public float OuterLPF;
1928 		public float InnerReverb;
1929 		public float OuterReverb;
1930 	}
1931 
1932 	[StructLayout(LayoutKind.Sequential, Pack = 1)]
1933 	public struct F3DAUDIO_LISTENER
1934 	{
1935 		public F3DAUDIO_VECTOR OrientFront;
1936 		public F3DAUDIO_VECTOR OrientTop;
1937 		public F3DAUDIO_VECTOR Position;
1938 		public F3DAUDIO_VECTOR Velocity;
1939 		public IntPtr pCone; /* F3DAUDIO_CONE* */
1940 	}
1941 
1942 	[StructLayout(LayoutKind.Sequential, Pack = 1)]
1943 	public struct F3DAUDIO_EMITTER
1944 	{
1945 		public IntPtr pCone; /* F3DAUDIO_CONE* */
1946 		public F3DAUDIO_VECTOR OrientFront;
1947 		public F3DAUDIO_VECTOR OrientTop;
1948 		public F3DAUDIO_VECTOR Position;
1949 		public F3DAUDIO_VECTOR Velocity;
1950 		public float InnerRadius;
1951 		public float InnerRadiusAngle;
1952 		public uint ChannelCount;
1953 		public float ChannelRadius;
1954 		public IntPtr pChannelAzimuths; /* float */
1955 		public IntPtr pVolumeCurve;
1956 		public IntPtr pLFECurve; /* F3DAUDIO_DISTANCE_CURVE* */
1957 		public IntPtr pLPFDirectCurve; /* F3DAUDIO_DISTANCE_CURVE* */
1958 		public IntPtr pLPFReverbCurve; /* F3DAUDIO_DISTANCE_CURVE* */
1959 		public IntPtr pReverbCurve; /* F3DAUDIO_DISTANCE_CURVE* */
1960 		public float CurveDistanceScaler;
1961 		public float DopplerScaler;
1962 	}
1963 
1964 	[StructLayout(LayoutKind.Sequential, Pack = 1)]
1965 	public struct F3DAUDIO_DSP_SETTINGS
1966 	{
1967 		public IntPtr pMatrixCoefficients; /* float* */
1968 		public IntPtr pDelayTimes; /* float* */
1969 		public uint SrcChannelCount;
1970 		public uint DstChannelCount;
1971 		public float LPFDirectCoefficient;
1972 		public float LPFReverbCoefficient;
1973 		public float ReverbLevel;
1974 		public float DopplerFactor;
1975 		public float EmitterToListenerAngle;
1976 		public float EmitterToListenerDistance;
1977 		public float EmitterVelocityComponent;
1978 		public float ListenerVelocityComponent;
1979 	}
1980 
1981 	/* Functions */
1982 
1983 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
F3DAudioInitialize( uint SpeakerChannelMask, float SpeedOfSound, byte[] Instance )1984 	public static extern void F3DAudioInitialize(
1985 		uint SpeakerChannelMask,
1986 		float SpeedOfSound,
1987 		byte[] Instance // F3DAUDIO_HANDLE
1988 	);
1989 
1990 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
F3DAudioInitialize8( uint SpeakerChannelMask, float SpeedOfSound, byte[] Instance )1991 	public static extern uint F3DAudioInitialize8(
1992 		uint SpeakerChannelMask,
1993 		float SpeedOfSound,
1994 		byte[] Instance // F3DAUDIO_HANDLE
1995 	);
1996 
1997 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
F3DAudioCalculate( byte[] Instance, ref F3DAUDIO_LISTENER pListener, ref F3DAUDIO_EMITTER pEmitter, uint Flags, ref F3DAUDIO_DSP_SETTINGS pDSPSettings )1998 	public static extern void F3DAudioCalculate(
1999 		byte[] Instance, // F3DAUDIO_HANDLE
2000 		ref F3DAUDIO_LISTENER pListener,
2001 		ref F3DAUDIO_EMITTER pEmitter,
2002 		uint Flags,
2003 		ref F3DAUDIO_DSP_SETTINGS pDSPSettings
2004 	);
2005 
2006 	#endregion
2007 
2008 	#region FACT3D API
2009 
2010 	/* Constants */
2011 
2012 	public const float LEFT_AZIMUTH =			(3.0f * F3DAUDIO_PI / 2.0f);
2013 	public const float RIGHT_AZIMUTH =			(F3DAUDIO_PI / 2.0f);
2014 	public const float FRONT_LEFT_AZIMUTH =			(7.0f * F3DAUDIO_PI / 4.0f);
2015 	public const float FRONT_RIGHT_AZIMUTH =		(F3DAUDIO_PI / 4.0f);
2016 	public const float FRONT_CENTER_AZIMUTH =		0.0f;
2017 	public const float LOW_FREQUENCY_AZIMUTH =		F3DAUDIO_2PI;
2018 	public const float BACK_LEFT_AZIMUTH =			(5.0f * F3DAUDIO_PI / 4.0f);
2019 	public const float BACK_RIGHT_AZIMUTH =			(3.0f * F3DAUDIO_PI / 4.0f);
2020 	public const float BACK_CENTER_AZIMUTH =		F3DAUDIO_PI;
2021 	public const float FRONT_LEFT_OF_CENTER_AZIMUTH =	(15.0f * F3DAUDIO_PI / 8.0f);
2022 	public const float FRONT_RIGHT_OF_CENTER_AZIMUTH =	(F3DAUDIO_PI / 8.0f);
2023 
2024 	public static readonly float[] aStereoLayout = new float[]
2025 	{
2026 		LEFT_AZIMUTH,
2027 		RIGHT_AZIMUTH
2028 	};
2029 	public static readonly float[] a2Point1Layout = new float[]
2030 	{
2031 		LEFT_AZIMUTH,
2032 		RIGHT_AZIMUTH,
2033 		LOW_FREQUENCY_AZIMUTH
2034 	};
2035 	public static readonly float[] aQuadLayout = new float[]
2036 	{
2037 		FRONT_LEFT_AZIMUTH,
2038 		FRONT_RIGHT_AZIMUTH,
2039 		BACK_LEFT_AZIMUTH,
2040 		BACK_RIGHT_AZIMUTH
2041 	};
2042 	public static readonly float[] a4Point1Layout = new float[]
2043 	{
2044 		FRONT_LEFT_AZIMUTH,
2045 		FRONT_RIGHT_AZIMUTH,
2046 		LOW_FREQUENCY_AZIMUTH,
2047 		BACK_LEFT_AZIMUTH,
2048 		BACK_RIGHT_AZIMUTH
2049 	};
2050 	public static readonly float[] a5Point1Layout = new float[]
2051 	{
2052 		FRONT_LEFT_AZIMUTH,
2053 		FRONT_RIGHT_AZIMUTH,
2054 		FRONT_CENTER_AZIMUTH,
2055 		LOW_FREQUENCY_AZIMUTH,
2056 		BACK_LEFT_AZIMUTH,
2057 		BACK_RIGHT_AZIMUTH
2058 	};
2059 	public static readonly float[] a7Point1Layout = new float[]
2060 	{
2061 		FRONT_LEFT_AZIMUTH,
2062 		FRONT_RIGHT_AZIMUTH,
2063 		FRONT_CENTER_AZIMUTH,
2064 		LOW_FREQUENCY_AZIMUTH,
2065 		BACK_LEFT_AZIMUTH,
2066 		BACK_RIGHT_AZIMUTH,
2067 		LEFT_AZIMUTH,
2068 		RIGHT_AZIMUTH
2069 	};
2070 
2071 	/* Functions */
2072 
2073 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FACT3DInitialize( IntPtr pEngine, byte[] D3FInstance )2074 	public static extern uint FACT3DInitialize(
2075 		IntPtr pEngine, /* FACTAudioEngine* */
2076 		byte[] D3FInstance // F3DAUDIO_HANDLE
2077 	);
2078 
2079 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FACT3DCalculate( byte[] F3DInstance, ref F3DAUDIO_LISTENER pListener, ref F3DAUDIO_EMITTER pEmitter, ref F3DAUDIO_DSP_SETTINGS pDSPSettings )2080 	public static extern uint FACT3DCalculate(
2081 		byte[] F3DInstance, // F3DAUDIO_HANDLE
2082 		ref F3DAUDIO_LISTENER pListener,
2083 		ref F3DAUDIO_EMITTER pEmitter,
2084 		ref F3DAUDIO_DSP_SETTINGS pDSPSettings
2085 	);
2086 
2087 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FACT3DApply( ref F3DAUDIO_DSP_SETTINGS pDSPSettings, IntPtr pCue )2088 	public static extern uint FACT3DApply(
2089 		ref F3DAUDIO_DSP_SETTINGS pDSPSettings,
2090 		IntPtr pCue /* FACTCue* */
2091 	);
2092 
2093 	#endregion
2094 
2095 	#region XNA Song API
2096 
2097 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
XNA_SongInit()2098 	public static extern void XNA_SongInit();
2099 
2100 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
XNA_SongQuit()2101 	public static extern void XNA_SongQuit();
2102 
2103 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
XNA_PlaySong(byte* name)2104 	private static extern unsafe float XNA_PlaySong(byte* name);
XNA_PlaySong(string name)2105 	public static unsafe float XNA_PlaySong(string name)
2106 	{
2107 		int utf8BufSize = Utf8Size(name);
2108 		byte* utf8Buf = stackalloc byte[utf8BufSize];
2109 		return XNA_PlaySong(Utf8Encode(name, utf8Buf, utf8BufSize));
2110 	}
2111 
2112 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
XNA_PauseSong()2113 	public static extern void XNA_PauseSong();
2114 
2115 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
XNA_ResumeSong()2116 	public static extern void XNA_ResumeSong();
2117 
2118 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
XNA_StopSong()2119 	public static extern void XNA_StopSong();
2120 
2121 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
XNA_SetSongVolume(float volume)2122 	public static extern void XNA_SetSongVolume(float volume);
2123 
2124 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
XNA_GetSongEnded()2125 	public static extern uint XNA_GetSongEnded();
2126 
2127 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
XNA_EnableVisualization(uint enable)2128 	public static extern void XNA_EnableVisualization(uint enable);
2129 
2130 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
XNA_VisualizationEnabled()2131 	public static extern uint XNA_VisualizationEnabled();
2132 
2133 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
XNA_GetSongVisualizationData( float[] frequencies, float[] samples, uint count )2134 	public static extern void XNA_GetSongVisualizationData(
2135 		float[] frequencies,
2136 		float[] samples,
2137 		uint count
2138 	);
2139 
2140 	#endregion
2141 
2142 	#region FAudio I/O API
2143 
2144 	/* Delegates */
2145 
2146 	/* IntPtr refers to a size_t */
2147 	[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
FAudio_readfunc( IntPtr data, IntPtr dst, IntPtr size, IntPtr count )2148 	public delegate IntPtr FAudio_readfunc(
2149 		IntPtr data, /* void* */
2150 		IntPtr dst, /* void* */
2151 		IntPtr size, /* size_t */
2152 		IntPtr count /* size_t */
2153 	);
2154 
2155 	[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
FAudio_seekfunc( IntPtr data, long offset, int whence )2156 	public delegate long FAudio_seekfunc(
2157 		IntPtr data, /* void* */
2158 		long offset,
2159 		int whence
2160 	);
2161 
2162 	[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
FAudio_closefunc(IntPtr data)2163 	public delegate int FAudio_closefunc(IntPtr data);
2164 
2165 	/* Structures */
2166 
2167 	[StructLayout(LayoutKind.Sequential)]
2168 	public struct FAudioIOStream
2169 	{
2170 		public IntPtr data;
2171 		public IntPtr read; /* FAudio_readfunc */
2172 		public IntPtr seek; /* FAudio_seekfunc */
2173 		public IntPtr close; /* FAudio_closefunc */
2174 		public IntPtr ioLock; /* lock, lolC# */
2175 	}
2176 
2177 	/* Functions */
2178 
2179 	/* IntPtr refers to an FAudioIOStream* */
2180 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FAudio_fopen(byte* path)2181 	private static extern unsafe IntPtr FAudio_fopen(byte* path);
FAudio_fopen(string path)2182 	public static unsafe IntPtr FAudio_fopen(string path)
2183 	{
2184 		int utf8BufSize = Utf8Size(path);
2185 		byte* utf8Buf = stackalloc byte[utf8BufSize];
2186 		return FAudio_fopen(Utf8Encode(path, utf8Buf, utf8BufSize));
2187 	}
2188 
2189 	/* IntPtr refers to an FAudioIOStream* */
2190 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FAudio_memopen(IntPtr mem, int len)2191 	public static extern IntPtr FAudio_memopen(IntPtr mem, int len);
2192 
2193 	/* IntPtr refers to a uint8_t* */
2194 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FAudio_memptr(IntPtr io, IntPtr offset)2195 	public static extern IntPtr FAudio_memptr(IntPtr io, IntPtr offset);
2196 
2197 	/* io refers to an FAudioIOStream* */
2198 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
FAudio_close(IntPtr io)2199 	public static extern void FAudio_close(IntPtr io);
2200 
2201 	#endregion
2202 
2203 	#region stb_vorbis
2204 
2205 	/* Because why not? */
2206 
2207 	[StructLayout(LayoutKind.Sequential)]
2208 	public struct stb_vorbis_alloc
2209 	{
2210 		public IntPtr alloc_buffer;
2211 		public int alloc_buffer_length_in_bytes;
2212 	}
2213 
2214 	[StructLayout(LayoutKind.Sequential)]
2215 	public struct stb_vorbis_info
2216 	{
2217 		public uint sample_rate;
2218 		public int channels;
2219 
2220 		public uint setup_memory_required;
2221 		public uint setup_temp_memory_required;
2222 		public uint temp_memory_required;
2223 
2224 		public int max_frame_size;
2225 	}
2226 
2227 	[StructLayout(LayoutKind.Sequential)]
2228 	public struct stb_vorbis_comment
2229 	{
2230 		public IntPtr vendor;
2231 
2232 		public int comment_list_length;
2233 		public IntPtr comment_list;
2234 	}
2235 
2236 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
stb_vorbis_get_info(IntPtr f)2237 	public static extern stb_vorbis_info stb_vorbis_get_info(IntPtr f);
2238 
2239 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
stb_vorbis_get_comment(IntPtr f)2240 	public static extern stb_vorbis_comment stb_vorbis_get_comment(IntPtr f);
2241 
2242 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
stb_vorbis_get_error(IntPtr f)2243 	public static extern int stb_vorbis_get_error(IntPtr f);
2244 
2245 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
stb_vorbis_close(IntPtr f)2246 	public static extern void stb_vorbis_close(IntPtr f);
2247 
2248 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
stb_vorbis_get_sample_offset(IntPtr f)2249 	public static extern int stb_vorbis_get_sample_offset(IntPtr f);
2250 
2251 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
stb_vorbis_get_file_offset(IntPtr f)2252 	public static extern uint stb_vorbis_get_file_offset(IntPtr f);
2253 
2254 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
stb_vorbis_open_memory( IntPtr data, int len, out int error, IntPtr alloc_buffer )2255 	public static extern IntPtr stb_vorbis_open_memory(
2256 		IntPtr data,
2257 		int len,
2258 		out int error,
2259 		IntPtr alloc_buffer /* stb_vorbis_alloc* */
2260 	);
2261 
2262 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
stb_vorbis_open_filename( byte* filename, out int error, IntPtr alloc_buffer )2263 	private static extern unsafe IntPtr stb_vorbis_open_filename(
2264 		byte* filename,
2265 		out int error,
2266 		IntPtr alloc_buffer /* stb_vorbis_alloc* */
2267 	);
stb_vorbis_open_filename( string filename, out int error, IntPtr alloc_buffer )2268 	public static unsafe IntPtr stb_vorbis_open_filename(
2269 		string filename,
2270 		out int error,
2271 		IntPtr alloc_buffer /* stb_vorbis_alloc* */
2272 	) {
2273 		int utf8BufSize = Utf8Size(filename);
2274 		byte* utf8Buf = stackalloc byte[utf8BufSize];
2275 		return stb_vorbis_open_filename(
2276 			Utf8Encode(filename, utf8Buf, utf8BufSize),
2277 			out error,
2278 			alloc_buffer
2279 		);
2280 	}
2281 
2282 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
stb_vorbis_open_file( IntPtr f, int close_handle_on_close, out int error, IntPtr alloc_buffer )2283 	public static extern IntPtr stb_vorbis_open_file(
2284 		IntPtr f, /* FAudioIOStream* */
2285 		int close_handle_on_close,
2286 		out int error,
2287 		IntPtr alloc_buffer /* stb_vorbis_alloc* */
2288 	);
2289 
2290 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
stb_vorbis_open_file_section( IntPtr f, int close_handle_on_close, out int error, IntPtr alloc_buffer, uint len )2291 	public static extern IntPtr stb_vorbis_open_file_section(
2292 		IntPtr f, /* FAudioIOStream* */
2293 		int close_handle_on_close,
2294 		out int error,
2295 		IntPtr alloc_buffer, /* stb_vorbis_alloc* */
2296 		uint len
2297 	);
2298 
2299 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
stb_vorbis_seek_frame(IntPtr f, uint sample_number)2300 	public static extern int stb_vorbis_seek_frame(IntPtr f, uint sample_number);
2301 
2302 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
stb_vorbis_seek(IntPtr f, uint sample_number)2303 	public static extern int stb_vorbis_seek(IntPtr f, uint sample_number);
2304 
2305 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
stb_vorbis_seek_start(IntPtr f)2306 	public static extern int stb_vorbis_seek_start(IntPtr f);
2307 
2308 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
stb_vorbis_stream_length_in_samples(IntPtr f)2309 	public static extern uint stb_vorbis_stream_length_in_samples(IntPtr f);
2310 
2311 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
stb_vorbis_stream_length_in_seconds(IntPtr f)2312 	public static extern float stb_vorbis_stream_length_in_seconds(IntPtr f);
2313 
2314 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
stb_vorbis_get_frame_float( IntPtr f, out int channels, ref float[][] output )2315 	public static extern int stb_vorbis_get_frame_float(
2316 		IntPtr f,
2317 		out int channels,
2318 		ref float[][] output
2319 	);
2320 
2321 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
stb_vorbis_get_frame_float( IntPtr f, IntPtr channels, ref float[][] output )2322 	public static extern int stb_vorbis_get_frame_float(
2323 		IntPtr f,
2324 		IntPtr channels, /* IntPtr.Zero */
2325 		ref float[][] output
2326 	);
2327 
2328 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
stb_vorbis_get_samples_float_interleaved( IntPtr f, int channels, float[] buffer, int num_floats )2329 	public static extern int stb_vorbis_get_samples_float_interleaved(
2330 		IntPtr f,
2331 		int channels,
2332 		float[] buffer,
2333 		int num_floats
2334 	);
2335 
2336 	[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
stb_vorbis_get_samples_float( IntPtr f, int channels, float[][] buffer, int num_samples )2337 	public static extern int stb_vorbis_get_samples_float(
2338 		IntPtr f,
2339 		int channels,
2340 		float[][] buffer,
2341 		int num_samples
2342 	);
2343 
2344 	#endregion
2345 }
2346