mirror of
				https://git.tardis.systems/mirrors/yuzu
				synced 2025-11-04 04:34:07 +01:00 
			
		
		
		
	Merge pull request #9769 from Kelebek1/audio_oob
[audio_core] Fix depop prepare
This commit is contained in:
		
						commit
						744434de38
					
				@ -46,7 +46,7 @@ void CommandGenerator::GenerateDataSourceCommand(VoiceInfo& voice_info,
 | 
				
			|||||||
            while (destination != nullptr) {
 | 
					            while (destination != nullptr) {
 | 
				
			||||||
                if (destination->IsConfigured()) {
 | 
					                if (destination->IsConfigured()) {
 | 
				
			||||||
                    auto mix_id{destination->GetMixId()};
 | 
					                    auto mix_id{destination->GetMixId()};
 | 
				
			||||||
                    if (mix_id < mix_context.GetCount()) {
 | 
					                    if (mix_id < mix_context.GetCount() && mix_id != UnusedSplitterId) {
 | 
				
			||||||
                        auto mix_info{mix_context.GetInfo(mix_id)};
 | 
					                        auto mix_info{mix_context.GetInfo(mix_id)};
 | 
				
			||||||
                        command_buffer.GenerateDepopPrepareCommand(
 | 
					                        command_buffer.GenerateDepopPrepareCommand(
 | 
				
			||||||
                            voice_info.node_id, voice_state, render_context.depop_buffer,
 | 
					                            voice_info.node_id, voice_state, render_context.depop_buffer,
 | 
				
			||||||
 | 
				
			|||||||
@ -4,6 +4,7 @@
 | 
				
			|||||||
#include "audio_core/renderer/adsp/command_list_processor.h"
 | 
					#include "audio_core/renderer/adsp/command_list_processor.h"
 | 
				
			||||||
#include "audio_core/renderer/command/effect/aux_.h"
 | 
					#include "audio_core/renderer/command/effect/aux_.h"
 | 
				
			||||||
#include "audio_core/renderer/effect/aux_.h"
 | 
					#include "audio_core/renderer/effect/aux_.h"
 | 
				
			||||||
 | 
					#include "core/core.h"
 | 
				
			||||||
#include "core/memory.h"
 | 
					#include "core/memory.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace AudioCore::AudioRenderer {
 | 
					namespace AudioCore::AudioRenderer {
 | 
				
			||||||
@ -19,10 +20,24 @@ static void ResetAuxBufferDsp(Core::Memory::Memory& memory, const CpuAddr aux_in
 | 
				
			|||||||
        return;
 | 
					        return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    auto info{reinterpret_cast<AuxInfo::AuxInfoDsp*>(memory.GetPointer(aux_info))};
 | 
					    AuxInfo::AuxInfoDsp info{};
 | 
				
			||||||
    info->read_offset = 0;
 | 
					    auto info_ptr{&info};
 | 
				
			||||||
    info->write_offset = 0;
 | 
					    bool host_safe{(aux_info & Core::Memory::YUZU_PAGEMASK) <=
 | 
				
			||||||
    info->total_sample_count = 0;
 | 
					                   (Core::Memory::YUZU_PAGESIZE - sizeof(AuxInfo::AuxInfoDsp))};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (host_safe) [[likely]] {
 | 
				
			||||||
 | 
					        info_ptr = memory.GetPointer<AuxInfo::AuxInfoDsp>(aux_info);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        memory.ReadBlockUnsafe(aux_info, info_ptr, sizeof(AuxInfo::AuxInfoDsp));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    info_ptr->read_offset = 0;
 | 
				
			||||||
 | 
					    info_ptr->write_offset = 0;
 | 
				
			||||||
 | 
					    info_ptr->total_sample_count = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!host_safe) [[unlikely]] {
 | 
				
			||||||
 | 
					        memory.WriteBlockUnsafe(aux_info, info_ptr, sizeof(AuxInfo::AuxInfoDsp));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
@ -40,11 +55,10 @@ static void ResetAuxBufferDsp(Core::Memory::Memory& memory, const CpuAddr aux_in
 | 
				
			|||||||
 * @param update_count - If non-zero, send_info_ will be updated.
 | 
					 * @param update_count - If non-zero, send_info_ will be updated.
 | 
				
			||||||
 * @return Number of samples written.
 | 
					 * @return Number of samples written.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static u32 WriteAuxBufferDsp(Core::Memory::Memory& memory, const CpuAddr send_info_,
 | 
					static u32 WriteAuxBufferDsp(Core::Memory::Memory& memory, CpuAddr send_info_,
 | 
				
			||||||
                             [[maybe_unused]] u32 sample_count, const CpuAddr send_buffer,
 | 
					                             [[maybe_unused]] u32 sample_count, CpuAddr send_buffer, u32 count_max,
 | 
				
			||||||
                             const u32 count_max, std::span<const s32> input,
 | 
					                             std::span<const s32> input, u32 write_count_, u32 write_offset,
 | 
				
			||||||
                             const u32 write_count_, const u32 write_offset,
 | 
					                             u32 update_count) {
 | 
				
			||||||
                             const u32 update_count) {
 | 
					 | 
				
			||||||
    if (write_count_ > count_max) {
 | 
					    if (write_count_ > count_max) {
 | 
				
			||||||
        LOG_ERROR(Service_Audio,
 | 
					        LOG_ERROR(Service_Audio,
 | 
				
			||||||
                  "write_count must be smaller than count_max! write_count {}, count_max {}",
 | 
					                  "write_count must be smaller than count_max! write_count {}, count_max {}",
 | 
				
			||||||
@ -52,6 +66,11 @@ static u32 WriteAuxBufferDsp(Core::Memory::Memory& memory, const CpuAddr send_in
 | 
				
			|||||||
        return 0;
 | 
					        return 0;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (send_info_ == 0) {
 | 
				
			||||||
 | 
					        LOG_ERROR(Service_Audio, "send_info_ is 0!");
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (input.empty()) {
 | 
					    if (input.empty()) {
 | 
				
			||||||
        LOG_ERROR(Service_Audio, "input buffer is empty!");
 | 
					        LOG_ERROR(Service_Audio, "input buffer is empty!");
 | 
				
			||||||
        return 0;
 | 
					        return 0;
 | 
				
			||||||
@ -67,33 +86,47 @@ static u32 WriteAuxBufferDsp(Core::Memory::Memory& memory, const CpuAddr send_in
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    AuxInfo::AuxInfoDsp send_info{};
 | 
					    AuxInfo::AuxInfoDsp send_info{};
 | 
				
			||||||
    memory.ReadBlockUnsafe(send_info_, &send_info, sizeof(AuxInfo::AuxInfoDsp));
 | 
					    auto send_ptr = &send_info;
 | 
				
			||||||
 | 
					    bool host_safe = (send_info_ & Core::Memory::YUZU_PAGEMASK) <=
 | 
				
			||||||
 | 
					                     (Core::Memory::YUZU_PAGESIZE - sizeof(AuxInfo::AuxInfoDsp));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    u32 target_write_offset{send_info.write_offset + write_offset};
 | 
					    if (host_safe) [[likely]] {
 | 
				
			||||||
    if (target_write_offset > count_max || write_count_ == 0) {
 | 
					        send_ptr = memory.GetPointer<AuxInfo::AuxInfoDsp>(send_info_);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        memory.ReadBlockUnsafe(send_info_, send_ptr, sizeof(AuxInfo::AuxInfoDsp));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    u32 target_write_offset{send_ptr->write_offset + write_offset};
 | 
				
			||||||
 | 
					    if (target_write_offset > count_max) {
 | 
				
			||||||
        return 0;
 | 
					        return 0;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    u32 write_count{write_count_};
 | 
					    u32 write_count{write_count_};
 | 
				
			||||||
    u32 write_pos{0};
 | 
					    u32 read_pos{0};
 | 
				
			||||||
    while (write_count > 0) {
 | 
					    while (write_count > 0) {
 | 
				
			||||||
        u32 to_write{std::min(count_max - target_write_offset, write_count)};
 | 
					        u32 to_write{std::min(count_max - target_write_offset, write_count)};
 | 
				
			||||||
 | 
					        const auto write_addr = send_buffer + target_write_offset * sizeof(s32);
 | 
				
			||||||
        if (to_write > 0) {
 | 
					        bool write_safe{(write_addr & Core::Memory::YUZU_PAGEMASK) <=
 | 
				
			||||||
 | 
					                        (Core::Memory::YUZU_PAGESIZE - (write_addr + to_write * sizeof(s32)))};
 | 
				
			||||||
 | 
					        if (write_safe) [[likely]] {
 | 
				
			||||||
 | 
					            auto ptr = memory.GetPointer(write_addr);
 | 
				
			||||||
 | 
					            std::memcpy(ptr, &input[read_pos], to_write * sizeof(s32));
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
            memory.WriteBlockUnsafe(send_buffer + target_write_offset * sizeof(s32),
 | 
					            memory.WriteBlockUnsafe(send_buffer + target_write_offset * sizeof(s32),
 | 
				
			||||||
                                    &input[write_pos], to_write * sizeof(s32));
 | 
					                                    &input[read_pos], to_write * sizeof(s32));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					 | 
				
			||||||
        target_write_offset = (target_write_offset + to_write) % count_max;
 | 
					        target_write_offset = (target_write_offset + to_write) % count_max;
 | 
				
			||||||
        write_count -= to_write;
 | 
					        write_count -= to_write;
 | 
				
			||||||
        write_pos += to_write;
 | 
					        read_pos += to_write;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (update_count) {
 | 
					    if (update_count) {
 | 
				
			||||||
        send_info.write_offset = (send_info.write_offset + update_count) % count_max;
 | 
					        send_ptr->write_offset = (send_ptr->write_offset + update_count) % count_max;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    memory.WriteBlockUnsafe(send_info_, &send_info, sizeof(AuxInfo::AuxInfoDsp));
 | 
					    if (!host_safe) [[unlikely]] {
 | 
				
			||||||
 | 
					        memory.WriteBlockUnsafe(send_info_, send_ptr, sizeof(AuxInfo::AuxInfoDsp));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return write_count_;
 | 
					    return write_count_;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -102,7 +135,7 @@ static u32 WriteAuxBufferDsp(Core::Memory::Memory& memory, const CpuAddr send_in
 | 
				
			|||||||
 * Read the given memory at return_buffer into the output mix buffer, and update return_info_ if
 | 
					 * Read the given memory at return_buffer into the output mix buffer, and update return_info_ if
 | 
				
			||||||
 * update_count is set, to notify the game that an update happened.
 | 
					 * update_count is set, to notify the game that an update happened.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * @param memory        - Core memory for writing.
 | 
					 * @param memory        - Core memory for reading.
 | 
				
			||||||
 * @param return_info_  - Meta information for where to read the mix buffer.
 | 
					 * @param return_info_  - Meta information for where to read the mix buffer.
 | 
				
			||||||
 * @param return_buffer - Memory address to read the samples from.
 | 
					 * @param return_buffer - Memory address to read the samples from.
 | 
				
			||||||
 * @param count_max     - Maximum number of samples in the receiving buffer.
 | 
					 * @param count_max     - Maximum number of samples in the receiving buffer.
 | 
				
			||||||
@ -112,16 +145,21 @@ static u32 WriteAuxBufferDsp(Core::Memory::Memory& memory, const CpuAddr send_in
 | 
				
			|||||||
 * @param update_count  - If non-zero, send_info_ will be updated.
 | 
					 * @param update_count  - If non-zero, send_info_ will be updated.
 | 
				
			||||||
 * @return Number of samples read.
 | 
					 * @return Number of samples read.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static u32 ReadAuxBufferDsp(Core::Memory::Memory& memory, const CpuAddr return_info_,
 | 
					static u32 ReadAuxBufferDsp(Core::Memory::Memory& memory, CpuAddr return_info_,
 | 
				
			||||||
                            const CpuAddr return_buffer, const u32 count_max, std::span<s32> output,
 | 
					                            CpuAddr return_buffer, u32 count_max, std::span<s32> output,
 | 
				
			||||||
                            const u32 count_, const u32 read_offset, const u32 update_count) {
 | 
					                            u32 read_count_, u32 read_offset, u32 update_count) {
 | 
				
			||||||
    if (count_max == 0) {
 | 
					    if (count_max == 0) {
 | 
				
			||||||
        return 0;
 | 
					        return 0;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (count_ > count_max) {
 | 
					    if (read_count_ > count_max) {
 | 
				
			||||||
        LOG_ERROR(Service_Audio, "count must be smaller than count_max! count {}, count_max {}",
 | 
					        LOG_ERROR(Service_Audio, "count must be smaller than count_max! count {}, count_max {}",
 | 
				
			||||||
                  count_, count_max);
 | 
					                  read_count_, count_max);
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (return_info_ == 0) {
 | 
				
			||||||
 | 
					        LOG_ERROR(Service_Audio, "return_info_ is 0!");
 | 
				
			||||||
        return 0;
 | 
					        return 0;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -136,35 +174,49 @@ static u32 ReadAuxBufferDsp(Core::Memory::Memory& memory, const CpuAddr return_i
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    AuxInfo::AuxInfoDsp return_info{};
 | 
					    AuxInfo::AuxInfoDsp return_info{};
 | 
				
			||||||
    memory.ReadBlockUnsafe(return_info_, &return_info, sizeof(AuxInfo::AuxInfoDsp));
 | 
					    auto return_ptr = &return_info;
 | 
				
			||||||
 | 
					    bool host_safe = (return_info_ & Core::Memory::YUZU_PAGEMASK) <=
 | 
				
			||||||
 | 
					                     (Core::Memory::YUZU_PAGESIZE - sizeof(AuxInfo::AuxInfoDsp));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    u32 target_read_offset{return_info.read_offset + read_offset};
 | 
					    if (host_safe) [[likely]] {
 | 
				
			||||||
 | 
					        return_ptr = memory.GetPointer<AuxInfo::AuxInfoDsp>(return_info_);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        memory.ReadBlockUnsafe(return_info_, return_ptr, sizeof(AuxInfo::AuxInfoDsp));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    u32 target_read_offset{return_ptr->read_offset + read_offset};
 | 
				
			||||||
    if (target_read_offset > count_max) {
 | 
					    if (target_read_offset > count_max) {
 | 
				
			||||||
        return 0;
 | 
					        return 0;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    u32 read_count{count_};
 | 
					    u32 read_count{read_count_};
 | 
				
			||||||
    u32 read_pos{0};
 | 
					    u32 write_pos{0};
 | 
				
			||||||
    while (read_count > 0) {
 | 
					    while (read_count > 0) {
 | 
				
			||||||
        u32 to_read{std::min(count_max - target_read_offset, read_count)};
 | 
					        u32 to_read{std::min(count_max - target_read_offset, read_count)};
 | 
				
			||||||
 | 
					        const auto read_addr = return_buffer + target_read_offset * sizeof(s32);
 | 
				
			||||||
        if (to_read > 0) {
 | 
					        bool read_safe{(read_addr & Core::Memory::YUZU_PAGEMASK) <=
 | 
				
			||||||
 | 
					                       (Core::Memory::YUZU_PAGESIZE - (read_addr + to_read * sizeof(s32)))};
 | 
				
			||||||
 | 
					        if (read_safe) [[likely]] {
 | 
				
			||||||
 | 
					            auto ptr = memory.GetPointer(read_addr);
 | 
				
			||||||
 | 
					            std::memcpy(&output[write_pos], ptr, to_read * sizeof(s32));
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
            memory.ReadBlockUnsafe(return_buffer + target_read_offset * sizeof(s32),
 | 
					            memory.ReadBlockUnsafe(return_buffer + target_read_offset * sizeof(s32),
 | 
				
			||||||
                                   &output[read_pos], to_read * sizeof(s32));
 | 
					                                   &output[write_pos], to_read * sizeof(s32));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					 | 
				
			||||||
        target_read_offset = (target_read_offset + to_read) % count_max;
 | 
					        target_read_offset = (target_read_offset + to_read) % count_max;
 | 
				
			||||||
        read_count -= to_read;
 | 
					        read_count -= to_read;
 | 
				
			||||||
        read_pos += to_read;
 | 
					        write_pos += to_read;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (update_count) {
 | 
					    if (update_count) {
 | 
				
			||||||
        return_info.read_offset = (return_info.read_offset + update_count) % count_max;
 | 
					        return_ptr->read_offset = (return_ptr->read_offset + update_count) % count_max;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    memory.WriteBlockUnsafe(return_info_, &return_info, sizeof(AuxInfo::AuxInfoDsp));
 | 
					    if (!host_safe) [[unlikely]] {
 | 
				
			||||||
 | 
					        memory.WriteBlockUnsafe(return_info_, return_ptr, sizeof(AuxInfo::AuxInfoDsp));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return count_;
 | 
					    return read_count_;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void AuxCommand::Dump([[maybe_unused]] const ADSP::CommandListProcessor& processor,
 | 
					void AuxCommand::Dump([[maybe_unused]] const ADSP::CommandListProcessor& processor,
 | 
				
			||||||
@ -189,7 +241,7 @@ void AuxCommand::Process(const ADSP::CommandListProcessor& processor) {
 | 
				
			|||||||
                                   update_count)};
 | 
					                                   update_count)};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (read != processor.sample_count) {
 | 
					        if (read != processor.sample_count) {
 | 
				
			||||||
            std::memset(&output_buffer[read], 0, processor.sample_count - read);
 | 
					            std::memset(&output_buffer[read], 0, (processor.sample_count - read) * sizeof(s32));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        ResetAuxBufferDsp(*processor.memory, send_buffer_info);
 | 
					        ResetAuxBufferDsp(*processor.memory, send_buffer_info);
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user