From 4f81fcd5cccff79821eb4dc8365c62238e8ec922 Mon Sep 17 00:00:00 2001 From: Megamouse Date: Sat, 28 May 2022 13:35:28 +0200 Subject: [PATCH] cellAudioOutConfigure: move sound_modes to fxo, implement waitForEvent --- rpcs3/Emu/Cell/Modules/cellAudioOut.cpp | 134 +++++++++++++++++++----- rpcs3/Emu/Cell/Modules/cellAudioOut.h | 4 + 2 files changed, 113 insertions(+), 25 deletions(-) diff --git a/rpcs3/Emu/Cell/Modules/cellAudioOut.cpp b/rpcs3/Emu/Cell/Modules/cellAudioOut.cpp index c875d4ec0c..ba8974a56d 100644 --- a/rpcs3/Emu/Cell/Modules/cellAudioOut.cpp +++ b/rpcs3/Emu/Cell/Modules/cellAudioOut.cpp @@ -1,10 +1,11 @@ #include "stdafx.h" #include "Emu/Cell/PPUModule.h" +#include "Emu/Cell/lv2/sys_rsxaudio.h" #include "Emu/IdManager.h" +#include "Emu/System.h" #include "cellAudioOut.h" #include "cellAudio.h" -#include "Emu/Cell/lv2/sys_rsxaudio.h" LOG_CHANNEL(cellSysutil); @@ -29,6 +30,35 @@ void fmt_class_string::format(std::string& out, u64 arg) }); } +audio_out_configuration::audio_out_configuration() +{ + CellAudioOutSoundMode mode{}; + + mode.type = CELL_AUDIO_OUT_CODING_TYPE_LPCM; + mode.channel = CELL_AUDIO_OUT_CHNUM_8; + mode.fs = CELL_AUDIO_OUT_FS_48KHZ; + mode.layout = CELL_AUDIO_OUT_SPEAKER_LAYOUT_8CH_LREClrxy; + + out.at(CELL_AUDIO_OUT_PRIMARY).sound_modes.push_back(mode); + out.at(CELL_AUDIO_OUT_SECONDARY).sound_modes.push_back(mode); + + mode.type = CELL_AUDIO_OUT_CODING_TYPE_LPCM; + mode.channel = CELL_AUDIO_OUT_CHNUM_6; + mode.fs = CELL_AUDIO_OUT_FS_48KHZ; + mode.layout = CELL_AUDIO_OUT_SPEAKER_LAYOUT_6CH_LREClr; + + out.at(CELL_AUDIO_OUT_PRIMARY).sound_modes.push_back(mode); + out.at(CELL_AUDIO_OUT_SECONDARY).sound_modes.push_back(mode); + + mode.type = CELL_AUDIO_OUT_CODING_TYPE_LPCM; + mode.channel = CELL_AUDIO_OUT_CHNUM_2; + mode.fs = CELL_AUDIO_OUT_FS_48KHZ; + mode.layout = CELL_AUDIO_OUT_SPEAKER_LAYOUT_2CH; + + out.at(CELL_AUDIO_OUT_PRIMARY).sound_modes.push_back(mode); + out.at(CELL_AUDIO_OUT_SECONDARY).sound_modes.push_back(mode); +} + error_code cellAudioOutGetNumberOfDevice(u32 audioOut); error_code cellAudioOutGetSoundAvailability(u32 audioOut, u32 type, u32 fs, u32 option) @@ -158,14 +188,37 @@ error_code cellAudioOutGetState(u32 audioOut, u32 deviceIndex, vm::ptrget(); + std::lock_guard lock(cfg.mtx); + audio_out_configuration::audio_out& out = cfg.out.at(audioOut); + + const auto it = std::find_if(out.sound_modes.cbegin(), out.sound_modes.cend(), [&channels, &out](const CellAudioOutSoundMode& mode) + { + if (mode.type == out.encoder) + { + switch (mode.type) + { + case CELL_AUDIO_OUT_CODING_TYPE_LPCM: + return mode.channel == static_cast(channels); + case CELL_AUDIO_OUT_CODING_TYPE_AC3: + case CELL_AUDIO_OUT_CODING_TYPE_DTS: + return true; // We currently only have one possible sound mode for these types + default: + return false; + } + } + + return false; + }); + + ensure(it != out.sound_modes.cend()); + + _state.state = out.state; + _state.encoder = out.encoder; + _state.downMixer = out.downmixer; + _state.soundMode = *it; break; } default: @@ -198,11 +251,20 @@ error_code cellAudioOutConfigure(u32 audioOut, vm::ptrget(); { - audio_out_configuration& cfg = g_fxo->get(); std::lock_guard lock(cfg.mtx); audio_out_configuration::audio_out& out = cfg.out.at(audioOut); + + if (out.sound_modes.cend() == std::find_if(out.sound_modes.cbegin(), out.sound_modes.cend(), [&config](const CellAudioOutSoundMode& mode) + { + return mode.channel == config->channel && mode.type == config->encoder && config->downMixer <= CELL_AUDIO_OUT_DOWNMIXER_TYPE_B; + })) + { + return CELL_AUDIO_OUT_ERROR_ILLEGAL_CONFIGURATION; // TODO: confirm + } + out_old = out; out.channels = config->channel; @@ -215,8 +277,31 @@ error_code cellAudioOutConfigure(u32 audioOut, vm::ptr void + { + audio_out_configuration& cfg = g_fxo->get(); + { + std::lock_guard lock(cfg.mtx); + cfg.out.at(audioOut).state = CELL_AUDIO_OUT_OUTPUT_STATE_DISABLED; + } + + audio::configure_audio(); + audio::configure_rsxaudio(); + + { + std::lock_guard lock(cfg.mtx); + cfg.out.at(audioOut).state = CELL_AUDIO_OUT_OUTPUT_STATE_ENABLED; + } + }; + + if (waitForEvent) + { + reset_audio(); + } + else + { + Emu.CallFromMainThread(reset_audio); + } } cellSysutil.notice("cellAudioOutConfigure: channels=%d, encoder=%d, downMixer=%d", config->channel, config->encoder, config->downMixer); @@ -302,24 +387,23 @@ error_code cellAudioOutGetDeviceInfo(u32 audioOut, u32 deviceIndex, vm::ptrget(); + std::lock_guard lock(cfg.mtx); + ensure(audioOut < cfg.out.size()); + audio_out_configuration::audio_out& out = cfg.out.at(audioOut); + ensure(out.sound_modes.size() <= 16); + CellAudioOutDeviceInfo _info{}; _info.portType = CELL_AUDIO_OUT_PORT_HDMI; - _info.availableModeCount = 3; + _info.availableModeCount = ::narrow(out.sound_modes.size()); _info.state = CELL_AUDIO_OUT_DEVICE_STATE_AVAILABLE; _info.latency = 1000; - _info.availableModes[0].type = CELL_AUDIO_OUT_CODING_TYPE_LPCM; - _info.availableModes[0].channel = CELL_AUDIO_OUT_CHNUM_8; - _info.availableModes[0].fs = CELL_AUDIO_OUT_FS_48KHZ; - _info.availableModes[0].layout = CELL_AUDIO_OUT_SPEAKER_LAYOUT_8CH_LREClrxy; - _info.availableModes[1].type = CELL_AUDIO_OUT_CODING_TYPE_LPCM; - _info.availableModes[1].channel = CELL_AUDIO_OUT_CHNUM_2; - _info.availableModes[1].fs = CELL_AUDIO_OUT_FS_48KHZ; - _info.availableModes[1].layout = CELL_AUDIO_OUT_SPEAKER_LAYOUT_2CH; - _info.availableModes[2].type = CELL_AUDIO_OUT_CODING_TYPE_LPCM; - _info.availableModes[2].channel = CELL_AUDIO_OUT_CHNUM_6; - _info.availableModes[2].fs = CELL_AUDIO_OUT_FS_48KHZ; - _info.availableModes[2].layout = CELL_AUDIO_OUT_SPEAKER_LAYOUT_6CH_LREClr; + + for (usz i = 0; i < out.sound_modes.size(); i++) + { + _info.availableModes[i] = out.sound_modes.at(i); + } *info = _info; return CELL_OK; diff --git a/rpcs3/Emu/Cell/Modules/cellAudioOut.h b/rpcs3/Emu/Cell/Modules/cellAudioOut.h index 34b26b42fb..6aad9e64d4 100644 --- a/rpcs3/Emu/Cell/Modules/cellAudioOut.h +++ b/rpcs3/Emu/Cell/Modules/cellAudioOut.h @@ -196,11 +196,15 @@ struct audio_out_configuration struct audio_out { + u32 state = CELL_AUDIO_OUT_OUTPUT_STATE_ENABLED; u32 channels = CELL_AUDIO_OUT_CHNUM_8; u32 encoder = CELL_AUDIO_OUT_CODING_TYPE_LPCM; u32 downmixer = CELL_AUDIO_OUT_DOWNMIXER_NONE; u32 copy_control = CELL_AUDIO_OUT_COPY_CONTROL_COPY_FREE; + std::vector sound_modes; }; std::array out; + + audio_out_configuration(); };