Hi, i couldn't start the Zelda BOTW at all (it was freezing on the first screen), and sound was linked to the issue. I let DS4Flash running in loop till it fixed it locally, here's the resume if it helps:
Symptom
On Linux, Cemu logs the following during title boot and then hangs at the
loading screen:
can't initialize tv audio: failed to find selected device while trying to create audio device
No audio output is produced. This happens with any audio device selected
("default", a specific sink, etc.).
Root cause
-
CemuConfig::audio_api defaults to 0
(src/config/CemuConfig.h) and is loaded with the same fallback
(src/config/CemuConfig.cpp: audio_api = audio.get("api", 0)).
-
The AudioAPI enum (src/audio/IAudioAPI.h) is:
enum AudioAPI
{
DirectSound = 0,
XAudio27,
XAudio2,
Cubeb,
AudioAPIEnd,
};
So audio_api = 0 selects DirectSound.
-
DirectSound is a Windows-only backend. On non-Windows builds it is correctly
not reported as available (src/audio/IAudioAPI.cpp, guarded by
#if BOOST_OS_WINDOWS).
-
In IAudioAPI::CreateDeviceFromConfig
(src/audio/IAudioAPI.cpp), the device lookup is only performed when the
configured API is available:
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");
With audio_api = DirectSound (unavailable on Linux) the lookup is skipped
entirely, device_description stays nullptr, and the function throws
failed to find selected device ....
-
The exception is caught and logged by the audio init path
(src/Cafe/OS/libs/snd_core/ax_out.cpp), but no audio device / mixer is
ever created. Games wait for their audio subsystem during boot, so they
hang at the loading screen indefinitely.
Why the selected device name is irrelevant
Because the device lookup is skipped when the API is unavailable, every device
string fails identically (default, a real sink name, etc.). This is why
keys.txt, the GPU backend, and the audio device all appeared to be the
problem before the API selection was investigated.
Workaround (no rebuild)
In settings.xml, force the Cubeb backend:
<Audio>
<api>3</api>
<TVDevice>default</TVDevice>
</Audio>
(3 = Cubeb.) This is what makes audio work on Linux today.
The fix
-
Default audio_api to Cubeb on non-Windows platforms.
src/config/CemuConfig.h — struct member default.
src/config/CemuConfig.cpp — audio.get("api", ...) fallback.
On Windows the default remains DirectSound.
-
Fall back to an available audio API instead of failing.
In IAudioAPI::CreateDeviceFromConfig, if the configured API is not
available on this platform (e.g. a stale DirectSound value in an existing
settings.xml), select the first available API instead of skipping the
lookup and throwing.
-
Run without audio instead of throwing when nothing usable exists.
If no audio backend or device is available, return an empty device (silent
audio) — matching the existing behavior of an unset output device — rather
than throwing and letting the game hang at boot.
Files changed
src/config/CemuConfig.h
src/config/CemuConfig.cpp
src/audio/IAudioAPI.cpp
Testing
- Linux (PipeWire + PulseAudio): game boots with audio,
Cemu Cubeb stream
visible in pactl list sink-inputs.
- Linux with an existing
settings.xml containing <api>0</api>: audio
still works via the API fallback.
- Windows: unchanged (DirectSound remains the default and is available).
Hi, i couldn't start the Zelda BOTW at all (it was freezing on the first screen), and sound was linked to the issue. I let DS4Flash running in loop till it fixed it locally, here's the resume if it helps:
Symptom
On Linux, Cemu logs the following during title boot and then hangs at the
loading screen:
No audio output is produced. This happens with any audio device selected
("default", a specific sink, etc.).
Root cause
CemuConfig::audio_apidefaults to0(
src/config/CemuConfig.h) and is loaded with the same fallback(
src/config/CemuConfig.cpp:audio_api = audio.get("api", 0)).The
AudioAPIenum (src/audio/IAudioAPI.h) is:So
audio_api = 0selects DirectSound.DirectSound is a Windows-only backend. On non-Windows builds it is correctly
not reported as available (
src/audio/IAudioAPI.cpp, guarded by#if BOOST_OS_WINDOWS).In
IAudioAPI::CreateDeviceFromConfig(
src/audio/IAudioAPI.cpp), the device lookup is only performed when theconfigured API is available:
With
audio_api = DirectSound(unavailable on Linux) the lookup is skippedentirely,
device_descriptionstaysnullptr, and the function throwsfailed to find selected device ....The exception is caught and logged by the audio init path
(
src/Cafe/OS/libs/snd_core/ax_out.cpp), but no audio device / mixer isever created. Games wait for their audio subsystem during boot, so they
hang at the loading screen indefinitely.
Why the selected device name is irrelevant
Because the device lookup is skipped when the API is unavailable, every device
string fails identically (
default, a real sink name, etc.). This is whykeys.txt, the GPU backend, and the audio device all appeared to be theproblem before the API selection was investigated.
Workaround (no rebuild)
In
settings.xml, force the Cubeb backend:(
3=Cubeb.) This is what makes audio work on Linux today.The fix
Default
audio_apito Cubeb on non-Windows platforms.src/config/CemuConfig.h— struct member default.src/config/CemuConfig.cpp—audio.get("api", ...)fallback.On Windows the default remains DirectSound.
Fall back to an available audio API instead of failing.
In
IAudioAPI::CreateDeviceFromConfig, if the configured API is notavailable on this platform (e.g. a stale
DirectSoundvalue in an existingsettings.xml), select the first available API instead of skipping thelookup and throwing.
Run without audio instead of throwing when nothing usable exists.
If no audio backend or device is available, return an empty device (silent
audio) — matching the existing behavior of an unset output device — rather
than throwing and letting the game hang at boot.
Files changed
src/config/CemuConfig.hsrc/config/CemuConfig.cppsrc/audio/IAudioAPI.cppTesting
Cemu Cubebstreamvisible in
pactl list sink-inputs.settings.xmlcontaining<api>0</api>: audiostill works via the API fallback.