diff options
Diffstat (limited to 'src/audio_core/renderer/system.cpp')
| -rw-r--r-- | src/audio_core/renderer/system.cpp | 85 |
1 files changed, 54 insertions, 31 deletions
diff --git a/src/audio_core/renderer/system.cpp b/src/audio_core/renderer/system.cpp index bde794cd1..4fac30c7c 100644 --- a/src/audio_core/renderer/system.cpp +++ b/src/audio_core/renderer/system.cpp | |||
| @@ -98,9 +98,8 @@ System::System(Core::System& core_, Kernel::KEvent* adsp_rendered_event_) | |||
| 98 | : core{core_}, adsp{core.AudioCore().GetADSP()}, adsp_rendered_event{adsp_rendered_event_} {} | 98 | : core{core_}, adsp{core.AudioCore().GetADSP()}, adsp_rendered_event{adsp_rendered_event_} {} |
| 99 | 99 | ||
| 100 | Result System::Initialize(const AudioRendererParameterInternal& params, | 100 | Result System::Initialize(const AudioRendererParameterInternal& params, |
| 101 | Kernel::KTransferMemory* transfer_memory, const u64 transfer_memory_size, | 101 | Kernel::KTransferMemory* transfer_memory, u64 transfer_memory_size, |
| 102 | const u32 process_handle_, const u64 applet_resource_user_id_, | 102 | u32 process_handle_, u64 applet_resource_user_id_, s32 session_id_) { |
| 103 | const s32 session_id_) { | ||
| 104 | if (!CheckValidRevision(params.revision)) { | 103 | if (!CheckValidRevision(params.revision)) { |
| 105 | return Service::Audio::ERR_INVALID_REVISION; | 104 | return Service::Audio::ERR_INVALID_REVISION; |
| 106 | } | 105 | } |
| @@ -354,6 +353,8 @@ Result System::Initialize(const AudioRendererParameterInternal& params, | |||
| 354 | 353 | ||
| 355 | render_time_limit_percent = 100; | 354 | render_time_limit_percent = 100; |
| 356 | drop_voice = params.voice_drop_enabled && params.execution_mode == ExecutionMode::Auto; | 355 | drop_voice = params.voice_drop_enabled && params.execution_mode == ExecutionMode::Auto; |
| 356 | drop_voice_param = 1.0f; | ||
| 357 | num_voices_dropped = 0; | ||
| 357 | 358 | ||
| 358 | allocator.Align(0x40); | 359 | allocator.Align(0x40); |
| 359 | command_workbuffer_size = allocator.GetRemainingSize(); | 360 | command_workbuffer_size = allocator.GetRemainingSize(); |
| @@ -547,7 +548,7 @@ u32 System::GetRenderingTimeLimit() const { | |||
| 547 | return render_time_limit_percent; | 548 | return render_time_limit_percent; |
| 548 | } | 549 | } |
| 549 | 550 | ||
| 550 | void System::SetRenderingTimeLimit(const u32 limit) { | 551 | void System::SetRenderingTimeLimit(u32 limit) { |
| 551 | render_time_limit_percent = limit; | 552 | render_time_limit_percent = limit; |
| 552 | } | 553 | } |
| 553 | 554 | ||
| @@ -635,7 +636,7 @@ void System::SendCommandToDsp() { | |||
| 635 | } | 636 | } |
| 636 | 637 | ||
| 637 | u64 System::GenerateCommand(std::span<u8> in_command_buffer, | 638 | u64 System::GenerateCommand(std::span<u8> in_command_buffer, |
| 638 | [[maybe_unused]] const u64 command_buffer_size_) { | 639 | [[maybe_unused]] u64 command_buffer_size_) { |
| 639 | PoolMapper::ClearUseState(memory_pool_workbuffer, memory_pool_count); | 640 | PoolMapper::ClearUseState(memory_pool_workbuffer, memory_pool_count); |
| 640 | const auto start_time{core.CoreTiming().GetClockTicks()}; | 641 | const auto start_time{core.CoreTiming().GetClockTicks()}; |
| 641 | 642 | ||
| @@ -693,7 +694,8 @@ u64 System::GenerateCommand(std::span<u8> in_command_buffer, | |||
| 693 | 694 | ||
| 694 | voice_context.SortInfo(); | 695 | voice_context.SortInfo(); |
| 695 | 696 | ||
| 696 | const auto start_estimated_time{command_buffer.estimated_process_time}; | 697 | const auto start_estimated_time{drop_voice_param * |
| 698 | static_cast<f32>(command_buffer.estimated_process_time)}; | ||
| 697 | 699 | ||
| 698 | command_generator.GenerateVoiceCommands(); | 700 | command_generator.GenerateVoiceCommands(); |
| 699 | command_generator.GenerateSubMixCommands(); | 701 | command_generator.GenerateSubMixCommands(); |
| @@ -712,11 +714,16 @@ u64 System::GenerateCommand(std::span<u8> in_command_buffer, | |||
| 712 | render_context.behavior->IsAudioRendererProcessingTimeLimit70PercentSupported(); | 714 | render_context.behavior->IsAudioRendererProcessingTimeLimit70PercentSupported(); |
| 713 | time_limit_percent = 70.0f; | 715 | time_limit_percent = 70.0f; |
| 714 | } | 716 | } |
| 717 | |||
| 718 | const auto end_estimated_time{drop_voice_param * | ||
| 719 | static_cast<f32>(command_buffer.estimated_process_time)}; | ||
| 720 | const auto estimated_time{start_estimated_time - end_estimated_time}; | ||
| 721 | |||
| 715 | const auto time_limit{static_cast<u32>( | 722 | const auto time_limit{static_cast<u32>( |
| 716 | static_cast<f32>(start_estimated_time - command_buffer.estimated_process_time) + | 723 | estimated_time + (((time_limit_percent / 100.0f) * 2'880'000.0) * |
| 717 | (((time_limit_percent / 100.0f) * 2'880'000.0) * | 724 | (static_cast<f32>(render_time_limit_percent) / 100.0f)))}; |
| 718 | (static_cast<f32>(render_time_limit_percent) / 100.0f)))}; | 725 | num_voices_dropped = |
| 719 | num_voices_dropped = DropVoices(command_buffer, start_estimated_time, time_limit); | 726 | DropVoices(command_buffer, static_cast<u32>(start_estimated_time), time_limit); |
| 720 | } | 727 | } |
| 721 | 728 | ||
| 722 | command_list_header->buffer_size = command_buffer.size; | 729 | command_list_header->buffer_size = command_buffer.size; |
| @@ -737,24 +744,33 @@ u64 System::GenerateCommand(std::span<u8> in_command_buffer, | |||
| 737 | return command_buffer.size; | 744 | return command_buffer.size; |
| 738 | } | 745 | } |
| 739 | 746 | ||
| 740 | u32 System::DropVoices(CommandBuffer& command_buffer, const u32 estimated_process_time, | 747 | f32 System::GetVoiceDropParameter() const { |
| 741 | const u32 time_limit) { | 748 | return drop_voice_param; |
| 749 | } | ||
| 750 | |||
| 751 | void System::SetVoiceDropParameter(f32 voice_drop_) { | ||
| 752 | drop_voice_param = voice_drop_; | ||
| 753 | } | ||
| 754 | |||
| 755 | u32 System::DropVoices(CommandBuffer& command_buffer, u32 estimated_process_time, u32 time_limit) { | ||
| 742 | u32 i{0}; | 756 | u32 i{0}; |
| 743 | auto command_list{command_buffer.command_list.data() + sizeof(CommandListHeader)}; | 757 | auto command_list{command_buffer.command_list.data() + sizeof(CommandListHeader)}; |
| 744 | ICommand* cmd{}; | 758 | ICommand* cmd{nullptr}; |
| 745 | 759 | ||
| 746 | for (; i < command_buffer.count; i++) { | 760 | // Find a first valid voice to drop |
| 761 | while (i < command_buffer.count) { | ||
| 747 | cmd = reinterpret_cast<ICommand*>(command_list); | 762 | cmd = reinterpret_cast<ICommand*>(command_list); |
| 748 | if (cmd->type != CommandId::Performance && | 763 | if (cmd->type == CommandId::Performance || |
| 749 | cmd->type != CommandId::DataSourcePcmInt16Version1 && | 764 | cmd->type == CommandId::DataSourcePcmInt16Version1 || |
| 750 | cmd->type != CommandId::DataSourcePcmInt16Version2 && | 765 | cmd->type == CommandId::DataSourcePcmInt16Version2 || |
| 751 | cmd->type != CommandId::DataSourcePcmFloatVersion1 && | 766 | cmd->type == CommandId::DataSourcePcmFloatVersion1 || |
| 752 | cmd->type != CommandId::DataSourcePcmFloatVersion2 && | 767 | cmd->type == CommandId::DataSourcePcmFloatVersion2 || |
| 753 | cmd->type != CommandId::DataSourceAdpcmVersion1 && | 768 | cmd->type == CommandId::DataSourceAdpcmVersion1 || |
| 754 | cmd->type != CommandId::DataSourceAdpcmVersion2) { | 769 | cmd->type == CommandId::DataSourceAdpcmVersion2) { |
| 755 | break; | 770 | break; |
| 756 | } | 771 | } |
| 757 | command_list += cmd->size; | 772 | command_list += cmd->size; |
| 773 | i++; | ||
| 758 | } | 774 | } |
| 759 | 775 | ||
| 760 | if (cmd == nullptr || command_buffer.count == 0 || i >= command_buffer.count) { | 776 | 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 | |||
| 767 | const auto node_id_type{cmd->node_id >> 28}; | 783 | const auto node_id_type{cmd->node_id >> 28}; |
| 768 | const auto node_id_base{cmd->node_id & 0xFFF}; | 784 | const auto node_id_base{cmd->node_id & 0xFFF}; |
| 769 | 785 | ||
| 786 | // If the new estimated process time falls below the limit, we're done dropping. | ||
| 770 | if (estimated_process_time <= time_limit) { | 787 | if (estimated_process_time <= time_limit) { |
| 771 | break; | 788 | break; |
| 772 | } | 789 | } |
| @@ -775,6 +792,7 @@ u32 System::DropVoices(CommandBuffer& command_buffer, const u32 estimated_proces | |||
| 775 | break; | 792 | break; |
| 776 | } | 793 | } |
| 777 | 794 | ||
| 795 | // Don't drop voices marked with the highest priority. | ||
| 778 | auto& voice_info{voice_context.GetInfo(node_id_base)}; | 796 | auto& voice_info{voice_context.GetInfo(node_id_base)}; |
| 779 | if (voice_info.priority == HighestVoicePriority) { | 797 | if (voice_info.priority == HighestVoicePriority) { |
| 780 | break; | 798 | break; |
| @@ -783,18 +801,23 @@ u32 System::DropVoices(CommandBuffer& command_buffer, const u32 estimated_proces | |||
| 783 | voices_dropped++; | 801 | voices_dropped++; |
| 784 | voice_info.voice_dropped = true; | 802 | voice_info.voice_dropped = true; |
| 785 | 803 | ||
| 786 | if (i < command_buffer.count) { | 804 | // First iteration should drop the voice, and then iterate through all of the commands tied |
| 787 | while (cmd->node_id == node_id) { | 805 | // to the voice. We don't need reverb on a voice which we've just removed, for example. |
| 788 | if (cmd->type == CommandId::DepopPrepare) { | 806 | // Depops can't be removed otherwise we'll introduce audio popping, and we don't |
| 789 | cmd->enabled = true; | 807 | // remove perf commands. Lower the estimated time for each command dropped. |
| 790 | } else if (cmd->type == CommandId::Performance || !cmd->enabled) { | 808 | while (i < command_buffer.count && cmd->node_id == node_id) { |
| 791 | cmd->enabled = false; | 809 | if (cmd->type == CommandId::DepopPrepare) { |
| 792 | } | 810 | cmd->enabled = true; |
| 793 | i++; | 811 | } else if (cmd->enabled && cmd->type != CommandId::Performance) { |
| 794 | command_list += cmd->size; | 812 | cmd->enabled = false; |
| 795 | cmd = reinterpret_cast<ICommand*>(command_list); | 813 | estimated_process_time -= static_cast<u32>( |
| 814 | drop_voice_param * static_cast<f32>(cmd->estimated_process_time)); | ||
| 796 | } | 815 | } |
| 816 | command_list += cmd->size; | ||
| 817 | cmd = reinterpret_cast<ICommand*>(command_list); | ||
| 818 | i++; | ||
| 797 | } | 819 | } |
| 820 | i++; | ||
| 798 | } | 821 | } |
| 799 | return voices_dropped; | 822 | return voices_dropped; |
| 800 | } | 823 | } |