mirror of
https://github.com/cemu-project/Cemu.git
synced 2025-07-09 00:11:17 +12:00
Play bootSound.btsnd while shaders/pipelines are compiling (#1047)
This commit is contained in:
parent
b53b223ba9
commit
3738ccd2e6
17 changed files with 310 additions and 128 deletions
|
@ -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()
|
||||
|
|
|
@ -97,7 +97,40 @@ bool IAudioAPI::IsAudioAPIAvailable(AudioAPI api)
|
|||
return false;
|
||||
}
|
||||
|
||||
AudioAPIPtr IAudioAPI::CreateDeviceFromConfig(bool TV, sint32 rate, sint32 samples_per_block, sint32 bits_per_sample)
|
||||
{
|
||||
auto& config = GetConfig();
|
||||
sint32 channels = CemuConfig::AudioChannelsToNChannels(TV ? config.tv_channels : config.pad_channels);
|
||||
return CreateDeviceFromConfig(TV, rate, channels, samples_per_block, bits_per_sample);
|
||||
}
|
||||
|
||||
AudioAPIPtr IAudioAPI::CreateDeviceFromConfig(bool TV, sint32 rate, sint32 channels, sint32 samples_per_block, sint32 bits_per_sample)
|
||||
{
|
||||
AudioAPIPtr audioAPIDev;
|
||||
|
||||
auto& config = GetConfig();
|
||||
|
||||
const auto audio_api = (IAudioAPI::AudioAPI)config.audio_api;
|
||||
auto& selectedDevice = TV ? config.tv_device : config.pad_device;
|
||||
|
||||
if(selectedDevice.empty())
|
||||
return {};
|
||||
|
||||
IAudioAPI::DeviceDescriptionPtr device_description;
|
||||
if (IAudioAPI::IsAudioAPIAvailable(audio_api))
|
||||
{
|
||||
auto devices = IAudioAPI::GetDevices(audio_api);
|
||||
const auto it = std::find_if(devices.begin(), devices.end(), [&selectedDevice](const auto& d) {return d->GetIdentifier() == selectedDevice; });
|
||||
if (it != devices.end())
|
||||
device_description = *it;
|
||||
}
|
||||
if (!device_description)
|
||||
throw std::runtime_error("failed to find selected device while trying to create audio device");
|
||||
|
||||
audioAPIDev = CreateDevice(audio_api, device_description, rate, channels, samples_per_block, bits_per_sample);
|
||||
audioAPIDev->SetVolume(TV ? config.tv_volume : config.pad_volume);
|
||||
return audioAPIDev;
|
||||
}
|
||||
|
||||
AudioAPIPtr IAudioAPI::CreateDevice(AudioAPI api, const DeviceDescriptionPtr& device, sint32 samplerate, sint32 channels, sint32 samples_per_block, sint32 bits_per_sample)
|
||||
{
|
||||
|
@ -167,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,11 +55,15 @@ 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();
|
||||
static bool IsAudioAPIAvailable(AudioAPI api);
|
||||
|
||||
|
||||
static std::unique_ptr<IAudioAPI> CreateDeviceFromConfig(bool TV, sint32 rate, sint32 samples_per_block, sint32 bits_per_sample);
|
||||
static std::unique_ptr<IAudioAPI> CreateDeviceFromConfig(bool TV, sint32 rate, sint32 channels, sint32 samples_per_block, sint32 bits_per_sample);
|
||||
static std::unique_ptr<IAudioAPI> CreateDevice(AudioAPI api, const DeviceDescriptionPtr& device, sint32 samplerate, sint32 channels, sint32 samples_per_block, sint32 bits_per_sample);
|
||||
static std::vector<DeviceDescriptionPtr> GetDevices(AudioAPI api);
|
||||
|
||||
|
@ -75,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 × 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;
|
||||
|
@ -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