From 9d3877e448b6d985a82aa1ef521ca77fd33dc669 Mon Sep 17 00:00:00 2001 From: PJB3005 Date: Wed, 8 Apr 2026 13:30:50 +0200 Subject: [PATCH 1/3] Fix JKRDecomp crash I caused By changing more things :sloggers: --- libs/JSystem/src/JKernel/JKRThread.cpp | 6 +++++- src/dusk/OSThread.cpp | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/libs/JSystem/src/JKernel/JKRThread.cpp b/libs/JSystem/src/JKernel/JKRThread.cpp index 103e6bbcbc..31c2cbe6e5 100644 --- a/libs/JSystem/src/JKernel/JKRThread.cpp +++ b/libs/JSystem/src/JKernel/JKRThread.cpp @@ -88,7 +88,11 @@ void JKRThread::setCommon_heapSpecified(JKRHeap* heap, u32 stack_size, int param mThreadRecord = (OSThread*)JKRAllocFromHeap(mHeap, sizeof(OSThread), 0x20); JUT_ASSERT(168, mThreadRecord); - OSCreateThread(mThreadRecord, start, this, (u8*)mStackMemory + mStackSize, mStackSize, param_3, 1); +#if TARGET_PC + OSCreateThread(mThreadRecord, start, this, (u8*)mStackMemory + mStackSize, mStackSize, param_3, 0); +#else + OSCreateThread(mThreadRecord, start, this, (u8*)mStackMemory + mStackSize, mStackSize, param_3, OS_THREAD_ATTR_DETACH); +#endif } void* JKRThread::start(void* thread) { diff --git a/src/dusk/OSThread.cpp b/src/dusk/OSThread.cpp index af339e8656..d5d73df243 100644 --- a/src/dusk/OSThread.cpp +++ b/src/dusk/OSThread.cpp @@ -41,7 +41,7 @@ struct PCThreadData { bool suspended = false; ~PCThreadData() { - if (dusk::IsShuttingDown) { + if (dusk::IsShuttingDown && nativeThread.joinable()) { // Don't care about threads if we're shutting down. nativeThread.detach(); } From 4ad00e3f043e9d9bf682bab687356305b418f47b Mon Sep 17 00:00:00 2001 From: PJB3005 Date: Wed, 8 Apr 2026 01:06:42 +0200 Subject: [PATCH 2/3] Make waitForTick properly sleep MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It was spinwaiting 💀 --- libs/JSystem/src/JFramework/JFWDisplay.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/libs/JSystem/src/JFramework/JFWDisplay.cpp b/libs/JSystem/src/JFramework/JFWDisplay.cpp index 26788f9f38..a726889863 100644 --- a/libs/JSystem/src/JFramework/JFWDisplay.cpp +++ b/libs/JSystem/src/JFramework/JFWDisplay.cpp @@ -5,6 +5,7 @@ #include #include #include +#include "SDL3/SDL_timer.h" #include "JSystem/J2DGraph/J2DOrthoGraph.h" #include "JSystem/JFramework/JFWDisplay.h" #include "JSystem/JKernel/JKRHeap.h" @@ -384,6 +385,12 @@ static void waitForTick(u32 p1, u16 p2) { JSUList JFWAlarm::sList(false); +#if TARGET_PC +void JFWDisplay::threadSleep(s64 time) { + SDL_DelayNS(OSTicksToMicroseconds(time) * 1'000); +} +#else + static void JFWThreadAlarmHandler(OSAlarm* p_alarm, OSContext* p_ctx) { JFWAlarm* alarm = static_cast(p_alarm); alarm->removeLink(); @@ -401,6 +408,7 @@ void JFWDisplay::threadSleep(s64 time) { OSSuspendThread(alarm.getThread()); OSRestoreInterrupts(status); } +#endif static void dummy() { JUTXfb::getManager()->setDisplayingXfbIndex(0); From 5753aa400494e941f985a1e7fca18e582cacd69c Mon Sep 17 00:00:00 2001 From: madeline Date: Thu, 9 Apr 2026 14:44:55 -0700 Subject: [PATCH 3/3] IIR filter --- src/dusk/audio/DuskDsp.cpp | 40 ++++++++++++++++++++++++++++++++++++++ src/dusk/audio/DuskDsp.hpp | 10 ++++++++++ 2 files changed, 50 insertions(+) diff --git a/src/dusk/audio/DuskDsp.cpp b/src/dusk/audio/DuskDsp.cpp index e7dff6a2a5..b5c3e2588c 100644 --- a/src/dusk/audio/DuskDsp.cpp +++ b/src/dusk/audio/DuskDsp.cpp @@ -116,6 +116,14 @@ static void ResetChannel(JASDsp::TChannel& channel, ChannelAuxData& aux) { aux.resamplePos = 0.0; aux.resamplePrev = 0; + aux.prev_lp_out = 0.0f; + aux.prev_lp_in = 0.0f; + + aux.biq_in1 = 0.0f; + aux.biq_in2 = 0.0f; + aux.biq_out1 = 0.0f; + aux.biq_out2 = 0.0f; + for (auto& volume : aux.prevVolume) { volume = NAN; } @@ -519,6 +527,38 @@ static void RenderChannel( channelAux.resamplePos = pos; channelAux.resamplePrev = prev; + // IIR FILTER + + // IIR part 1, low-pass: out[n] = (in[n] - in[n-1]) * (coeff/128) + out[n-1] + if (s16 coeff = channel.iir_filter_params[4]; coeff != 0) { + for (f32& sample : audioLoadBuffer) { + f32 out = std::clamp( + (sample - channelAux.prev_lp_in) * ((f32)coeff / 128.0f) + channelAux.prev_lp_out, -1.0f, 1.0f + ); + + channelAux.prev_lp_in = sample; // in[n-1] = in[n] + sample = channelAux.prev_lp_out = out; // out[n-1] = out[n] + } + } + + // IIR part 2, biquad: out[n] = (b1*in[n-1] + b2*in[n-2] + a1*out[n-1] + a2*out[n-2]) / 32768 + if ((channel.mFilterMode & 0x20) != 0) { + for (f32& sample : audioLoadBuffer) { + f32 out = std::clamp(( + channel.iir_filter_params[0] * channelAux.biq_in1 + // b1 + channel.iir_filter_params[1] * channelAux.biq_in2 + // b2 + channel.iir_filter_params[2] * channelAux.biq_out1 + // a1 + channel.iir_filter_params[3] * channelAux.biq_out2 // a2 + ) / 32768.0f, -1.0f, 1.0f); + + // shift history, then store new input and output + channelAux.biq_in2 = channelAux.biq_in1; // in[n-2] = in[n-1] + channelAux.biq_in1 = sample; // in[n-1] = in[n] + channelAux.biq_out2 = channelAux.biq_out1; // out[n-2] = out[n-1] + sample = channelAux.biq_out1 = out; // out[n-1] = out[n] + } + } + // move any remaining samples in the decode buf to the beginning int remainingDecodeBuf = channelAux.decodeBufCount - srcIdx; if (remainingDecodeBuf > 0) { diff --git a/src/dusk/audio/DuskDsp.hpp b/src/dusk/audio/DuskDsp.hpp index c7cb751458..3ca90d6311 100644 --- a/src/dusk/audio/DuskDsp.hpp +++ b/src/dusk/audio/DuskDsp.hpp @@ -52,6 +52,16 @@ namespace dusk::audio { f32 resamplePos; // last consumed sample from decodeBuf s16 resamplePrev; + + // low pass previous state + f32 prev_lp_out; // out[n-1] + f32 prev_lp_in; // in[n-1] + + // biquad state + f32 biq_in1; // in[n-1] + f32 biq_in2; // in[n-2] + f32 biq_out1; // out[n-1] + f32 biq_out2; // out[n-2] }; extern ChannelAuxData ChannelAux[DSP_CHANNELS];