Browse Source

[audio] persistent device volume control (#4416)

- [x] I have read and followed the [Contribution Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/CONTRIBUTING.md#code-contributions).
- [x] I have read and followed the [AI Policy](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/policies/AI.md)
- [x] I have read and followed the [Coding Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/policies/Coding.md) to the best of my ability.

-------------------
So, upon investigating AC3 not booting when fw 20+ and overlay applet disabled, i found the leads:
"LibAppletOff" and "AudioTvOutput". By further decoding instructions i've found a guest assert comparing device volume with hdmi volume. Since we implemented no  proper master volume when no streams are created the assert were failing causing guest to panic (why?????????)
Anyway. ac3 now works fw20+ and no overlay applet.. Maybe other games too.

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4416
Reviewed-by: lizzie <lizzie@eden-emu.dev>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
master
xbzk 12 hours ago
committed by crueter
parent
commit
93318ef697
No known key found for this signature in database GPG Key ID: 425ACD2D4830EBC6
  1. 8
      src/audio_core/sink/cubeb_sink.cpp
  2. 13
      src/audio_core/sink/null_sink.h
  3. 8
      src/audio_core/sink/sdl3_sink.cpp
  4. 5
      src/audio_core/sink/sink.h

8
src/audio_core/sink/cubeb_sink.cpp

@ -261,6 +261,7 @@ SinkStream* CubebSink::AcquireSinkStream(Core::System& system, u32 system_channe
system_channels = system_channels_; system_channels = system_channels_;
SinkStreamPtr& stream = sink_streams.emplace_back(std::make_unique<CubebSinkStream>( SinkStreamPtr& stream = sink_streams.emplace_back(std::make_unique<CubebSinkStream>(
ctx, device_channels, system_channels, output_device, input_device, name, type, system)); ctx, device_channels, system_channels, output_device, input_device, name, type, system));
stream->SetDeviceVolume(device_volume);
return stream.get(); return stream.get();
} }
@ -280,14 +281,11 @@ void CubebSink::CloseStreams() {
} }
f32 CubebSink::GetDeviceVolume() const { f32 CubebSink::GetDeviceVolume() const {
if (sink_streams.empty()) {
return 1.0f;
}
return sink_streams[0]->GetDeviceVolume();
return device_volume;
} }
void CubebSink::SetDeviceVolume(f32 volume) { void CubebSink::SetDeviceVolume(f32 volume) {
device_volume = volume;
for (auto& stream : sink_streams) { for (auto& stream : sink_streams) {
stream->SetDeviceVolume(volume); stream->SetDeviceVolume(volume);
} }

13
src/audio_core/sink/null_sink.h

@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
@ -38,6 +41,7 @@ public:
StreamType type) override { StreamType type) override {
if (null_sink == nullptr) { if (null_sink == nullptr) {
null_sink = std::make_unique<NullSinkStreamImpl>(system, type); null_sink = std::make_unique<NullSinkStreamImpl>(system, type);
null_sink->SetDeviceVolume(device_volume);
} }
return null_sink.get(); return null_sink.get();
} }
@ -45,9 +49,14 @@ public:
void CloseStream(SinkStream*) override {} void CloseStream(SinkStream*) override {}
void CloseStreams() override {} void CloseStreams() override {}
f32 GetDeviceVolume() const override { f32 GetDeviceVolume() const override {
return 1.0f;
return device_volume;
}
void SetDeviceVolume(f32 volume) override {
device_volume = volume;
if (null_sink != nullptr) {
null_sink->SetDeviceVolume(volume);
}
} }
void SetDeviceVolume(f32 volume) override {}
void SetSystemVolume(f32 volume) override {} void SetSystemVolume(f32 volume) override {}
private: private:

8
src/audio_core/sink/sdl3_sink.cpp

@ -246,6 +246,7 @@ SinkStream* SDLSink::AcquireSinkStream(Core::System& system, u32 system_channels
system_channels = system_channels_; system_channels = system_channels_;
SinkStreamPtr& stream = sink_streams.emplace_back(std::make_unique<SDLSinkStream>( SinkStreamPtr& stream = sink_streams.emplace_back(std::make_unique<SDLSinkStream>(
device_channels, system_channels, output_device, input_device, type, system)); device_channels, system_channels, output_device, input_device, type, system));
stream->SetDeviceVolume(device_volume);
return stream.get(); return stream.get();
} }
@ -264,14 +265,11 @@ void SDLSink::CloseStreams() {
} }
f32 SDLSink::GetDeviceVolume() const { f32 SDLSink::GetDeviceVolume() const {
if (sink_streams.empty()) {
return 1.0f;
}
return sink_streams[0]->GetDeviceVolume();
return device_volume;
} }
void SDLSink::SetDeviceVolume(f32 volume) { void SDLSink::SetDeviceVolume(f32 volume) {
device_volume = volume;
for (auto& stream : sink_streams) { for (auto& stream : sink_streams) {
stream->SetDeviceVolume(volume); stream->SetDeviceVolume(volume);
} }

5
src/audio_core/sink/sink.h

@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
@ -96,6 +99,8 @@ public:
} }
protected: protected:
/// Master volume, persists stream lifetimes
f32 device_volume{1.0f};
/// Number of device channels supported by the hardware /// Number of device channels supported by the hardware
u32 device_channels{2}; u32 device_channels{2};
/// Number of channels the game is sending /// Number of channels the game is sending

Loading…
Cancel
Save