Minor Audio Refactor (and fix sm:IUserManager service name)

This makes some tiny changes to audio to make them compliant with the guidelines. In addition, to changing `IUserManager:IUserManager` to `sm:IUserManager`.
This commit is contained in:
◱ PixelyIon 2020-03-26 19:50:08 +05:30 committed by ◱ PixelyIon
parent 9f0ad46903
commit d75d30b809
17 changed files with 52 additions and 79 deletions

View File

@ -53,7 +53,7 @@ add_library(skyline SHARED
${source_DIR}/skyline/services/audio/IAudioRendererManager.cpp
${source_DIR}/skyline/services/audio/IAudioRenderer/IAudioRenderer.cpp
${source_DIR}/skyline/services/audio/IAudioRenderer/voice.cpp
${source_DIR}/skyline/services/audio/IAudioRenderer/memoryPool.cpp
${source_DIR}/skyline/services/audio/IAudioRenderer/memory_pool.cpp
${source_DIR}/skyline/services/settings/ISystemSettingsServer.cpp
${source_DIR}/skyline/services/apm/IManager.cpp
${source_DIR}/skyline/services/apm/ISession.cpp

View File

@ -112,10 +112,10 @@ namespace skyline::audio {
{-58, 4354, 26130, 2338}, {-54, 4199, 26169, 2451}, {-50, 4046, 26202, 2568}, {-46, 3897, 26230, 2688},
{-42, 3751, 26253, 2811}, {-38, 3608, 26270, 2936}, {-34, 3467, 26281, 3064}, {-32, 3329, 26287, 3195}}};
std::vector<i16> Resampler::ResampleBuffer(std::vector<i16> &inputBuffer, double ratio, int channelCount) {
uint step = static_cast<uint>(ratio * 0x8000);
uint outputSize = static_cast<uint>(static_cast<double>(inputBuffer.size()) / ratio);
std::vector<i16> outputBuffer(static_cast<size_t>(outputSize));
std::vector<i16> Resampler::ResampleBuffer(const std::vector<i16> &inputBuffer, double ratio, int channelCount) {
auto step = static_cast<uint>(ratio * 0x8000);
auto outputSize = static_cast<size_t>(inputBuffer.size() / ratio);
std::vector<i16> outputBuffer(outputSize);
const std::array<skyline::audio::LutEntry, 128> &lut = [step] {
if (step > 0xaaaa)
@ -126,20 +126,19 @@ namespace skyline::audio {
return CurveLut2;
}();
for (uint outIndex = 0, inIndex = 0; outIndex < outputBuffer.size(); outIndex += channelCount) {
uint lutIndex = (fraction >> 8) << 2;
for (auto outIndex = 0, inIndex = 0; outIndex < outputBuffer.size(); outIndex += channelCount) {
auto lutIndex = (fraction >> 8) << 2;
for (int channel = 0; channel < channelCount; channel++) {
int data = inputBuffer[(inIndex + 0) * channelCount + channel] * lut[lutIndex].a +
i32 data = inputBuffer[(inIndex + 0) * channelCount + channel] * lut[lutIndex].a +
inputBuffer[(inIndex + 1) * channelCount + channel] * lut[lutIndex].b +
inputBuffer[(inIndex + 2) * channelCount + channel] * lut[lutIndex].c +
inputBuffer[(inIndex + 3) * channelCount + channel] * lut[lutIndex].d;
outputBuffer[outIndex + channel] = static_cast<i16>(std::clamp(data >> 15,
static_cast<int>(std::numeric_limits<i16>::min()), static_cast<int>(std::numeric_limits<i16>::max())));
outputBuffer[outIndex + channel] = static_cast<i16>(std::clamp(data >> 15, static_cast<i32>(std::numeric_limits<i16>::min()), static_cast<i32>(std::numeric_limits<i16>::max())));
}
uint newOffset = fraction + step;
auto newOffset = fraction + step;
inIndex += newOffset >> 15;
fraction = newOffset & 0x7fff;
}

View File

@ -8,7 +8,7 @@ namespace skyline::audio {
*/
class Resampler {
private:
uint fraction{}; //!< The fractional value used for storing the resamplers last frame
u32 fraction{}; //!< The fractional value used for storing the resamplers last frame
public:
/**
@ -17,6 +17,6 @@ namespace skyline::audio {
* @param ratio The conversion ratio needed
* @param channelCount The amount of channels the buffer contains
*/
std::vector<i16> ResampleBuffer(std::vector<i16> &inputBuffer, double ratio, int channelCount);
std::vector<i16> ResampleBuffer(const std::vector<i16> &inputBuffer, double ratio, int channelCount);
};
}

View File

@ -30,7 +30,7 @@ namespace skyline::audio {
std::vector<u64> AudioTrack::GetReleasedBuffers(u32 max) {
std::vector<u64> bufferIds;
for (u32 i = 0; i < max; i++) {
for (auto i = 0; i < max; i++) {
if (!identifierQueue.back().released)
break;
bufferIds.push_back(identifierQueue.back().tag);
@ -54,7 +54,7 @@ namespace skyline::audio {
bufferLock.lock();
identifierQueue.push_front(identifier);
for (auto &sample : sampleData)
for (const auto &sample : sampleData)
sampleQueue.push(sample);
bufferLock.unlock();

View File

@ -128,7 +128,7 @@ namespace skyline::kernel::type {
pread64(memFd, destination, size, offset);
}
void KProcess::WriteMemory(void *source, const u64 offset, const size_t size, const bool forceGuest) const {
void KProcess::WriteMemory(const void *source, const u64 offset, const size_t size, const bool forceGuest) const {
if (!forceGuest) {
auto destination = GetHostAddress(offset);
@ -139,7 +139,7 @@ namespace skyline::kernel::type {
}
struct iovec local{
.iov_base = source,
.iov_base = const_cast<void *>(source),
.iov_len = size,
};

View File

@ -259,7 +259,7 @@ namespace skyline {
* @param size The amount of memory to be written
* @param forceGuest This flag forces the write to be performed in guest address space
*/
void WriteMemory(void *source, const u64 offset, const size_t size, const bool forceGuest = false) const;
void WriteMemory(const void *source, const u64 offset, const size_t size, const bool forceGuest = false) const;
/**
* @brief Copy one chunk to another in the guest's memory

View File

@ -40,7 +40,7 @@ namespace skyline::service::audio {
u64 sampleSize;
u64 sampleOffset;
} data = state.process->GetObject<Data>(request.inputBuf.at(0).address);
u64 tag = request.Pop<u64>();
auto tag = request.Pop<u64>();
state.logger->Debug("IAudioOut: Appending buffer with address: 0x{:X}, size: 0x{:X}", data.sampleBufferPtr, data.sampleSize);
@ -57,9 +57,9 @@ namespace skyline::service::audio {
}
void IAudioOut::GetReleasedAudioOutBuffer(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
u32 maxCount = static_cast<u32>(request.outputBuf.at(0).size >> 3);
auto maxCount = static_cast<u32>(request.outputBuf.at(0).size >> 3);
std::vector<u64> releasedBuffers = track->GetReleasedBuffers(maxCount);
u32 count = static_cast<u32>(releasedBuffers.size());
auto count = static_cast<u32>(releasedBuffers.size());
// Fill rest of output buffer with zeros
releasedBuffers.resize(maxCount, 0);
@ -69,7 +69,7 @@ namespace skyline::service::audio {
}
void IAudioOut::ContainsAudioOutBuffer(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
u64 tag = request.Pop<u64>();
auto tag = request.Pop<u64>();
response.Push(static_cast<u32>(track->ContainsBuffer(tag)));
}

View File

@ -9,8 +9,7 @@ namespace skyline::service::audio {
}) {}
void IAudioOutManager::ListAudioOuts(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
state.process->WriteMemory(reinterpret_cast<void *>(const_cast<char *>(constant::DefaultAudioOutName.data())),
request.outputBuf.at(0).address, constant::DefaultAudioOutName.size());
state.process->WriteMemory(reinterpret_cast<void *>(const_cast<char *>(constant::DefaultAudioOutName.data())), request.outputBuf.at(0).address, constant::DefaultAudioOutName.size());
}
void IAudioOutManager::OpenAudioOut(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {

View File

@ -47,7 +47,7 @@ namespace skyline::service::audio::IAudioRenderer {
}
void IAudioRenderer::RequestUpdate(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
u64 inputAddress = request.inputBuf.at(0).address;
auto inputAddress = request.inputBuf.at(0).address;
auto inputHeader = state.process->GetObject<UpdateDataHeader>(inputAddress);
revisionInfo.SetUserRevision(inputHeader.revision);
@ -58,7 +58,7 @@ namespace skyline::service::audio::IAudioRenderer {
state.process->ReadMemory(memoryPoolsIn.data(), inputAddress, memoryPoolCount * sizeof(MemoryPoolIn));
inputAddress += inputHeader.memoryPoolSize;
for (int i = 0; i < memoryPoolsIn.size(); i++)
for (auto i = 0; i < memoryPoolsIn.size(); i++)
memoryPools[i].ProcessInput(memoryPoolsIn[i]);
inputAddress += inputHeader.voiceResourceSize;
@ -66,13 +66,13 @@ namespace skyline::service::audio::IAudioRenderer {
state.process->ReadMemory(voicesIn.data(), inputAddress, rendererParams.voiceCount * sizeof(VoiceIn));
inputAddress += inputHeader.voiceSize;
for (int i = 0; i < voicesIn.size(); i++)
for (auto i = 0; i < voicesIn.size(); i++)
voices[i].ProcessInput(voicesIn[i]);
std::vector<EffectIn> effectsIn(rendererParams.effectCount);
state.process->ReadMemory(effectsIn.data(), inputAddress, rendererParams.effectCount * sizeof(EffectIn));
for (int i = 0; i < effectsIn.size(); i++)
for (auto i = 0; i < effectsIn.size(); i++)
effects[i].ProcessInput(effectsIn[i]);
UpdateAudio();
@ -105,24 +105,24 @@ namespace skyline::service::audio::IAudioRenderer {
state.process->WriteMemory(outputHeader, outputAddress);
outputAddress += sizeof(UpdateDataHeader);
for (auto &memoryPool : memoryPools) {
for (const auto &memoryPool : memoryPools) {
state.process->WriteMemory(memoryPool.output, outputAddress);
outputAddress += sizeof(MemoryPoolOut);
}
for (auto &voice : voices) {
for (const auto &voice : voices) {
state.process->WriteMemory(voice.output, outputAddress);
outputAddress += sizeof(VoiceOut);
}
for (auto &effect : effects) {
for (const auto &effect : effects) {
state.process->WriteMemory(effect.output, outputAddress);
outputAddress += sizeof(EffectOut);
}
}
void IAudioRenderer::UpdateAudio() {
std::vector<u64> released = track->GetReleasedBuffers(2);
auto released = track->GetReleasedBuffers(2);
for (auto &tag : released) {
MixFinalBuffer();
@ -153,14 +153,11 @@ namespace skyline::service::audio::IAudioRenderer {
for (int i = voiceBufferOffset; i < voiceBufferOffset + voiceBufferSize; i++) {
if (setIndex == bufferOffset) {
sampleBuffer[bufferOffset] = static_cast<i16>(std::clamp(static_cast<int>(static_cast<float>(voiceSamples[i]) *
voice.volume), static_cast<int>(std::numeric_limits<i16>::min()), static_cast<int>(std::numeric_limits<i16>::max())));
sampleBuffer[bufferOffset] = static_cast<i16>(std::clamp(static_cast<int>(static_cast<float>(voiceSamples[i]) * voice.volume), static_cast<int>(std::numeric_limits<i16>::min()), static_cast<int>(std::numeric_limits<i16>::max())));
setIndex++;
} else {
sampleBuffer[bufferOffset] += static_cast<i16>(std::clamp(static_cast<int>(sampleBuffer[voiceSamples[i]]) +
static_cast<int>(static_cast<float>(voiceSamples[i]) * voice.volume),
static_cast<int>(std::numeric_limits<i16>::min()), static_cast<int>(std::numeric_limits<i16>::max())));
sampleBuffer[bufferOffset] += static_cast<i16>(std::clamp(static_cast<int>(sampleBuffer[voiceSamples[i]]) + static_cast<int>(static_cast<float>(voiceSamples[i]) * voice.volume), static_cast<int>(std::numeric_limits<i16>::min()), static_cast<int>(std::numeric_limits<i16>::max())));
}
bufferOffset++;

View File

@ -4,10 +4,10 @@
#include <services/base_service.h>
#include <services/serviceman.h>
#include <audio.h>
#include "memoryPool.h"
#include "memory_pool.h"
#include "effect.h"
#include "voice.h"
#include "revisionInfo.h"
#include "revision_info.h"
namespace skyline {
namespace constant {

View File

@ -1,4 +1,4 @@
#include "memoryPool.h"
#include "memory_pool.h"
namespace skyline::service::audio::IAudioRenderer {
void MemoryPool::ProcessInput(const MemoryPoolIn &input) {

View File

@ -41,7 +41,7 @@ namespace skyline::service::audio::IAudioRenderer {
}
void Voice::UpdateBuffers() {
WaveBuffer &currentBuffer = waveBuffers.at(bufferIndex);
const auto &currentBuffer = waveBuffers.at(bufferIndex);
if (currentBuffer.size == 0)
return;
@ -49,7 +49,7 @@ namespace skyline::service::audio::IAudioRenderer {
switch (pcmFormat) {
case skyline::audio::PcmFormat::Int16:
sampleBuffer.resize(currentBuffer.size / sizeof(i16));
state.process->ReadMemory(sampleBuffer.data(), currentBuffer.position, currentBuffer.size);
state.process->ReadMemory(sampleBuffer.data(), currentBuffer.address, currentBuffer.size);
break;
default:
throw exception("Unsupported voice PCM format: {}", pcmFormat);
@ -59,11 +59,11 @@ namespace skyline::service::audio::IAudioRenderer {
sampleBuffer = resampler.ResampleBuffer(sampleBuffer, static_cast<double>(sampleRate) / constant::SampleRate, channelCount);
if (channelCount == 1 && constant::ChannelCount != channelCount) {
size_t originalSize = sampleBuffer.size();
auto originalSize = sampleBuffer.size();
sampleBuffer.resize((originalSize / channelCount) * constant::ChannelCount);
for (size_t monoIndex = originalSize - 1, targetIndex = sampleBuffer.size(); monoIndex > 0; monoIndex--)
for (uint i = 0; i < constant::ChannelCount; i++)
for (auto monoIndex = originalSize - 1, targetIndex = sampleBuffer.size(); monoIndex > 0; monoIndex--)
for (auto i = 0; i < constant::ChannelCount; i++)
sampleBuffer[--targetIndex] = sampleBuffer[monoIndex];
}
}

View File

@ -24,7 +24,7 @@ namespace skyline::service::audio::IAudioRenderer {
* @brief This stores information of a wave buffer of samples
*/
struct WaveBuffer {
u64 position; //!< The position of the wave buffer in guest memory
u64 address; //!< The address of the wave buffer in guest memory
u64 size; //!< The size of the wave buffer
u32 firstSampleOffset; //!< The offset of the first sample in the buffer
u32 lastSampleOffset; //!< The offset of the last sample in the buffer

View File

@ -11,8 +11,7 @@ namespace skyline::service::audio {
void IAudioRendererManager::OpenAudioRenderer(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
IAudioRenderer::AudioRendererParams params = request.Pop<IAudioRenderer::AudioRendererParams>();
state.logger->Debug("IAudioRendererManager: Opening a rev {} IAudioRenderer with sample rate: {}, voice count: {}, effect count: {}",
IAudioRenderer::ExtractVersionFromRevision(params.revision), params.sampleRate, params.voiceCount, params.effectCount);
state.logger->Debug("IAudioRendererManager: Opening a rev {} IAudioRenderer with sample rate: {}, voice count: {}, effect count: {}", IAudioRenderer::ExtractVersionFromRevision(params.revision), params.sampleRate, params.voiceCount, params.effectCount);
manager.RegisterService(std::make_shared<IAudioRenderer::IAudioRenderer>(state, manager, params), session, response);
}
@ -31,10 +30,7 @@ namespace skyline::service::audio {
params.voiceCount * 0x3F0 +
utils::AlignUp(totalMixCount * 8, 16) +
utils::AlignUp(params.voiceCount * 8, 16) +
utils::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;
utils::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;
if (revisionInfo.SplitterSupported()) {
i32 nodeStateWorkSize = utils::AlignUp(totalMixCount, constant::BufferAlignment);
@ -54,45 +50,27 @@ namespace skyline::service::audio {
i64 splitterWorkSize = 0;
if (revisionInfo.SplitterSupported()) {
splitterWorkSize += params.splitterDestinationDataCount * 0xE0 +
params.splitterCount * 0x20;
splitterWorkSize += params.splitterDestinationDataCount * 0xE0 + params.splitterCount * 0x20;
if (revisionInfo.SplitterBugFixed())
splitterWorkSize += utils::AlignUp(4 * params.splitterDestinationDataCount, 16);
}
size = params.sinkCount * 0x170 +
(params.sinkCount + params.subMixCount) * 0x280 +
params.effectCount * 0x4C0 +
((size + splitterWorkSize + 0x30 * params.effectCount + (4 * params.voiceCount) + 0x8F) & ~0x3Fl) +
((params.voiceCount << 8) | 0x40);
size = params.sinkCount * 0x170 + (params.sinkCount + params.subMixCount) * 0x280 + params.effectCount * 0x4C0 + ((size + splitterWorkSize + 0x30 * params.effectCount + (4 * params.voiceCount) + 0x8F) & ~0x3Fl) + ((params.voiceCount << 8) | 0x40);
if (params.performanceManagerCount > 0) {
i64 performanceMetricsBufferSize;
if (revisionInfo.UsesPerformanceMetricDataFormatV2()) {
performanceMetricsBufferSize = (params.voiceCount +
params.effectCount +
totalMixCount +
params.sinkCount) + 0x990;
performanceMetricsBufferSize = (params.voiceCount + params.effectCount + totalMixCount + params.sinkCount) + 0x990;
} else {
performanceMetricsBufferSize = ((static_cast<i64>((params.voiceCount +
params.effectCount +
totalMixCount +
params.sinkCount)) << 32) >> 0x1C) + 0x658;
performanceMetricsBufferSize = ((static_cast<i64>((params.voiceCount + params.effectCount + totalMixCount + params.sinkCount)) << 32) >> 0x1C) + 0x658;
}
size += (performanceMetricsBufferSize * (params.performanceManagerCount + 1) + 0xFF) & ~0x3Fl;
}
if (revisionInfo.VaradicCommandBufferSizeSupported()) {
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;
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;
} else {
size += 0x1807E;
}

View File

@ -1,7 +1,7 @@
#include "IUserInterface.h"
namespace skyline::service::sm {
IUserInterface::IUserInterface(const DeviceState &state, ServiceManager &manager) : BaseService(state, manager, Service::sm_IUserInterface, "IUserInterface:IUserInterface", {
IUserInterface::IUserInterface(const DeviceState &state, ServiceManager &manager) : BaseService(state, manager, Service::sm_IUserInterface, "sm:IUserInterface", {
{0x0, SFUNC(IUserInterface::Initialize)},
{0x1, SFUNC(IUserInterface::GetService)}
}) {}