2020-04-19 23:04:05 +02:00
|
|
|
// SPDX-License-Identifier: MPL-2.0
|
2020-03-27 20:36:02 +01:00
|
|
|
// Copyright © 2020 Skyline Team and Contributors (https://github.com/skyline-emu/)
|
|
|
|
|
2020-02-17 20:11:59 +01:00
|
|
|
#include "IAudioRenderer/IAudioRenderer.h"
|
2020-07-09 15:48:14 +02:00
|
|
|
#include "IAudioDevice.h"
|
2020-02-17 20:11:59 +01:00
|
|
|
#include "IAudioRendererManager.h"
|
2020-01-24 23:04:16 +01:00
|
|
|
|
2020-02-17 20:11:59 +01:00
|
|
|
namespace skyline::service::audio {
|
2020-09-21 12:04:26 +02:00
|
|
|
IAudioRendererManager::IAudioRendererManager(const DeviceState &state, ServiceManager &manager) : BaseService(state, manager) {}
|
2020-01-24 23:04:16 +01:00
|
|
|
|
2020-09-03 20:43:52 +02:00
|
|
|
Result IAudioRendererManager::OpenAudioRenderer(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
2020-09-26 07:17:57 +02:00
|
|
|
IAudioRenderer::AudioRendererParameters params{request.Pop<IAudioRenderer::AudioRendererParameters>()};
|
2020-01-24 23:04:16 +01:00
|
|
|
|
2021-11-10 23:21:43 +01:00
|
|
|
Logger::Debug("Opening a rev {} IAudioRenderer with sample rate: {}, voice count: {}, effect count: {}", IAudioRenderer::ExtractVersionFromRevision(params.revision), params.sampleRate, params.voiceCount, params.effectCount);
|
2020-01-24 23:04:16 +01:00
|
|
|
|
2020-02-17 20:11:59 +01:00
|
|
|
manager.RegisterService(std::make_shared<IAudioRenderer::IAudioRenderer>(state, manager, params), session, response);
|
2020-09-03 20:43:52 +02:00
|
|
|
|
|
|
|
return {};
|
2020-01-24 23:04:16 +01:00
|
|
|
}
|
|
|
|
|
2020-09-03 20:43:52 +02:00
|
|
|
Result IAudioRendererManager::GetAudioRendererWorkBufferSize(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
2020-09-26 07:17:57 +02:00
|
|
|
IAudioRenderer::AudioRendererParameters params{request.Pop<IAudioRenderer::AudioRendererParameters>()};
|
2020-01-24 23:04:16 +01:00
|
|
|
|
2020-02-17 20:11:59 +01:00
|
|
|
IAudioRenderer::RevisionInfo revisionInfo{};
|
2020-01-24 23:04:16 +01:00
|
|
|
revisionInfo.SetUserRevision(params.revision);
|
|
|
|
|
2020-08-21 15:28:47 +02:00
|
|
|
u32 totalMixCount{params.subMixCount + 1};
|
2020-01-24 23:04:16 +01:00
|
|
|
|
2021-10-24 21:45:29 +02:00
|
|
|
u64 size{util::AlignUp(params.mixBufferCount * 4, constant::BufferAlignment) +
|
2020-01-24 23:04:16 +01:00
|
|
|
params.subMixCount * 0x400 +
|
|
|
|
totalMixCount * 0x940 +
|
|
|
|
params.voiceCount * 0x3F0 +
|
2020-04-17 23:23:38 +02:00
|
|
|
util::AlignUp(totalMixCount * 8, 16) +
|
|
|
|
util::AlignUp(params.voiceCount * 8, 16) +
|
2020-08-21 15:28:47 +02:00
|
|
|
util::AlignUp(((params.sinkCount + params.subMixCount) * 0x3C0 + params.sampleCount * 4) * (params.mixBufferCount + 6), constant::BufferAlignment) + (params.sinkCount + params.subMixCount) * 0x2C0 + (params.effectCount + params.voiceCount * 4) * 0x30 + 0x50};
|
2020-01-24 23:04:16 +01:00
|
|
|
|
|
|
|
if (revisionInfo.SplitterSupported()) {
|
2021-10-24 21:45:29 +02:00
|
|
|
i32 nodeStateWorkSize{static_cast<i32>(util::AlignUp(totalMixCount, constant::BufferAlignment))};
|
2020-01-24 23:04:16 +01:00
|
|
|
if (nodeStateWorkSize < 0)
|
|
|
|
nodeStateWorkSize |= 7;
|
|
|
|
|
2021-10-24 21:45:29 +02:00
|
|
|
nodeStateWorkSize = static_cast<i32>(4 * (totalMixCount * totalMixCount) + 12 * totalMixCount + static_cast<u32>(2 * (nodeStateWorkSize / 8)));
|
2020-01-24 23:04:16 +01:00
|
|
|
|
2021-10-24 21:45:29 +02:00
|
|
|
i32 edgeMatrixWorkSize{static_cast<i32>(util::AlignUp(totalMixCount * totalMixCount, constant::BufferAlignment))};
|
2020-01-24 23:04:16 +01:00
|
|
|
if (edgeMatrixWorkSize < 0)
|
|
|
|
edgeMatrixWorkSize |= 7;
|
|
|
|
|
|
|
|
edgeMatrixWorkSize /= 8;
|
2021-10-24 21:45:29 +02:00
|
|
|
size += util::AlignUp(static_cast<u32>(edgeMatrixWorkSize + nodeStateWorkSize), 16);
|
2020-01-24 23:04:16 +01:00
|
|
|
}
|
|
|
|
|
2021-10-24 21:45:29 +02:00
|
|
|
u64 splitterWorkSize{};
|
2020-01-24 23:04:16 +01:00
|
|
|
if (revisionInfo.SplitterSupported()) {
|
2020-03-26 15:20:08 +01:00
|
|
|
splitterWorkSize += params.splitterDestinationDataCount * 0xE0 + params.splitterCount * 0x20;
|
2020-01-24 23:04:16 +01:00
|
|
|
|
|
|
|
if (revisionInfo.SplitterBugFixed())
|
2020-04-17 23:23:38 +02:00
|
|
|
splitterWorkSize += util::AlignUp(4 * params.splitterDestinationDataCount, 16);
|
2020-01-24 23:04:16 +01:00
|
|
|
}
|
2020-04-17 23:23:38 +02:00
|
|
|
|
2021-10-24 21:45:29 +02:00
|
|
|
size = params.sinkCount * 0x170 + (params.sinkCount + params.subMixCount) * 0x280 + params.effectCount * 0x4C0 + ((size + splitterWorkSize + 0x30 * params.effectCount + (4 * params.voiceCount) + 0x8F) & ~0x3FUL) + ((params.voiceCount << 8) | 0x40);
|
2020-01-24 23:04:16 +01:00
|
|
|
|
|
|
|
if (params.performanceManagerCount > 0) {
|
2020-08-21 15:28:47 +02:00
|
|
|
i64 performanceMetricsBufferSize{};
|
2020-01-24 23:04:16 +01:00
|
|
|
if (revisionInfo.UsesPerformanceMetricDataFormatV2()) {
|
2020-03-26 15:20:08 +01:00
|
|
|
performanceMetricsBufferSize = (params.voiceCount + params.effectCount + totalMixCount + params.sinkCount) + 0x990;
|
2020-01-24 23:04:16 +01:00
|
|
|
} else {
|
2020-03-26 15:20:08 +01:00
|
|
|
performanceMetricsBufferSize = ((static_cast<i64>((params.voiceCount + params.effectCount + totalMixCount + params.sinkCount)) << 32) >> 0x1C) + 0x658;
|
2020-01-24 23:04:16 +01:00
|
|
|
}
|
|
|
|
|
2021-10-24 21:45:29 +02:00
|
|
|
size += static_cast<u64>((performanceMetricsBufferSize * (params.performanceManagerCount + 1) + 0xFF) & ~0x3FL);
|
2020-01-24 23:04:16 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if (revisionInfo.VaradicCommandBufferSizeSupported()) {
|
2020-03-26 15:20:08 +01:00
|
|
|
size += params.effectCount * 0x840 + params.subMixCount * 0x5A38 + params.sinkCount * 0x148 + params.splitterDestinationDataCount * 0x540 + (params.splitterCount * 0x68 + 0x2E0) * params.voiceCount + ((params.voiceCount + params.subMixCount + params.effectCount + params.sinkCount + 0x65) << 6) + 0x3F8 + 0x7E;
|
2020-01-24 23:04:16 +01:00
|
|
|
} else {
|
|
|
|
size += 0x1807E;
|
|
|
|
}
|
|
|
|
|
2020-04-17 23:23:38 +02:00
|
|
|
size = util::AlignUp(size, 0x1000);
|
2020-01-24 23:04:16 +01:00
|
|
|
|
2021-11-10 23:21:43 +01:00
|
|
|
Logger::Debug("Work buffer size: 0x{:X}", size);
|
2021-10-24 21:45:29 +02:00
|
|
|
response.Push<u64>(size);
|
2020-09-03 20:43:52 +02:00
|
|
|
return {};
|
2020-01-24 23:04:16 +01:00
|
|
|
}
|
2020-07-09 15:48:14 +02:00
|
|
|
|
2020-09-03 20:43:52 +02:00
|
|
|
Result IAudioRendererManager::GetAudioDeviceService(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
2020-07-09 15:48:14 +02:00
|
|
|
manager.RegisterService(SRVREG(IAudioDevice), session, response);
|
2020-09-03 20:43:52 +02:00
|
|
|
return {};
|
2020-07-09 15:48:14 +02:00
|
|
|
}
|
2020-01-24 23:04:16 +01:00
|
|
|
}
|