Merge pull request #9096 from Kelebek1/audio_15

[audio_core] Update for firmware 15.0.0
This commit is contained in:
bunnei 2022-10-20 13:17:26 -07:00 committed by GitHub
commit c0b1bdd237
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 114 additions and 33 deletions

View file

@ -98,9 +98,8 @@ System::System(Core::System& core_, Kernel::KEvent* adsp_rendered_event_)
: core{core_}, adsp{core.AudioCore().GetADSP()}, adsp_rendered_event{adsp_rendered_event_} {} : core{core_}, adsp{core.AudioCore().GetADSP()}, adsp_rendered_event{adsp_rendered_event_} {}
Result System::Initialize(const AudioRendererParameterInternal& params, Result System::Initialize(const AudioRendererParameterInternal& params,
Kernel::KTransferMemory* transfer_memory, const u64 transfer_memory_size, Kernel::KTransferMemory* transfer_memory, u64 transfer_memory_size,
const u32 process_handle_, const u64 applet_resource_user_id_, u32 process_handle_, u64 applet_resource_user_id_, s32 session_id_) {
const s32 session_id_) {
if (!CheckValidRevision(params.revision)) { if (!CheckValidRevision(params.revision)) {
return Service::Audio::ERR_INVALID_REVISION; return Service::Audio::ERR_INVALID_REVISION;
} }
@ -354,6 +353,8 @@ Result System::Initialize(const AudioRendererParameterInternal& params,
render_time_limit_percent = 100; render_time_limit_percent = 100;
drop_voice = params.voice_drop_enabled && params.execution_mode == ExecutionMode::Auto; drop_voice = params.voice_drop_enabled && params.execution_mode == ExecutionMode::Auto;
drop_voice_param = 1.0f;
num_voices_dropped = 0;
allocator.Align(0x40); allocator.Align(0x40);
command_workbuffer_size = allocator.GetRemainingSize(); command_workbuffer_size = allocator.GetRemainingSize();
@ -547,7 +548,7 @@ u32 System::GetRenderingTimeLimit() const {
return render_time_limit_percent; return render_time_limit_percent;
} }
void System::SetRenderingTimeLimit(const u32 limit) { void System::SetRenderingTimeLimit(u32 limit) {
render_time_limit_percent = limit; render_time_limit_percent = limit;
} }
@ -635,7 +636,7 @@ void System::SendCommandToDsp() {
} }
u64 System::GenerateCommand(std::span<u8> in_command_buffer, u64 System::GenerateCommand(std::span<u8> in_command_buffer,
[[maybe_unused]] const u64 command_buffer_size_) { [[maybe_unused]] u64 command_buffer_size_) {
PoolMapper::ClearUseState(memory_pool_workbuffer, memory_pool_count); PoolMapper::ClearUseState(memory_pool_workbuffer, memory_pool_count);
const auto start_time{core.CoreTiming().GetClockTicks()}; const auto start_time{core.CoreTiming().GetClockTicks()};
@ -693,7 +694,8 @@ u64 System::GenerateCommand(std::span<u8> in_command_buffer,
voice_context.SortInfo(); voice_context.SortInfo();
const auto start_estimated_time{command_buffer.estimated_process_time}; const auto start_estimated_time{drop_voice_param *
static_cast<f32>(command_buffer.estimated_process_time)};
command_generator.GenerateVoiceCommands(); command_generator.GenerateVoiceCommands();
command_generator.GenerateSubMixCommands(); command_generator.GenerateSubMixCommands();
@ -712,11 +714,16 @@ u64 System::GenerateCommand(std::span<u8> in_command_buffer,
render_context.behavior->IsAudioRendererProcessingTimeLimit70PercentSupported(); render_context.behavior->IsAudioRendererProcessingTimeLimit70PercentSupported();
time_limit_percent = 70.0f; time_limit_percent = 70.0f;
} }
const auto end_estimated_time{drop_voice_param *
static_cast<f32>(command_buffer.estimated_process_time)};
const auto estimated_time{start_estimated_time - end_estimated_time};
const auto time_limit{static_cast<u32>( const auto time_limit{static_cast<u32>(
static_cast<f32>(start_estimated_time - command_buffer.estimated_process_time) + estimated_time + (((time_limit_percent / 100.0f) * 2'880'000.0) *
(((time_limit_percent / 100.0f) * 2'880'000.0) * (static_cast<f32>(render_time_limit_percent) / 100.0f)))};
(static_cast<f32>(render_time_limit_percent) / 100.0f)))}; num_voices_dropped =
num_voices_dropped = DropVoices(command_buffer, start_estimated_time, time_limit); DropVoices(command_buffer, static_cast<u32>(start_estimated_time), time_limit);
} }
command_list_header->buffer_size = command_buffer.size; command_list_header->buffer_size = command_buffer.size;
@ -737,24 +744,33 @@ u64 System::GenerateCommand(std::span<u8> in_command_buffer,
return command_buffer.size; return command_buffer.size;
} }
u32 System::DropVoices(CommandBuffer& command_buffer, const u32 estimated_process_time, f32 System::GetVoiceDropParameter() const {
const u32 time_limit) { return drop_voice_param;
}
void System::SetVoiceDropParameter(f32 voice_drop_) {
drop_voice_param = voice_drop_;
}
u32 System::DropVoices(CommandBuffer& command_buffer, u32 estimated_process_time, u32 time_limit) {
u32 i{0}; u32 i{0};
auto command_list{command_buffer.command_list.data() + sizeof(CommandListHeader)}; auto command_list{command_buffer.command_list.data() + sizeof(CommandListHeader)};
ICommand* cmd{}; ICommand* cmd{nullptr};
for (; i < command_buffer.count; i++) { // Find a first valid voice to drop
while (i < command_buffer.count) {
cmd = reinterpret_cast<ICommand*>(command_list); cmd = reinterpret_cast<ICommand*>(command_list);
if (cmd->type != CommandId::Performance && if (cmd->type == CommandId::Performance ||
cmd->type != CommandId::DataSourcePcmInt16Version1 && cmd->type == CommandId::DataSourcePcmInt16Version1 ||
cmd->type != CommandId::DataSourcePcmInt16Version2 && cmd->type == CommandId::DataSourcePcmInt16Version2 ||
cmd->type != CommandId::DataSourcePcmFloatVersion1 && cmd->type == CommandId::DataSourcePcmFloatVersion1 ||
cmd->type != CommandId::DataSourcePcmFloatVersion2 && cmd->type == CommandId::DataSourcePcmFloatVersion2 ||
cmd->type != CommandId::DataSourceAdpcmVersion1 && cmd->type == CommandId::DataSourceAdpcmVersion1 ||
cmd->type != CommandId::DataSourceAdpcmVersion2) { cmd->type == CommandId::DataSourceAdpcmVersion2) {
break; break;
} }
command_list += cmd->size; command_list += cmd->size;
i++;
} }
if (cmd == nullptr || command_buffer.count == 0 || i >= command_buffer.count) { if (cmd == nullptr || command_buffer.count == 0 || i >= command_buffer.count) {
@ -767,6 +783,7 @@ u32 System::DropVoices(CommandBuffer& command_buffer, const u32 estimated_proces
const auto node_id_type{cmd->node_id >> 28}; const auto node_id_type{cmd->node_id >> 28};
const auto node_id_base{cmd->node_id & 0xFFF}; const auto node_id_base{cmd->node_id & 0xFFF};
// If the new estimated process time falls below the limit, we're done dropping.
if (estimated_process_time <= time_limit) { if (estimated_process_time <= time_limit) {
break; break;
} }
@ -775,6 +792,7 @@ u32 System::DropVoices(CommandBuffer& command_buffer, const u32 estimated_proces
break; break;
} }
// Don't drop voices marked with the highest priority.
auto& voice_info{voice_context.GetInfo(node_id_base)}; auto& voice_info{voice_context.GetInfo(node_id_base)};
if (voice_info.priority == HighestVoicePriority) { if (voice_info.priority == HighestVoicePriority) {
break; break;
@ -783,18 +801,23 @@ u32 System::DropVoices(CommandBuffer& command_buffer, const u32 estimated_proces
voices_dropped++; voices_dropped++;
voice_info.voice_dropped = true; voice_info.voice_dropped = true;
if (i < command_buffer.count) { // First iteration should drop the voice, and then iterate through all of the commands tied
while (cmd->node_id == node_id) { // to the voice. We don't need reverb on a voice which we've just removed, for example.
if (cmd->type == CommandId::DepopPrepare) { // Depops can't be removed otherwise we'll introduce audio popping, and we don't
cmd->enabled = true; // remove perf commands. Lower the estimated time for each command dropped.
} else if (cmd->type == CommandId::Performance || !cmd->enabled) { while (i < command_buffer.count && cmd->node_id == node_id) {
cmd->enabled = false; if (cmd->type == CommandId::DepopPrepare) {
} cmd->enabled = true;
i++; } else if (cmd->enabled && cmd->type != CommandId::Performance) {
command_list += cmd->size; cmd->enabled = false;
cmd = reinterpret_cast<ICommand*>(command_list); estimated_process_time -= static_cast<u32>(
drop_voice_param * static_cast<f32>(cmd->estimated_process_time));
} }
command_list += cmd->size;
cmd = reinterpret_cast<ICommand*>(command_list);
i++;
} }
i++;
} }
return voices_dropped; return voices_dropped;
} }

View file

@ -196,6 +196,20 @@ public:
*/ */
u32 DropVoices(CommandBuffer& command_buffer, u32 estimated_process_time, u32 time_limit); u32 DropVoices(CommandBuffer& command_buffer, u32 estimated_process_time, u32 time_limit);
/**
* Get the current voice drop parameter.
*
* @return The current voice drop.
*/
f32 GetVoiceDropParameter() const;
/**
* Set the voice drop parameter.
*
* @param The new voice drop.
*/
void SetVoiceDropParameter(f32 voice_drop);
private: private:
/// Core system /// Core system
Core::System& core; Core::System& core;
@ -301,6 +315,8 @@ private:
u32 num_voices_dropped{}; u32 num_voices_dropped{};
/// Tick that rendering started /// Tick that rendering started
u64 render_start_tick{}; u64 render_start_tick{};
/// Parameter to control the threshold for dropping voices if the audio graph gets too large
f32 drop_voice_param{1.0f};
}; };
} // namespace AudioRenderer } // namespace AudioRenderer

View file

@ -74,8 +74,8 @@ void VoiceContext::SortInfo() {
} }
std::ranges::sort(sorted_voice_info, [](const VoiceInfo* a, const VoiceInfo* b) { std::ranges::sort(sorted_voice_info, [](const VoiceInfo* a, const VoiceInfo* b) {
return a->priority != b->priority ? a->priority < b->priority return a->priority != b->priority ? a->priority > b->priority
: a->sort_order < b->sort_order; : a->sort_order > b->sort_order;
}); });
} }

View file

@ -45,9 +45,25 @@ AudCtl::AudCtl(Core::System& system_) : ServiceFramework{system_, "audctl"} {
{32, nullptr, "GetActiveOutputTarget"}, {32, nullptr, "GetActiveOutputTarget"},
{33, nullptr, "GetTargetDeviceInfo"}, {33, nullptr, "GetTargetDeviceInfo"},
{34, nullptr, "AcquireTargetNotification"}, {34, nullptr, "AcquireTargetNotification"},
{35, nullptr, "SetHearingProtectionSafeguardTimerRemainingTimeForDebug"},
{36, nullptr, "GetHearingProtectionSafeguardTimerRemainingTimeForDebug"},
{37, nullptr, "SetHearingProtectionSafeguardEnabled"},
{38, nullptr, "IsHearingProtectionSafeguardEnabled"},
{39, nullptr, "IsHearingProtectionSafeguardMonitoringOutputForDebug"},
{40, nullptr, "GetSystemInformationForDebug"},
{41, nullptr, "SetVolumeButtonLongPressTime"},
{42, nullptr, "SetNativeVolumeForDebug"},
{10000, nullptr, "NotifyAudioOutputTargetForPlayReport"}, {10000, nullptr, "NotifyAudioOutputTargetForPlayReport"},
{10001, nullptr, "NotifyAudioOutputChannelCountForPlayReport"}, {10001, nullptr, "NotifyAudioOutputChannelCountForPlayReport"},
{10002, nullptr, "NotifyUnsupportedUsbOutputDeviceAttachedForPlayReport"}, {10002, nullptr, "NotifyUnsupportedUsbOutputDeviceAttachedForPlayReport"},
{10100, nullptr, "GetAudioVolumeDataForPlayReport"},
{10101, nullptr, "BindAudioVolumeUpdateEventForPlayReport"},
{10102, nullptr, "BindAudioOutputTargetUpdateEventForPlayReport"},
{10103, nullptr, "GetAudioOutputTargetForPlayReport"},
{10104, nullptr, "GetAudioOutputChannelCountForPlayReport"},
{10105, nullptr, "BindAudioOutputChannelCountUpdateEventForPlayReport"},
{10106, nullptr, "GetDefaultAudioOutputTargetForPlayReport"},
{50000, nullptr, "SetAnalogInputBoostGainForPrototyping"},
}; };
// clang-format on // clang-format on

View file

@ -52,6 +52,8 @@ public:
{9, &IAudioRenderer::GetRenderingTimeLimit, "GetRenderingTimeLimit"}, {9, &IAudioRenderer::GetRenderingTimeLimit, "GetRenderingTimeLimit"},
{10, &IAudioRenderer::RequestUpdate, "RequestUpdateAuto"}, {10, &IAudioRenderer::RequestUpdate, "RequestUpdateAuto"},
{11, nullptr, "ExecuteAudioRendererRendering"}, {11, nullptr, "ExecuteAudioRendererRendering"},
{12, &IAudioRenderer::SetVoiceDropParameter, "SetVoiceDropParameter"},
{13, &IAudioRenderer::GetVoiceDropParameter, "GetVoiceDropParameter"},
}; };
// clang-format on // clang-format on
RegisterHandlers(functions); RegisterHandlers(functions);
@ -205,6 +207,30 @@ private:
LOG_DEBUG(Service_Audio, "called"); LOG_DEBUG(Service_Audio, "called");
} }
void SetVoiceDropParameter(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_Audio, "called");
IPC::RequestParser rp{ctx};
auto voice_drop_param{rp.Pop<f32>()};
auto& system_ = impl->GetSystem();
system_.SetVoiceDropParameter(voice_drop_param);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
void GetVoiceDropParameter(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_Audio, "called");
auto& system_ = impl->GetSystem();
auto voice_drop_param{system_.GetVoiceDropParameter()};
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
rb.Push(voice_drop_param);
}
KernelHelpers::ServiceContext service_context; KernelHelpers::ServiceContext service_context;
Kernel::KEvent* rendered_event; Kernel::KEvent* rendered_event;
Manager& manager; Manager& manager;