Skip to content

Commit

Permalink
Fix no audio on zero latency bug. make Xaudio consistent with other APIs
Browse files Browse the repository at this point in the history
  • Loading branch information
goeiecool9999 committed Dec 23, 2023
1 parent 4468e7a commit da9c3c8
Show file tree
Hide file tree
Showing 9 changed files with 45 additions and 16 deletions.
9 changes: 6 additions & 3 deletions src/Cafe/HW/Latte/Core/LatteShaderCache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -833,12 +833,15 @@ void LatteShaderCache_StreamBootSound()
try
{
bootSndAudioDev = IAudioAPI::CreateDeviceFromConfig(true, 48000, 2, samplesPerBlock, 16);
if(!bootSndAudioDev)
return;
}
catch (const std::runtime_error& ex)
{
cemuLog_log(LogType::Force, "Failed to initialise audio device for bootup sound");
return;
}
bootSndAudioDev->SetAudioDelayOverride(4);
bootSndAudioDev->Play();

std::string sndPath = fmt::format("{}/meta/{}", CafeSystem::GetMlcStoragePath(CafeSystem::GetForegroundTitleId()), "bootSound.btsnd");
Expand All @@ -853,10 +856,10 @@ void LatteShaderCache_StreamBootSound()
{
while(audiothread_keeprunning)
{
if (bootSndAudioDev->NeedAdditionalBlocks())
while (bootSndAudioDev->NeedAdditionalBlocks())
bootSndAudioDev->FeedBlock(bootSndFileReader->getSamples());
// sleep for half the duration of a single block
std::this_thread::sleep_for(std::chrono::milliseconds(samplesPerBlock / (48'000/ 1'000) / 2));
// sleep for the duration of a single block
std::this_thread::sleep_for(std::chrono::milliseconds(samplesPerBlock / (48'000/ 1'000)));
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/audio/CubebAPI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ CubebAPI::~CubebAPI()
bool CubebAPI::NeedAdditionalBlocks() const
{
std::shared_lock lock(m_mutex);
return m_buffer.size() < s_audioDelay * m_bytesPerBlock;
return m_buffer.size() < GetAudioDelay() * m_bytesPerBlock;
}

bool CubebAPI::FeedBlock(sint16* data)
Expand Down
2 changes: 1 addition & 1 deletion src/audio/DirectSoundAPI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ void DirectSoundAPI::SetVolume(sint32 volume)
bool DirectSoundAPI::NeedAdditionalBlocks() const
{
std::shared_lock lock(m_mutex);
return m_buffer.size() < s_audioDelay;
return m_buffer.size() < GetAudioDelay();
}

std::vector<DirectSoundAPI::DeviceDescriptionPtr> DirectSoundAPI::GetDevices()
Expand Down
9 changes: 9 additions & 0 deletions src/audio/IAudioAPI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -200,3 +200,12 @@ std::vector<IAudioAPI::DeviceDescriptionPtr> IAudioAPI::GetDevices(AudioAPI api)
}
}

void IAudioAPI::SetAudioDelayOverride(uint32 delay)
{
m_audioDelayOverride = delay;
}

uint32 IAudioAPI::GetAudioDelay() const
{
return m_audioDelayOverride > 0 ? m_audioDelayOverride : s_audioDelay;
}
5 changes: 4 additions & 1 deletion src/audio/IAudioAPI.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ class IAudioAPI
virtual bool FeedBlock(sint16* data) = 0;
virtual bool Play() = 0;
virtual bool Stop() = 0;
void SetAudioDelayOverride(uint32 delay);
uint32 GetAudioDelay() const;

static void PrintLogging();
static void InitializeStatic();
Expand All @@ -77,9 +79,10 @@ class IAudioAPI
bool m_playing = false;

static std::array<bool, AudioAPIEnd> s_availableApis;
static uint32 s_audioDelay;
uint32 m_audioDelayOverride = 0;

private:
static uint32 s_audioDelay;
void InitWFX(sint32 samplerate, sint32 channels, sint32 bits_per_sample);

};
Expand Down
17 changes: 11 additions & 6 deletions src/audio/XAudio27API.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ XAudio27API::XAudio27API(uint32 device_id, uint32 samplerate, uint32 channels, u
m_wfx.Format.nChannels = channels;
m_wfx.Format.nSamplesPerSec = samplerate;
m_wfx.Format.wBitsPerSample = bits_per_sample;
m_wfx.Format.nBlockAlign = (m_wfx.Format.nChannels * m_wfx.Format.wBitsPerSample) / 8; // must equal (nChannels × wBitsPerSample) / 8
m_wfx.Format.nAvgBytesPerSec = m_wfx.Format.nSamplesPerSec * m_wfx.Format.nBlockAlign; // must equal nSamplesPerSec × nBlockAlign.
m_wfx.Format.nBlockAlign = (m_wfx.Format.nChannels * m_wfx.Format.wBitsPerSample) / 8; // must equal (nChannels wBitsPerSample) / 8
m_wfx.Format.nAvgBytesPerSec = m_wfx.Format.nSamplesPerSec * m_wfx.Format.nBlockAlign; // must equal nSamplesPerSec nBlockAlign.
m_wfx.Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX);

m_wfx.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
Expand Down Expand Up @@ -199,9 +199,7 @@ bool XAudio27API::FeedBlock(sint16* data)
// check if we queued too many blocks
if(m_blocks_queued >= kBlockCount)
{
XAUDIO2_VOICE_STATE state{};
m_source_voice->GetState(&state);
m_blocks_queued = state.BuffersQueued;
m_blocks_queued = GetQueuedBuffers();

if (m_blocks_queued >= kBlockCount)
{
Expand All @@ -222,7 +220,14 @@ bool XAudio27API::FeedBlock(sint16* data)
return true;
}

uint32 XAudio27API::GetQueuedBuffers() const
{
XAUDIO2_VOICE_STATE state{};
m_source_voice->GetState(&state);
return state.BuffersQueued;
}

bool XAudio27API::NeedAdditionalBlocks() const
{
return m_blocks_queued < s_audioDelay;
return GetQueuedBuffers() < GetAudioDelay();
}
2 changes: 2 additions & 0 deletions src/audio/XAudio27API.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ class XAudio27API : public IAudioAPI
static std::vector<DeviceDescriptionPtr> GetDevices();

private:
uint32 GetQueuedBuffers() const;

struct XAudioDeleter
{
void operator()(IXAudio2* ptr) const;
Expand Down
13 changes: 9 additions & 4 deletions src/audio/XAudio2API.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -270,9 +270,7 @@ bool XAudio2API::FeedBlock(sint16* data)
// check if we queued too many blocks
if (m_blocks_queued >= kBlockCount)
{
XAUDIO2_VOICE_STATE state{};
m_source_voice->GetState(&state);
m_blocks_queued = state.BuffersQueued;
m_blocks_queued = GetQueuedBuffers();

if (m_blocks_queued >= kBlockCount)
{
Expand All @@ -293,7 +291,14 @@ bool XAudio2API::FeedBlock(sint16* data)
return true;
}

uint32 XAudio2API::GetQueuedBuffers() const
{
XAUDIO2_VOICE_STATE state{};
m_source_voice->GetState(&state);
return state.BuffersQueued;
}

bool XAudio2API::NeedAdditionalBlocks() const
{
return m_blocks_queued < s_audioDelay;
return GetQueuedBuffers() < GetAudioDelay();
}
2 changes: 2 additions & 0 deletions src/audio/XAudio2API.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ class XAudio2API : public IAudioAPI
static const std::vector<DeviceDescriptionPtr>& GetDevices() { return s_devices; }

private:
uint32 GetQueuedBuffers() const;

static const std::vector<DeviceDescriptionPtr>& RefreshDevices();

struct XAudioDeleter
Expand Down

0 comments on commit da9c3c8

Please sign in to comment.