mirror of
https://github.com/elasota/Aerofoil.git
synced 2025-12-14 03:59:36 +00:00
Refactor audio buffering API, this should mainly prevent SDL audio driver from allocating memory in the mixer callback.
This commit is contained in:
67
GpAudioDriver_XAudio2/GpAudioBufferXAudio2.cpp
Normal file
67
GpAudioDriver_XAudio2/GpAudioBufferXAudio2.cpp
Normal file
@@ -0,0 +1,67 @@
|
||||
#include "GpAudioBufferXAudio2.h"
|
||||
#include "CoreDefs.h"
|
||||
#include "GpWindows.h"
|
||||
|
||||
#include <malloc.h>
|
||||
#include <string.h>
|
||||
#include <new>
|
||||
|
||||
GpAudioBufferXAudio2 *GpAudioBufferXAudio2::Create(const void *buffer, size_t size)
|
||||
{
|
||||
size_t baseSize = sizeof(GpAudioBufferXAudio2);
|
||||
baseSize = baseSize + GP_SYSTEM_MEMORY_ALIGNMENT - 1;
|
||||
baseSize -= baseSize % GP_SYSTEM_MEMORY_ALIGNMENT;
|
||||
|
||||
size_t totalSize = baseSize + size;
|
||||
|
||||
void *storage = _aligned_malloc(totalSize, GP_SYSTEM_MEMORY_ALIGNMENT);
|
||||
if (!storage)
|
||||
return nullptr;
|
||||
|
||||
void *dataPos = static_cast<uint8_t*>(storage) + baseSize;
|
||||
|
||||
memcpy(dataPos, buffer, size);
|
||||
return new (storage) GpAudioBufferXAudio2(dataPos, size);
|
||||
}
|
||||
|
||||
void GpAudioBufferXAudio2::AddRef()
|
||||
{
|
||||
InterlockedIncrement(&m_count);
|
||||
}
|
||||
|
||||
void GpAudioBufferXAudio2::Release()
|
||||
{
|
||||
if (InterlockedDecrement(&m_count) == 0)
|
||||
this->Destroy();
|
||||
}
|
||||
|
||||
const XAUDIO2_BUFFER *GpAudioBufferXAudio2::GetXA2Buffer() const
|
||||
{
|
||||
return &m_xa2Buffer;
|
||||
}
|
||||
|
||||
GpAudioBufferXAudio2::GpAudioBufferXAudio2(const void *data, size_t size)
|
||||
: m_data(data)
|
||||
, m_size(size)
|
||||
, m_count(1)
|
||||
{
|
||||
m_xa2Buffer.Flags = 0;
|
||||
m_xa2Buffer.AudioBytes = static_cast<UINT32>(size);
|
||||
m_xa2Buffer.pAudioData = static_cast<const BYTE*>(data);
|
||||
m_xa2Buffer.PlayBegin = 0;
|
||||
m_xa2Buffer.PlayLength = 0;
|
||||
m_xa2Buffer.LoopBegin = 0;
|
||||
m_xa2Buffer.LoopLength = 0;
|
||||
m_xa2Buffer.LoopCount = 0;
|
||||
m_xa2Buffer.pContext = this;
|
||||
}
|
||||
|
||||
GpAudioBufferXAudio2::~GpAudioBufferXAudio2()
|
||||
{
|
||||
}
|
||||
|
||||
void GpAudioBufferXAudio2::Destroy()
|
||||
{
|
||||
this->~GpAudioBufferXAudio2();
|
||||
_aligned_free(this);
|
||||
}
|
||||
29
GpAudioDriver_XAudio2/GpAudioBufferXAudio2.h
Normal file
29
GpAudioDriver_XAudio2/GpAudioBufferXAudio2.h
Normal file
@@ -0,0 +1,29 @@
|
||||
#pragma once
|
||||
|
||||
#include "IGpAudioBuffer.h"
|
||||
|
||||
#include <xaudio2.h>
|
||||
|
||||
class GpAudioBufferXAudio2 final : public IGpAudioBuffer
|
||||
{
|
||||
public:
|
||||
static GpAudioBufferXAudio2 *Create(const void *buffer, size_t size);
|
||||
|
||||
void AddRef() override;
|
||||
void Release() override;
|
||||
|
||||
const XAUDIO2_BUFFER *GetXA2Buffer() const;
|
||||
|
||||
private:
|
||||
GpAudioBufferXAudio2(const void *data, size_t size);
|
||||
~GpAudioBufferXAudio2();
|
||||
|
||||
void Destroy();
|
||||
|
||||
const void *m_data;
|
||||
size_t m_size;
|
||||
|
||||
XAUDIO2_BUFFER m_xa2Buffer;
|
||||
|
||||
volatile unsigned int m_count;
|
||||
};
|
||||
@@ -1,3 +1,4 @@
|
||||
#include "GpAudioBufferXAudio2.h"
|
||||
#include "GpAudioChannelXAudio2.h"
|
||||
#include "GpAudioDriverXAudio2.h"
|
||||
#include "IGpAudioChannelCallbacks.h"
|
||||
@@ -77,25 +78,25 @@ void GpAudioChannelXAudio2::SetAudioChannelContext(IGpAudioChannelCallbacks *cal
|
||||
m_contextCallbacks = callbacks;
|
||||
}
|
||||
|
||||
void GpAudioChannelXAudio2::PostBuffer(const void *buffer, size_t bufferSize)
|
||||
bool GpAudioChannelXAudio2::PostBuffer(IGpAudioBuffer *buffer)
|
||||
{
|
||||
XAUDIO2_BUFFER xa2Buffer;
|
||||
xa2Buffer.Flags = 0;
|
||||
xa2Buffer.AudioBytes = static_cast<UINT32>(bufferSize);
|
||||
xa2Buffer.pAudioData = static_cast<const BYTE*>(buffer);
|
||||
xa2Buffer.PlayBegin = 0;
|
||||
xa2Buffer.PlayLength = 0;
|
||||
xa2Buffer.LoopBegin = 0;
|
||||
xa2Buffer.LoopLength = 0;
|
||||
xa2Buffer.LoopCount = 0;
|
||||
xa2Buffer.pContext = nullptr;
|
||||
GpAudioBufferXAudio2 *xa2Buffer = static_cast<GpAudioBufferXAudio2*>(buffer);
|
||||
xa2Buffer->AddRef();
|
||||
|
||||
HRESULT result = m_sourceVoice->SubmitSourceBuffer(xa2Buffer->GetXA2Buffer(), nullptr);
|
||||
if (result != S_OK)
|
||||
{
|
||||
xa2Buffer->Release();
|
||||
return false;
|
||||
}
|
||||
|
||||
m_sourceVoice->SubmitSourceBuffer(&xa2Buffer, nullptr);
|
||||
if (m_voiceState == VoiceState_Idle)
|
||||
{
|
||||
m_voiceState = VoiceState_Active;
|
||||
m_sourceVoice->Start(0, 0);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void GpAudioChannelXAudio2::Stop()
|
||||
|
||||
@@ -16,7 +16,7 @@ public:
|
||||
static GpAudioChannelXAudio2 *Create(GpAudioDriverXAudio2 *driver);
|
||||
|
||||
void SetAudioChannelContext(IGpAudioChannelCallbacks *callbacks) override;
|
||||
void PostBuffer(const void *buffer, size_t bufferSize) override;
|
||||
bool PostBuffer(IGpAudioBuffer *buffer) override;
|
||||
void Stop() override;
|
||||
void Destroy() override;
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#include "GpAudioBufferXAudio2.h"
|
||||
#include "GpAudioChannelXAudio2Callbacks.h"
|
||||
#include "GpAudioChannelXAudio2.h"
|
||||
|
||||
@@ -24,6 +25,7 @@ void GpAudioChannelXAudio2Callbacks::OnBufferStart(void* pBufferContext)
|
||||
|
||||
void GpAudioChannelXAudio2Callbacks::OnBufferEnd(void* pBufferContext)
|
||||
{
|
||||
static_cast<GpAudioBufferXAudio2*>(pBufferContext)->Release();
|
||||
m_owner->OnBufferEnd();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
#include "GpAudioDriverXAudio2.h"
|
||||
|
||||
#include "IGpLogDriver.h"
|
||||
#include "GpAudioBufferXAudio2.h"
|
||||
#include "GpAudioChannelXAudio2.h"
|
||||
#include "CoreDefs.h"
|
||||
|
||||
#include <xaudio2.h>
|
||||
#include <malloc.h>
|
||||
|
||||
void GpAudioDriverXAudio2::Shutdown()
|
||||
{
|
||||
@@ -96,6 +99,11 @@ GpAudioDriverXAudio2 *GpAudioDriverXAudio2::Create(const GpAudioDriverProperties
|
||||
return new GpAudioDriverXAudio2(properties, realSampleRate, xa, mv);
|
||||
}
|
||||
|
||||
IGpAudioBuffer *GpAudioDriverXAudio2::CreateBuffer(const void *buffer, size_t bufferSize)
|
||||
{
|
||||
return GpAudioBufferXAudio2::Create(buffer, bufferSize);
|
||||
}
|
||||
|
||||
IGpAudioChannel *GpAudioDriverXAudio2::CreateChannel()
|
||||
{
|
||||
return GpAudioChannelXAudio2::Create(this);
|
||||
|
||||
@@ -10,6 +10,7 @@ struct IXAudio2MasteringVoice;
|
||||
class GpAudioDriverXAudio2 : public IGpAudioDriver
|
||||
{
|
||||
public:
|
||||
IGpAudioBuffer *CreateBuffer(const void *buffer, size_t bufferSize) override;
|
||||
IGpAudioChannel *CreateChannel() override;
|
||||
void SetMasterVolume(uint32_t vol, uint32_t maxVolume) override;
|
||||
void Shutdown() override;
|
||||
|
||||
@@ -38,11 +38,14 @@
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="..\GpCommon.props" />
|
||||
<Import Project="..\Common.props" />
|
||||
<Import Project="..\Debug.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="..\GpCommon.props" />
|
||||
<Import Project="..\Release.props" />
|
||||
<Import Project="..\Common.props" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup />
|
||||
@@ -69,12 +72,14 @@
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="GpAudioBufferXAudio2.h" />
|
||||
<ClInclude Include="GpAudioChannelXAudio2.h" />
|
||||
<ClInclude Include="GpAudioChannelXAudio2Callbacks.h" />
|
||||
<ClInclude Include="GpAudioDriverFactoryXAudio2.h" />
|
||||
<ClInclude Include="GpAudioDriverXAudio2.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="GpAudioBufferXAudio2.cpp" />
|
||||
<ClCompile Include="GpAudioChannelXAudio2.cpp" />
|
||||
<ClCompile Include="GpAudioChannelXAudio2Callbacks.cpp" />
|
||||
<ClCompile Include="GpAudioDriverFactoryXAudio2.cpp" />
|
||||
|
||||
@@ -27,6 +27,9 @@
|
||||
<ClInclude Include="GpAudioChannelXAudio2Callbacks.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="GpAudioBufferXAudio2.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="GpAudioDriverFactoryXAudio2.cpp">
|
||||
@@ -41,6 +44,9 @@
|
||||
<ClCompile Include="GpAudioChannelXAudio2Callbacks.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="GpAudioBufferXAudio2.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
|
||||
Reference in New Issue
Block a user