mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2026-09-30 12:16:18 +00:00
Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1fe88221d1 | |||
| e9bfd97c7f | |||
| 773c29ed85 | |||
| 09f05f0313 | |||
| 3b03ade8d8 | |||
| 78cacac308 | |||
| 84f43f2c63 | |||
| 3266c20e3f | |||
| 9cd24e85c2 | |||
| 74b5e10dc5 |
Vendored
+628
-583
File diff suppressed because it is too large
Load Diff
Vendored
+547
-502
File diff suppressed because it is too large
Load Diff
Vendored
+547
-502
File diff suppressed because it is too large
Load Diff
Vendored
+547
-502
File diff suppressed because it is too large
Load Diff
Vendored
+547
-502
File diff suppressed because it is too large
Load Diff
Vendored
+547
-502
File diff suppressed because it is too large
Load Diff
Vendored
+548
-503
File diff suppressed because it is too large
Load Diff
Vendored
+547
-502
File diff suppressed because it is too large
Load Diff
Vendored
+547
-502
File diff suppressed because it is too large
Load Diff
Vendored
+547
-502
File diff suppressed because it is too large
Load Diff
Vendored
+547
-502
File diff suppressed because it is too large
Load Diff
Vendored
+547
-502
File diff suppressed because it is too large
Load Diff
Vendored
+547
-502
File diff suppressed because it is too large
Load Diff
Vendored
+547
-502
File diff suppressed because it is too large
Load Diff
Vendored
+547
-502
File diff suppressed because it is too large
Load Diff
Vendored
+547
-502
File diff suppressed because it is too large
Load Diff
Vendored
+547
-502
File diff suppressed because it is too large
Load Diff
Vendored
+547
-502
File diff suppressed because it is too large
Load Diff
Vendored
+547
-502
File diff suppressed because it is too large
Load Diff
Vendored
+547
-502
File diff suppressed because it is too large
Load Diff
Vendored
+550
-508
File diff suppressed because it is too large
Load Diff
Vendored
+547
-502
File diff suppressed because it is too large
Load Diff
Vendored
+547
-502
File diff suppressed because it is too large
Load Diff
Vendored
+547
-502
File diff suppressed because it is too large
Load Diff
Vendored
+547
-502
File diff suppressed because it is too large
Load Diff
Vendored
+573
-527
File diff suppressed because it is too large
Load Diff
Vendored
+547
-502
File diff suppressed because it is too large
Load Diff
@@ -788,7 +788,7 @@ int Java_org_yuzu_yuzu_1emu_NativeLibrary_installFileToNand(JNIEnv* env, jobject
|
||||
jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_doesUpdateMatchProgram(JNIEnv* env, jobject jobj,
|
||||
jstring jprogramId,
|
||||
jstring jupdatePath) {
|
||||
u64 program_id = EmulationSession::GetProgramId(env, jprogramId);
|
||||
const u64 program_id = FileSys::GetBaseTitleID(EmulationSession::GetProgramId(env, jprogramId));
|
||||
std::string updatePath = Common::Android::GetJString(env, jupdatePath);
|
||||
std::shared_ptr<FileSys::NSP> nsp = std::make_shared<FileSys::NSP>(
|
||||
EmulationSession::GetInstance().System().GetFilesystem()->OpenFile(
|
||||
@@ -796,7 +796,7 @@ jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_doesUpdateMatchProgram(JNIEnv* en
|
||||
for (const auto& item : nsp->GetNCAs()) {
|
||||
for (const auto& nca_details : item.second) {
|
||||
if (nca_details.second->GetName().ends_with(".cnmt.nca")) {
|
||||
auto update_id = nca_details.second->GetTitleId() & ~0xFFFULL;
|
||||
const auto update_id = FileSys::GetBaseTitleID(nca_details.second->GetTitleId());
|
||||
if (update_id == program_id) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -289,6 +289,7 @@
|
||||
<string name="gpu_driver_fetcher">Obtenedor de controladores de la GPU</string>
|
||||
<string name="gpu_driver_manager">Gestor de controladores de la GPU</string>
|
||||
<string name="install_gpu_driver_description">Instale los controladores alternativos para obtener un posible mejor rendimiento o precisión</string>
|
||||
<string name="post_processing_add">Añadir efecto</string>
|
||||
<string name="post_processing_open_list">Abrir lista</string>
|
||||
<string name="post_processing_close_list">Cerrar lista</string>
|
||||
<string name="post_processing_reset">Restablecer a predeterminado</string>
|
||||
|
||||
@@ -318,6 +318,13 @@
|
||||
<string name="frame_gen_target_rate">Целевая частота кадров</string>
|
||||
<string name="frame_gen_target_rate_description">Выберите значение под ваш дисплей. Множитель подстроится сам, чтобы его держать, и откатит изменения, если игра начнёт тормозить.</string>
|
||||
<string name="frame_gen_target_rate_off">Использовать фиксированный множитель</string>
|
||||
<string name="frame_gen_on">Вкл.</string>
|
||||
<string name="frame_gen_off">Выкл.</string>
|
||||
<string name="frame_gen_fixed">Фикс.</string>
|
||||
<string name="frame_gen_flow_auto">Авто</string>
|
||||
<string name="frame_gen_quick_description">Включите или выключите генерацию кадров и выберите множитель кадров.</string>
|
||||
<string name="frame_gen_target_rate_quick_description">Генерация кадров с заданной частотой кадров. Множитель регулируется автоматически.</string>
|
||||
<string name="frame_gen_flow_scale_quick_description">Разрешение, используемое для оценки движения между кадрами. Меньшие значения экономят время ГПУ.</string>
|
||||
<string name="frame_gen_queue_target">Целевой размер очереди кадров</string>
|
||||
<string name="frame_gen_queue_target_description">Сколько готовых кадров может ожидать перед выводом на экран. Более длинные очереди сглаживают скачки ГПУ ценой задержки ввода.</string>
|
||||
<string name="frame_gen_queue_target_0">Минимальная задержка (Без буферизации)</string>
|
||||
@@ -328,12 +335,14 @@
|
||||
<string name="frame_gen_flow_scale">Разрешение оценки движения</string>
|
||||
<string name="frame_gen_flow_scale_description">Разрешение прохода оптического потока в долях от выходного разрешения. Его понижение — самый дешёвый способ вернуть производительность.</string>
|
||||
<string name="frame_gen_unsupported">Генерация кадров недоступна</string>
|
||||
<string name="frame_gen_unsupported_description">В этом ГПУ драйвере отсутствует поддержка модели памяти Vulkan или половинной точности (float16), которая требуется шейдерам Lossless Scaling.</string>
|
||||
<string name="lossless_scaling_setup_description">Опционально. Укажите свой Lossless.dll для включения генерации кадров позже.</string>
|
||||
<string name="lossless_scaling_install">Установить Lossless.dll</string>
|
||||
<string name="lossless_scaling_install_description">Для генерации кадров требуется ваша собственная легальная копия Lossless.dll из Lossless Scaling</string>
|
||||
<string name="lossless_scaling_replace_description">Выбрать другой файл Lossless.dll</string>
|
||||
<string name="frame_generation_support">Генерация кадров</string>
|
||||
<string name="frame_generation_supported">Поддерживается</string>
|
||||
<string name="frame_generation_unsupported">Не поддерживается (нет модели памяти Vulkan или float16)</string>
|
||||
<string name="lossless_scaling_description">Предоставьте свою копию Lossless.dll для включения генерации кадров</string>
|
||||
<string name="lossless_scaling_installed">Установлена</string>
|
||||
<string name="lossless_scaling_not_installed">Не установлена</string>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="MissingTranslation">
|
||||
|
||||
<string name="app_disclaimer">本软件可以运行用于 Nintendo Switch 游戏机的游戏。不包含任何游戏或密钥。<br /><br />在您开始之前, 请定位您设备存储上的 <![CDATA[<b> prod.keys </b>]]> 文件。<br /><br /><![CDATA[<a href=\"https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/user/QuickStart.md\">了解更多</a>]]></string>
|
||||
<string name="notice_notification_channel_name">错误与注意事项</string>
|
||||
<string name="notice_notification_channel_description">当发生错误时显示通知。</string>
|
||||
<string name="notification_permission_not_granted">未授予通知权限!</string>
|
||||
@@ -290,6 +291,25 @@
|
||||
<string name="gpu_driver_fetcher">GPU驱动获取器</string>
|
||||
<string name="gpu_driver_manager">GPU 驱动管理器</string>
|
||||
<string name="install_gpu_driver_description">安装替代的驱动程序以获得更好的性能和精度</string>
|
||||
<string name="post_processing">后处理效果</string>
|
||||
<string name="post_processing_description">在渲染完成后应用 ReShade FX 效果</string>
|
||||
<string name="post_processing_per_game_description">配置此游戏的效果链</string>
|
||||
<string name="post_processing_add">添加效果</string>
|
||||
<string name="post_processing_remove">移除</string>
|
||||
<string name="post_processing_open_list">打开列表</string>
|
||||
<string name="post_processing_close_list">关闭列表</string>
|
||||
<string name="post_processing_remove_all">移除效果</string>
|
||||
<string name="post_processing_preset_locked">预设已激活。在开始游戏前可以在后处理效果中编辑它。</string>
|
||||
<string name="post_processing_preset_modified">数值已从原始预设被更改。</string>
|
||||
<string name="post_processing_presets">预设</string>
|
||||
<string name="post_processing_preset_new">新建预设</string>
|
||||
<string name="post_processing_preset_new_description">把您加载的效果及当前数值保存为一个预设,以便今后选用。</string>
|
||||
<string name="post_processing_preset_name_invalid">请给预设起一个不含等号的名称。</string>
|
||||
<string name="post_processing_preset_none">无预设</string>
|
||||
<string name="post_processing_preset_delete">删除预设</string>
|
||||
<string name="post_processing_preset_reset">重置预设值</string>
|
||||
<string name="post_processing_reset">重置为默认值</string>
|
||||
<string name="post_processing_empty">找不到效果。请在此文件中放置 .fx 文件:</string>
|
||||
<string name="frame_gen">帧生成</string>
|
||||
<string name="frame_gen_per_game_description">配置针对此游戏的帧生成设定</string>
|
||||
<string name="frame_gen_description">设定要在使用无损缩放渲染的帧之间应用的插帧。启用后强制采用FIFO呈现模式 。</string>
|
||||
@@ -304,6 +324,13 @@
|
||||
<string name="frame_gen_target_rate_60">60 FPS</string>
|
||||
<string name="frame_gen_target_rate_90">90 FPS</string>
|
||||
<string name="frame_gen_target_rate_120">120 FPS</string>
|
||||
<string name="frame_gen_on">开</string>
|
||||
<string name="frame_gen_off">关</string>
|
||||
<string name="frame_gen_fixed">固定</string>
|
||||
<string name="frame_gen_flow_auto">自动</string>
|
||||
<string name="frame_gen_quick_description">打开或关闭帧生成并选择帧生成倍数。</string>
|
||||
<string name="frame_gen_target_rate_quick_description">生成帧到目标帧率。倍率会自动调整。</string>
|
||||
<string name="frame_gen_flow_scale_quick_description">用来估算帧间运动的分辨率。较低的值可以节省 GPU 时间。</string>
|
||||
<string name="frame_gen_queue_target">帧队列目标</string>
|
||||
<string name="frame_gen_queue_target_description">在显示之前有多少已完成渲染的帧正在等待。较大的队列可以缓解 GPU 突发的压力,但会增加输入延迟。</string>
|
||||
<string name="frame_gen_queue_target_0">最低延迟 (无缓冲)</string>
|
||||
@@ -314,12 +341,14 @@
|
||||
<string name="frame_gen_flow_scale">运动预估分辨率</string>
|
||||
<string name="frame_gen_flow_scale_description">光流通道的分辨率,以输出的比例表示。降低它是提升性能最经济的做法。</string>
|
||||
<string name="frame_gen_unsupported">帧生成不可用</string>
|
||||
<string name="frame_gen_unsupported_description">这个 GPU 驱动缺少 Lossless Scaling 着色器所需的 Vulkan 内存模型或半精度 (float16) 支持。</string>
|
||||
<string name="lossless_scaling_setup_description">作为可选项。请提供您自己的 Lossless.dll 以便在之后可以启用帧生成。</string>
|
||||
<string name="lossless_scaling_install">安装 Lossless.dll</string>
|
||||
<string name="lossless_scaling_install_description">帧生成需要您自己从 Lossless Scaling 获得合法的 Lossless.dll 副本</string>
|
||||
<string name="lossless_scaling_replace_description">选择其它 Lossless.dll 副本</string>
|
||||
<string name="frame_generation_support">帧生成</string>
|
||||
<string name="frame_generation_supported">支持</string>
|
||||
<string name="frame_generation_unsupported">不支持 (无 Vulkan 内存模型或 float16)</string>
|
||||
<string name="lossless_scaling">无损缩放</string>
|
||||
<string name="lossless_scaling_description">提供您自己的 Lossless.dll 文件以启用帧生成</string>
|
||||
<string name="lossless_scaling_installed">已安装</string>
|
||||
@@ -611,6 +640,11 @@
|
||||
<string name="log">日志记录</string>
|
||||
<string name="flush_by_line">按行刷新调试日志</string>
|
||||
<string name="flush_by_line_description">在每行写入时刷新调试日志,使在崩溃或冻结时调试更容易。</string>
|
||||
<string name="extended_logging">开启扩展日志</string>
|
||||
<string name="extended_logging_description">将最大日志文件大小从 100 MiB 提升至 1GiB。</string>
|
||||
<string name="log_filter">日志筛选器</string>
|
||||
<string name="log_filter_description">控制 Eden 的日志类别。例如: *:Info Service.LM:Debug</string>
|
||||
|
||||
<!-- GPU Logging strings -->
|
||||
<string name="gpu_logging_header">GPU 日志</string>
|
||||
<string name="gpu_log_level">日志等级</string>
|
||||
@@ -894,6 +928,8 @@
|
||||
<string name="loader_error_file_not_found">ROM 文件不存在</string>
|
||||
|
||||
<string name="loader_requires_firmware">游戏需要固件</string>
|
||||
<string name="loader_requires_firmware_description"><![CDATA[这个游戏可能需要固件才能正常运行,但您还没有安装任何固件。请在启动前安装固件,或者按 “确定” 继续启动。]]></string>
|
||||
|
||||
<!-- Intent Launch strings -->
|
||||
<string name="searching_for_game">正在搜索游戏...</string>
|
||||
<string name="game_not_found_for_title_id">未找到标题ID的游戏: %1$s</string>
|
||||
|
||||
@@ -229,7 +229,7 @@
|
||||
<string name="add_directory_success">遊戲目錄新增成功</string>
|
||||
<string name="enable_update_checks">檢查更新</string>
|
||||
<string name="enable_update_checks_description">在Eden啟動時檢查有無新版本並選擇是否要下載與安裝更新</string>
|
||||
<string name="update_available">偵測到新版本</string>
|
||||
<string name="update_available">發現新版本</string>
|
||||
<string name="update_available_description">有更新可供安裝:%1$s\n\n您要進行更新嗎?</string>
|
||||
<string name="downloading_update">下載更新中</string>
|
||||
<string name="update_download_failed">更新下載失敗</string>
|
||||
@@ -1020,9 +1020,40 @@
|
||||
<string name="memory_6gb">6GB (不穩定)</string>
|
||||
<string name="memory_8gb">8GB (不穩定)</string>
|
||||
|
||||
<!-- CPU clock levels -->
|
||||
<string name="clock_normal">正常</string>
|
||||
<string name="clock_boost">加速</string>
|
||||
<string name="clock_fast">超頻</string>
|
||||
|
||||
<!-- GPU clock levels -->
|
||||
<string name="fast_gpu_normal">正常</string>
|
||||
<string name="fast_gpu_medium">加速</string>
|
||||
<string name="fast_gpu_high">超頻</string>
|
||||
|
||||
<!-- GPU swizzle texture size -->
|
||||
<string name="gpu_texturesizeswizzle_verysmall">極小 (16MB)</string>
|
||||
<string name="gpu_texturesizeswizzle_small">小(32MB)</string>
|
||||
<string name="gpu_texturesizeswizzle_normal">正常(128MB)</string>
|
||||
<string name="gpu_texturesizeswizzle_large">大(256MB)</string>
|
||||
<string name="gpu_texturesizeswizzle_verylarge">極大(512MB)</string>
|
||||
|
||||
<!-- GPU swizzle streams -->
|
||||
<string name="gpu_swizzle_verylow">極小(4MB)</string>
|
||||
<string name="gpu_swizzle_low">小(8MB)</string>
|
||||
<string name="gpu_swizzle_normal">正常(16MB)</string>
|
||||
<string name="gpu_swizzle_medium">中(32MB)</string>
|
||||
<string name="gpu_swizzle_high">大(64MB)</string>
|
||||
|
||||
<!-- GPU swizzle chunks -->
|
||||
<string name="gpu_swizzlechunk_verylow">極小(32)</string>
|
||||
<string name="gpu_swizzlechunk_low">小(64)</string>
|
||||
<string name="gpu_swizzlechunk_normal">正常(128)</string>
|
||||
<string name="gpu_swizzlechunk_medium">中(256)</string>
|
||||
<string name="gpu_swizzlechunk_high">大(512)</string>
|
||||
|
||||
<!-- Temperature Units -->
|
||||
<string name="temperature_celsius">攝氏度</string>
|
||||
<string name="temperature_fahrenheit">華氏度</string>
|
||||
<string name="temperature_celsius">攝氏</string>
|
||||
<string name="temperature_fahrenheit">華氏</string>
|
||||
|
||||
<!-- Memory Sizes -->
|
||||
<string name="memory_byte_shorthand">B</string>
|
||||
@@ -1035,6 +1066,8 @@
|
||||
|
||||
<string name="renderer_none">無</string>
|
||||
|
||||
<!-- Renderer Accuracy -->
|
||||
<string name="renderer_accuracy_low">效能</string>
|
||||
<string name="renderer_accuracy_high">準確</string>
|
||||
|
||||
<!-- DMA Accuracy -->
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
namespace AudioCore {
|
||||
|
||||
AudioCore::AudioCore(Core::System& system) {
|
||||
audio_manager.emplace();
|
||||
audio_manager.emplace(system);
|
||||
CreateSinks();
|
||||
// Must be created after the sinks
|
||||
adsp.emplace(system, *output_sink);
|
||||
|
||||
@@ -15,12 +15,12 @@
|
||||
|
||||
namespace AudioCore::AudioIn {
|
||||
|
||||
Manager::Manager(Core::System& system_) : system{system_} {
|
||||
Manager::Manager(Core::System& system) {
|
||||
std::iota(session_ids.begin(), session_ids.end(), 0);
|
||||
num_free_sessions = MaxInSessions;
|
||||
}
|
||||
|
||||
Result Manager::AcquireSessionId(size_t& session_id) {
|
||||
Result Manager::AcquireSessionId(Core::System& system, size_t& session_id) {
|
||||
if (num_free_sessions == 0) {
|
||||
LOG_ERROR(Service_Audio, "All 4 AudioIn sessions are in use, cannot create any more");
|
||||
return Service::Audio::ResultOutOfSessions;
|
||||
@@ -31,7 +31,7 @@ Result Manager::AcquireSessionId(size_t& session_id) {
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
||||
void Manager::ReleaseSessionId(const size_t session_id) {
|
||||
void Manager::ReleaseSessionId(Core::System& system, const size_t session_id) {
|
||||
std::scoped_lock l{mutex};
|
||||
LOG_DEBUG(Service_Audio, "Freeing AudioIn session {}", session_id);
|
||||
session_ids[free_session_id] = session_id;
|
||||
@@ -41,21 +41,20 @@ void Manager::ReleaseSessionId(const size_t session_id) {
|
||||
applet_resource_user_ids[session_id] = 0;
|
||||
}
|
||||
|
||||
Result Manager::LinkToManager() {
|
||||
Result Manager::LinkToManager(Core::System& system) {
|
||||
std::scoped_lock l{mutex};
|
||||
if (!linked_to_manager) {
|
||||
system.AudioCore().GetAudioManager().SetInManager(std::bind(&Manager::BufferReleaseAndRegister, this));
|
||||
system.AudioCore().GetAudioManager().SetInManager(this, &Manager::BufferReleaseAndRegister);
|
||||
linked_to_manager = true;
|
||||
}
|
||||
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
||||
void Manager::Start() {
|
||||
void Manager::Start(Core::System& system) {
|
||||
if (sessions_started) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::scoped_lock l{mutex};
|
||||
for (auto& session : sessions) {
|
||||
if (session) {
|
||||
@@ -66,21 +65,19 @@ void Manager::Start() {
|
||||
sessions_started = true;
|
||||
}
|
||||
|
||||
void Manager::BufferReleaseAndRegister() {
|
||||
std::scoped_lock l{mutex};
|
||||
for (auto& session : sessions) {
|
||||
void Manager::BufferReleaseAndRegister(void *data, Core::System& system) noexcept {
|
||||
Manager* this_ = (Manager*)data;
|
||||
std::scoped_lock l{this_->mutex};
|
||||
for (auto& session : this_->sessions) {
|
||||
if (session != nullptr) {
|
||||
session->ReleaseAndRegisterBuffers();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
u32 Manager::GetDeviceNames(std::span<Renderer::AudioDevice::AudioDeviceName> names,
|
||||
[[maybe_unused]] const bool filter) {
|
||||
u32 Manager::GetDeviceNames(Core::System& system, std::span<Renderer::AudioDevice::AudioDeviceName> names, [[maybe_unused]] const bool filter) {
|
||||
std::scoped_lock l{mutex};
|
||||
|
||||
LinkToManager();
|
||||
|
||||
LinkToManager(system);
|
||||
auto input_devices{Sink::GetDeviceListForSink(Settings::values.sink_id.GetValue(), true)};
|
||||
if (!input_devices.empty() && !names.empty()) {
|
||||
names[0] = Renderer::AudioDevice::AudioDeviceName("Uac");
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
@@ -30,31 +33,29 @@ public:
|
||||
* @param session_id - Output session_id.
|
||||
* @return Result code.
|
||||
*/
|
||||
Result AcquireSessionId(size_t& session_id);
|
||||
Result AcquireSessionId(Core::System& system, size_t& session_id);
|
||||
|
||||
/**
|
||||
* Release a session id on close.
|
||||
*
|
||||
* @param session_id - Session id to free.
|
||||
*/
|
||||
void ReleaseSessionId(size_t session_id);
|
||||
void ReleaseSessionId(Core::System& system, const size_t session_id);
|
||||
|
||||
/**
|
||||
* Link the audio in manager to the main audio manager.
|
||||
*
|
||||
* @return Result code.
|
||||
*/
|
||||
Result LinkToManager();
|
||||
Result LinkToManager(Core::System& system);
|
||||
|
||||
/**
|
||||
* Start the audio in manager.
|
||||
*/
|
||||
void Start();
|
||||
void Start(Core::System& system);
|
||||
|
||||
/**
|
||||
* Callback function, called by the audio manager when the audio in event is signalled.
|
||||
*/
|
||||
void BufferReleaseAndRegister();
|
||||
/// @brief Callback function, called by the audio manager when the audio in event is signalled.
|
||||
static void BufferReleaseAndRegister(void *data, Core::System& system) noexcept;
|
||||
|
||||
/**
|
||||
* Get a list of audio in device names.
|
||||
@@ -64,10 +65,8 @@ public:
|
||||
*
|
||||
* @return Number of names written.
|
||||
*/
|
||||
u32 GetDeviceNames(std::span<Renderer::AudioDevice::AudioDeviceName> names, bool filter);
|
||||
u32 GetDeviceNames(Core::System& system, std::span<Renderer::AudioDevice::AudioDeviceName> names, bool filter);
|
||||
|
||||
/// Core system
|
||||
Core::System& system;
|
||||
/// Array of session ids
|
||||
std::array<size_t, MaxInSessions> session_ids{};
|
||||
/// Array of resource user ids
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
|
||||
namespace AudioCore {
|
||||
|
||||
AudioManager::AudioManager() {
|
||||
thread = std::jthread([this](std::stop_token stop_token) {
|
||||
AudioManager::AudioManager(Core::System& system) {
|
||||
thread = std::jthread([&](std::stop_token stop_token) {
|
||||
Common::SetCurrentThreadName("AudioManager");
|
||||
std::unique_lock l{events.GetAudioEventLock()};
|
||||
events.ClearEvents();
|
||||
@@ -25,7 +25,7 @@ AudioManager::AudioManager() {
|
||||
const auto event_type = Event::Type(i);
|
||||
if (events.CheckAudioEventSet(event_type) || timed_out) {
|
||||
if (buffer_events[i]) {
|
||||
buffer_events[i]();
|
||||
buffer_events[i](buffer_data[i], system);
|
||||
}
|
||||
}
|
||||
events.SetAudioEvent(event_type, false);
|
||||
@@ -42,12 +42,13 @@ void AudioManager::Shutdown() {
|
||||
}
|
||||
}
|
||||
|
||||
Result AudioManager::SetOutManager(BufferEventFunc buffer_func) {
|
||||
Result AudioManager::SetOutManager(void *data, BufferEventFunc buffer_func) {
|
||||
if (thread.joinable()) {
|
||||
std::scoped_lock l{lock};
|
||||
const auto index{events.GetManagerIndex(Event::Type::AudioOutManager)};
|
||||
if (buffer_events[index] == nullptr) {
|
||||
buffer_events[index] = std::move(buffer_func);
|
||||
buffer_data[index] = data;
|
||||
needs_update = true;
|
||||
events.SetAudioEvent(Event::Type::AudioOutManager, true);
|
||||
}
|
||||
@@ -56,12 +57,13 @@ Result AudioManager::SetOutManager(BufferEventFunc buffer_func) {
|
||||
return Service::Audio::ResultOperationFailed;
|
||||
}
|
||||
|
||||
Result AudioManager::SetInManager(BufferEventFunc buffer_func) {
|
||||
Result AudioManager::SetInManager(void *data, BufferEventFunc buffer_func) {
|
||||
if (thread.joinable()) {
|
||||
std::scoped_lock l{lock};
|
||||
const auto index{events.GetManagerIndex(Event::Type::AudioInManager)};
|
||||
if (buffer_events[index] == nullptr) {
|
||||
buffer_events[index] = std::move(buffer_func);
|
||||
buffer_data[index] = data;
|
||||
needs_update = true;
|
||||
events.SetAudioEvent(Event::Type::AudioInManager, true);
|
||||
}
|
||||
|
||||
@@ -16,6 +16,10 @@
|
||||
|
||||
#include "audio_core/audio_event.h"
|
||||
|
||||
namespace Core {
|
||||
class System;
|
||||
}
|
||||
|
||||
union Result;
|
||||
|
||||
namespace AudioCore {
|
||||
@@ -34,31 +38,24 @@ namespace AudioCore {
|
||||
* This is only used by audio in and audio out.
|
||||
*/
|
||||
class AudioManager {
|
||||
using BufferEventFunc = std::function<void()>;
|
||||
|
||||
using BufferEventFunc = void (*)(void *data, Core::System& system) noexcept;
|
||||
public:
|
||||
explicit AudioManager();
|
||||
explicit AudioManager(Core::System& system);
|
||||
|
||||
/**
|
||||
* Shutdown the audio manager.
|
||||
*/
|
||||
void Shutdown();
|
||||
|
||||
/**
|
||||
* Register the out manager, keeping a function to be called when the out event is signalled.
|
||||
*
|
||||
* @param buffer_func - Function to be called on signal.
|
||||
* @return Result code.
|
||||
*/
|
||||
Result SetOutManager(BufferEventFunc buffer_func);
|
||||
/// Register the out manager, keeping a function to be called when the out event is signalled.
|
||||
/// @param buffer_func - Function to be called on signal.
|
||||
/// @return Result code.
|
||||
Result SetOutManager(void *data, BufferEventFunc buffer_func);
|
||||
|
||||
/**
|
||||
* Register the in manager, keeping a function to be called when the in event is signalled.
|
||||
*
|
||||
* @param buffer_func - Function to be called on signal.
|
||||
* @return Result code.
|
||||
*/
|
||||
Result SetInManager(BufferEventFunc buffer_func);
|
||||
/// Register the in manager, keeping a function to be called when the in event is signalled.
|
||||
/// @param buffer_func - Function to be called on signal.
|
||||
/// @return Result code.
|
||||
Result SetInManager(void *data, BufferEventFunc buffer_func);
|
||||
|
||||
/**
|
||||
* Set an event to signalled, and signal the thread.
|
||||
@@ -73,8 +70,9 @@ private:
|
||||
bool needs_update{};
|
||||
/// Events to be set and signalled
|
||||
Event events{};
|
||||
/// Callbacks for each manager
|
||||
/// Callbacks (and user data) for each manager
|
||||
std::array<BufferEventFunc, 3> buffer_events{};
|
||||
std::array<void*, 3> buffer_data{};
|
||||
/// General lock
|
||||
std::mutex lock{};
|
||||
/// Main thread for waiting and callbacks
|
||||
|
||||
@@ -14,12 +14,12 @@
|
||||
|
||||
namespace AudioCore::AudioOut {
|
||||
|
||||
Manager::Manager(Core::System& system_) : system{system_} {
|
||||
Manager::Manager(Core::System& system) {
|
||||
std::iota(session_ids.begin(), session_ids.end(), 0);
|
||||
num_free_sessions = MaxOutSessions;
|
||||
}
|
||||
|
||||
Result Manager::AcquireSessionId(size_t& session_id) {
|
||||
Result Manager::AcquireSessionId(Core::System& system, size_t& session_id) {
|
||||
if (num_free_sessions == 0) {
|
||||
LOG_ERROR(Service_Audio, "All 12 Audio Out sessions are in use, cannot create any more");
|
||||
return Service::Audio::ResultOutOfSessions;
|
||||
@@ -30,7 +30,7 @@ Result Manager::AcquireSessionId(size_t& session_id) {
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
||||
void Manager::ReleaseSessionId(const size_t session_id) {
|
||||
void Manager::ReleaseSessionId(Core::System& system, const size_t session_id) {
|
||||
std::scoped_lock l{mutex};
|
||||
LOG_DEBUG(Service_Audio, "Freeing AudioOut session {}", session_id);
|
||||
session_ids[free_session_id] = session_id;
|
||||
@@ -40,44 +40,36 @@ void Manager::ReleaseSessionId(const size_t session_id) {
|
||||
applet_resource_user_ids[session_id] = 0;
|
||||
}
|
||||
|
||||
Result Manager::LinkToManager() {
|
||||
Result Manager::LinkToManager(Core::System& system) {
|
||||
std::scoped_lock l{mutex};
|
||||
if (!linked_to_manager) {
|
||||
system.AudioCore().GetAudioManager().SetOutManager(std::bind(&Manager::BufferReleaseAndRegister, this));
|
||||
system.AudioCore().GetAudioManager().SetOutManager(this, &Manager::BufferReleaseAndRegister);
|
||||
linked_to_manager = true;
|
||||
}
|
||||
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
||||
void Manager::Start() {
|
||||
if (sessions_started) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::scoped_lock l{mutex};
|
||||
for (auto& session : sessions) {
|
||||
if (session) {
|
||||
session->StartSession();
|
||||
void Manager::Start(Core::System& system) {
|
||||
if (!sessions_started) {
|
||||
std::scoped_lock l{mutex};
|
||||
for (auto& session : sessions) {
|
||||
if (session) {
|
||||
session->StartSession();
|
||||
}
|
||||
}
|
||||
sessions_started = true;
|
||||
}
|
||||
|
||||
sessions_started = true;
|
||||
}
|
||||
|
||||
void Manager::BufferReleaseAndRegister() {
|
||||
std::scoped_lock l{mutex};
|
||||
for (auto& session : sessions) {
|
||||
void Manager::BufferReleaseAndRegister(void *data, Core::System& system) noexcept {
|
||||
Manager* this_ = (Manager*)data;
|
||||
std::scoped_lock l{this_->mutex};
|
||||
for (auto& session : this_->sessions) {
|
||||
if (session != nullptr) {
|
||||
session->ReleaseAndRegisterBuffers();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
u32 Manager::GetAudioOutDeviceNames(
|
||||
std::vector<Renderer::AudioDevice::AudioDeviceName>& names) const {
|
||||
names.emplace_back("DeviceOut");
|
||||
return 1;
|
||||
}
|
||||
|
||||
} // namespace AudioCore::AudioOut
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
@@ -29,42 +32,32 @@ public:
|
||||
* @param session_id - Output session_id.
|
||||
* @return Result code.
|
||||
*/
|
||||
Result AcquireSessionId(size_t& session_id);
|
||||
Result AcquireSessionId(Core::System& system, size_t& session_id);
|
||||
|
||||
/**
|
||||
* Release a session id on close.
|
||||
*
|
||||
* @param session_id - Session id to free.
|
||||
*/
|
||||
void ReleaseSessionId(size_t session_id);
|
||||
void ReleaseSessionId(Core::System& system, const size_t session_id);
|
||||
|
||||
/**
|
||||
* Link this manager to the main audio manager.
|
||||
*
|
||||
* @return Result code.
|
||||
*/
|
||||
Result LinkToManager();
|
||||
Result LinkToManager(Core::System& system);
|
||||
|
||||
/**
|
||||
* Start the audio out manager.
|
||||
*/
|
||||
void Start();
|
||||
void Start(Core::System& system);
|
||||
|
||||
/**
|
||||
* Callback function, called by the audio manager when the audio out event is signalled.
|
||||
*/
|
||||
void BufferReleaseAndRegister();
|
||||
static void BufferReleaseAndRegister(void* data, Core::System& system) noexcept;
|
||||
|
||||
/**
|
||||
* Get a list of audio out device names.
|
||||
*
|
||||
* @param names - Output container to write names to.
|
||||
* @return Number of names written.
|
||||
*/
|
||||
u32 GetAudioOutDeviceNames(std::vector<Renderer::AudioDevice::AudioDeviceName>& names) const;
|
||||
|
||||
/// Core system
|
||||
Core::System& system;
|
||||
/// Array of session ids
|
||||
std::array<size_t, MaxOutSessions> session_ids{};
|
||||
/// Array of resource user ids
|
||||
|
||||
@@ -6,14 +6,14 @@
|
||||
|
||||
#include "audio_core/audio_render_manager.h"
|
||||
#include "audio_core/common/audio_renderer_parameter.h"
|
||||
#include "audio_core/renderer/system_manager.h"
|
||||
#include "audio_core/common/feature_support.h"
|
||||
#include "core/core.h"
|
||||
|
||||
namespace AudioCore::Renderer {
|
||||
|
||||
Manager::Manager(Core::System& system_)
|
||||
: system{system_}
|
||||
, system_manager{std::make_unique<SystemManager>(system)}
|
||||
: system_manager{std::make_unique<SystemManager>(system_)}
|
||||
{
|
||||
std::iota(session_ids.begin(), session_ids.end(), 0);
|
||||
}
|
||||
@@ -62,11 +62,11 @@ u32 Manager::GetSessionCount() const {
|
||||
return session_count;
|
||||
}
|
||||
|
||||
bool Manager::AddSystem(System& system_) {
|
||||
bool Manager::AddSystem(Renderer::System& system_) {
|
||||
return system_manager->Add(system_);
|
||||
}
|
||||
|
||||
bool Manager::RemoveSystem(System& system_) {
|
||||
bool Manager::RemoveSystem(Renderer::System& system_) {
|
||||
return system_manager->Remove(system_);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
@@ -71,7 +74,7 @@ public:
|
||||
* @param system - The system to add.
|
||||
* @return True if the system was successfully added, otherwise false.
|
||||
*/
|
||||
bool AddSystem(System& system);
|
||||
bool AddSystem(Renderer::System& system);
|
||||
|
||||
/**
|
||||
* Remove a renderer system from the manager.
|
||||
@@ -79,7 +82,7 @@ public:
|
||||
* @param system - The system to remove.
|
||||
* @return True if the system was successfully removed, otherwise false.
|
||||
*/
|
||||
bool RemoveSystem(System& system);
|
||||
bool RemoveSystem(Renderer::System& system);
|
||||
|
||||
/**
|
||||
* Free a session id when the system wants to shut down.
|
||||
@@ -89,8 +92,6 @@ public:
|
||||
void ReleaseSessionId(s32 session_id);
|
||||
|
||||
private:
|
||||
/// Core system
|
||||
Core::System& system;
|
||||
/// Session ids, -1 when in use
|
||||
std::array<s32, MaxRendererSessions> session_ids{};
|
||||
/// Number of active renderers
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
@@ -8,42 +11,43 @@
|
||||
namespace AudioCore::AudioIn {
|
||||
|
||||
In::In(Core::System& system_, Manager& manager_, Kernel::KEvent* event_, size_t session_id_)
|
||||
: manager{manager_}, parent_mutex{manager.mutex}, event{event_}, system{system_, event,
|
||||
session_id_} {}
|
||||
: manager{manager_}, parent_mutex{manager.mutex}, event{event_}
|
||||
, audio_system{system_, event, session_id_}
|
||||
{}
|
||||
|
||||
void In::Free() {
|
||||
void In::Free(Core::System& system) {
|
||||
std::scoped_lock l{parent_mutex};
|
||||
manager.ReleaseSessionId(system.GetSessionId());
|
||||
manager.ReleaseSessionId(system, audio_system.GetSessionId());
|
||||
}
|
||||
|
||||
System& In::GetSystem() {
|
||||
return system;
|
||||
return audio_system;
|
||||
}
|
||||
|
||||
AudioIn::State In::GetState() {
|
||||
std::scoped_lock l{parent_mutex};
|
||||
return system.GetState();
|
||||
return audio_system.GetState();
|
||||
}
|
||||
|
||||
Result In::StartSystem() {
|
||||
std::scoped_lock l{parent_mutex};
|
||||
return system.Start();
|
||||
return audio_system.Start();
|
||||
}
|
||||
|
||||
void In::StartSession() {
|
||||
std::scoped_lock l{parent_mutex};
|
||||
system.StartSession();
|
||||
audio_system.StartSession();
|
||||
}
|
||||
|
||||
Result In::StopSystem() {
|
||||
std::scoped_lock l{parent_mutex};
|
||||
return system.Stop();
|
||||
return audio_system.Stop();
|
||||
}
|
||||
|
||||
Result In::AppendBuffer(const AudioInBuffer& buffer, u64 tag) {
|
||||
std::scoped_lock l{parent_mutex};
|
||||
|
||||
if (system.AppendBuffer(buffer, tag)) {
|
||||
if (audio_system.AppendBuffer(buffer, tag)) {
|
||||
return ResultSuccess;
|
||||
}
|
||||
return Service::Audio::ResultBufferCountReached;
|
||||
@@ -51,20 +55,20 @@ Result In::AppendBuffer(const AudioInBuffer& buffer, u64 tag) {
|
||||
|
||||
void In::ReleaseAndRegisterBuffers() {
|
||||
std::scoped_lock l{parent_mutex};
|
||||
if (system.GetState() == State::Started) {
|
||||
system.ReleaseBuffers();
|
||||
system.RegisterBuffers();
|
||||
if (audio_system.GetState() == State::Started) {
|
||||
audio_system.ReleaseBuffers();
|
||||
audio_system.RegisterBuffers();
|
||||
}
|
||||
}
|
||||
|
||||
bool In::FlushAudioInBuffers() {
|
||||
std::scoped_lock l{parent_mutex};
|
||||
return system.FlushAudioInBuffers();
|
||||
return audio_system.FlushAudioInBuffers();
|
||||
}
|
||||
|
||||
u32 In::GetReleasedBuffers(std::span<u64> tags) {
|
||||
std::scoped_lock l{parent_mutex};
|
||||
return system.GetReleasedBuffers(tags);
|
||||
return audio_system.GetReleasedBuffers(tags);
|
||||
}
|
||||
|
||||
Kernel::KReadableEvent& In::GetBufferEvent() {
|
||||
@@ -74,27 +78,27 @@ Kernel::KReadableEvent& In::GetBufferEvent() {
|
||||
|
||||
f32 In::GetVolume() const {
|
||||
std::scoped_lock l{parent_mutex};
|
||||
return system.GetVolume();
|
||||
return audio_system.GetVolume();
|
||||
}
|
||||
|
||||
void In::SetVolume(f32 volume) {
|
||||
std::scoped_lock l{parent_mutex};
|
||||
system.SetVolume(volume);
|
||||
audio_system.SetVolume(volume);
|
||||
}
|
||||
|
||||
bool In::ContainsAudioBuffer(u64 tag) const {
|
||||
std::scoped_lock l{parent_mutex};
|
||||
return system.ContainsAudioBuffer(tag);
|
||||
return audio_system.ContainsAudioBuffer(tag);
|
||||
}
|
||||
|
||||
u32 In::GetBufferCount() const {
|
||||
std::scoped_lock l{parent_mutex};
|
||||
return system.GetBufferCount();
|
||||
return audio_system.GetBufferCount();
|
||||
}
|
||||
|
||||
u64 In::GetPlayedSampleCount() const {
|
||||
std::scoped_lock l{parent_mutex};
|
||||
return system.GetPlayedSampleCount();
|
||||
return audio_system.GetPlayedSampleCount();
|
||||
}
|
||||
|
||||
} // namespace AudioCore::AudioIn
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
@@ -30,7 +33,7 @@ public:
|
||||
/**
|
||||
* Free this audio in from the audio in manager.
|
||||
*/
|
||||
void Free();
|
||||
void Free(Core::System& system);
|
||||
|
||||
/**
|
||||
* Get this audio in's system.
|
||||
@@ -141,7 +144,7 @@ private:
|
||||
/// Buffer event, signalled when buffers are ready to be released
|
||||
Kernel::KEvent* event;
|
||||
/// Main audio in system
|
||||
System system;
|
||||
System audio_system;
|
||||
};
|
||||
|
||||
} // namespace AudioCore::AudioIn
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
@@ -8,42 +11,43 @@
|
||||
namespace AudioCore::AudioOut {
|
||||
|
||||
Out::Out(Core::System& system_, Manager& manager_, Kernel::KEvent* event_, size_t session_id_)
|
||||
: manager{manager_}, parent_mutex{manager.mutex}, event{event_}, system{system_, event,
|
||||
session_id_} {}
|
||||
: manager{manager_}, parent_mutex{manager.mutex}, event{event_}
|
||||
, audio_system{system_, event, session_id_}
|
||||
{}
|
||||
|
||||
void Out::Free() {
|
||||
void Out::Free(Core::System& system) {
|
||||
std::scoped_lock l{parent_mutex};
|
||||
manager.ReleaseSessionId(system.GetSessionId());
|
||||
manager.ReleaseSessionId(system, audio_system.GetSessionId());
|
||||
}
|
||||
|
||||
System& Out::GetSystem() {
|
||||
return system;
|
||||
return audio_system;
|
||||
}
|
||||
|
||||
AudioOut::State Out::GetState() {
|
||||
std::scoped_lock l{parent_mutex};
|
||||
return system.GetState();
|
||||
return audio_system.GetState();
|
||||
}
|
||||
|
||||
Result Out::StartSystem() {
|
||||
std::scoped_lock l{parent_mutex};
|
||||
return system.Start();
|
||||
return audio_system.Start();
|
||||
}
|
||||
|
||||
void Out::StartSession() {
|
||||
std::scoped_lock l{parent_mutex};
|
||||
system.StartSession();
|
||||
audio_system.StartSession();
|
||||
}
|
||||
|
||||
Result Out::StopSystem() {
|
||||
std::scoped_lock l{parent_mutex};
|
||||
return system.Stop();
|
||||
return audio_system.Stop();
|
||||
}
|
||||
|
||||
Result Out::AppendBuffer(const AudioOutBuffer& buffer, const u64 tag) {
|
||||
std::scoped_lock l{parent_mutex};
|
||||
|
||||
if (system.AppendBuffer(buffer, tag)) {
|
||||
if (audio_system.AppendBuffer(buffer, tag)) {
|
||||
return ResultSuccess;
|
||||
}
|
||||
return Service::Audio::ResultBufferCountReached;
|
||||
@@ -51,20 +55,20 @@ Result Out::AppendBuffer(const AudioOutBuffer& buffer, const u64 tag) {
|
||||
|
||||
void Out::ReleaseAndRegisterBuffers() {
|
||||
std::scoped_lock l{parent_mutex};
|
||||
if (system.GetState() == State::Started) {
|
||||
system.ReleaseBuffers();
|
||||
system.RegisterBuffers();
|
||||
if (audio_system.GetState() == State::Started) {
|
||||
audio_system.ReleaseBuffers();
|
||||
audio_system.RegisterBuffers();
|
||||
}
|
||||
}
|
||||
|
||||
bool Out::FlushAudioOutBuffers() {
|
||||
std::scoped_lock l{parent_mutex};
|
||||
return system.FlushAudioOutBuffers();
|
||||
return audio_system.FlushAudioOutBuffers();
|
||||
}
|
||||
|
||||
u32 Out::GetReleasedBuffers(std::span<u64> tags) {
|
||||
std::scoped_lock l{parent_mutex};
|
||||
return system.GetReleasedBuffers(tags);
|
||||
return audio_system.GetReleasedBuffers(tags);
|
||||
}
|
||||
|
||||
Kernel::KReadableEvent& Out::GetBufferEvent() {
|
||||
@@ -74,27 +78,27 @@ Kernel::KReadableEvent& Out::GetBufferEvent() {
|
||||
|
||||
f32 Out::GetVolume() const {
|
||||
std::scoped_lock l{parent_mutex};
|
||||
return system.GetVolume();
|
||||
return audio_system.GetVolume();
|
||||
}
|
||||
|
||||
void Out::SetVolume(const f32 volume) {
|
||||
std::scoped_lock l{parent_mutex};
|
||||
system.SetVolume(volume);
|
||||
audio_system.SetVolume(volume);
|
||||
}
|
||||
|
||||
bool Out::ContainsAudioBuffer(const u64 tag) const {
|
||||
std::scoped_lock l{parent_mutex};
|
||||
return system.ContainsAudioBuffer(tag);
|
||||
return audio_system.ContainsAudioBuffer(tag);
|
||||
}
|
||||
|
||||
u32 Out::GetBufferCount() const {
|
||||
std::scoped_lock l{parent_mutex};
|
||||
return system.GetBufferCount();
|
||||
return audio_system.GetBufferCount();
|
||||
}
|
||||
|
||||
u64 Out::GetPlayedSampleCount() const {
|
||||
std::scoped_lock l{parent_mutex};
|
||||
return system.GetPlayedSampleCount();
|
||||
return audio_system.GetPlayedSampleCount();
|
||||
}
|
||||
|
||||
} // namespace AudioCore::AudioOut
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
@@ -30,7 +33,7 @@ public:
|
||||
/**
|
||||
* Free this audio out from the audio out manager.
|
||||
*/
|
||||
void Free();
|
||||
void Free(Core::System& system);
|
||||
|
||||
/**
|
||||
* Get this audio out's system.
|
||||
@@ -141,7 +144,7 @@ private:
|
||||
/// Buffer event, signalled when buffers are ready to be released
|
||||
Kernel::KEvent* event;
|
||||
/// Main audio out system
|
||||
System system;
|
||||
System audio_system;
|
||||
};
|
||||
|
||||
} // namespace AudioCore::AudioOut
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||
@@ -34,42 +34,37 @@ constexpr std::array output_device_names{
|
||||
AudioDevice::AudioDeviceName{"AudioExternalOutput"},
|
||||
};
|
||||
|
||||
AudioDevice::AudioDevice(Core::System& system, const u64 applet_resource_user_id_,
|
||||
const u32 revision)
|
||||
: output_sink{system.AudioCore().GetOutputSink()},
|
||||
applet_resource_user_id{applet_resource_user_id_}, user_revision{revision} {}
|
||||
AudioDevice::AudioDevice(Core::System& system, const u64 applet_resource_user_id_, const u32 revision)
|
||||
: applet_resource_user_id{applet_resource_user_id_}
|
||||
, user_revision{revision}
|
||||
{}
|
||||
|
||||
u32 AudioDevice::ListAudioDeviceName(std::span<AudioDeviceName> out_buffer) const {
|
||||
std::span<const AudioDeviceName> names{};
|
||||
|
||||
if (CheckFeatureSupported(SupportTags::AudioUsbDeviceOutput, user_revision)) {
|
||||
names = usb_device_names;
|
||||
} else {
|
||||
names = device_names;
|
||||
}
|
||||
|
||||
const u32 out_count{static_cast<u32>((std::min)(out_buffer.size(), names.size()))};
|
||||
for (u32 i = 0; i < out_count; i++) {
|
||||
const u32 out_count = u32((std::min)(out_buffer.size(), names.size()));
|
||||
for (u32 i = 0; i < out_count; i++)
|
||||
out_buffer[i] = names[i];
|
||||
}
|
||||
return out_count;
|
||||
}
|
||||
|
||||
u32 AudioDevice::ListAudioOutputDeviceName(std::span<AudioDeviceName> out_buffer) const {
|
||||
const u32 out_count{static_cast<u32>((std::min)(out_buffer.size(), output_device_names.size()))};
|
||||
|
||||
for (u32 i = 0; i < out_count; i++) {
|
||||
const u32 out_count = u32((std::min)(out_buffer.size(), output_device_names.size()));
|
||||
for (u32 i = 0; i < out_count; i++)
|
||||
out_buffer[i] = output_device_names[i];
|
||||
}
|
||||
return out_count;
|
||||
}
|
||||
|
||||
void AudioDevice::SetDeviceVolumes(const f32 volume) {
|
||||
output_sink.SetDeviceVolume(volume);
|
||||
void AudioDevice::SetDeviceVolumes(Core::System& system, const f32 volume) {
|
||||
system.AudioCore().GetOutputSink().SetDeviceVolume(volume);
|
||||
}
|
||||
|
||||
f32 AudioDevice::GetDeviceVolume([[maybe_unused]] std::string_view name) const {
|
||||
return output_sink.GetDeviceVolume();
|
||||
f32 AudioDevice::GetDeviceVolume(Core::System& system, [[maybe_unused]] std::string_view name) const {
|
||||
return system.AudioCore().GetOutputSink().GetDeviceVolume();
|
||||
}
|
||||
|
||||
} // namespace AudioCore::Renderer
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
@@ -54,7 +57,7 @@ public:
|
||||
*
|
||||
* @param volume - Volume to set.
|
||||
*/
|
||||
void SetDeviceVolumes(f32 volume);
|
||||
void SetDeviceVolumes(Core::System& system, f32 volume);
|
||||
|
||||
/**
|
||||
* Get the volume for a given device name.
|
||||
@@ -63,11 +66,9 @@ public:
|
||||
* @param name - Name of the device to check. Unused.
|
||||
* @return Volume of the device.
|
||||
*/
|
||||
f32 GetDeviceVolume(std::string_view name) const;
|
||||
f32 GetDeviceVolume(Core::System& system, std::string_view name) const;
|
||||
|
||||
private:
|
||||
/// Backend output sink for the device
|
||||
Sink::Sink& output_sink;
|
||||
/// Resource id this device is used for
|
||||
const u64 applet_resource_user_id;
|
||||
/// User audio renderer revision
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
@@ -13,56 +16,46 @@
|
||||
namespace AudioCore::Renderer {
|
||||
|
||||
Renderer::Renderer(Core::System& system_, Manager& manager_, Kernel::KEvent* rendered_event)
|
||||
: core{system_}, manager{manager_}, system{system_, rendered_event} {}
|
||||
: manager{manager_}
|
||||
, audio_system{system_, rendered_event}
|
||||
{}
|
||||
|
||||
Result Renderer::Initialize(const AudioRendererParameterInternal& params,
|
||||
Kernel::KTransferMemory* transfer_memory,
|
||||
const u64 transfer_memory_size, Kernel::KProcess* process_handle,
|
||||
const u64 applet_resource_user_id, const s32 session_id) {
|
||||
Result Renderer::Initialize(const AudioRendererParameterInternal& params, Kernel::KTransferMemory* transfer_memory, const u64 transfer_memory_size, Kernel::KProcess* process_handle, const u64 applet_resource_user_id, const s32 session_id) {
|
||||
if (params.execution_mode == ExecutionMode::Auto) {
|
||||
if (!manager.AddSystem(system)) {
|
||||
LOG_ERROR(Service_Audio,
|
||||
"Both Audio Render sessions are in use, cannot create any more");
|
||||
if (!manager.AddSystem(audio_system)) {
|
||||
LOG_ERROR(Service_Audio, "Both Audio Render sessions are in use, cannot create any more");
|
||||
return Service::Audio::ResultOutOfSessions;
|
||||
}
|
||||
system_registered = true;
|
||||
}
|
||||
|
||||
initialized = true;
|
||||
system.Initialize(params, transfer_memory, transfer_memory_size, process_handle,
|
||||
applet_resource_user_id, session_id);
|
||||
|
||||
audio_system.Initialize(params, transfer_memory, transfer_memory_size, process_handle, applet_resource_user_id, session_id);
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
||||
void Renderer::Finalize() {
|
||||
auto session_id{system.GetSessionId()};
|
||||
|
||||
system.Finalize();
|
||||
|
||||
auto const session_id{audio_system.GetSessionId()};
|
||||
audio_system.Finalize();
|
||||
if (system_registered) {
|
||||
manager.RemoveSystem(system);
|
||||
manager.RemoveSystem(audio_system);
|
||||
system_registered = false;
|
||||
}
|
||||
|
||||
manager.ReleaseSessionId(session_id);
|
||||
}
|
||||
|
||||
System& Renderer::GetSystem() {
|
||||
return system;
|
||||
return audio_system;
|
||||
}
|
||||
|
||||
void Renderer::Start() {
|
||||
system.Start();
|
||||
audio_system.Start();
|
||||
}
|
||||
|
||||
void Renderer::Stop() {
|
||||
system.Stop();
|
||||
audio_system.Stop();
|
||||
}
|
||||
|
||||
Result Renderer::RequestUpdate(std::span<const u8> input, std::span<u8> performance,
|
||||
std::span<u8> output) {
|
||||
return system.Update(input, performance, output);
|
||||
Result Renderer::RequestUpdate(std::span<const u8> input, std::span<u8> performance, std::span<u8> output) {
|
||||
return audio_system.Update(input, performance, output);
|
||||
}
|
||||
|
||||
} // namespace AudioCore::Renderer
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
@@ -83,16 +86,12 @@ public:
|
||||
std::span<u8> output);
|
||||
|
||||
private:
|
||||
/// System core
|
||||
Core::System& core;
|
||||
/// Manager this renderer is registered with
|
||||
Manager& manager;
|
||||
/// Is the audio renderer initialized?
|
||||
bool initialized{};
|
||||
/// Is the system registered with the manager?
|
||||
bool system_registered{};
|
||||
/// Audio render system, main driver of audio rendering
|
||||
System system;
|
||||
System audio_system;
|
||||
};
|
||||
|
||||
} // namespace Renderer
|
||||
|
||||
@@ -100,8 +100,9 @@ u64 System::GetWorkBufferSize(const AudioRendererParameterInternal& params) {
|
||||
}
|
||||
|
||||
System::System(Core::System& core_, Kernel::KEvent* adsp_rendered_event_)
|
||||
: core{core_}, audio_renderer{core.AudioCore().ADSP().AudioRenderer()},
|
||||
adsp_rendered_event{adsp_rendered_event_} {}
|
||||
: core{core_}
|
||||
, adsp_rendered_event{adsp_rendered_event_}
|
||||
{}
|
||||
|
||||
Result System::Initialize(const AudioRendererParameterInternal& params,
|
||||
Kernel::KTransferMemory* transfer_memory, u64 transfer_memory_size,
|
||||
@@ -406,7 +407,7 @@ void System::Finalize() {
|
||||
return;
|
||||
}
|
||||
|
||||
if (active) {
|
||||
if (IsActive()) {
|
||||
Stop();
|
||||
}
|
||||
|
||||
@@ -433,14 +434,12 @@ void System::Start() {
|
||||
std::scoped_lock l{lock};
|
||||
frames_elapsed = 0;
|
||||
state = State::Started;
|
||||
active = true;
|
||||
}
|
||||
|
||||
void System::Stop() {
|
||||
{
|
||||
std::scoped_lock l{lock};
|
||||
state = State::Stopped;
|
||||
active = false;
|
||||
}
|
||||
|
||||
if (execution_mode == ExecutionMode::Auto) {
|
||||
@@ -480,8 +479,7 @@ Result System::Update(std::span<const u8> input, std::span<u8> performance, std:
|
||||
return result;
|
||||
}
|
||||
|
||||
result = info_updater.UpdateEffects(effect_context, active, memory_pool_workbuffer,
|
||||
memory_pool_count);
|
||||
result = info_updater.UpdateEffects(effect_context, IsActive(), memory_pool_workbuffer, memory_pool_count);
|
||||
if (result.IsError()) {
|
||||
LOG_ERROR(Service_Audio, "Failed to update Effects!");
|
||||
return result;
|
||||
@@ -582,16 +580,16 @@ u32 System::GetRenderingDevice() const {
|
||||
}
|
||||
|
||||
bool System::IsActive() const {
|
||||
return active;
|
||||
return state == State::Started;
|
||||
}
|
||||
|
||||
void System::SendCommandToDsp() {
|
||||
std::scoped_lock l{lock};
|
||||
|
||||
auto& audio_renderer = core.AudioCore().ADSP().AudioRenderer();
|
||||
if (initialized) {
|
||||
if (active) {
|
||||
if (IsActive()) {
|
||||
terminate_event.Reset();
|
||||
const auto remaining_command_count{audio_renderer.GetRemainCommandCount(session_id)};
|
||||
const auto remaining_command_count = audio_renderer.GetRemainCommandCount(session_id);
|
||||
u64 command_size{0};
|
||||
|
||||
if (remaining_command_count) {
|
||||
@@ -738,7 +736,7 @@ u64 System::GenerateCommand(std::span<u8> in_command_buffer,
|
||||
const auto end_time{core.CoreTiming().GetGlobalTimeNs().count()};
|
||||
total_ticks_elapsed += end_time - start_time;
|
||||
num_command_lists_generated++;
|
||||
render_start_tick = audio_renderer.GetRenderingStartTick(session_id);
|
||||
render_start_tick = core.AudioCore().ADSP().AudioRenderer().GetRenderingStartTick(session_id);
|
||||
frames_elapsed++;
|
||||
|
||||
return command_buffer.size;
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
@@ -219,12 +222,8 @@ public:
|
||||
private:
|
||||
/// Core system
|
||||
Core::System& core;
|
||||
/// Reference to the ADSP's AudioRenderer for communication
|
||||
::AudioCore::ADSP::AudioRenderer::AudioRenderer& audio_renderer;
|
||||
/// Is this system initialized?
|
||||
bool initialized{};
|
||||
/// Is this system currently active?
|
||||
std::atomic<bool> active{};
|
||||
/// State of the system
|
||||
State state{State::Stopped};
|
||||
/// Sample rate for the system
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||
@@ -16,22 +16,22 @@
|
||||
namespace AudioCore::Renderer {
|
||||
|
||||
SystemManager::SystemManager(Core::System& core_)
|
||||
: core{core_}, audio_renderer{core.AudioCore().ADSP().AudioRenderer()} {}
|
||||
: core{core_}
|
||||
{}
|
||||
|
||||
SystemManager::~SystemManager() {
|
||||
Stop();
|
||||
}
|
||||
|
||||
void SystemManager::InitializeUnsafe() {
|
||||
if (!active) {
|
||||
active = true;
|
||||
audio_renderer.Start();
|
||||
if (!thread.joinable()) {
|
||||
core.AudioCore().ADSP().AudioRenderer().Start();
|
||||
thread = std::jthread([this](std::stop_token stop_token) {
|
||||
Common::SetCurrentThreadName("AudioRenderSystemManager");
|
||||
Common::SetCurrentThreadPriority(Common::ThreadPriority::High);
|
||||
while (active && !stop_token.stop_requested()) {
|
||||
auto& audio_renderer = core.AudioCore().ADSP().AudioRenderer();
|
||||
while (!stop_token.stop_requested()) {
|
||||
{
|
||||
std::scoped_lock l{mutex1};
|
||||
std::scoped_lock lk{mutex};
|
||||
for (auto system : systems)
|
||||
system->SendCommandToDsp();
|
||||
}
|
||||
@@ -43,39 +43,31 @@ void SystemManager::InitializeUnsafe() {
|
||||
}
|
||||
|
||||
void SystemManager::Stop() {
|
||||
if (active) {
|
||||
active = false;
|
||||
if (thread.joinable()) {
|
||||
thread.request_stop();
|
||||
thread.join();
|
||||
audio_renderer.Stop();
|
||||
core.AudioCore().ADSP().AudioRenderer().Stop();
|
||||
}
|
||||
}
|
||||
|
||||
bool SystemManager::Add(System& system_) {
|
||||
std::scoped_lock l2{mutex2};
|
||||
std::scoped_lock lk{mutex};
|
||||
if (systems.size() + 1 > MaxRendererSessions) {
|
||||
LOG_ERROR(Service_Audio, "Maximum AudioRenderer Systems active, cannot add more!");
|
||||
return false;
|
||||
}
|
||||
{
|
||||
std::scoped_lock l{mutex1};
|
||||
if (systems.empty())
|
||||
InitializeUnsafe();
|
||||
}
|
||||
if (systems.empty())
|
||||
InitializeUnsafe();
|
||||
systems.push_back(&system_);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SystemManager::Remove(System& system_) {
|
||||
std::scoped_lock l2{mutex2};
|
||||
{
|
||||
std::scoped_lock l{mutex1};
|
||||
if (systems.remove(&system_) == 0) {
|
||||
LOG_ERROR(Service_Audio, "Failed to remove a render system, it was not found in the list!");
|
||||
return false;
|
||||
}
|
||||
std::scoped_lock lk{mutex};
|
||||
if (systems.remove(&system_) == 0) {
|
||||
LOG_ERROR(Service_Audio, "Failed to remove a render system, it was not found in the list!");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (systems.empty())
|
||||
Stop();
|
||||
return true;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||
@@ -75,14 +75,8 @@ private:
|
||||
std::list<System*> systems{};
|
||||
/// Main worker thread for generating command lists
|
||||
std::jthread thread;
|
||||
/// Mutex for the systems
|
||||
std::mutex mutex1{};
|
||||
/// Mutex for adding/removing systems
|
||||
std::mutex mutex2{};
|
||||
/// Is the system manager thread active?
|
||||
std::atomic<bool> active{};
|
||||
/// Reference to the ADSP's AudioRenderer for communication
|
||||
::AudioCore::ADSP::AudioRenderer::AudioRenderer& audio_renderer;
|
||||
/// Mutex for the systems list
|
||||
std::mutex mutex{};
|
||||
};
|
||||
|
||||
} // namespace AudioCore::Renderer
|
||||
|
||||
@@ -35,19 +35,22 @@ static IPSFileType IdentifyMagic(std::span<const u8> magic) {
|
||||
}
|
||||
|
||||
static bool IsEOF(IPSFileType type, std::span<const u8> magic) {
|
||||
return (type == IPSFileType::IPS && magic.size() > 3 && std::memcmp(magic.data(), "EOF", 3) == 0)
|
||||
|| (type == IPSFileType::IPS32 && magic.size() > 4 && std::memcmp(magic.data(), "EEOF", 4) == 0);
|
||||
return (type == IPSFileType::IPS && magic.size() >= 3 && std::memcmp(magic.data(), "EOF", 3) == 0)
|
||||
|| (type == IPSFileType::IPS32 && magic.size() >= 4 && std::memcmp(magic.data(), "EEOF", 4) == 0);
|
||||
}
|
||||
|
||||
VirtualFile PatchIPS(const VirtualFile& in, const VirtualFile& ips) {
|
||||
if (in == nullptr || ips == nullptr)
|
||||
return nullptr;
|
||||
|
||||
auto in_data = in->ReadAllBytes();
|
||||
auto const type = IdentifyMagic(in_data);
|
||||
const auto type = IdentifyMagic(ips->ReadBytes(0x5));
|
||||
if (type == IPSFileType::Error)
|
||||
return nullptr;
|
||||
|
||||
auto in_data = in->ReadAllBytes();
|
||||
if (in_data.size() == 0)
|
||||
return nullptr;
|
||||
|
||||
std::vector<u8> temp(type == IPSFileType::IPS ? 3 : 4);
|
||||
u64 offset = 5; // After header
|
||||
while (ips->Read(temp.data(), temp.size(), offset) == temp.size()) {
|
||||
|
||||
@@ -97,7 +97,7 @@ Result IAudioDevice::SetAudioDeviceOutputVolumeAuto(
|
||||
LOG_DEBUG(Service_Audio, "called. name={}, volume={}", device_name, volume);
|
||||
|
||||
if (device_name == "AudioTvOutput") {
|
||||
impl->SetDeviceVolumes(volume);
|
||||
impl->SetDeviceVolumes(system, volume);
|
||||
}
|
||||
|
||||
R_SUCCEED();
|
||||
@@ -112,7 +112,7 @@ Result IAudioDevice::GetAudioDeviceOutputVolumeAuto(
|
||||
|
||||
*out_volume = 1.0f;
|
||||
if (device_name == "AudioTvOutput") {
|
||||
*out_volume = impl->GetDeviceVolume(device_name);
|
||||
*out_volume = impl->GetDeviceVolume(system, device_name);
|
||||
}
|
||||
|
||||
R_SUCCEED();
|
||||
|
||||
@@ -50,7 +50,7 @@ IAudioIn::IAudioIn(Core::System& system_, Manager& manager, size_t session_id,
|
||||
}
|
||||
|
||||
IAudioIn::~IAudioIn() {
|
||||
impl->Free();
|
||||
impl->Free(system);
|
||||
service_context.CloseEvent(event);
|
||||
process->Close(system.Kernel());
|
||||
}
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
@@ -65,7 +68,7 @@ Result IAudioInManager::OpenAudioInAuto(
|
||||
Result IAudioInManager::ListAudioInsAutoFiltered(
|
||||
OutArray<AudioDeviceName, BufferAttr_HipcAutoSelect> out_audio_ins, Out<u32> out_count) {
|
||||
LOG_DEBUG(Service_Audio, "called");
|
||||
*out_count = impl->GetDeviceNames(out_audio_ins, true);
|
||||
*out_count = impl->GetDeviceNames(system, out_audio_ins, true);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
@@ -90,8 +93,8 @@ Result IAudioInManager::OpenAudioInProtocolSpecified(
|
||||
|
||||
size_t new_session_id{};
|
||||
|
||||
R_TRY(impl->LinkToManager());
|
||||
R_TRY(impl->AcquireSessionId(new_session_id));
|
||||
R_TRY(impl->LinkToManager(system));
|
||||
R_TRY(impl->AcquireSessionId(system, new_session_id));
|
||||
|
||||
LOG_DEBUG(Service_Audio, "Opening new AudioIn, session_id={}, free sessions={}", new_session_id,
|
||||
impl->num_free_sessions);
|
||||
|
||||
@@ -46,7 +46,7 @@ IAudioOut::IAudioOut(Core::System& system_, Manager& manager, size_t session_id,
|
||||
}
|
||||
|
||||
IAudioOut::~IAudioOut() {
|
||||
impl->Free();
|
||||
impl->Free(system);
|
||||
service_context.CloseEvent(event);
|
||||
process->Close(system.Kernel());
|
||||
}
|
||||
|
||||
@@ -77,8 +77,8 @@ Result IAudioOutManager::OpenAudioOutAuto(
|
||||
}
|
||||
|
||||
size_t new_session_id{};
|
||||
R_TRY(impl->LinkToManager());
|
||||
R_TRY(impl->AcquireSessionId(new_session_id));
|
||||
R_TRY(impl->LinkToManager(system));
|
||||
R_TRY(impl->AcquireSessionId(system, new_session_id));
|
||||
|
||||
const auto device_name = Common::StringFromBuffer(name[0].name);
|
||||
LOG_DEBUG(Service_Audio, "Opening new AudioOut, sessionid={}, free sessions={}", new_session_id,
|
||||
|
||||
Reference in New Issue
Block a user