mirror of
https://github.com/cemu-project/Cemu.git
synced 2025-07-07 23:41:18 +12:00
Fix no audio on zero latency bug. make Xaudio consistent with other APIs
This commit is contained in:
parent
4468e7a7f2
commit
da9c3c84e8
9 changed files with 45 additions and 16 deletions
|
@ -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");
|
||||
|
@ -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)));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -55,6 +55,8 @@ public:
|
|||
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();
|
||||
|
@ -77,9 +79,10 @@ protected:
|
|||
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);
|
||||
|
||||
};
|
||||
|
|
|
@ -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 <EFBFBD> wBitsPerSample) / 8
|
||||
m_wfx.Format.nAvgBytesPerSec = m_wfx.Format.nSamplesPerSec * m_wfx.Format.nBlockAlign; // must equal nSamplesPerSec <EFBFBD> nBlockAlign.
|
||||
m_wfx.Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX);
|
||||
|
||||
m_wfx.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -47,6 +47,8 @@ public:
|
|||
static std::vector<DeviceDescriptionPtr> GetDevices();
|
||||
|
||||
private:
|
||||
uint32 GetQueuedBuffers() const;
|
||||
|
||||
struct XAudioDeleter
|
||||
{
|
||||
void operator()(IXAudio2* ptr) const;
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -46,6 +46,8 @@ public:
|
|||
static const std::vector<DeviceDescriptionPtr>& GetDevices() { return s_devices; }
|
||||
|
||||
private:
|
||||
uint32 GetQueuedBuffers() const;
|
||||
|
||||
static const std::vector<DeviceDescriptionPtr>& RefreshDevices();
|
||||
|
||||
struct XAudioDeleter
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue