diff --git a/Source/Core/Core/HW/DSPHLE/UCodes/AX.cpp b/Source/Core/Core/HW/DSPHLE/UCodes/AX.cpp index d9619a0408..95a12765b2 100644 --- a/Source/Core/Core/HW/DSPHLE/UCodes/AX.cpp +++ b/Source/Core/Core/HW/DSPHLE/UCodes/AX.cpp @@ -362,7 +362,7 @@ void AXUCode::SetupProcessing(u32 init_addr) init_data[i] = HLEMemory_Read_U16(init_addr + 2 * i); // List of all buffers we have to initialize - int* buffers[] = {m_samples_left, m_samples_right, m_samples_surround, + int* buffers[] = {m_samples_main_left, m_samples_main_right, m_samples_main_surround, m_samples_auxA_left, m_samples_auxA_right, m_samples_auxA_surround, m_samples_auxB_left, m_samples_auxB_right, m_samples_auxB_surround}; @@ -391,7 +391,7 @@ void AXUCode::SetupProcessing(u32 init_addr) void AXUCode::DownloadAndMixWithVolume(u32 addr, u16 vol_main, u16 vol_auxa, u16 vol_auxb) { - int* buffers_main[3] = {m_samples_left, m_samples_right, m_samples_surround}; + int* buffers_main[3] = {m_samples_main_left, m_samples_main_right, m_samples_main_surround}; int* buffers_auxa[3] = {m_samples_auxA_left, m_samples_auxA_right, m_samples_auxA_surround}; int* buffers_auxb[3] = {m_samples_auxB_left, m_samples_auxB_right, m_samples_auxB_surround}; int** buffers[3] = {buffers_main, buffers_auxa, buffers_auxb}; @@ -424,9 +424,9 @@ void AXUCode::ProcessPBList(u32 pb_addr) while (pb_addr) { - AXBuffers buffers = {{m_samples_left, m_samples_right, m_samples_surround, m_samples_auxA_left, - m_samples_auxA_right, m_samples_auxA_surround, m_samples_auxB_left, - m_samples_auxB_right, m_samples_auxB_surround}}; + AXBuffers buffers = {{m_samples_main_left, m_samples_main_right, m_samples_main_surround, + m_samples_auxA_left, m_samples_auxA_right, m_samples_auxA_surround, + m_samples_auxB_left, m_samples_auxB_right, m_samples_auxB_surround}}; ReadPB(pb_addr, pb, m_crc); @@ -481,11 +481,11 @@ void AXUCode::MixAUXSamples(int aux_id, u32 write_addr, u32 read_addr) // Then, we read the new temp from the CPU and add to our current // temp. int* ptr = (int*)HLEMemory_Get_Pointer(read_addr); - for (auto& sample : m_samples_left) + for (auto& sample : m_samples_main_left) sample += (int)Common::swap32(*ptr++); - for (auto& sample : m_samples_right) + for (auto& sample : m_samples_main_right) sample += (int)Common::swap32(*ptr++); - for (auto& sample : m_samples_surround) + for (auto& sample : m_samples_main_surround) sample += (int)Common::swap32(*ptr++); } @@ -495,9 +495,9 @@ void AXUCode::UploadLRS(u32 dst_addr) for (u32 i = 0; i < 5 * 32; ++i) { - buffers[0][i] = Common::swap32(m_samples_left[i]); - buffers[1][i] = Common::swap32(m_samples_right[i]); - buffers[2][i] = Common::swap32(m_samples_surround[i]); + buffers[0][i] = Common::swap32(m_samples_main_left[i]); + buffers[1][i] = Common::swap32(m_samples_main_right[i]); + buffers[2][i] = Common::swap32(m_samples_main_surround[i]); } memcpy(HLEMemory_Get_Pointer(dst_addr), buffers, sizeof(buffers)); } @@ -508,9 +508,9 @@ void AXUCode::SetMainLR(u32 src_addr) for (u32 i = 0; i < 5 * 32; ++i) { int samp = (int)Common::swap32(*ptr++); - m_samples_left[i] = samp; - m_samples_right[i] = samp; - m_samples_surround[i] = 0; + m_samples_main_left[i] = samp; + m_samples_main_right[i] = samp; + m_samples_main_surround[i] = 0; } } @@ -520,8 +520,8 @@ void AXUCode::RunCompressor(u16 threshold, u16 release_frames, u32 table_addr, u bool triggered = false; for (u32 i = 0; i < 32 * millis; ++i) { - if (std::abs(m_samples_left[i]) > int(threshold) || - std::abs(m_samples_right[i]) > int(threshold)) + if (std::abs(m_samples_main_left[i]) > int(threshold) || + std::abs(m_samples_main_right[i]) > int(threshold)) { triggered = true; break; @@ -555,8 +555,8 @@ void AXUCode::RunCompressor(u16 threshold, u16 release_frames, u32 table_addr, u for (u32 i = 0; i < 32 * millis; ++i) { u16 coef = Common::swap16(*ramp++); - m_samples_left[i] = (s64(m_samples_left[i]) * coef) >> 15; - m_samples_right[i] = (s64(m_samples_right[i]) * coef) >> 15; + m_samples_main_left[i] = (s64(m_samples_main_left[i]) * coef) >> 15; + m_samples_main_right[i] = (s64(m_samples_main_right[i]) * coef) >> 15; } } @@ -565,7 +565,7 @@ void AXUCode::OutputSamples(u32 lr_addr, u32 surround_addr) int surround_buffer[5 * 32]; for (u32 i = 0; i < 5 * 32; ++i) - surround_buffer[i] = Common::swap32(m_samples_surround[i]); + surround_buffer[i] = Common::swap32(m_samples_main_surround[i]); memcpy(HLEMemory_Get_Pointer(surround_addr), surround_buffer, sizeof(surround_buffer)); // 32 samples per ms, 5 ms, 2 channels @@ -574,8 +574,8 @@ void AXUCode::OutputSamples(u32 lr_addr, u32 surround_addr) // Output samples clamped to 16 bits and interlaced RLRLRLRLRL... for (u32 i = 0; i < 5 * 32; ++i) { - int left = std::clamp(m_samples_left[i], -32767, 32767); - int right = std::clamp(m_samples_right[i], -32767, 32767); + int left = std::clamp(m_samples_main_left[i], -32767, 32767); + int right = std::clamp(m_samples_main_right[i], -32767, 32767); buffer[2 * i + 0] = Common::swap16(right); buffer[2 * i + 1] = Common::swap16(left); @@ -599,13 +599,13 @@ void AXUCode::MixAUXBLR(u32 ul_addr, u32 dl_addr) { int samp = Common::swap32(*ptr++); m_samples_auxB_left[i] = samp; - m_samples_left[i] += samp; + m_samples_main_left[i] += samp; } for (u32 i = 0; i < 5 * 32; ++i) { int samp = Common::swap32(*ptr++); m_samples_auxB_right[i] = samp; - m_samples_right[i] += samp; + m_samples_main_right[i] += samp; } } @@ -615,9 +615,9 @@ void AXUCode::SetOppositeLR(u32 src_addr) for (u32 i = 0; i < 5 * 32; ++i) { int inp = Common::swap32(*ptr++); - m_samples_left[i] = -inp; - m_samples_right[i] = inp; - m_samples_surround[i] = 0; + m_samples_main_left[i] = -inp; + m_samples_main_right[i] = inp; + m_samples_main_surround[i] = 0; } } @@ -646,8 +646,8 @@ void AXUCode::SendAUXAndMix(u32 main_auxa_up, u32 auxb_s_up, u32 main_l_dl, u32 // Download buffers and addresses const std::array dl_buffers{ - m_samples_left, - m_samples_right, + m_samples_main_left, + m_samples_main_right, m_samples_auxB_left, m_samples_auxB_right, }; @@ -745,9 +745,9 @@ void AXUCode::DoAXState(PointerWrap& p) p.Do(m_cmdlist); p.Do(m_cmdlist_size); - p.Do(m_samples_left); - p.Do(m_samples_right); - p.Do(m_samples_surround); + p.Do(m_samples_main_left); + p.Do(m_samples_main_right); + p.Do(m_samples_main_surround); p.Do(m_samples_auxA_left); p.Do(m_samples_auxA_right); p.Do(m_samples_auxA_surround); diff --git a/Source/Core/Core/HW/DSPHLE/UCodes/AX.h b/Source/Core/Core/HW/DSPHLE/UCodes/AX.h index a9ddab8e08..9e37b39035 100644 --- a/Source/Core/Core/HW/DSPHLE/UCodes/AX.h +++ b/Source/Core/Core/HW/DSPHLE/UCodes/AX.h @@ -82,9 +82,9 @@ protected: }; // 32 * 5 because 32 samples per millisecond, for max 5 milliseconds. - int m_samples_left[32 * 5]{}; - int m_samples_right[32 * 5]{}; - int m_samples_surround[32 * 5]{}; + int m_samples_main_left[32 * 5]{}; + int m_samples_main_right[32 * 5]{}; + int m_samples_main_surround[32 * 5]{}; int m_samples_auxA_left[32 * 5]{}; int m_samples_auxA_right[32 * 5]{}; int m_samples_auxA_surround[32 * 5]{}; diff --git a/Source/Core/Core/HW/DSPHLE/UCodes/AXStructs.h b/Source/Core/Core/HW/DSPHLE/UCodes/AXStructs.h index bbb8e67770..74f1338dec 100644 --- a/Source/Core/Core/HW/DSPHLE/UCodes/AXStructs.h +++ b/Source/Core/Core/HW/DSPHLE/UCodes/AXStructs.h @@ -7,87 +7,45 @@ namespace DSP::HLE { +struct VolumeData +{ + u16 volume; + u16 volume_delta; +}; + struct PBMixer { - u16 left; - u16 left_delta; - u16 right; - u16 right_delta; - - u16 auxA_left; - u16 auxA_left_delta; - u16 auxA_right; - u16 auxA_right_delta; - - u16 auxB_left; - u16 auxB_left_delta; - u16 auxB_right; - u16 auxB_right_delta; - - u16 auxB_surround; - u16 auxB_surround_delta; - u16 surround; - u16 surround_delta; - u16 auxA_surround; - u16 auxA_surround_delta; + VolumeData main_left, main_right; + VolumeData auxA_left, auxA_right; + VolumeData auxB_left, auxB_right; + // This somewhat strange-looking order of surround channels + // allows the ucode to use the 2-channel IROM function mix_two_add() + // when mixing (auxb_s and main_s) or (main_s and auxa_s). + VolumeData auxB_surround; + VolumeData main_surround; + VolumeData auxA_surround; }; struct PBMixerWii { - // volume mixing values in .15, 0x8000 = ca. 1.0 - u16 left; - u16 left_delta; - u16 right; - u16 right_delta; - - u16 auxA_left; - u16 auxA_left_delta; - u16 auxA_right; - u16 auxA_right_delta; - - u16 auxB_left; - u16 auxB_left_delta; - u16 auxB_right; - u16 auxB_right_delta; - + VolumeData main_left, main_right; + VolumeData auxA_left, auxA_right; + VolumeData auxB_left, auxB_right; // Note: the following elements usage changes a little in DPL2 mode // TODO: implement and comment it in the mixer - u16 auxC_left; - u16 auxC_left_delta; - u16 auxC_right; - u16 auxC_right_delta; - - u16 surround; - u16 surround_delta; - u16 auxA_surround; - u16 auxA_surround_delta; - u16 auxB_surround; - u16 auxB_surround_delta; - u16 auxC_surround; - u16 auxC_surround_delta; + VolumeData auxC_left, auxC_right; + VolumeData main_surround; + VolumeData auxA_surround; + VolumeData auxB_surround; + VolumeData auxC_surround; }; struct PBMixerWM { - u16 main0; - u16 main0_delta; - u16 aux0; - u16 aux0_delta; - - u16 main1; - u16 main1_delta; - u16 aux1; - u16 aux1_delta; - - u16 main2; - u16 main2_delta; - u16 aux2; - u16 aux2_delta; - - u16 main3; - u16 main3_delta; - u16 aux3; - u16 aux3_delta; + VolumeData main0, aux0; + VolumeData main1, aux1; + VolumeData main2, aux2; + VolumeData main3, aux3; }; struct PBInitialTimeDelay diff --git a/Source/Core/Core/HW/DSPHLE/UCodes/AXVoice.h b/Source/Core/Core/HW/DSPHLE/UCodes/AXVoice.h index f40f17cb6d..a5fa30f165 100644 --- a/Source/Core/Core/HW/DSPHLE/UCodes/AXVoice.h +++ b/Source/Core/Core/HW/DSPHLE/UCodes/AXVoice.h @@ -51,9 +51,9 @@ union AXBuffers { struct { - int* left; - int* right; - int* surround; + int* main_left; + int* main_right; + int* main_surround; int* auxA_left; int* auxA_right; @@ -361,10 +361,10 @@ void GetInputSamples(PB_TYPE& pb, s16* samples, u16 count, const s16* coeffs) } // Add samples to an output buffer, with optional volume ramping. -void MixAdd(int* out, const s16* input, u32 count, u16* pvol, s16* dpop, bool ramp) +void MixAdd(int* out, const s16* input, u32 count, VolumeData* vd, s16* dpop, bool ramp) { - u16& volume = pvol[0]; - u16 volume_delta = pvol[1]; + u16& volume = vd->volume; + u16 volume_delta = vd->volume_delta; // If volume ramping is disabled, set volume_delta to 0. That way, the // mixing loop can avoid testing if volume ramping is enabled at each step, @@ -411,8 +411,8 @@ void ProcessVoice(PB_TYPE& pb, const AXBuffers& buffers, u16 count, AXMixControl // Apply a global volume ramp using the volume envelope parameters. for (u32 i = 0; i < count; ++i) { - samples[i] = std::clamp(((s32)samples[i] * pb.vol_env.cur_volume) >> 15, -32767, - 32767); // -32768 ? + const s32 sample = ((s32)samples[i] * pb.vol_env.cur_volume) >> 15; + samples[i] = std::clamp(sample, -32767, 32767); // -32768 ? pb.vol_env.cur_volume += pb.vol_env.cur_volume_delta; } @@ -429,11 +429,12 @@ void ProcessVoice(PB_TYPE& pb, const AXBuffers& buffers, u16 count, AXMixControl #define RAMP_ON(C) (0 != (mctrl & MIX_##C##_RAMP)) if (MIX_ON(L)) - MixAdd(buffers.left, samples, count, &pb.mixer.left, &pb.dpop.left, RAMP_ON(L)); + MixAdd(buffers.main_left, samples, count, &pb.mixer.main_left, &pb.dpop.left, RAMP_ON(L)); if (MIX_ON(R)) - MixAdd(buffers.right, samples, count, &pb.mixer.right, &pb.dpop.right, RAMP_ON(R)); + MixAdd(buffers.main_right, samples, count, &pb.mixer.main_right, &pb.dpop.right, RAMP_ON(R)); if (MIX_ON(S)) - MixAdd(buffers.surround, samples, count, &pb.mixer.surround, &pb.dpop.surround, RAMP_ON(S)); + MixAdd(buffers.main_surround, samples, count, &pb.mixer.main_surround, &pb.dpop.surround, + RAMP_ON(S)); if (MIX_ON(AUXA_L)) MixAdd(buffers.auxA_left, samples, count, &pb.mixer.auxA_left, &pb.dpop.auxA_left, diff --git a/Source/Core/Core/HW/DSPHLE/UCodes/AXWii.cpp b/Source/Core/Core/HW/DSPHLE/UCodes/AXWii.cpp index a960f5c6c7..e7a50c52cf 100644 --- a/Source/Core/Core/HW/DSPHLE/UCodes/AXWii.cpp +++ b/Source/Core/Core/HW/DSPHLE/UCodes/AXWii.cpp @@ -265,7 +265,7 @@ void AXWiiUCode::SetupProcessing(u32 init_addr) int* ptr; u32 samples; } buffers[] = { - {m_samples_left, 32}, {m_samples_right, 32}, {m_samples_surround, 32}, + {m_samples_main_left, 32}, {m_samples_main_right, 32}, {m_samples_main_surround, 32}, {m_samples_auxA_left, 32}, {m_samples_auxA_right, 32}, {m_samples_auxA_surround, 32}, {m_samples_auxB_left, 32}, {m_samples_auxB_right, 32}, {m_samples_auxB_surround, 32}, {m_samples_auxC_left, 32}, {m_samples_auxC_right, 32}, {m_samples_auxC_surround, 32}, @@ -306,8 +306,8 @@ void AXWiiUCode::AddToLR(u32 val_addr, bool neg) if (neg) val = -val; - m_samples_left[i] += val; - m_samples_right[i] += val; + m_samples_main_left[i] += val; + m_samples_main_right[i] += val; } } @@ -317,12 +317,12 @@ void AXWiiUCode::AddSubToLR(u32 val_addr) for (int i = 0; i < 32 * 3; ++i) { int val = (int)Common::swap32(*ptr++); - m_samples_left[i] += val; + m_samples_main_left[i] += val; } for (int i = 0; i < 32 * 3; ++i) { int val = (int)Common::swap32(*ptr++); - m_samples_right[i] -= val; + m_samples_main_right[i] -= val; } } @@ -453,7 +453,7 @@ void AXWiiUCode::ProcessPBList(u32 pb_addr) while (pb_addr) { - AXBuffers buffers = {{m_samples_left, m_samples_right, m_samples_surround, + AXBuffers buffers = {{m_samples_main_left, m_samples_main_right, m_samples_main_surround, m_samples_auxA_left, m_samples_auxA_right, m_samples_auxA_surround, m_samples_auxB_left, m_samples_auxB_right, m_samples_auxB_surround, m_samples_auxC_left, m_samples_auxC_right, m_samples_auxC_surround, @@ -498,9 +498,9 @@ void AXWiiUCode::MixAUXSamples(int aux_id, u32 write_addr, u32 read_addr, u16 vo m_last_aux_volumes[aux_id] = volume; std::array main_buffers{ - m_samples_left, - m_samples_right, - m_samples_surround, + m_samples_main_left, + m_samples_main_right, + m_samples_main_surround, }; std::array buffers{}; @@ -578,7 +578,8 @@ void AXWiiUCode::UploadAUXMixLRSC(int aux_id, u32* addresses, u16 volume) GenerateVolumeRamp(volume_ramp, m_last_aux_volumes[aux_id], volume, 96); m_last_aux_volumes[aux_id] = volume; - int* mix_dest[4] = {m_samples_left, m_samples_right, m_samples_surround, m_samples_auxC_left}; + int* mix_dest[4] = {m_samples_main_left, m_samples_main_right, m_samples_main_surround, + m_samples_auxC_left}; for (u32 mix_i = 0; mix_i < 4; ++mix_i) { int* dl_ptr = (int*)HLEMemory_Get_Pointer(addresses[2 + mix_i]); @@ -603,7 +604,7 @@ void AXWiiUCode::OutputSamples(u32 lr_addr, u32 surround_addr, u16 volume, bool std::array upload_buffer{}; for (size_t i = 0; i < upload_buffer.size(); ++i) - upload_buffer[i] = Common::swap32(m_samples_surround[i]); + upload_buffer[i] = Common::swap32(m_samples_main_surround[i]); memcpy(HLEMemory_Get_Pointer(surround_addr), upload_buffer.data(), sizeof(upload_buffer)); if (upload_auxc) @@ -617,22 +618,22 @@ void AXWiiUCode::OutputSamples(u32 lr_addr, u32 surround_addr, u16 volume, bool // Clamp internal buffers to 16 bits. for (size_t i = 0; i < volume_ramp.size(); ++i) { - int left = m_samples_left[i]; - int right = m_samples_right[i]; + int left = m_samples_main_left[i]; + int right = m_samples_main_right[i]; // Apply global volume. Cast to s64 to avoid overflow. left = ((s64)left * volume_ramp[i]) >> 15; right = ((s64)right * volume_ramp[i]) >> 15; - m_samples_left[i] = std::clamp(left, -32767, 32767); - m_samples_right[i] = std::clamp(right, -32767, 32767); + m_samples_main_left[i] = std::clamp(left, -32767, 32767); + m_samples_main_right[i] = std::clamp(right, -32767, 32767); } std::array buffer; for (size_t i = 0; i < 3 * 32; ++i) { - buffer[2 * i] = Common::swap16(m_samples_right[i]); - buffer[2 * i + 1] = Common::swap16(m_samples_left[i]); + buffer[2 * i] = Common::swap16(m_samples_main_right[i]); + buffer[2 * i + 1] = Common::swap16(m_samples_main_left[i]); } memcpy(HLEMemory_Get_Pointer(lr_addr), buffer.data(), sizeof(buffer));