summaryrefslogtreecommitdiff
path: root/src/audio_core/renderer
diff options
context:
space:
mode:
authorGravatar Kelebek12022-10-19 05:38:12 +0100
committerGravatar Kelebek12022-10-19 06:16:15 +0100
commit7bd3930939dfafc463b87b6df965b8b4391f1f56 (patch)
tree48fef17d69a55a94bd6ec8f2d843ed2730032b50 /src/audio_core/renderer
parentMerge pull request #9054 from Docteh/just_lz4 (diff)
downloadyuzu-7bd3930939dfafc463b87b6df965b8b4391f1f56.tar.gz
yuzu-7bd3930939dfafc463b87b6df965b8b4391f1f56.tar.xz
yuzu-7bd3930939dfafc463b87b6df965b8b4391f1f56.zip
Update audio_core for firmware 15.0.0
Diffstat (limited to 'src/audio_core/renderer')
-rw-r--r--src/audio_core/renderer/system.cpp85
-rw-r--r--src/audio_core/renderer/system.h16
-rw-r--r--src/audio_core/renderer/voice/voice_context.cpp4
3 files changed, 72 insertions, 33 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
100Result System::Initialize(const AudioRendererParameterInternal& params, 100Result 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
550void System::SetRenderingTimeLimit(const u32 limit) { 551void 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
637u64 System::GenerateCommand(std::span<u8> in_command_buffer, 638u64 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
740u32 System::DropVoices(CommandBuffer& command_buffer, const u32 estimated_process_time, 747f32 System::GetVoiceDropParameter() const {
741 const u32 time_limit) { 748 return drop_voice_param;
749}
750
751void System::SetVoiceDropParameter(f32 voice_drop_) {
752 drop_voice_param = voice_drop_;
753}
754
755u32 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}
diff --git a/src/audio_core/renderer/system.h b/src/audio_core/renderer/system.h
index bcbe65b07..429196e41 100644
--- a/src/audio_core/renderer/system.h
+++ b/src/audio_core/renderer/system.h
@@ -196,6 +196,20 @@ public:
196 */ 196 */
197 u32 DropVoices(CommandBuffer& command_buffer, u32 estimated_process_time, u32 time_limit); 197 u32 DropVoices(CommandBuffer& command_buffer, u32 estimated_process_time, u32 time_limit);
198 198
199 /**
200 * Get the current voice drop parameter.
201 *
202 * @return The current voice drop.
203 */
204 f32 GetVoiceDropParameter() const;
205
206 /**
207 * Set the voice drop parameter.
208 *
209 * @param The new voice drop.
210 */
211 void SetVoiceDropParameter(f32 voice_drop);
212
199private: 213private:
200 /// Core system 214 /// Core system
201 Core::System& core; 215 Core::System& core;
@@ -301,6 +315,8 @@ private:
301 u32 num_voices_dropped{}; 315 u32 num_voices_dropped{};
302 /// Tick that rendering started 316 /// Tick that rendering started
303 u64 render_start_tick{}; 317 u64 render_start_tick{};
318 /// Parameter to control the threshold for dropping voices if the audio graph gets too large
319 f32 drop_voice_param{1.0f};
304}; 320};
305 321
306} // namespace AudioRenderer 322} // namespace AudioRenderer
diff --git a/src/audio_core/renderer/voice/voice_context.cpp b/src/audio_core/renderer/voice/voice_context.cpp
index eafb51b01..a501a677d 100644
--- a/src/audio_core/renderer/voice/voice_context.cpp
+++ b/src/audio_core/renderer/voice/voice_context.cpp
@@ -74,8 +74,8 @@ void VoiceContext::SortInfo() {
74 } 74 }
75 75
76 std::ranges::sort(sorted_voice_info, [](const VoiceInfo* a, const VoiceInfo* b) { 76 std::ranges::sort(sorted_voice_info, [](const VoiceInfo* a, const VoiceInfo* b) {
77 return a->priority != b->priority ? a->priority < b->priority 77 return a->priority != b->priority ? a->priority > b->priority
78 : a->sort_order < b->sort_order; 78 : a->sort_order > b->sort_order;
79 }); 79 });
80} 80}
81 81