//-------------------------------------------------------------------------------------- // File: Audio.h // // DirectXTK for Audio header // // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. // // http://go.microsoft.com/fwlink/?LinkId=248929 // http://go.microsoft.com/fwlink/?LinkID=615561 //-------------------------------------------------------------------------------------- #pragma once #include #include #include #if (defined(_XBOX_ONE) && defined(_TITLE)) || defined(_GAMING_XBOX) #include #pragma comment(lib,"acphal.lib") #endif #ifndef XAUDIO2_HELPER_FUNCTIONS #define XAUDIO2_HELPER_FUNCTIONS #endif #if defined(USING_XAUDIO2_REDIST) || (_WIN32_WINNT >= 0x0A00 /*_WIN32_WINNT_WIN10*/) || defined(_XBOX_ONE) #define USING_XAUDIO2_9 #elif (_WIN32_WINNT >= 0x0602 /*_WIN32_WINNT_WIN8*/) #define USING_XAUDIO2_8 #elif (_WIN32_WINNT >= 0x0601 /*_WIN32_WINNT_WIN7*/) #error Windows 7 SP1 requires the XAudio2Redist NuGet package https://aka.ms/xaudio2redist #else #error DirectX Tool Kit for Audio not supported on this platform #endif #include #include #include #include #ifndef USING_XAUDIO2_REDIST #if defined(USING_XAUDIO2_8) && defined(NTDDI_WIN10) && !defined(_M_IX86) // The xaudio2_8.lib in the Windows 10 SDK for x86 is incorrectly annotated as __cdecl instead of __stdcall, so avoid using it in this case. #pragma comment(lib,"xaudio2_8.lib") #else #pragma comment(lib,"xaudio2.lib") #endif #endif #include #include #include #include #include #include namespace DirectX { class SoundEffectInstance; class SoundStreamInstance; //---------------------------------------------------------------------------------- struct AudioStatistics { size_t playingOneShots; // Number of one-shot sounds currently playing size_t playingInstances; // Number of sound effect instances currently playing size_t allocatedInstances; // Number of SoundEffectInstance allocated size_t allocatedVoices; // Number of XAudio2 voices allocated (standard, 3D, one-shots, and idle one-shots) size_t allocatedVoices3d; // Number of XAudio2 voices allocated for 3D size_t allocatedVoicesOneShot; // Number of XAudio2 voices allocated for one-shot sounds size_t allocatedVoicesIdle; // Number of XAudio2 voices allocated for one-shot sounds but not currently in use size_t audioBytes; // Total wave data (in bytes) in SoundEffects and in-memory WaveBanks #if (defined(_XBOX_ONE) && defined(_TITLE)) || defined(_GAMING_XBOX) size_t xmaAudioBytes; // Total wave data (in bytes) in SoundEffects and in-memory WaveBanks allocated with ApuAlloc #endif size_t streamingBytes; // Total size of streaming buffers (in bytes) in streaming WaveBanks }; //---------------------------------------------------------------------------------- class IVoiceNotify { public: virtual ~IVoiceNotify() = default; IVoiceNotify(const IVoiceNotify&) = delete; IVoiceNotify& operator=(const IVoiceNotify&) = delete; IVoiceNotify(IVoiceNotify&&) = default; IVoiceNotify& operator=(IVoiceNotify&&) = default; virtual void __cdecl OnBufferEnd() = 0; // Notfication that a voice buffer has finished // Note this is called from XAudio2's worker thread, so it should perform very minimal and thread-safe operations virtual void __cdecl OnCriticalError() = 0; // Notification that the audio engine encountered a critical error virtual void __cdecl OnReset() = 0; // Notification of an audio engine reset virtual void __cdecl OnUpdate() = 0; // Notification of an audio engine per-frame update (opt-in) virtual void __cdecl OnDestroyEngine() noexcept = 0; // Notification that the audio engine is being destroyed virtual void __cdecl OnTrim() = 0; // Notification of a request to trim the voice pool virtual void __cdecl GatherStatistics(AudioStatistics& stats) const = 0; // Contribute to statistics request virtual void __cdecl OnDestroyParent() noexcept = 0; // Optional notification used by some objects protected: IVoiceNotify() = default; }; //---------------------------------------------------------------------------------- enum AUDIO_ENGINE_FLAGS : uint32_t { AudioEngine_Default = 0x0, AudioEngine_EnvironmentalReverb = 0x1, AudioEngine_ReverbUseFilters = 0x2, AudioEngine_UseMasteringLimiter = 0x4, AudioEngine_Debug = 0x10000, AudioEngine_ThrowOnNoAudioHW = 0x20000, AudioEngine_DisableVoiceReuse = 0x40000, }; enum SOUND_EFFECT_INSTANCE_FLAGS : uint32_t { SoundEffectInstance_Default = 0x0, SoundEffectInstance_Use3D = 0x1, SoundEffectInstance_ReverbUseFilters = 0x2, SoundEffectInstance_NoSetPitch = 0x4, SoundEffectInstance_UseRedirectLFE = 0x10000, }; enum AUDIO_ENGINE_REVERB : unsigned int { Reverb_Off, Reverb_Default, Reverb_Generic, Reverb_Forest, Reverb_PaddedCell, Reverb_Room, Reverb_Bathroom, Reverb_LivingRoom, Reverb_StoneRoom, Reverb_Auditorium, Reverb_ConcertHall, Reverb_Cave, Reverb_Arena, Reverb_Hangar, Reverb_CarpetedHallway, Reverb_Hallway, Reverb_StoneCorridor, Reverb_Alley, Reverb_City, Reverb_Mountains, Reverb_Quarry, Reverb_Plain, Reverb_ParkingLot, Reverb_SewerPipe, Reverb_Underwater, Reverb_SmallRoom, Reverb_MediumRoom, Reverb_LargeRoom, Reverb_MediumHall, Reverb_LargeHall, Reverb_Plate, Reverb_MAX }; enum SoundState { STOPPED = 0, PLAYING, PAUSED }; //---------------------------------------------------------------------------------- class AudioEngine { public: explicit AudioEngine( AUDIO_ENGINE_FLAGS flags = AudioEngine_Default, _In_opt_ const WAVEFORMATEX* wfx = nullptr, _In_opt_z_ const wchar_t* deviceId = nullptr, AUDIO_STREAM_CATEGORY category = AudioCategory_GameEffects) noexcept(false); AudioEngine(AudioEngine&& moveFrom) noexcept; AudioEngine& operator= (AudioEngine&& moveFrom) noexcept; AudioEngine(AudioEngine const&) = delete; AudioEngine& operator= (AudioEngine const&) = delete; virtual ~AudioEngine(); bool __cdecl Update(); // Performs per-frame processing for the audio engine, returns false if in 'silent mode' bool __cdecl Reset(_In_opt_ const WAVEFORMATEX* wfx = nullptr, _In_opt_z_ const wchar_t* deviceId = nullptr); // Reset audio engine from critical error/silent mode using a new device; can also 'migrate' the graph // Returns true if succesfully reset, false if in 'silent mode' due to no default device // Note: One shots are lost, all SoundEffectInstances are in the STOPPED state after successful reset void __cdecl Suspend() noexcept; void __cdecl Resume(); // Suspend/resumes audio processing (i.e. global pause/resume) float __cdecl GetMasterVolume() const noexcept; void __cdecl SetMasterVolume(float volume); // Master volume property for all sounds void __cdecl SetReverb(AUDIO_ENGINE_REVERB reverb); void __cdecl SetReverb(_In_opt_ const XAUDIO2FX_REVERB_PARAMETERS* native); // Sets environmental reverb for 3D positional audio (if active) void __cdecl SetMasteringLimit(int release, int loudness); // Sets the mastering volume limiter properties (if active) AudioStatistics __cdecl GetStatistics() const; // Gathers audio engine statistics WAVEFORMATEXTENSIBLE __cdecl GetOutputFormat() const noexcept; // Returns the format consumed by the mastering voice (which is the same as the device output if defaults are used) uint32_t __cdecl GetChannelMask() const noexcept; // Returns the output channel mask unsigned int __cdecl GetOutputChannels() const noexcept; // Returns the number of output channels bool __cdecl IsAudioDevicePresent() const noexcept; // Returns true if the audio graph is operating normally, false if in 'silent mode' bool __cdecl IsCriticalError() const noexcept; // Returns true if the audio graph is halted due to a critical error (which also places the engine into 'silent mode') // Voice pool management. void __cdecl SetDefaultSampleRate(int sampleRate); // Sample rate for voices in the reuse pool (defaults to 44100) void __cdecl SetMaxVoicePool(size_t maxOneShots, size_t maxInstances); // Maximum number of voices to allocate for one-shots and instances // Note: one-shots over this limit are ignored; too many instance voices throws an exception void __cdecl TrimVoicePool(); // Releases any currently unused voices // Internal-use functions void __cdecl AllocateVoice(_In_ const WAVEFORMATEX* wfx, SOUND_EFFECT_INSTANCE_FLAGS flags, bool oneshot, _Outptr_result_maybenull_ IXAudio2SourceVoice** voice); void __cdecl DestroyVoice(_In_ IXAudio2SourceVoice* voice) noexcept; // Should only be called for instance voices, not one-shots void __cdecl RegisterNotify(_In_ IVoiceNotify* notify, bool usesUpdate); void __cdecl UnregisterNotify(_In_ IVoiceNotify* notify, bool usesOneShots, bool usesUpdate); // XAudio2 interface access IXAudio2* __cdecl GetInterface() const noexcept; IXAudio2MasteringVoice* __cdecl GetMasterVoice() const noexcept; IXAudio2SubmixVoice* __cdecl GetReverbVoice() const noexcept; X3DAUDIO_HANDLE& __cdecl Get3DHandle() const noexcept; // Static functions struct RendererDetail { std::wstring deviceId; std::wstring description; }; static std::vector __cdecl GetRendererDetails(); // Returns a list of valid audio endpoint devices private: // Private implementation. class Impl; std::unique_ptr pImpl; }; //---------------------------------------------------------------------------------- class WaveBank { public: WaveBank(_In_ AudioEngine* engine, _In_z_ const wchar_t* wbFileName); WaveBank(WaveBank&& moveFrom) noexcept; WaveBank& operator= (WaveBank&& moveFrom) noexcept; WaveBank(WaveBank const&) = delete; WaveBank& operator= (WaveBank const&) = delete; virtual ~WaveBank(); void __cdecl Play(unsigned int index); void __cdecl Play(unsigned int index, float volume, float pitch, float pan); void __cdecl Play(_In_z_ const char* name); void __cdecl Play(_In_z_ const char* name, float volume, float pitch, float pan); std::unique_ptr __cdecl CreateInstance(unsigned int index, SOUND_EFFECT_INSTANCE_FLAGS flags = SoundEffectInstance_Default); std::unique_ptr __cdecl CreateInstance(_In_z_ const char* name, SOUND_EFFECT_INSTANCE_FLAGS flags = SoundEffectInstance_Default); std::unique_ptr __cdecl CreateStreamInstance(unsigned int index, SOUND_EFFECT_INSTANCE_FLAGS flags = SoundEffectInstance_Default); std::unique_ptr __cdecl CreateStreamInstance(_In_z_ const char* name, SOUND_EFFECT_INSTANCE_FLAGS flags = SoundEffectInstance_Default); bool __cdecl IsPrepared() const noexcept; bool __cdecl IsInUse() const noexcept; bool __cdecl IsStreamingBank() const noexcept; size_t __cdecl GetSampleSizeInBytes(unsigned int index) const noexcept; // Returns size of wave audio data size_t __cdecl GetSampleDuration(unsigned int index) const noexcept; // Returns the duration in samples size_t __cdecl GetSampleDurationMS(unsigned int index) const noexcept; // Returns the duration in milliseconds const WAVEFORMATEX* __cdecl GetFormat(unsigned int index, _Out_writes_bytes_(maxsize) WAVEFORMATEX* wfx, size_t maxsize) const noexcept; int __cdecl Find(_In_z_ const char* name) const; #ifdef USING_XAUDIO2_9 bool __cdecl FillSubmitBuffer(unsigned int index, _Out_ XAUDIO2_BUFFER& buffer, _Out_ XAUDIO2_BUFFER_WMA& wmaBuffer) const; #else void __cdecl FillSubmitBuffer(unsigned int index, _Out_ XAUDIO2_BUFFER& buffer) const; #endif void __cdecl UnregisterInstance(_In_ IVoiceNotify* instance); HANDLE __cdecl GetAsyncHandle() const noexcept; bool __cdecl GetPrivateData(unsigned int index, _Out_writes_bytes_(datasize) void* data, size_t datasize); private: // Private implementation. class Impl; std::unique_ptr pImpl; }; //---------------------------------------------------------------------------------- class SoundEffect { public: SoundEffect(_In_ AudioEngine* engine, _In_z_ const wchar_t* waveFileName); SoundEffect(_In_ AudioEngine* engine, _Inout_ std::unique_ptr& wavData, _In_ const WAVEFORMATEX* wfx, _In_reads_bytes_(audioBytes) const uint8_t* startAudio, size_t audioBytes); SoundEffect(_In_ AudioEngine* engine, _Inout_ std::unique_ptr& wavData, _In_ const WAVEFORMATEX* wfx, _In_reads_bytes_(audioBytes) const uint8_t* startAudio, size_t audioBytes, uint32_t loopStart, uint32_t loopLength); #ifdef USING_XAUDIO2_9 SoundEffect(_In_ AudioEngine* engine, _Inout_ std::unique_ptr& wavData, _In_ const WAVEFORMATEX* wfx, _In_reads_bytes_(audioBytes) const uint8_t* startAudio, size_t audioBytes, _In_reads_(seekCount) const uint32_t* seekTable, size_t seekCount); #endif SoundEffect(SoundEffect&& moveFrom) noexcept; SoundEffect& operator= (SoundEffect&& moveFrom) noexcept; SoundEffect(SoundEffect const&) = delete; SoundEffect& operator= (SoundEffect const&) = delete; virtual ~SoundEffect(); void __cdecl Play(); void __cdecl Play(float volume, float pitch, float pan); std::unique_ptr __cdecl CreateInstance(SOUND_EFFECT_INSTANCE_FLAGS flags = SoundEffectInstance_Default); bool __cdecl IsInUse() const noexcept; size_t __cdecl GetSampleSizeInBytes() const noexcept; // Returns size of wave audio data size_t __cdecl GetSampleDuration() const noexcept; // Returns the duration in samples size_t __cdecl GetSampleDurationMS() const noexcept; // Returns the duration in milliseconds const WAVEFORMATEX* __cdecl GetFormat() const noexcept; #ifdef USING_XAUDIO2_9 bool __cdecl FillSubmitBuffer(_Out_ XAUDIO2_BUFFER& buffer, _Out_ XAUDIO2_BUFFER_WMA& wmaBuffer) const; #else void __cdecl FillSubmitBuffer(_Out_ XAUDIO2_BUFFER& buffer) const; #endif void __cdecl UnregisterInstance(_In_ IVoiceNotify* instance); private: // Private implementation. class Impl; std::unique_ptr pImpl; }; //---------------------------------------------------------------------------------- struct AudioListener : public X3DAUDIO_LISTENER { AudioListener() noexcept { memset(this, 0, sizeof(X3DAUDIO_LISTENER)); OrientFront.z = -1.f; OrientTop.y = 1.f; } void XM_CALLCONV SetPosition(FXMVECTOR v) noexcept { XMStoreFloat3(reinterpret_cast(&Position), v); } void __cdecl SetPosition(const XMFLOAT3& pos) noexcept { Position.x = pos.x; Position.y = pos.y; Position.z = pos.z; } void XM_CALLCONV SetVelocity(FXMVECTOR v) noexcept { XMStoreFloat3(reinterpret_cast(&Velocity), v); } void __cdecl SetVelocity(const XMFLOAT3& vel) noexcept { Velocity.x = vel.x; Velocity.y = vel.y; Velocity.z = vel.z; } void XM_CALLCONV SetOrientation(FXMVECTOR forward, FXMVECTOR up) noexcept { XMStoreFloat3(reinterpret_cast(&OrientFront), forward); XMStoreFloat3(reinterpret_cast(&OrientTop), up); } void __cdecl SetOrientation(const XMFLOAT3& forward, const XMFLOAT3& up) noexcept { OrientFront.x = forward.x; OrientTop.x = up.x; OrientFront.y = forward.y; OrientTop.y = up.y; OrientFront.z = forward.z; OrientTop.z = up.z; } void XM_CALLCONV SetOrientationFromQuaternion(FXMVECTOR quat) noexcept { XMVECTOR forward = XMVector3Rotate(g_XMIdentityR2, quat); XMStoreFloat3(reinterpret_cast(&OrientFront), forward); XMVECTOR up = XMVector3Rotate(g_XMIdentityR1, quat); XMStoreFloat3(reinterpret_cast(&OrientTop), up); } void XM_CALLCONV Update(FXMVECTOR newPos, XMVECTOR upDir, float dt) noexcept // Updates velocity and orientation by tracking changes in position over time... { if (dt > 0.f) { XMVECTOR lastPos = XMLoadFloat3(reinterpret_cast(&Position)); XMVECTOR vDelta = XMVectorSubtract(newPos, lastPos); XMVECTOR vt = XMVectorReplicate(dt); XMVECTOR v = XMVectorDivide(vDelta, vt); XMStoreFloat3(reinterpret_cast(&Velocity), v); vDelta = XMVector3Normalize(vDelta); XMStoreFloat3(reinterpret_cast(&OrientFront), vDelta); v = XMVector3Cross(upDir, vDelta); v = XMVector3Normalize(v); v = XMVector3Cross(vDelta, v); v = XMVector3Normalize(v); XMStoreFloat3(reinterpret_cast(&OrientTop), v); XMStoreFloat3(reinterpret_cast(&Position), newPos); } } }; //---------------------------------------------------------------------------------- struct AudioEmitter : public X3DAUDIO_EMITTER { float EmitterAzimuths[XAUDIO2_MAX_AUDIO_CHANNELS]; AudioEmitter() noexcept : EmitterAzimuths{} { memset(this, 0, sizeof(X3DAUDIO_EMITTER)); OrientFront.z = -1.f; OrientTop.y = ChannelRadius = CurveDistanceScaler = DopplerScaler = 1.f; ChannelCount = 1; pChannelAzimuths = EmitterAzimuths; InnerRadiusAngle = X3DAUDIO_PI / 4.0f; } void XM_CALLCONV SetPosition(FXMVECTOR v) noexcept { XMStoreFloat3(reinterpret_cast(&Position), v); } void __cdecl SetPosition(const XMFLOAT3& pos) noexcept { Position.x = pos.x; Position.y = pos.y; Position.z = pos.z; } void XM_CALLCONV SetVelocity(FXMVECTOR v) noexcept { XMStoreFloat3(reinterpret_cast(&Velocity), v); } void __cdecl SetVelocity(const XMFLOAT3& vel) noexcept { Velocity.x = vel.x; Velocity.y = vel.y; Velocity.z = vel.z; } void XM_CALLCONV SetOrientation(FXMVECTOR forward, FXMVECTOR up) noexcept { XMStoreFloat3(reinterpret_cast(&OrientFront), forward); XMStoreFloat3(reinterpret_cast(&OrientTop), up); } void __cdecl SetOrientation(const XMFLOAT3& forward, const XMFLOAT3& up) noexcept { OrientFront.x = forward.x; OrientTop.x = up.x; OrientFront.y = forward.y; OrientTop.y = up.y; OrientFront.z = forward.z; OrientTop.z = up.z; } void XM_CALLCONV SetOrientationFromQuaternion(FXMVECTOR quat) noexcept { XMVECTOR forward = XMVector3Rotate(g_XMIdentityR2, quat); XMStoreFloat3(reinterpret_cast(&OrientFront), forward); XMVECTOR up = XMVector3Rotate(g_XMIdentityR1, quat); XMStoreFloat3(reinterpret_cast(&OrientTop), up); } void XM_CALLCONV Update(FXMVECTOR newPos, XMVECTOR upDir, float dt) noexcept // Updates velocity and orientation by tracking changes in position over time... { if (dt > 0.f) { XMVECTOR lastPos = XMLoadFloat3(reinterpret_cast(&Position)); XMVECTOR vDelta = XMVectorSubtract(newPos, lastPos); XMVECTOR vt = XMVectorReplicate(dt); XMVECTOR v = XMVectorDivide(vDelta, vt); XMStoreFloat3(reinterpret_cast(&Velocity), v); vDelta = XMVector3Normalize(vDelta); XMStoreFloat3(reinterpret_cast(&OrientFront), vDelta); v = XMVector3Cross(upDir, vDelta); v = XMVector3Normalize(v); v = XMVector3Cross(vDelta, v); v = XMVector3Normalize(v); XMStoreFloat3(reinterpret_cast(&OrientTop), v); XMStoreFloat3(reinterpret_cast(&Position), newPos); } } }; //---------------------------------------------------------------------------------- class SoundEffectInstance { public: SoundEffectInstance(SoundEffectInstance&& moveFrom) noexcept; SoundEffectInstance& operator= (SoundEffectInstance&& moveFrom) noexcept; SoundEffectInstance(SoundEffectInstance const&) = delete; SoundEffectInstance& operator= (SoundEffectInstance const&) = delete; virtual ~SoundEffectInstance(); void __cdecl Play(bool loop = false); void __cdecl Stop(bool immediate = true) noexcept; void __cdecl Pause() noexcept; void __cdecl Resume(); void __cdecl SetVolume(float volume); void __cdecl SetPitch(float pitch); void __cdecl SetPan(float pan); void __cdecl Apply3D(const AudioListener& listener, const AudioEmitter& emitter, bool rhcoords = true); bool __cdecl IsLooped() const noexcept; SoundState __cdecl GetState() noexcept; IVoiceNotify* __cdecl GetVoiceNotify() const noexcept; private: // Private implementation. class Impl; std::unique_ptr pImpl; // Private constructors SoundEffectInstance(_In_ AudioEngine* engine, _In_ SoundEffect* effect, SOUND_EFFECT_INSTANCE_FLAGS flags); SoundEffectInstance(_In_ AudioEngine* engine, _In_ WaveBank* effect, unsigned int index, SOUND_EFFECT_INSTANCE_FLAGS flags); friend std::unique_ptr __cdecl SoundEffect::CreateInstance(SOUND_EFFECT_INSTANCE_FLAGS); friend std::unique_ptr __cdecl WaveBank::CreateInstance(unsigned int, SOUND_EFFECT_INSTANCE_FLAGS); }; //---------------------------------------------------------------------------------- class SoundStreamInstance { public: SoundStreamInstance(SoundStreamInstance&& moveFrom) noexcept; SoundStreamInstance& operator= (SoundStreamInstance&& moveFrom) noexcept; SoundStreamInstance(SoundStreamInstance const&) = delete; SoundStreamInstance& operator= (SoundStreamInstance const&) = delete; virtual ~SoundStreamInstance(); void __cdecl Play(bool loop = false); void __cdecl Stop(bool immediate = true) noexcept; void __cdecl Pause() noexcept; void __cdecl Resume(); void __cdecl SetVolume(float volume); void __cdecl SetPitch(float pitch); void __cdecl SetPan(float pan); void __cdecl Apply3D(const AudioListener& listener, const AudioEmitter& emitter, bool rhcoords = true); bool __cdecl IsLooped() const noexcept; SoundState __cdecl GetState() noexcept; IVoiceNotify* __cdecl GetVoiceNotify() const noexcept; private: // Private implementation. class Impl; std::unique_ptr pImpl; // Private constructors SoundStreamInstance(_In_ AudioEngine* engine, _In_ WaveBank* effect, unsigned int index, SOUND_EFFECT_INSTANCE_FLAGS flags); friend std::unique_ptr __cdecl WaveBank::CreateStreamInstance(unsigned int, SOUND_EFFECT_INSTANCE_FLAGS); }; //---------------------------------------------------------------------------------- class DynamicSoundEffectInstance { public: DynamicSoundEffectInstance(_In_ AudioEngine* engine, _In_opt_ std::function bufferNeeded, int sampleRate, int channels, int sampleBits = 16, SOUND_EFFECT_INSTANCE_FLAGS flags = SoundEffectInstance_Default); DynamicSoundEffectInstance(DynamicSoundEffectInstance&& moveFrom) noexcept; DynamicSoundEffectInstance& operator= (DynamicSoundEffectInstance&& moveFrom) noexcept; DynamicSoundEffectInstance(DynamicSoundEffectInstance const&) = delete; DynamicSoundEffectInstance& operator= (DynamicSoundEffectInstance const&) = delete; virtual ~DynamicSoundEffectInstance(); void __cdecl Play(); void __cdecl Stop(bool immediate = true) noexcept; void __cdecl Pause() noexcept; void __cdecl Resume(); void __cdecl SetVolume(float volume); void __cdecl SetPitch(float pitch); void __cdecl SetPan(float pan); void __cdecl Apply3D(const AudioListener& listener, const AudioEmitter& emitter, bool rhcoords = true); void __cdecl SubmitBuffer(_In_reads_bytes_(audioBytes) const uint8_t* pAudioData, size_t audioBytes); void __cdecl SubmitBuffer(_In_reads_bytes_(audioBytes) const uint8_t* pAudioData, uint32_t offset, size_t audioBytes); SoundState __cdecl GetState() noexcept; size_t __cdecl GetSampleDuration(size_t bytes) const noexcept; // Returns duration in samples of a buffer of a given size size_t __cdecl GetSampleDurationMS(size_t bytes) const noexcept; // Returns duration in milliseconds of a buffer of a given size size_t __cdecl GetSampleSizeInBytes(uint64_t duration) const noexcept; // Returns size of a buffer for a duration given in milliseconds int __cdecl GetPendingBufferCount() const noexcept; const WAVEFORMATEX* __cdecl GetFormat() const noexcept; private: // Private implementation. class Impl; std::unique_ptr pImpl; }; #ifdef __clang__ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-dynamic-exception-spec" #endif DEFINE_ENUM_FLAG_OPERATORS(AUDIO_ENGINE_FLAGS); DEFINE_ENUM_FLAG_OPERATORS(SOUND_EFFECT_INSTANCE_FLAGS); #ifdef __clang__ #pragma clang diagnostic pop #endif }