From f9f9447013af71920a1826901f50e7d09505d8a7 Mon Sep 17 00:00:00 2001 From: Stenzek <stenzek@gmail.com> Date: Fri, 29 Mar 2024 15:08:12 +1000 Subject: [PATCH] SPU: Ignore End+Mute flag for noise channels Fixes the noise effects cutting out too early in Motor Toon Grand Prix. --- src/core/spu.cpp | 154 +++++++++++++++++++++++++---------------------- 1 file changed, 81 insertions(+), 73 deletions(-) diff --git a/src/core/spu.cpp b/src/core/spu.cpp index 51dab9cd6..b44c9c9e5 100644 --- a/src/core/spu.cpp +++ b/src/core/spu.cpp @@ -430,10 +430,10 @@ void SPU::Initialize() void SPU::CreateOutputStream() { - Log_InfoPrintf( - "Creating '%s' audio stream, sample rate = %u, channels = %u, buffer = %u, latency = %u, stretching = %s", - Settings::GetAudioBackendName(g_settings.audio_backend), SAMPLE_RATE, NUM_CHANNELS, g_settings.audio_buffer_ms, - g_settings.audio_output_latency_ms, AudioStream::GetStretchModeName(g_settings.audio_stretch_mode)); + Log_InfoFmt("Creating '{}' audio stream, sample rate = {}, channels = {}, buffer = {}, latency = {}, stretching = {}", + Settings::GetAudioBackendName(g_settings.audio_backend), static_cast<u32>(SAMPLE_RATE), + static_cast<u32>(NUM_CHANNELS), g_settings.audio_buffer_ms, g_settings.audio_output_latency_ms, + AudioStream::GetStretchModeName(g_settings.audio_stretch_mode)); s_audio_stream = Host::CreateAudioStream(g_settings.audio_backend, SAMPLE_RATE, NUM_CHANNELS, g_settings.audio_buffer_ms, @@ -656,28 +656,28 @@ u16 SPU::ReadRegister(u32 offset) return s_reverb_registers.mBASE; case 0x1F801DA4 - SPU_BASE: - Log_TracePrintf("SPU IRQ address -> 0x%04X", ZeroExtend32(s_irq_address)); + Log_TraceFmt("SPU IRQ address -> 0x{:04X}", s_irq_address); return s_irq_address; case 0x1F801DA6 - SPU_BASE: - Log_TracePrintf("SPU transfer address register -> 0x%04X", ZeroExtend32(s_transfer_address_reg)); + Log_TraceFmt("SPU transfer address register -> 0x{:04X}", s_transfer_address_reg); return s_transfer_address_reg; case 0x1F801DA8 - SPU_BASE: - Log_TracePrintf("SPU transfer data register read"); + Log_TraceFmt("SPU transfer data register read"); return UINT16_C(0xFFFF); case 0x1F801DAA - SPU_BASE: - Log_TracePrintf("SPU control register -> 0x%04X", ZeroExtend32(s_SPUCNT.bits)); + Log_TraceFmt("SPU control register -> 0x{:04X}", s_SPUCNT.bits); return s_SPUCNT.bits; case 0x1F801DAC - SPU_BASE: - Log_TracePrintf("SPU transfer control register -> 0x%04X", ZeroExtend32(s_transfer_control.bits)); + Log_TraceFmt("SPU transfer control register -> 0x{:04X}", s_transfer_control.bits); return s_transfer_control.bits; case 0x1F801DAE - SPU_BASE: GeneratePendingSamples(); - Log_TracePrintf("SPU status register -> 0x%04X", ZeroExtend32(s_SPUCNT.bits)); + Log_TraceFmt("SPU status register -> 0x{:04X}", s_SPUCNT.bits); return s_SPUSTAT.bits; case 0x1F801DB0 - SPU_BASE: @@ -718,7 +718,7 @@ u16 SPU::ReadRegister(u32 offset) return s_voices[voice_index].right_volume.current_level; } - Log_DevPrintf("Unknown SPU register read: offset 0x%X (address 0x%08X)", offset, offset | SPU_BASE); + Log_DevFmt("Unknown SPU register read: offset 0x{:X} (address 0x{:08X})", offset, offset | SPU_BASE); return UINT16_C(0xFFFF); } } @@ -730,7 +730,7 @@ void SPU::WriteRegister(u32 offset, u16 value) { case 0x1F801D80 - SPU_BASE: { - Log_DebugPrintf("SPU main volume left <- 0x%04X", ZeroExtend32(value)); + Log_DebugFmt("SPU main volume left <- 0x{:04X}", value); GeneratePendingSamples(); s_main_volume_left_reg.bits = value; s_main_volume_left.Reset(s_main_volume_left_reg); @@ -739,7 +739,7 @@ void SPU::WriteRegister(u32 offset, u16 value) case 0x1F801D82 - SPU_BASE: { - Log_DebugPrintf("SPU main volume right <- 0x%04X", ZeroExtend32(value)); + Log_DebugFmt("SPU main volume right <- 0x{:04X}", value); GeneratePendingSamples(); s_main_volume_right_reg.bits = value; s_main_volume_right.Reset(s_main_volume_right_reg); @@ -748,7 +748,7 @@ void SPU::WriteRegister(u32 offset, u16 value) case 0x1F801D84 - SPU_BASE: { - Log_DebugPrintf("SPU reverb output volume left <- 0x%04X", ZeroExtend32(value)); + Log_DebugFmt("SPU reverb output volume left <- 0x{:04X}", value); GeneratePendingSamples(); s_reverb_registers.vLOUT = value; return; @@ -756,7 +756,7 @@ void SPU::WriteRegister(u32 offset, u16 value) case 0x1F801D86 - SPU_BASE: { - Log_DebugPrintf("SPU reverb output volume right <- 0x%04X", ZeroExtend32(value)); + Log_DebugFmt("SPU reverb output volume right <- 0x{:04X}", value); GeneratePendingSamples(); s_reverb_registers.vROUT = value; return; @@ -764,7 +764,7 @@ void SPU::WriteRegister(u32 offset, u16 value) case 0x1F801D88 - SPU_BASE: { - Log_DebugPrintf("SPU key on low <- 0x%04X", ZeroExtend32(value)); + Log_DebugFmt("SPU key on low <- 0x{:04X}", value); GeneratePendingSamples(); s_key_on_register = (s_key_on_register & 0xFFFF0000) | ZeroExtend32(value); } @@ -772,7 +772,7 @@ void SPU::WriteRegister(u32 offset, u16 value) case 0x1F801D8A - SPU_BASE: { - Log_DebugPrintf("SPU key on high <- 0x%04X", ZeroExtend32(value)); + Log_DebugFmt("SPU key on high <- 0x{:04X}", value); GeneratePendingSamples(); s_key_on_register = (s_key_on_register & 0x0000FFFF) | (ZeroExtend32(value) << 16); } @@ -780,7 +780,7 @@ void SPU::WriteRegister(u32 offset, u16 value) case 0x1F801D8C - SPU_BASE: { - Log_DebugPrintf("SPU key off low <- 0x%04X", ZeroExtend32(value)); + Log_DebugFmt("SPU key off low <- 0x{:04X}", value); GeneratePendingSamples(); s_key_off_register = (s_key_off_register & 0xFFFF0000) | ZeroExtend32(value); } @@ -788,7 +788,7 @@ void SPU::WriteRegister(u32 offset, u16 value) case 0x1F801D8E - SPU_BASE: { - Log_DebugPrintf("SPU key off high <- 0x%04X", ZeroExtend32(value)); + Log_DebugFmt("SPU key off high <- 0x{:04X}", value); GeneratePendingSamples(); s_key_off_register = (s_key_off_register & 0x0000FFFF) | (ZeroExtend32(value) << 16); } @@ -798,7 +798,7 @@ void SPU::WriteRegister(u32 offset, u16 value) { GeneratePendingSamples(); s_pitch_modulation_enable_register = (s_pitch_modulation_enable_register & 0xFFFF0000) | ZeroExtend32(value); - Log_DebugPrintf("SPU pitch modulation enable register <- 0x%08X", s_pitch_modulation_enable_register); + Log_DebugFmt("SPU pitch modulation enable register <- 0x{:08X}", s_pitch_modulation_enable_register); } break; @@ -807,13 +807,13 @@ void SPU::WriteRegister(u32 offset, u16 value) GeneratePendingSamples(); s_pitch_modulation_enable_register = (s_pitch_modulation_enable_register & 0x0000FFFF) | (ZeroExtend32(value) << 16); - Log_DebugPrintf("SPU pitch modulation enable register <- 0x%08X", s_pitch_modulation_enable_register); + Log_DebugFmt("SPU pitch modulation enable register <- 0x{:08X}", s_pitch_modulation_enable_register); } break; case 0x1F801D94 - SPU_BASE: { - Log_DebugPrintf("SPU noise mode register <- 0x%04X", ZeroExtend32(value)); + Log_DebugFmt("SPU noise mode register <- 0x{:04X}", value); GeneratePendingSamples(); s_noise_mode_register = (s_noise_mode_register & 0xFFFF0000) | ZeroExtend32(value); } @@ -821,7 +821,7 @@ void SPU::WriteRegister(u32 offset, u16 value) case 0x1F801D96 - SPU_BASE: { - Log_DebugPrintf("SPU noise mode register <- 0x%04X", ZeroExtend32(value)); + Log_DebugFmt("SPU noise mode register <- 0x{:04X}", value); GeneratePendingSamples(); s_noise_mode_register = (s_noise_mode_register & 0x0000FFFF) | (ZeroExtend32(value) << 16); } @@ -829,7 +829,7 @@ void SPU::WriteRegister(u32 offset, u16 value) case 0x1F801D98 - SPU_BASE: { - Log_DebugPrintf("SPU reverb on register <- 0x%04X", ZeroExtend32(value)); + Log_DebugFmt("SPU reverb on register <- 0x{:04X}", value); GeneratePendingSamples(); s_reverb_on_register = (s_reverb_on_register & 0xFFFF0000) | ZeroExtend32(value); } @@ -837,7 +837,7 @@ void SPU::WriteRegister(u32 offset, u16 value) case 0x1F801D9A - SPU_BASE: { - Log_DebugPrintf("SPU reverb on register <- 0x%04X", ZeroExtend32(value)); + Log_DebugFmt("SPU reverb on register <- 0x{:04X}", value); GeneratePendingSamples(); s_reverb_on_register = (s_reverb_on_register & 0x0000FFFF) | (ZeroExtend32(value) << 16); } @@ -845,7 +845,7 @@ void SPU::WriteRegister(u32 offset, u16 value) case 0x1F801DA2 - SPU_BASE: { - Log_DebugPrintf("SPU reverb base address < 0x%04X", ZeroExtend32(value)); + Log_DebugFmt("SPU reverb base address < 0x{:04X}", value); GeneratePendingSamples(); s_reverb_registers.mBASE = value; s_reverb_base_address = ZeroExtend32(value << 2) & 0x3FFFFu; @@ -855,7 +855,7 @@ void SPU::WriteRegister(u32 offset, u16 value) case 0x1F801DA4 - SPU_BASE: { - Log_DebugPrintf("SPU IRQ address register <- 0x%04X", ZeroExtend32(value)); + Log_DebugFmt("SPU IRQ address register <- 0x{:04X}", value); GeneratePendingSamples(); s_irq_address = value; @@ -867,14 +867,14 @@ void SPU::WriteRegister(u32 offset, u16 value) case 0x1F801DA6 - SPU_BASE: { - Log_DebugPrintf("SPU transfer address register <- 0x%04X", ZeroExtend32(value)); + Log_DebugFmt("SPU transfer address register <- 0x{:04X}", value); s_transfer_event->InvokeEarly(); s_transfer_address_reg = value; s_transfer_address = ZeroExtend32(value) * 8; if (IsRAMIRQTriggerable() && CheckRAMIRQ(s_transfer_address)) { - Log_DebugPrintf("Trigger IRQ @ %08X %04X from transfer address reg set", s_transfer_address, - s_transfer_address / 8); + Log_DebugFmt("Trigger IRQ @ {:08X} {:04X} from transfer address reg set", s_transfer_address, + s_transfer_address / 8); TriggerRAMIRQ(); } return; @@ -882,8 +882,8 @@ void SPU::WriteRegister(u32 offset, u16 value) case 0x1F801DA8 - SPU_BASE: { - Log_TracePrintf("SPU transfer data register <- 0x%04X (RAM offset 0x%08X)", ZeroExtend32(value), - s_transfer_address); + Log_TraceFmt("SPU transfer data register <- 0x{:04X} (RAM offset 0x{:08X})", ZeroExtend32(value), + s_transfer_address); ManualTransferWrite(value); return; @@ -891,7 +891,7 @@ void SPU::WriteRegister(u32 offset, u16 value) case 0x1F801DAA - SPU_BASE: { - Log_DebugPrintf("SPU control register <- 0x%04X", ZeroExtend32(value)); + Log_DebugFmt("SPU control register <- 0x{:04X}", value); GeneratePendingSamples(); const SPUCNT new_value{value}; @@ -905,14 +905,14 @@ void SPU::WriteRegister(u32 offset, u16 value) { // I would guess on the console it would gradually write the FIFO out. Hopefully nothing relies on this // level of timing granularity if we force it all out here. - Log_WarningPrintf("Draining write SPU transfer FIFO with %u bytes left", s_transfer_fifo.GetSize()); + Log_WarningFmt("Draining write SPU transfer FIFO with {} bytes left", s_transfer_fifo.GetSize()); TickCount ticks = std::numeric_limits<TickCount>::max(); ExecuteFIFOWriteToRAM(ticks); DebugAssert(s_transfer_fifo.IsEmpty()); } else { - Log_DebugPrintf("Clearing read SPU transfer FIFO with %u bytes left", s_transfer_fifo.GetSize()); + Log_DebugFmt("Clearing read SPU transfer FIFO with {} bytes left", s_transfer_fifo.GetSize()); s_transfer_fifo.Clear(); } } @@ -947,14 +947,14 @@ void SPU::WriteRegister(u32 offset, u16 value) case 0x1F801DAC - SPU_BASE: { - Log_DebugPrintf("SPU transfer control register <- 0x%04X", ZeroExtend32(value)); + Log_DebugFmt("SPU transfer control register <- 0x{:04X}", value); s_transfer_control.bits = value; return; } case 0x1F801DB0 - SPU_BASE: { - Log_DebugPrintf("SPU left cd audio register <- 0x%04X", ZeroExtend32(value)); + Log_DebugFmt("SPU left cd audio register <- 0x{:04X}", value); GeneratePendingSamples(); s_cd_audio_volume_left = value; } @@ -962,7 +962,7 @@ void SPU::WriteRegister(u32 offset, u16 value) case 0x1F801DB2 - SPU_BASE: { - Log_DebugPrintf("SPU right cd audio register <- 0x%04X", ZeroExtend32(value)); + Log_DebugFmt("SPU right cd audio register <- 0x{:04X}", value); GeneratePendingSamples(); s_cd_audio_volume_right = value; } @@ -971,7 +971,7 @@ void SPU::WriteRegister(u32 offset, u16 value) case 0x1F801DB4 - SPU_BASE: { // External volumes aren't used, so don't bother syncing. - Log_DebugPrintf("SPU left external volume register <- 0x%04X", ZeroExtend32(value)); + Log_DebugFmt("SPU left external volume register <- 0x{:04X}", value); s_external_volume_left = value; } break; @@ -979,7 +979,7 @@ void SPU::WriteRegister(u32 offset, u16 value) case 0x1F801DB6 - SPU_BASE: { // External volumes aren't used, so don't bother syncing. - Log_DebugPrintf("SPU right external volume register <- 0x%04X", ZeroExtend32(value)); + Log_DebugFmt("SPU right external volume register <- 0x{:04X}", value); s_external_volume_right = value; } break; @@ -1001,14 +1001,14 @@ void SPU::WriteRegister(u32 offset, u16 value) if (offset >= (0x1F801DC0 - SPU_BASE) && offset < (0x1F801E00 - SPU_BASE)) { const u32 reg = (offset - (0x1F801DC0 - SPU_BASE)) / 2; - Log_DebugPrintf("SPU reverb register %u <- 0x%04X", reg, value); + Log_DebugFmt("SPU reverb register {} <- 0x{:04X}", reg, value); GeneratePendingSamples(); s_reverb_registers.rev[reg] = value; return; } - Log_DevPrintf("Unknown SPU register write: offset 0x%X (address 0x%08X) value 0x%04X", offset, offset | SPU_BASE, - ZeroExtend32(value)); + Log_DevFmt("Unknown SPU register write: offset 0x{:X} (address 0x{:08X}) value 0x{:04X}", offset, + offset | SPU_BASE, value); return; } } @@ -1025,7 +1025,7 @@ u16 SPU::ReadVoiceRegister(u32 offset) if (reg_index >= 6 && (voice.IsOn() || s_key_on_register & (1u << voice_index))) GeneratePendingSamples(); - Log_TracePrintf("Read voice %u register %u -> 0x%02X", voice_index, reg_index, voice.regs.index[reg_index]); + Log_TraceFmt("Read voice {} register {} -> 0x{:02X}", voice_index, reg_index, voice.regs.index[reg_index]); return voice.regs.index[reg_index]; } @@ -1044,7 +1044,7 @@ void SPU::WriteVoiceRegister(u32 offset, u16 value) { case 0x00: // volume left { - Log_DebugPrintf("SPU voice %u volume left <- 0x%04X", voice_index, value); + Log_DebugFmt("SPU voice {} volume left <- 0x{:04X}", voice_index, value); voice.regs.volume_left.bits = value; voice.left_volume.Reset(voice.regs.volume_left); } @@ -1052,7 +1052,7 @@ void SPU::WriteVoiceRegister(u32 offset, u16 value) case 0x02: // volume right { - Log_DebugPrintf("SPU voice %u volume right <- 0x%04X", voice_index, value); + Log_DebugFmt("SPU voice {} volume right <- 0x{:04X}", voice_index, value); voice.regs.volume_right.bits = value; voice.right_volume.Reset(voice.regs.volume_right); } @@ -1060,21 +1060,21 @@ void SPU::WriteVoiceRegister(u32 offset, u16 value) case 0x04: // sample rate { - Log_DebugPrintf("SPU voice %u ADPCM sample rate <- 0x%04X", voice_index, value); + Log_DebugFmt("SPU voice {} ADPCM sample rate <- 0x{:04X}", voice_index, value); voice.regs.adpcm_sample_rate = value; } break; case 0x06: // start address { - Log_DebugPrintf("SPU voice %u ADPCM start address <- 0x%04X", voice_index, value); + Log_DebugFmt("SPU voice {} ADPCM start address <- 0x{:04X}", voice_index, value); voice.regs.adpcm_start_address = value; } break; case 0x08: // adsr low { - Log_DebugPrintf("SPU voice %u ADSR low <- 0x%04X (was 0x%04X)", voice_index, value, voice.regs.adsr.bits_low); + Log_DebugFmt("SPU voice {} ADSR low <- 0x{:04X} (was 0x{:04X})", voice_index, value, voice.regs.adsr.bits_low); voice.regs.adsr.bits_low = value; if (voice.IsOn()) voice.UpdateADSREnvelope(); @@ -1083,7 +1083,7 @@ void SPU::WriteVoiceRegister(u32 offset, u16 value) case 0x0A: // adsr high { - Log_DebugPrintf("SPU voice %u ADSR high <- 0x%04X (was 0x%04X)", voice_index, value, voice.regs.adsr.bits_low); + Log_DebugFmt("SPU voice {} ADSR high <- 0x{:04X} (was 0x{:04X})", voice_index, value, voice.regs.adsr.bits_low); voice.regs.adsr.bits_high = value; if (voice.IsOn()) voice.UpdateADSREnvelope(); @@ -1092,7 +1092,7 @@ void SPU::WriteVoiceRegister(u32 offset, u16 value) case 0x0C: // adsr volume { - Log_DebugPrintf("SPU voice %u ADSR volume <- 0x%04X (was 0x%04X)", voice_index, value, voice.regs.adsr_volume); + Log_DebugFmt("SPU voice {} ADSR volume <- 0x{:04X} (was 0x{:04X})", voice_index, value, voice.regs.adsr_volume); voice.regs.adsr_volume = value; } break; @@ -1106,22 +1106,22 @@ void SPU::WriteVoiceRegister(u32 offset, u16 value) // - Valkyrie Profile const bool ignore_loop_address = voice.IsOn() && !voice.is_first_block; - Log_DebugPrintf("SPU voice %u ADPCM repeat address <- 0x%04X", voice_index, value); + Log_DebugFmt("SPU voice {} ADPCM repeat address <- 0x{:04X}", voice_index, value); voice.regs.adpcm_repeat_address = value; voice.ignore_loop_address |= ignore_loop_address; if (!ignore_loop_address) { - Log_DevPrintf("Not ignoring loop address, the ADPCM repeat address of 0x%04X for voice %u will be overwritten", - value, voice_index); + Log_DevFmt("Not ignoring loop address, the ADPCM repeat address of 0x{:04X} for voice {} will be overwritten", + value, voice_index); } } break; default: { - Log_ErrorPrintf("Unknown SPU voice %u register write: offset 0x%X (address 0x%08X) value 0x%04X", offset, - voice_index, offset | SPU_BASE, ZeroExtend32(value)); + Log_ErrorFmt("Unknown SPU voice {} register write: offset 0x%X (address 0x{:08X}) value 0x{:04X}", offset, + voice_index, offset | SPU_BASE, ZeroExtend32(value)); } break; } @@ -1168,7 +1168,7 @@ void SPU::CheckForLateRAMIRQs() { if (CheckRAMIRQ(s_transfer_address)) { - Log_DebugPrintf("Trigger IRQ @ %08X %04X from late transfer", s_transfer_address, s_transfer_address / 8); + Log_DebugFmt("Trigger IRQ @ {:08X} {:04X} from late transfer", s_transfer_address, s_transfer_address / 8); TriggerRAMIRQ(); return; } @@ -1184,7 +1184,7 @@ void SPU::CheckForLateRAMIRQs() const u32 address = v.current_address * 8; if (CheckRAMIRQ(address) || CheckRAMIRQ((address + 8) & RAM_MASK)) { - Log_DebugPrintf("Trigger IRQ @ %08X %04X from late", address, address / 8); + Log_DebugFmt("Trigger IRQ @ {:08X} ({:04X}) from late", address, address / 8); TriggerRAMIRQ(); return; } @@ -1194,11 +1194,11 @@ void SPU::CheckForLateRAMIRQs() void SPU::WriteToCaptureBuffer(u32 index, s16 value) { const u32 ram_address = (index * CAPTURE_BUFFER_SIZE_PER_CHANNEL) | ZeroExtend16(s_capture_buffer_position); - // Log_DebugPrintf("write to capture buffer %u (0x%08X) <- 0x%04X", index, ram_address, u16(value)); + // Log_DebugFmt("write to capture buffer {} (0x{:08X}) <- 0x{:04X}", index, ram_address, u16(value)); std::memcpy(&s_ram[ram_address], &value, sizeof(value)); if (IsRAMIRQTriggerable() && CheckRAMIRQ(ram_address)) { - Log_DebugPrintf("Trigger IRQ @ %08X %04X from capture buffer", ram_address, ram_address / 8); + Log_DebugFmt("Trigger IRQ @ {:08X} ({:04X}) from capture buffer", ram_address, ram_address / 8); TriggerRAMIRQ(); } } @@ -1222,7 +1222,7 @@ ALWAYS_INLINE_RELEASE void SPU::ExecuteFIFOReadFromRAM(TickCount& ticks) if (IsRAMIRQTriggerable() && CheckRAMIRQ(s_transfer_address)) { - Log_DebugPrintf("Trigger IRQ @ %08X %04X from transfer read", s_transfer_address, s_transfer_address / 8); + Log_DebugFmt("Trigger IRQ @ {:08X} ({:04X}) from transfer read", s_transfer_address, s_transfer_address / 8); TriggerRAMIRQ(); } } @@ -1239,7 +1239,7 @@ ALWAYS_INLINE_RELEASE void SPU::ExecuteFIFOWriteToRAM(TickCount& ticks) if (IsRAMIRQTriggerable() && CheckRAMIRQ(s_transfer_address)) { - Log_DebugPrintf("Trigger IRQ @ %08X %04X from transfer write", s_transfer_address, s_transfer_address / 8); + Log_DebugFmt("Trigger IRQ @ {:08X} ({:04X}) from transfer write", s_transfer_address, s_transfer_address / 8); TriggerRAMIRQ(); } } @@ -1303,7 +1303,7 @@ void SPU::ManualTransferWrite(u16 value) { if (!s_transfer_fifo.IsEmpty() && s_SPUCNT.ram_transfer_mode != RAMTransferMode::DMARead) { - Log_WarningPrintf("FIFO not empty on manual SPU write, draining to hopefully avoid corruption. Game is silly."); + Log_WarningPrint("FIFO not empty on manual SPU write, draining to hopefully avoid corruption. Game is silly."); if (s_SPUCNT.ram_transfer_mode != RAMTransferMode::Stopped) ExecuteTransfer(nullptr, std::numeric_limits<s32>::max(), 0); } @@ -1313,7 +1313,7 @@ void SPU::ManualTransferWrite(u16 value) if (IsRAMIRQTriggerable() && CheckRAMIRQ(s_transfer_address)) { - Log_DebugPrintf("Trigger IRQ @ %08X %04X from manual write", s_transfer_address, s_transfer_address / 8); + Log_DebugFmt("Trigger IRQ @ {:08X} ({:04X}) from manual write", s_transfer_address, s_transfer_address / 8); TriggerRAMIRQ(); } } @@ -1431,7 +1431,7 @@ void SPU::DMARead(u32* words, u32 word_count) fill_value = halfwords[size - 1]; } - Log_WarningPrintf("Transfer FIFO underflow, filling with 0x%04X", fill_value); + Log_WarningFmt("Transfer FIFO underflow, filling with 0x{:04X}", fill_value); std::fill_n(&halfwords[size], halfword_count - size, fill_value); } else @@ -1452,7 +1452,7 @@ void SPU::DMAWrite(const u32* words, u32 word_count) s_transfer_fifo.PushRange(halfwords, words_to_transfer); if (words_to_transfer != halfword_count) [[unlikely]] - Log_WarningPrintf("Transfer FIFO overflow, dropping %u halfwords", halfword_count - words_to_transfer); + Log_WarningFmt("Transfer FIFO overflow, dropping {} halfwords", halfword_count - words_to_transfer); UpdateDMARequest(); UpdateTransferEvent(); @@ -1491,7 +1491,7 @@ bool SPU::StartDumpingAudio(const char* filename) s_dump_writer = std::make_unique<WAVWriter>(); if (!s_dump_writer->Open(filename, SAMPLE_RATE, 2)) { - Log_ErrorPrintf("Failed to open '%s'", filename); + Log_ErrorFmt("Failed to open '{}'", filename); s_dump_writer.reset(); return false; } @@ -1511,7 +1511,7 @@ bool SPU::StartDumpingAudio(const char* filename) const std::string voice_filename = Path::ReplaceExtension(filename, new_suffix); if (!s_voice_dump_writers[i]->Open(voice_filename.c_str(), SAMPLE_RATE, 2)) { - Log_ErrorPrintf("Failed to open voice dump filename '%s'", voice_filename.c_str()); + Log_ErrorFmt("Failed to open voice dump filename '{}'", voice_filename.c_str()); s_voice_dump_writers[i].reset(); } } @@ -1916,7 +1916,7 @@ void SPU::ReadADPCMBlock(u16 address, ADPCMBlock* block) u32 ram_address = (ZeroExtend32(address) * 8) & RAM_MASK; if (IsRAMIRQTriggerable() && (CheckRAMIRQ(ram_address) || CheckRAMIRQ((ram_address + 8) & RAM_MASK))) { - Log_DebugPrintf("Trigger IRQ @ %08X %04X from ADPCM reader", ram_address, ram_address / 8); + Log_DebugFmt("Trigger IRQ @ {:08X} ({:04X}) from ADPCM reader", ram_address, ram_address / 8); TriggerRAMIRQ(); } @@ -1965,7 +1965,7 @@ ALWAYS_INLINE_RELEASE std::tuple<s32, s32> SPU::SampleVoice(u32 voice_index) if (voice.current_block_flags.loop_start && !voice.ignore_loop_address) { - Log_TracePrintf("Voice %u loop start @ 0x%08X", voice_index, ZeroExtend32(voice.current_address)); + Log_TraceFmt("Voice {} loop start @ 0x{:08X}", voice_index, voice.current_address); voice.regs.adpcm_repeat_address = voice.current_address; } } @@ -2024,12 +2024,20 @@ ALWAYS_INLINE_RELEASE std::tuple<s32, s32> SPU::SampleVoice(u32 voice_index) if (!voice.current_block_flags.loop_repeat) { - Log_TracePrintf("Voice %u loop end+mute @ 0x%08X", voice_index, ZeroExtend32(voice.current_address)); - voice.ForceOff(); + // End+Mute flags are ignored when noise is enabled. ADPCM data is still decoded. + if (!IsVoiceNoiseEnabled(voice_index)) + { + Log_TraceFmt("Voice {} loop end+mute @ 0x{:04X}", voice_index, voice.current_address); + voice.ForceOff(); + } + else + { + Log_TraceFmt("IGNORING voice {} loop end+mute @ 0x{:04X}", voice_index, voice.current_address); + } } else { - Log_TracePrintf("Voice %u loop end+repeat @ 0x%08X", voice_index, ZeroExtend32(voice.current_address)); + Log_TraceFmt("Voice {} loop end+repeat @ 0x{:04X}", voice_index, voice.current_address); } } }