Files
Odin/vendor/windows/XAudio2/xaudio2.odin
2025-05-26 21:17:44 +02:00

818 lines
42 KiB
Odin

#+build windows
/*
Bindings for Windows XAudio2:
https://learn.microsoft.com/en-us/windows/win32/xaudio2/xaudio2-introduction
Compiling for Windows 10 RS5 (1809) and later
*/
package windows_xaudio2
import win "core:sys/windows"
import "core:math"
foreign import xa2 "system:xaudio2.lib"
HRESULT :: win.HRESULT
IUnknown :: win.IUnknown
IUnknown_VTable :: win.IUnknown_VTable
WAVEFORMATEX :: win.WAVEFORMATEX
/**************************************************************************
*
* XAudio2 constants, flags and error codes.
*
**************************************************************************/
// Numeric boundary values
MAX_BUFFER_BYTES :: 0x80000000 // Maximum bytes allowed in a source buffer
MAX_QUEUED_BUFFERS :: 64 // Maximum buffers allowed in a voice queue
MAX_BUFFERS_SYSTEM :: 2 // Maximum buffers allowed for system threads (Xbox 360 only)
MAX_AUDIO_CHANNELS :: 64 // Maximum channels in an audio stream
MIN_SAMPLE_RATE :: 1000 // Minimum audio sample rate supported
MAX_SAMPLE_RATE :: 200000 // Maximum audio sample rate supported
MAX_VOLUME_LEVEL :: 16777216.0 // Maximum acceptable volume level (2^24)
MIN_FREQ_RATIO :: (1.0 / 1024.0) // Minimum SetFrequencyRatio argument
MAX_FREQ_RATIO :: 1024.0 // Maximum MaxFrequencyRatio argument
DEFAULT_FREQ_RATIO :: 2.0 // Default MaxFrequencyRatio argument
MAX_FILTER_ONEOVERQ :: 1.5 // Maximum FILTER_PARAMETERS.OneOverQ
MAX_FILTER_FREQUENCY :: 1.0 // Maximum FILTER_PARAMETERS.Frequency
MAX_LOOP_COUNT :: 254 // Maximum non-infinite BUFFER.LoopCount
MAX_INSTANCES :: 8 // Maximum simultaneous XAudio2 objects on Xbox 360
// For XMA voices on Xbox 360 there is an additional restriction on the MaxFrequencyRatio argument and the voice's sample rate: the product of these numbers cannot exceed 600000 for one-channel voices or 300000 for voices with more than one channel.
MAX_RATIO_TIMES_RATE_XMA_MONO :: 600000
MAX_RATIO_TIMES_RATE_XMA_MULTICHANNEL :: 300000
// Numeric values with special meanings
COMMIT_NOW :: 0 // Used as an OperationSet argument
COMMIT_ALL :: 0 // Used in IXAudio2.CommitChanges
INVALID_OPSET :: 0xffffffff // Not allowed for OperationSet arguments
NO_LOOP_REGION :: 0 // Used in BUFFER.LoopCount
LOOP_INFINITE :: 255 // Used in BUFFER.LoopCount
DEFAULT_CHANNELS :: 0 // Used in CreateMasteringVoice
DEFAULT_SAMPLERATE :: 0 // Used in CreateMasteringVoice
// Flags
FLAGS :: distinct bit_set[FLAG; u32]
FLAG :: enum u32 {
DEBUG_ENGINE = 0, // Used in Create
VOICE_NOPITCH = 1, // Used in IXAudio2.CreateSourceVoice
VOICE_NOSRC = 2, // Used in IXAudio2.CreateSourceVoice
VOICE_USEFILTER = 3, // Used in IXAudio2.CreateSource/SubmixVoice
PLAY_TAILS = 5, // Used in IXAudio2SourceVoice.Stop
END_OF_STREAM = 6, // Used in BUFFER.Flags
SEND_USEFILTER = 7, // Used in SEND_DESCRIPTOR.Flags
VOICE_NOSAMPLESPLAYED = 8, // Used in IXAudio2SourceVoice.GetState
STOP_ENGINE_WHEN_IDLE = 13, // Used in Create to force the engine to Stop when no source voices are Started, and Start when a voice is Started
QUANTUM_1024 = 15, // Used in Create to specify nondefault processing quantum of 21.33 ms (1024 samples at 48KHz)
NO_VIRTUAL_AUDIO_CLIENT = 16, // Used in CreateMasteringVoice to create a virtual audio client
}
// Default parameters for the built-in filter
DEFAULT_FILTER_TYPE :: FILTER_TYPE.LowPassFilter
DEFAULT_FILTER_FREQUENCY :: MAX_FILTER_FREQUENCY
DEFAULT_FILTER_ONEOVERQ :: 1.0
// Internal XAudio2 constants
// The audio frame quantum can be calculated by reducing the fraction:
// SamplesPerAudioFrame / SamplesPerSecond
QUANTUM_NUMERATOR :: 1 // On Windows, XAudio2 processes audio
QUANTUM_DENOMINATOR :: 100 // in 10ms chunks (= 1/100 seconds)
QUANTUM_MS :: (1000.0 * QUANTUM_NUMERATOR / QUANTUM_DENOMINATOR)
// XAudio2 error codes
INVALID_CALL :: HRESULT(-2003435519) // 0x88960001 An API call or one of its arguments was illegal
XMA_DECODER_ERROR :: HRESULT(-2003435518) // 0x88960002 The XMA hardware suffered an unrecoverable error
XAPO_CREATION_FAILED :: HRESULT(-2003435517) // 0x88960003 XAudio2 failed to initialize an XAPO effect
DEVICE_INVALIDATED :: HRESULT(-2003435516) // 0x88960004 An audio device became unusable (unplugged, etc)
/**************************************************************************
*
* XAudio2 structures and enumerations.
*
**************************************************************************/
// Used in Create, specifies which CPU(s) to use.
PROCESSOR_FLAGS :: distinct bit_set[PROCESSOR_FLAG; u32]
PROCESSOR_FLAG :: enum u32 {
Processor1 = 0,
Processor2 = 1,
Processor3 = 2,
Processor4 = 3,
Processor5 = 4,
Processor6 = 5,
Processor7 = 6,
Processor8 = 7,
Processor9 = 8,
Processor10 = 9,
Processor11 = 10,
Processor12 = 11,
Processor13 = 12,
Processor14 = 13,
Processor15 = 14,
Processor16 = 15,
Processor17 = 16,
Processor18 = 17,
Processor19 = 18,
Processor20 = 19,
Processor21 = 20,
Processor22 = 21,
Processor23 = 22,
Processor24 = 23,
Processor25 = 24,
Processor26 = 25,
Processor27 = 26,
Processor28 = 27,
Processor29 = 28,
Processor30 = 29,
Processor31 = 30,
Processor32 = 31,
}
//ANY_PROCESSOR :: 0xffffffff
USE_DEFAULT_PROCESSOR :: PROCESSOR_FLAGS{}
// Returned by IXAudio2Voice.GetVoiceDetails
VOICE_DETAILS :: struct #packed {
CreatingFlags: FLAGS,
ActiveFlags: FLAGS,
InputChannels: u32,
InputSampleRate: u32,
}
// Used in VOICE_SENDS below
SEND_DESCRIPTOR :: struct #packed {
Flags: FLAGS, // Either 0 or SEND_USEFILTER.
pOutputVoice: ^IXAudio2Voice, // This send's destination voice.
}
// Used in the voice creation functions and in IXAudio2Voice.SetOutputVoices
VOICE_SENDS :: struct #packed {
SendCount: u32, // Number of sends from this voice.
pSends: [^]SEND_DESCRIPTOR `fmt:"v,SendCount"`, // Array of SendCount send descriptors.
}
// Used in EFFECT_CHAIN below
EFFECT_DESCRIPTOR :: struct #packed {
pEffect: ^IUnknown, // Pointer to the effect object's IUnknown interface.
InitialState: b32, // TRUE if the effect should begin in the enabled state.
OutputChannels: u32, // How many output channels the effect should produce.
}
// Used in the voice creation functions and in IXAudio2Voice.SetEffectChain
EFFECT_CHAIN :: struct #packed {
EffectCount: u32, // Number of effects in this voice's effect chain.
pEffectDescriptors: [^]EFFECT_DESCRIPTOR `fmt:"v,EffectCount"`, // Array of effect descriptors.
}
// Used in FILTER_PARAMETERS below
FILTER_TYPE :: enum i32 {
LowPassFilter, // Attenuates frequencies above the cutoff frequency (state-variable filter).
BandPassFilter, // Attenuates frequencies outside a given range (state-variable filter).
HighPassFilter, // Attenuates frequencies below the cutoff frequency (state-variable filter).
NotchFilter, // Attenuates frequencies inside a given range (state-variable filter).
LowPassOnePoleFilter, // Attenuates frequencies above the cutoff frequency (one-pole filter, FILTER_PARAMETERS.OneOverQ has no effect)
HighPassOnePoleFilter, // Attenuates frequencies below the cutoff frequency (one-pole filter, FILTER_PARAMETERS.OneOverQ has no effect)
}
// Used in IXAudio2Voice.Set/GetFilterParameters and Set/GetOutputFilterParameters
FILTER_PARAMETERS :: struct #packed {
Type: FILTER_TYPE, // Filter type.
Frequency: f32, // Filter coefficient. Must be >= 0 and <= MAX_FILTER_FREQUENCY. See CutoffFrequencyToRadians() for state-variable filter types and CutoffFrequencyToOnePoleCoefficient() for one-pole filter types.
OneOverQ: f32, // Reciprocal of the filter's quality factor Q; must be > 0 and <= MAX_FILTER_ONEOVERQ. Has no effect for one-pole filters.
}
// Used in IXAudio2SourceVoice.SubmitSourceBuffer
BUFFER :: struct #packed {
Flags: FLAGS, // Either 0 or END_OF_STREAM.
AudioBytes: u32, // Size of the audio data buffer in bytes.
pAudioData: [^]byte `fmt:"v,AudioBytes"`, // Pointer to the audio data buffer.
PlayBegin: u32, // First sample in this buffer to be played.
PlayLength: u32, // Length of the region to be played in samples, or 0 to play the whole buffer.
LoopBegin: u32, // First sample of the region to be looped.
LoopLength: u32, // Length of the desired loop region in samples, or 0 to loop the entire buffer.
LoopCount: u32, // Number of times to repeat the loop region, or LOOP_INFINITE to loop forever.
pContext: rawptr, // Context value to be passed back in callbacks.
}
// Used in IXAudio2SourceVoice.SubmitSourceBuffer when submitting XWMA data.
// NOTE: If an XWMA sound is submitted in more than one buffer, each buffer's pDecodedPacketCumulativeBytes[PacketCount-1] value must be subtracted from all the entries in the next buffer's pDecodedPacketCumulativeBytes array.
// And whether a sound is submitted in more than one buffer or not, the final buffer of the sound should use the END_OF_STREAM flag, or else the client must call IXAudio2SourceVoice.Discontinuity after submitting it.
BUFFER_WMA :: struct #packed {
pDecodedPacketCumulativeBytes: [^]u32 `fmt:"v,PacketCount"`, // Decoded packet's cumulative size array. Each element is the number of bytes accumulated when the corresponding XWMA packet is decoded in order. The array must have PacketCount elements.
PacketCount: u32, // Number of XWMA packets submitted. Must be >= 1 and divide evenly into BUFFER.AudioBytes.
}
// Returned by IXAudio2SourceVoice.GetState
VOICE_STATE :: struct #packed {
pCurrentBufferContext: rawptr, // The pContext value provided in the BUFFER that is currently being processed, or nil if there are no buffers in the queue.
BuffersQueued: u32, // Number of buffers currently queued on the voice (including the one that is being processed).
SamplesPlayed: u64, // Total number of samples produced by the voice since it began processing the current audio stream. If VOICE_NOSAMPLESPLAYED is specified in the call to IXAudio2SourceVoice.GetState, this member will not be calculated, saving CPU.
}
// Returned by IXAudio2.GetPerformanceData
PERFORMANCE_DATA :: struct #packed {
// CPU usage information
AudioCyclesSinceLastQuery: u64, // CPU cycles spent on audio processing since the last call to StartEngine or GetPerformanceData.
TotalCyclesSinceLastQuery: u64, // Total CPU cycles elapsed since the last call (only counts the CPU XAudio2 is running on).
MinimumCyclesPerQuantum: u32, // Fewest CPU cycles spent processing any one audio quantum since the last call.
MaximumCyclesPerQuantum: u32, // Most CPU cycles spent processing any one audio quantum since the last call.
// Memory usage information
MemoryUsageInBytes: u32, // Total heap space currently in use.
// Audio latency and glitching information
CurrentLatencyInSamples: u32, // Minimum delay from when a sample is read from a source buffer to when it reaches the speakers.
GlitchesSinceEngineStarted: u32, // Audio dropouts since the engine was started.
// Data about XAudio2's current workload
ActiveSourceVoiceCount: u32, // Source voices currently playing.
TotalSourceVoiceCount: u32, // Source voices currently existing.
ActiveSubmixVoiceCount: u32, // Submix voices currently playing/existing.
ActiveResamplerCount: u32, // Resample xAPOs currently active.
ActiveMatrixMixCount: u32, // MatrixMix xAPOs currently active.
// Usage of the hardware XMA decoder (Xbox 360 only)
ActiveXmaSourceVoices: u32, // Number of source voices decoding XMA data.
ActiveXmaStreams: u32, // A voice can use more than one XMA stream.
}
// Used in IXAudio2.SetDebugConfiguration
DEBUG_CONFIGURATION :: struct #packed {
TraceMask: DEBUG_CONFIG_FLAGS, // Bitmap of enabled debug message types.
BreakMask: DEBUG_CONFIG_FLAGS, // Message types that will break into the debugger.
LogThreadID: b32, // Whether to log the thread ID with each message.
LogFileline: b32, // Whether to log the source file and line number.
LogFunctionName: b32, // Whether to log the function name.
LogTiming: b32, // Whether to log message timestamps.
}
// Values for the TraceMask and BreakMask bitmaps. Only ERRORS and WARNINGS are valid in BreakMask.
// WARNINGS implies ERRORS, DETAIL implies INFO, and FUNC_CALLS implies API_CALLS.
// By default, TraceMask is ERRORS and WARNINGS and all the other settings are zero.
DEBUG_CONFIG_FLAGS :: distinct bit_set[DEBUG_CONFIG_FLAG; u32]
DEBUG_CONFIG_FLAG :: enum u32 {
ERRORS = 0, // For handled errors with serious effects.
WARNINGS = 1, // For handled errors that may be recoverable.
INFO = 2, // Informational chit-chat (e.g. state changes).
DETAIL = 3, // More detailed chit-chat.
API_CALLS = 4, // Public API function entries and exits.
FUNC_CALLS = 5, // Internal function entries and exits.
TIMING = 6, // Delays detected and other timing data.
LOCKS = 7, // Usage of critical sections and mutexes.
MEMORY = 8, // Memory heap usage information.
STREAMING = 12, // Audio streaming information.
}
/**************************************************************************
*
* IXAudio2: Top-level XAudio2 COM interface.
*
**************************************************************************/
IXAudio2_UUID_STRING :: "2B02E3CF-2E0B-4ec3-BE45-1B2A3FE7210D"
IXAudio2_UUID := &win.IID{0x2B02E3CF, 0x2E0B, 0x4ec3, {0xBE, 0x45, 0x1B, 0x2A, 0x3F, 0xE7, 0x21, 0x0D}}
IXAudio2 :: struct #raw_union {
#subtype iunknown: IUnknown,
using ixaudio2_vtable: ^IXAudio2_VTable,
}
IXAudio2_VTable :: struct {
using iunknown_vtable: IUnknown_VTable,
// NAME: IXAudio2.RegisterForCallbacks
// DESCRIPTION: Adds a new client to receive XAudio2's engine callbacks.
// ARGUMENTS:
// pCallback - Callback interface to be called during each processing pass.
RegisterForCallbacks: proc "system" (this: ^IXAudio2, pCallback: ^IXAudio2EngineCallback) -> HRESULT,
// NAME: IXAudio2.UnregisterForCallbacks
// DESCRIPTION: Removes an existing receiver of XAudio2 engine callbacks.
// ARGUMENTS:
// pCallback - Previously registered callback interface to be removed.
UnregisterForCallbacks: proc "system" (this: ^IXAudio2, pCallback: ^IXAudio2EngineCallback),
// NAME: IXAudio2.CreateSourceVoice
// DESCRIPTION: Creates and configures a source voice.
// ARGUMENTS:
// ppSourceVoice - Returns the new object's IXAudio2SourceVoice interface.
// pSourceFormat - Format of the audio that will be fed to the voice.
// Flags - VOICE flags specifying the source voice's behavior.
// MaxFrequencyRatio - Maximum SetFrequencyRatio argument to be allowed.
// pCallback - Optional pointer to a client-provided callback interface.
// pSendList - Optional list of voices this voice should send audio to.
// pEffectChain - Optional list of effects to apply to the audio data.
CreateSourceVoice: proc "system" (this: ^IXAudio2, ppSourceVoice: ^^IXAudio2SourceVoice, pSourceFormat: ^WAVEFORMATEX, Flags: FLAGS = {}, MaxFrequencyRatio: f32 = DEFAULT_FREQ_RATIO, pCallback: ^IXAudio2VoiceCallback = nil, pSendList: [^]VOICE_SENDS = nil, pEffectChain: [^]EFFECT_CHAIN = nil) -> HRESULT,
// NAME: IXAudio2.CreateSubmixVoice
// DESCRIPTION: Creates and configures a submix voice.
// ARGUMENTS:
// ppSubmixVoice - Returns the new object's IXAudio2SubmixVoice interface.
// InputChannels - Number of channels in this voice's input audio data.
// InputSampleRate - Sample rate of this voice's input audio data.
// Flags - VOICE flags specifying the submix voice's behavior.
// ProcessingStage - Arbitrary number that determines the processing order.
// pSendList - Optional list of voices this voice should send audio to.
// pEffectChain - Optional list of effects to apply to the audio data.
CreateSubmixVoice: proc "system" (this: ^IXAudio2, ppSubmixVoice: ^^IXAudio2SubmixVoice, InputChannels: u32, InputSampleRate: u32, Flags: FLAGS = {}, ProcessingStage: u32 = 0, pSendList: [^]VOICE_SENDS = nil, pEffectChain: [^]EFFECT_CHAIN = nil) -> HRESULT,
// NAME: IXAudio2.CreateMasteringVoice
// DESCRIPTION: Creates and configures a mastering voice.
// ARGUMENTS:
// ppMasteringVoice - Returns the new object's IXAudio2MasteringVoice interface.
// InputChannels - Number of channels in this voice's input audio data.
// InputSampleRate - Sample rate of this voice's input audio data.
// Flags - VOICE flags specifying the mastering voice's behavior.
// szDeviceId - Identifier of the device to receive the output audio.
// pEffectChain - Optional list of effects to apply to the audio data.
// StreamCategory - The audio stream category to use for this mastering voice
CreateMasteringVoice: proc "system" (this: ^IXAudio2, ppMasteringVoice: ^^IXAudio2MasteringVoice, InputChannels: u32 = DEFAULT_CHANNELS, InputSampleRate: u32 = DEFAULT_SAMPLERATE, Flags: FLAGS = {}, szDeviceId: win.LPCWSTR = nil, pEffectChain: [^]EFFECT_CHAIN = nil, StreamCategory: AUDIO_STREAM_CATEGORY = .GameEffects) -> HRESULT,
// NAME: IXAudio2.:StartEngine
// DESCRIPTION: Creates and starts the audio processing thread.
StartEngine: proc "system" (this: ^IXAudio2) -> HRESULT,
// NAME: IXAudio2.StopEngine
// DESCRIPTION: Stops and destroys the audio processing thread.
StopEngine: proc "system" (this: ^IXAudio2),
// NAME: IXAudio2.CommitChanges
// DESCRIPTION: Atomically applies a set of operations previously tagged with a given identifier.
// ARGUMENTS:
// OperationSet - Identifier of the set of operations to be applied.
CommitChanges: proc "system" (this: ^IXAudio2, OperationSet: u32) -> HRESULT,
// NAME: IXAudio2.GetPerformanceData
// DESCRIPTION: Returns current resource usage details: memory, CPU, etc.
// ARGUMENTS:
// pPerfData - Returns the performance data structure.
GetPerformanceData: proc "system" (this: ^IXAudio2, pPerfData: ^PERFORMANCE_DATA),
// NAME: IXAudio2.SetDebugConfiguration
// DESCRIPTION: Configures XAudio2's debug output (in debug builds only).
// ARGUMENTS:
// pDebugConfiguration - Structure describing the debug output behavior.
// pReserved - Optional parameter; must be nil.
SetDebugConfiguration: proc "system" (this: ^IXAudio2, pDebugConfiguration: ^DEBUG_CONFIGURATION, pReserved: rawptr = nil),
}
// This interface extends IXAudio2 with additional functionality.
// Use IXAudio2.QueryInterface to obtain a pointer to this interface.
IXAudio2Extension_UUID_STRING :: "84ac29bb-d619-44d2-b197-e4acf7df3ed6"
IXAudio2Extension_UUID := &win.IID{0x84ac29bb, 0xd619, 0x44d2, {0xb1, 0x97, 0xe4, 0xac, 0xf7, 0xdf, 0x3e, 0xd6}}
IXAudio2Extension :: struct #raw_union {
#subtype iunknown: IUnknown,
using ixaudio2extension_vtable: ^IXAudio2Extension_VTable,
}
IXAudio2Extension_VTable :: struct {
using iunknown_vtable: IUnknown_VTable,
// NAME: IXAudio2Extension.GetProcessingQuantum
// DESCRIPTION: Returns the processing quantum
// quantumMilliseconds = (1000.0f * quantumNumerator / quantumDenominator)
// ARGUMENTS:
// quantumNumerator - Quantum numerator
// quantumDenominator - Quantum denominator
GetProcessingQuantum: proc "system" (this: ^IXAudio2Extension, quantumNumerator: ^u32, quantumDenominator: ^u32),
// NAME: IXAudio2Extension.GetProcessor
// DESCRIPTION: Returns the number of the processor used by XAudio2
// ARGUMENTS:
// processor - Non-zero Processor number
GetProcessor: proc "system" (this: ^IXAudio2Extension, processor: ^PROCESSOR_FLAGS),
}
/**************************************************************************
*
* IXAudio2Voice: Base voice management interface.
*
**************************************************************************/
IXAudio2Voice :: struct {
using ixaudio2voice_vtable: ^IXAudio2Voice_VTable,
}
IXAudio2Voice_VTable :: struct {
// NAME: IXAudio2Voice.GetVoiceDetails
// DESCRIPTION: Returns the basic characteristics of this voice.
// ARGUMENTS:
// pVoiceDetails - Returns the voice's details.
GetVoiceDetails: proc "system" (this: ^IXAudio2Voice, pVoiceDetails: ^VOICE_DETAILS),
// NAME: IXAudio2Voice.SetOutputVoices
// DESCRIPTION: Replaces the set of submix/mastering voices that receive this voice's output.
// ARGUMENTS:
// pSendList - Optional list of voices this voice should send audio to.
SetOutputVoices: proc "system" (this: ^IXAudio2Voice, pSendList: [^]VOICE_SENDS) -> HRESULT,
// NAME: IXAudio2Voice.SetEffectChain
// DESCRIPTION: Replaces this voice's current effect chain with a new one.
// ARGUMENTS:
// pEffectChain - Structure describing the new effect chain to be used.
SetEffectChain: proc "system" (this: ^IXAudio2Voice, pEffectChain: ^EFFECT_CHAIN) -> HRESULT,
// NAME: IXAudio2Voice.EnableEffect
// DESCRIPTION: Enables an effect in this voice's effect chain.
// ARGUMENTS:
// EffectIndex - Index of an effect within this voice's effect chain.
// OperationSet - Used to identify this call as part of a deferred batch.
EnableEffect: proc "system" (this: ^IXAudio2Voice, EffectIndex: u32, OperationSet: u32 = COMMIT_NOW) -> HRESULT,
// NAME: IXAudio2Voice.DisableEffect
// DESCRIPTION: Disables an effect in this voice's effect chain.
// ARGUMENTS:
// EffectIndex - Index of an effect within this voice's effect chain.
// OperationSet - Used to identify this call as part of a deferred batch.
DisableEffect: proc "system" (this: ^IXAudio2Voice, EffectIndex: u32, OperationSet: u32 = COMMIT_NOW) -> HRESULT,
// NAME: IXAudio2Voice.GetEffectState
// DESCRIPTION: Returns the running state of an effect.
// ARGUMENTS:
// EffectIndex - Index of an effect within this voice's effect chain.
// pEnabled - Returns the enabled/disabled state of the given effect.
GetEffectState: proc "system" (this: ^IXAudio2Voice, EffectIndex: u32, pEnabled: ^b32),
// NAME: IXAudio2Voice.SetEffectParameters
// DESCRIPTION: Sets effect-specific parameters.
// REMARKS: Unlike IXAPOParameters.SetParameters, this method may be called from any thread. XAudio2 implements appropriate synchronization to copy the parameters to the realtime audio processing thread.
// ARGUMENTS:
// EffectIndex - Index of an effect within this voice's effect chain.
// pParameters - Pointer to an effect-specific parameters block.
// ParametersByteSize - Size of the pParameters array in bytes.
// OperationSet - Used to identify this call as part of a deferred batch.
SetEffectParameters: proc "system" (this: ^IXAudio2Voice, EffectIndex: u32, pParameters: rawptr, ParametersByteSize: u32, OperationSet: u32 = COMMIT_NOW) -> HRESULT,
// NAME: IXAudio2Voice.GetEffectParameters
// DESCRIPTION: Obtains the current effect-specific parameters.
// ARGUMENTS:
// EffectIndex - Index of an effect within this voice's effect chain.
// pParameters - Returns the current values of the effect-specific parameters.
// ParametersByteSize - Size of the pParameters array in bytes.
GetEffectParameters: proc "system" (this: ^IXAudio2Voice, EffectIndex: u32, pParameters: rawptr, ParametersByteSize: u32) -> HRESULT,
// NAME: IXAudio2Voice.SetFilterParameters
// DESCRIPTION: Sets this voice's filter parameters.
// ARGUMENTS:
// pParameters - Pointer to the filter's parameter structure.
// OperationSet - Used to identify this call as part of a deferred batch.
SetFilterParameters: proc "system" (this: ^IXAudio2Voice, pParameters: ^FILTER_PARAMETERS, OperationSet: u32 = COMMIT_NOW) -> HRESULT,
// NAME: IXAudio2Voice.GetFilterParameters
// DESCRIPTION: Returns this voice's current filter parameters.
// ARGUMENTS:
// pParameters - Returns the filter parameters.
GetFilterParameters: proc "system" (this: ^IXAudio2Voice, pParameters: ^FILTER_PARAMETERS),
// NAME: IXAudio2Voice.SetOutputFilterParameters
// DESCRIPTION: Sets the filter parameters on one of this voice's sends.
// ARGUMENTS:
// pDestinationVoice - Destination voice of the send whose filter parameters will be set.
// pParameters - Pointer to the filter's parameter structure.
// OperationSet - Used to identify this call as part of a deferred batch.
SetOutputFilterParameters: proc "system" (this: ^IXAudio2Voice, pDestinationVoice: ^IXAudio2Voice, pParameters: ^FILTER_PARAMETERS, OperationSet: u32 = COMMIT_NOW) -> HRESULT,
// NAME: IXAudio2Voice.GetOutputFilterParameters
// DESCRIPTION: Returns the filter parameters from one of this voice's sends.
// ARGUMENTS:
// pDestinationVoice - Destination voice of the send whose filter parameters will be read.
// pParameters - Returns the filter parameters.
GetOutputFilterParameters: proc "system" (this: ^IXAudio2Voice, pDestinationVoice: ^IXAudio2Voice, pParameters: ^FILTER_PARAMETERS),
// NAME: IXAudio2Voice.SetVolume
// DESCRIPTION: Sets this voice's overall volume level.
// ARGUMENTS:
// Volume - New overall volume level to be used, as an amplitude factor.
// OperationSet - Used to identify this call as part of a deferred batch.
SetVolume: proc "system" (this: ^IXAudio2Voice, Volume: f32, OperationSet: u32 = COMMIT_NOW) -> HRESULT,
// NAME: IXAudio2Voice.GetVolume
// DESCRIPTION: Obtains this voice's current overall volume level.
// ARGUMENTS:
// pVolume: Returns the voice's current overall volume level.
GetVolume: proc "system" (this: ^IXAudio2Voice, pVolume: ^f32),
// NAME: IXAudio2Voice.SetChannelVolumes
// DESCRIPTION: Sets this voice's per-channel volume levels.
// ARGUMENTS:
// Channels - Used to confirm the voice's channel count.
// pVolumes - Array of per-channel volume levels to be used.
// OperationSet - Used to identify this call as part of a deferred batch.
SetChannelVolumes: proc "system" (this: ^IXAudio2Voice, Channels: u32, pVolumes: [^]f32, OperationSet: u32 = COMMIT_NOW) -> HRESULT,
// NAME: IXAudio2Voice.GetChannelVolumes
// DESCRIPTION: Returns this voice's current per-channel volume levels.
// ARGUMENTS:
// Channels - Used to confirm the voice's channel count.
// pVolumes - Returns an array of the current per-channel volume levels.
GetChannelVolumes: proc "system" (this: ^IXAudio2Voice, Channels: u32, pVolumes: [^]f32),
// NAME: IXAudio2Voice.SetOutputMatrix
// DESCRIPTION: Sets the volume levels used to mix from each channel of this voice's output audio to each channel of a given destination voice's input audio.
// ARGUMENTS:
// pDestinationVoice - The destination voice whose mix matrix to change.
// SourceChannels - Used to confirm this voice's output channel count (the number of channels produced by the last effect in the chain).
// DestinationChannels - Confirms the destination voice's input channels.
// pLevelMatrix - Array of [SourceChannels * DestinationChannels] send levels. The level used to send from source channel S to destination channel D should be in pLevelMatrix[S + SourceChannels * D].
// OperationSet - Used to identify this call as part of a deferred batch.
SetOutputMatrix: proc "system" (this: ^IXAudio2Voice, pDestinationVoice: ^IXAudio2Voice, SourceChannels: u32, DestinationChannels: u32, pLevelMatrix: [^]f32, OperationSet: u32 = COMMIT_NOW) -> HRESULT,
// NAME: IXAudio2Voice.GetOutputMatrix
// DESCRIPTION: Obtains the volume levels used to send each channel of this voice's output audio to each channel of a given destination voice's input audio.
// ARGUMENTS:
// pDestinationVoice - The destination voice whose mix matrix to obtain.
// SourceChannels - Used to confirm this voice's output channel count (the number of channels produced by the last effect in the chain).
// DestinationChannels - Confirms the destination voice's input channels.
// pLevelMatrix - Array of send levels, as above.
GetOutputMatrix: proc "system" (this: ^IXAudio2Voice, pDestinationVoice: ^IXAudio2Voice, SourceChannels: u32, DestinationChannels: u32, pLevelMatrix: [^]f32),
// NAME: IXAudio2Voice.DestroyVoice
// DESCRIPTION: Destroys this voice, stopping it if necessary and removing it from the XAudio2 graph.
DestroyVoice: proc "system" (this: ^IXAudio2Voice),
}
/**************************************************************************
*
* IXAudio2SourceVoice: Source voice management interface.
*
**************************************************************************/
IXAudio2SourceVoice :: struct #raw_union {
#subtype ixaudio2voice: IXAudio2Voice,
using ixaudio2sourcevoice_vtable: ^IXAudio2SourceVoice_VTable,
}
IXAudio2SourceVoice_VTable :: struct {
using ixaudio2voice_vtable: IXAudio2Voice_VTable,
// NAME: IXAudio2SourceVoice.Start
// DESCRIPTION: Makes this voice start consuming and processing audio.
// ARGUMENTS:
// Flags - Flags controlling how the voice should be started.
// OperationSet - Used to identify this call as part of a deferred batch.
Start: proc "system" (this: ^IXAudio2SourceVoice, Flags: FLAGS = {}, OperationSet: u32 = COMMIT_NOW) -> HRESULT,
// NAME: IXAudio2SourceVoice.Stop
// DESCRIPTION: Makes this voice stop consuming audio.
// ARGUMENTS:
// Flags - Flags controlling how the voice should be stopped.
// OperationSet - Used to identify this call as part of a deferred batch.
Stop: proc "system" (this: ^IXAudio2SourceVoice, Flags: FLAGS = {}, OperationSet: u32 = COMMIT_NOW) -> HRESULT,
// NAME: IXAudio2SourceVoice.SubmitSourceBuffer
// DESCRIPTION: Adds a new audio buffer to this voice's input queue.
// ARGUMENTS:
// pBuffer - Pointer to the buffer structure to be queued.
// pBufferWMA - Additional structure used only when submitting XWMA data.
SubmitSourceBuffer: proc "system" (this: ^IXAudio2SourceVoice, pBuffer: ^BUFFER, pBufferWMA: ^BUFFER_WMA = nil) -> HRESULT,
// NAME: IXAudio2SourceVoice.FlushSourceBuffers
// DESCRIPTION: Removes all pending audio buffers from this voice's queue.
FlushSourceBuffers: proc "system" (this: ^IXAudio2SourceVoice) -> HRESULT,
// NAME: IXAudio2SourceVoice.Discontinuity
// DESCRIPTION: Notifies the voice of an intentional break in the stream of audio buffers (e.g. the end of a sound), to prevent XAudio2 from interpreting an empty buffer queue as a glitch.
Discontinuity: proc "system" (this: ^IXAudio2SourceVoice) -> HRESULT,
// NAME: IXAudio2SourceVoice.ExitLoop
// DESCRIPTION: Breaks out of the current loop when its end is reached.
// ARGUMENTS:
// OperationSet - Used to identify this call as part of a deferred batch.
ExitLoop: proc "system" (this: ^IXAudio2SourceVoice, OperationSet: u32 = COMMIT_NOW) -> HRESULT,
// NAME: IXAudio2SourceVoice.GetState
// DESCRIPTION: Returns the number of buffers currently queued on this voice, the pContext value associated with the currently processing buffer (if any), and other voice state information.
// ARGUMENTS:
// pVoiceState - Returns the state information.
// Flags - Flags controlling what voice state is returned.
GetState: proc "system" (this: ^IXAudio2SourceVoice, pVoiceState: ^VOICE_STATE, Flags: FLAGS = {}),
// NAME: IXAudio2SourceVoice.SetFrequencyRatio
// DESCRIPTION: Sets this voice's frequency adjustment, i.e. its pitch.
// ARGUMENTS:
// Ratio - Frequency change, expressed as source frequency / target frequency.
// OperationSet - Used to identify this call as part of a deferred batch.
SetFrequencyRatio: proc "system" (this: ^IXAudio2SourceVoice, Ratio: f32, OperationSet: u32 = COMMIT_NOW) -> HRESULT,
// NAME: IXAudio2SourceVoice.GetFrequencyRatio
// DESCRIPTION: Returns this voice's current frequency adjustment ratio.
// ARGUMENTS:
// pRatio - Returns the frequency adjustment.
GetFrequencyRatio: proc "system" (this: ^IXAudio2SourceVoice, pRatio: ^f32),
// NAME: IXAudio2SourceVoice.SetSourceSampleRate
// DESCRIPTION: Reconfigures this voice to treat its source data as being at a different sample rate than the original one specified in CreateSourceVoice's pSourceFormat argument.
// ARGUMENTS:
// UINT32 - The intended sample rate of further submitted source data.
SetSourceSampleRate: proc "system" (this: ^IXAudio2SourceVoice, NewSourceSampleRate: u32) -> HRESULT,
}
/**************************************************************************
*
* IXAudio2SubmixVoice: Submixing voice management interface.
*
**************************************************************************/
IXAudio2SubmixVoice :: struct #raw_union {
#subtype ixaudio2voice: IXAudio2Voice,
using ixaudio2submixvoice_vtable: ^IXAudio2SubmixVoice_VTable,
}
IXAudio2SubmixVoice_VTable :: struct {
using ixaudio2voice_vtable: IXAudio2Voice_VTable,
// There are currently no methods specific to submix voices.
}
/**************************************************************************
*
* IXAudio2MasteringVoice: Mastering voice management interface.
*
**************************************************************************/
IXAudio2MasteringVoice :: struct #raw_union {
#subtype ixaudio2voice: IXAudio2Voice,
using ixaudio2masteringvoice_vtable: ^IXAudio2MasteringVoice_VTable,
}
IXAudio2MasteringVoice_VTable :: struct {
using ixaudio2voice_vtable: IXAudio2Voice_VTable,
// NAME: IXAudio2MasteringVoice.GetChannelMask
// DESCRIPTION: Returns the channel mask for this voice
// ARGUMENTS:
// pChannelMask - returns the channel mask for this voice. This corresponds to the dwChannelMask member of WAVEFORMATEXTENSIBLE.
GetChannelMask: proc "system" (this: ^IXAudio2MasteringVoice, pChannelmask: ^win.DWORD) -> HRESULT,
}
/**************************************************************************
*
* IXAudio2EngineCallback: Client notification interface for engine events.
*
* REMARKS: Contains methods to notify the client when certain events happen in the XAudio2 engine. This interface should be implemented by the client.
* XAudio2 will call these methods via the interface pointer provided by the client when it calls IXAudio2.RegisterForCallbacks.
*
**************************************************************************/
IXAudio2EngineCallback :: struct {
using ixaudio2enginecallback_vtable: ^IXAudio2EngineCallback_VTable,
}
IXAudio2EngineCallback_VTable :: struct {
// Called by XAudio2 just before an audio processing pass begins.
OnProcessingPassStart: proc "system" (this: ^IXAudio2EngineCallback),
// Called just after an audio processing pass ends.
OnProcessingPassEnd: proc "system" (this: ^IXAudio2EngineCallback),
// Called in the event of a critical system error which requires XAudio2 to be closed down and restarted. The error code is given in Error.
OnCriticalError: proc "system" (this: ^IXAudio2EngineCallback, Error: HRESULT),
}
/**************************************************************************
*
* IXAudio2VoiceCallback: Client notification interface for voice events.
*
* REMARKS: Contains methods to notify the client when certain events happen in an XAudio2 voice. This interface should be implemented by the client.
* XAudio2 will call these methods via an interface pointer provided by the client in the IXAudio2.CreateSourceVoice call.
*
**************************************************************************/
IXAudio2VoiceCallback :: struct {
using ixaudio2voicecallback_vtable: ^IXAudio2VoiceCallback_VTable,
}
IXAudio2VoiceCallback_VTable :: struct {
// Called just before this voice's processing pass begins.
OnVoiceProcessingPassStart: proc "system" (this: ^IXAudio2VoiceCallback, BytesRequired: u32),
// Called just after this voice's processing pass ends.
OnVoiceProcessingPassEnd: proc "system" (this: ^IXAudio2VoiceCallback),
// Called when this voice has just finished playing a buffer stream (as marked with the END_OF_STREAM flag on the last buffer).
OnStreamEnd: proc "system" (this: ^IXAudio2VoiceCallback),
// Called when this voice is about to start processing a new buffer.
OnBufferStart: proc "system" (this: ^IXAudio2VoiceCallback, pBufferContext: rawptr),
// Called when this voice has just finished processing a buffer.
// The buffer can now be reused or destroyed.
OnBufferEnd: proc "system" (this: ^IXAudio2VoiceCallback, pBufferContext: rawptr),
// Called when this voice has just reached the end position of a loop.
OnLoopEnd: proc "system" (this: ^IXAudio2VoiceCallback, pBufferContext: rawptr),
// Called in the event of a critical error during voice processing, such as a failing xAPO or an error from the hardware XMA decoder.
// The voice may have to be destroyed and re-created to recover from the error.
// The callback arguments report which buffer was being processed when the error occurred, and its HRESULT code.
OnVoiceError: proc "system" (this: ^IXAudio2VoiceCallback, pBufferContext: rawptr, Error: HRESULT),
}
/**************************************************************************
*
* XAudio2Create: Top-level function that creates an XAudio2 instance.
*
* ARGUMENTS:
*
* Flags - Flags specifying the XAudio2 object's behavior.
*
* Processor - A PROCESSOR_FLAGS value that specifies the hardware threads (Xbox) or processors (Windows) that XAudio2 will use.
* Note that XAudio2 supports concurrent processing on multiple threads, using any combination of PROCESSOR_FLAGS flags.
* The values are platform-specific; platform-independent code can use USE_DEFAULT_PROCESSOR to use the default on each platform.
*
**************************************************************************/
@(default_calling_convention="system", link_prefix="XAudio2")
foreign xa2 {
Create :: proc(ppXaudio2: ^^IXAudio2, Flags: FLAGS = {}, Processor: PROCESSOR_FLAGS = {.Processor1}) -> HRESULT ---
}
/**************************************************************************
*
* Utility functions used to convert from pitch in semitones and volume in decibels to the frequency and amplitude ratio units used by XAudio2.
*
**************************************************************************/
// Calculate the argument to SetVolume from a decibel value
DecibelsToAmplitudeRatio :: #force_inline proc "contextless" (Decibels: f32) -> f32 {
return math.pow_f32(10.0, Decibels / 20.0)
}
// Recover a volume in decibels from an amplitude factor
AmplitudeRatioToDecibels :: #force_inline proc "contextless" (Volume: f32) -> f32 {
if Volume == 0 {
return min(f32)
}
return 20.0 * math.log10_f32(Volume)
}
// Calculate the argument to SetFrequencyRatio from a semitone value
SemitonesToFrequencyRatio :: #force_inline proc "contextless" (Semitones: f32) -> f32 {
// FrequencyRatio = 2 ^ Octaves
// = 2 ^ (Semitones / 12)
return math.pow_f32(2.0, Semitones / 12.0)
}
// Recover a pitch in semitones from a frequency ratio
FrequencyRatioToSemitones :: #force_inline proc "contextless" (FrequencyRatio: f32) -> f32 {
// Semitones = 12 * log2(FrequencyRatio)
// = 12 * log2(10) * log10(FrequencyRatio)
return 12.0 * math.log2_f32(FrequencyRatio)
}
// Convert from filter cutoff frequencies expressed in Hertz to the radian frequency values used in FILTER_PARAMETERS.Frequency, state-variable filter types only.
// Use CutoffFrequencyToOnePoleCoefficient() for one-pole filter types.
// Note that the highest CutoffFrequency supported is SampleRate/6.
// Higher values of CutoffFrequency will return MAX_FILTER_FREQUENCY.
CutoffFrequencyToRadians :: #force_inline proc "contextless" (CutoffFrequency: f32, SampleRate: u32) -> f32 {
if u32(CutoffFrequency * 6.0) >= SampleRate {
return MAX_FILTER_FREQUENCY
}
return 2.0 * math.sin_f32(math.PI * CutoffFrequency / f32(SampleRate))
}
// Convert from radian frequencies back to absolute frequencies in Hertz
RadiansToCutoffFrequency :: #force_inline proc "contextless" (Radians: f32, SampleRate: f32) -> f32 {
return SampleRate * math.asin_f32(Radians / 2.0) / math.PI
}
// Convert from filter cutoff frequencies expressed in Hertz to the filter coefficients used with FILTER_PARAMETERS.Frequency,
// LowPassOnePoleFilter and HighPassOnePoleFilter filter types only.
// Use CutoffFrequencyToRadians() for state-variable filter types.
CutoffFrequencyToOnePoleCoefficient :: #force_inline proc "contextless" (CutoffFrequency: f32, SampleRate: u32) -> f32 {
if u32(CutoffFrequency) >= SampleRate {
return MAX_FILTER_FREQUENCY
}
return 1.0 - math.pow_f32(1.0 - 2.0 * CutoffFrequency / f32(SampleRate), 2.0)
}
//-------------------------------------------------------------------------
// Description: Audio stream categories
//
// Other - All other streams (default)
// ForegroundOnlyMedia - (deprecated for Win10) Music, Streaming audio
// BackgroundCapableMedia - (deprecated for Win10) Video with audio
// Communications - VOIP, chat, phone call
// Alerts - Alarm, Ring tones
// SoundEffects - Sound effects, clicks, dings
// GameEffects - Game sound effects
// GameMedia - Background audio for games
// GameChat - In game player chat
// Speech - Speech recognition
// Media - Music, Streaming audio
// Movie - Video with audio
// FarFieldSpeech - Capture of far field speech
// UniformSpeech - Uniform, device agnostic speech processing
// VoiceTyping - Dictation, typing by voice
//
AUDIO_STREAM_CATEGORY :: enum i32 {
Other = 0,
//ForegroundOnlyMedia = 1,
//BackgroundCapableMedia = 2,
Communications = 3,
Alerts = 4,
SoundEffects = 5,
GameEffects = 6,
GameMedia = 7,
GameChat = 8,
Speech = 9,
Movie = 10,
Media = 11,
FarFieldSpeech = 12,
UniformSpeech = 13,
VoiceTyping = 14,
}