From 231bece8486695fc20093dcfb5d41f4d151285cd Mon Sep 17 00:00:00 2001 From: tildearrow Date: Thu, 22 Aug 2024 22:20:25 -0500 Subject: [PATCH 1/6] SDL audio: don't close audio device if not open issue #2068 --- src/audio/sdlAudio.cpp | 4 +++- src/audio/sdlAudio.h | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/audio/sdlAudio.cpp b/src/audio/sdlAudio.cpp index 8f074a5aa..cf464e835 100644 --- a/src/audio/sdlAudio.cpp +++ b/src/audio/sdlAudio.cpp @@ -46,7 +46,9 @@ void* TAAudioSDL::getContext() { bool TAAudioSDL::quit() { if (!initialized) return false; - SDL_CloseAudioDevice(ai); + if (ai!=0) { + SDL_CloseAudioDevice(ai); + } if (running) { running=false; diff --git a/src/audio/sdlAudio.h b/src/audio/sdlAudio.h index b3b0a1843..b9c12fd20 100644 --- a/src/audio/sdlAudio.h +++ b/src/audio/sdlAudio.h @@ -34,5 +34,6 @@ class TAAudioSDL: public TAAudio { std::vector listAudioDevices(); bool init(TAAudioDesc& request, TAAudioDesc& response); TAAudioSDL(): + ai(0), audioSysStarted(false) {} }; From 8a18f962f936d0398818ac06e20f234ea77dda54 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Thu, 22 Aug 2024 23:17:22 -0500 Subject: [PATCH 2/6] VGM export: don't generate garbage stop sample com issue #2072 --- src/engine/engine.h | 2 +- src/engine/vgmOps.cpp | 25 +++++++++++++++++-------- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/engine/engine.h b/src/engine/engine.h index 64d406964..0720a3e8d 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -580,7 +580,7 @@ class DivEngine { void processRow(int i, bool afterDelay); void nextOrder(); void nextRow(); - void performVGMWrite(SafeWriter* w, DivSystem sys, DivRegWrite& write, int streamOff, double* loopTimer, double* loopFreq, int* loopSample, bool* sampleDir, bool isSecond, int* pendingFreq, int* playingSample, int* setPos, unsigned int* sampleOff8, unsigned int* sampleLen8, size_t bankOffset, bool directStream); + void performVGMWrite(SafeWriter* w, DivSystem sys, DivRegWrite& write, int streamOff, double* loopTimer, double* loopFreq, int* loopSample, bool* sampleDir, bool isSecond, int* pendingFreq, int* playingSample, int* setPos, unsigned int* sampleOff8, unsigned int* sampleLen8, size_t bankOffset, bool directStream, bool* sampleStoppable); // returns true if end of song. bool nextTick(bool noAccum=false, bool inhibitLowLat=false); bool perSystemEffect(int ch, unsigned char effect, unsigned char effectVal); diff --git a/src/engine/vgmOps.cpp b/src/engine/vgmOps.cpp index a8a1fab74..9529631a1 100644 --- a/src/engine/vgmOps.cpp +++ b/src/engine/vgmOps.cpp @@ -24,7 +24,9 @@ constexpr int MASTER_CLOCK_PREC=(sizeof(void*)==8)?8:0; -void DivEngine::performVGMWrite(SafeWriter* w, DivSystem sys, DivRegWrite& write, int streamOff, double* loopTimer, double* loopFreq, int* loopSample, bool* sampleDir, bool isSecond, int* pendingFreq, int* playingSample, int* setPos, unsigned int* sampleOff8, unsigned int* sampleLen8, size_t bankOffset, bool directStream) { +// this function is so long +// may as well make it something else +void DivEngine::performVGMWrite(SafeWriter* w, DivSystem sys, DivRegWrite& write, int streamOff, double* loopTimer, double* loopFreq, int* loopSample, bool* sampleDir, bool isSecond, int* pendingFreq, int* playingSample, int* setPos, unsigned int* sampleOff8, unsigned int* sampleLen8, size_t bankOffset, bool directStream, bool* sampleStoppable) { unsigned char baseAddr1=isSecond?0xa0:0x50; unsigned char baseAddr2=isSecond?0x80:0; unsigned short baseAddr2S=isSecond?0x8000:0; @@ -647,6 +649,7 @@ void DivEngine::performVGMWrite(SafeWriter* w, DivSystem sys, DivRegWrite& write logD("writing stream command %x:%x with stream ID %d",write.addr,write.val,streamID); switch (write.addr&0xff) { case 0: // play sample + sampleStoppable[streamID]=true; if (write.val<(unsigned int)song.sampleLen) { if (playingSample[streamID]!=(int)write.val) { pendingFreq[streamID]=write.val; @@ -685,6 +688,7 @@ void DivEngine::performVGMWrite(SafeWriter* w, DivSystem sys, DivRegWrite& write } break; case 1: { // set sample freq + sampleStoppable[streamID]=true; int realFreq=write.val; if (realFreq<0) realFreq=0; if (realFreq>44100) realFreq=44100; @@ -728,11 +732,14 @@ void DivEngine::performVGMWrite(SafeWriter* w, DivSystem sys, DivRegWrite& write break; } case 2: // stop sample - w->writeC(0x94); - w->writeC(streamID); - loopSample[streamID]=-1; - playingSample[streamID]=-1; - pendingFreq[streamID]=-1; + if (sampleStoppable[streamID]) { + w->writeC(0x94); + w->writeC(streamID); + loopSample[streamID]=-1; + playingSample[streamID]=-1; + pendingFreq[streamID]=-1; + sampleStoppable[streamID]=false; + } break; case 3: // set sample direction sampleDir[streamID]=write.val; @@ -1224,6 +1231,7 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version, bool p bool sampleDir[DIV_MAX_CHANS]; int pendingFreq[DIV_MAX_CHANS]; int playingSample[DIV_MAX_CHANS]; + bool sampleStoppable[DIV_MAX_CHANS]; int setPos[DIV_MAX_CHANS]; std::vector chipVol; std::vector delayedWrites[DIV_MAX_CHIPS]; @@ -1246,6 +1254,7 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version, bool p playingSample[i]=-1; setPos[i]=0; sampleDir[i]=false; + sampleStoppable[i]=true; } bool writeDACSamples=false; @@ -2514,7 +2523,7 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version, bool p for (int i=0; i& writes=disCont[i].dispatch->getRegisterWrites(); for (DivRegWrite& j: writes) { - performVGMWrite(w,song.system[i],j,streamIDs[i],loopTimer,loopFreq,loopSample,sampleDir,isSecond[i],pendingFreq,playingSample,setPos,sampleOff8,sampleLen8,bankOffset[i],directStream); + performVGMWrite(w,song.system[i],j,streamIDs[i],loopTimer,loopFreq,loopSample,sampleDir,isSecond[i],pendingFreq,playingSample,setPos,sampleOff8,sampleLen8,bankOffset[i],directStream,sampleStoppable); writeCount++; } writes.clear(); @@ -2554,7 +2563,7 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version, bool p lastOne=i.second.time; } // write write - performVGMWrite(w,song.system[i.first],i.second.write,streamIDs[i.first],loopTimer,loopFreq,loopSample,sampleDir,isSecond[i.first],pendingFreq,playingSample,setPos,sampleOff8,sampleLen8,bankOffset[i.first],directStream); + performVGMWrite(w,song.system[i.first],i.second.write,streamIDs[i.first],loopTimer,loopFreq,loopSample,sampleDir,isSecond[i.first],pendingFreq,playingSample,setPos,sampleOff8,sampleLen8,bankOffset[i.first],directStream,sampleStoppable); // handle global Furnace commands writeCount++; From 9f9638931daa94e9ba7e224c39dda0497d6df3ff Mon Sep 17 00:00:00 2001 From: LTVA1 <87536432+LTVA1@users.noreply.github.com> Date: Thu, 22 Aug 2024 20:26:54 +0300 Subject: [PATCH 3/6] yeah --- src/engine/platform/snes.cpp | 4 +++ src/engine/platform/snes.h | 1 + src/engine/platform/sound/snes/SPC_DSP.cpp | 41 +++++++++++++++------- src/engine/platform/sound/snes/SPC_DSP.h | 4 +++ src/gui/sysConf.cpp | 7 ++++ 5 files changed, 44 insertions(+), 13 deletions(-) diff --git a/src/engine/platform/snes.cpp b/src/engine/platform/snes.cpp index 4c133ec28..fb36cabdb 100644 --- a/src/engine/platform/snes.cpp +++ b/src/engine/platform/snes.cpp @@ -841,6 +841,8 @@ void DivPlatformSNES::reset() { memcpy(sampleMem,copyOfSampleMem,65536); dsp.init(sampleMem); dsp.set_output(NULL,0); + dsp.setupInterpolation(interpolationOn); + memset(regPool,0,128); // this can't be 0 or channel 1 won't play // this can't be 0x100 either as that's used by SPC700 page 1 and the stack @@ -1023,6 +1025,8 @@ void DivPlatformSNES::setFlags(const DivConfig& flags) { initEchoFIR[7]=flags.getInt("echoFilter7",0); initEchoMask=flags.getInt("echoMask",0); + + interpolationOn=flags.getBool("interpolationOn",true); } int DivPlatformSNES::init(DivEngine* p, int channels, int sugRate, const DivConfig& flags) { diff --git a/src/engine/platform/snes.h b/src/engine/platform/snes.h index a2eea2853..a1aae9734 100644 --- a/src/engine/platform/snes.h +++ b/src/engine/platform/snes.h @@ -69,6 +69,7 @@ class DivPlatformSNES: public DivDispatch { bool writeEcho; bool writeDryVol; bool echoOn; + bool interpolationOn; bool initEchoOn; signed char initEchoVolL; diff --git a/src/engine/platform/sound/snes/SPC_DSP.cpp b/src/engine/platform/sound/snes/SPC_DSP.cpp index 6ae8275bc..25cddd884 100644 --- a/src/engine/platform/sound/snes/SPC_DSP.cpp +++ b/src/engine/platform/sound/snes/SPC_DSP.cpp @@ -135,24 +135,39 @@ static short const gauss [512] = 1299,1300,1300,1301,1302,1302,1303,1303,1303,1304,1304,1304,1304,1304,1305,1305, }; +void SPC_DSP::setupInterpolation(bool interpolate) +{ + for(int i = 0; i < voice_count; i++) + { + m.voices[i].interpolate = interpolate; + } +} + inline int SPC_DSP::interpolate( voice_t const* v ) { // Make pointers into gaussian based on fractional position between samples - int offset = v->interp_pos >> 4 & 0xFF; - short const* fwd = gauss + 255 - offset; - short const* rev = gauss + offset; // mirror left half of gaussian + if(v->interpolate) + { + int offset = v->interp_pos >> 4 & 0xFF; + short const* fwd = gauss + 255 - offset; + short const* rev = gauss + offset; // mirror left half of gaussian - int const* in = &v->buf [(v->interp_pos >> 12) + v->buf_pos]; - int out; - out = (fwd [ 0] * in [0]) >> 11; - out += (fwd [256] * in [1]) >> 11; - out += (rev [256] * in [2]) >> 11; - out = (int16_t) out; - out += (rev [ 0] * in [3]) >> 11; + int const* in = &v->buf [(v->interp_pos >> 12) + v->buf_pos]; + int out; + out = (fwd [ 0] * in [0]) >> 11; + out += (fwd [256] * in [1]) >> 11; + out += (rev [256] * in [2]) >> 11; + out = (int16_t) out; + out += (rev [ 0] * in [3]) >> 11; - CLAMP16( out ); - out &= ~1; - return out; + CLAMP16( out ); + out &= ~1; + return out; + } + else + { + return v->buf [(v->interp_pos >> 12) + v->buf_pos]; //Furnace addition -- no interpolation + } } diff --git a/src/engine/platform/sound/snes/SPC_DSP.h b/src/engine/platform/sound/snes/SPC_DSP.h index 924d9ae2c..6c6ff64ce 100644 --- a/src/engine/platform/sound/snes/SPC_DSP.h +++ b/src/engine/platform/sound/snes/SPC_DSP.h @@ -27,6 +27,9 @@ public: // output buffer could hold. int sample_count() const; + // Furnace addition: disable/enable Gaussian interpolation + void setupInterpolation(bool interpolate); + // Emulation // Resets DSP to power-on state @@ -122,6 +125,7 @@ public: int hidden_env; // used by GAIN mode 7, very obscure quirk uint8_t t_envx_out; sample_t out[2]; // Furnace addition, for per-channel oscilloscope + bool interpolate; // Furnace addition, to disable interpolation }; // Furnace addition, gets a voice diff --git a/src/gui/sysConf.cpp b/src/gui/sysConf.cpp index f460a5434..6e2b0f7ca 100644 --- a/src/gui/sysConf.cpp +++ b/src/gui/sysConf.cpp @@ -1969,6 +1969,8 @@ bool FurnaceGUI::drawSysConf(int chan, int sysPos, DivSystem type, DivConfig& fl echoFilter[6]=flags.getInt("echoFilter6",0); echoFilter[7]=flags.getInt("echoFilter7",0); + bool interpolationOn=flags.getBool("interpolationOn",true); + ImGui::Text(_("Volume scale:")); if (CWSliderInt(_("Left##VolScaleL"),&vsL,0,127)) { if (vsL<0) vsL=0; @@ -2084,6 +2086,10 @@ bool FurnaceGUI::drawSysConf(int chan, int sysPos, DivSystem type, DivConfig& fl ImGui::Text(_("sum: %d"),filterSum); ImGui::PopStyleColor(); + if (ImGui::Checkbox(_("Gaussian interpolation"),&interpolationOn)) { + altered=true; + } + if (altered) { e->lockSave([&]() { flags.set("volScaleL",127-vsL); @@ -2102,6 +2108,7 @@ bool FurnaceGUI::drawSysConf(int chan, int sysPos, DivSystem type, DivConfig& fl flags.set("echoFilter6",echoFilter[6]); flags.set("echoFilter7",echoFilter[7]); flags.set("echoMask",echoMask); + flags.set("interpolationOn",interpolationOn); }); } From 3b6ddebc64a270e94ac21ca99f99fb465dfde1c2 Mon Sep 17 00:00:00 2001 From: LTVA1 <87536432+LTVA1@users.noreply.github.com> Date: Fri, 23 Aug 2024 07:30:06 +0300 Subject: [PATCH 4/6] disable --- src/engine/platform/snes.cpp | 4 ++-- src/engine/platform/snes.h | 2 +- src/gui/sysConf.cpp | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/engine/platform/snes.cpp b/src/engine/platform/snes.cpp index fb36cabdb..ad955cf98 100644 --- a/src/engine/platform/snes.cpp +++ b/src/engine/platform/snes.cpp @@ -841,7 +841,7 @@ void DivPlatformSNES::reset() { memcpy(sampleMem,copyOfSampleMem,65536); dsp.init(sampleMem); dsp.set_output(NULL,0); - dsp.setupInterpolation(interpolationOn); + dsp.setupInterpolation(!interpolationOff); memset(regPool,0,128); // this can't be 0 or channel 1 won't play @@ -1026,7 +1026,7 @@ void DivPlatformSNES::setFlags(const DivConfig& flags) { initEchoMask=flags.getInt("echoMask",0); - interpolationOn=flags.getBool("interpolationOn",true); + interpolationOff=flags.getBool("interpolationOff",false); } int DivPlatformSNES::init(DivEngine* p, int channels, int sugRate, const DivConfig& flags) { diff --git a/src/engine/platform/snes.h b/src/engine/platform/snes.h index a1aae9734..8c8329065 100644 --- a/src/engine/platform/snes.h +++ b/src/engine/platform/snes.h @@ -69,7 +69,7 @@ class DivPlatformSNES: public DivDispatch { bool writeEcho; bool writeDryVol; bool echoOn; - bool interpolationOn; + bool interpolationOff; bool initEchoOn; signed char initEchoVolL; diff --git a/src/gui/sysConf.cpp b/src/gui/sysConf.cpp index 6e2b0f7ca..854caccfd 100644 --- a/src/gui/sysConf.cpp +++ b/src/gui/sysConf.cpp @@ -1969,7 +1969,7 @@ bool FurnaceGUI::drawSysConf(int chan, int sysPos, DivSystem type, DivConfig& fl echoFilter[6]=flags.getInt("echoFilter6",0); echoFilter[7]=flags.getInt("echoFilter7",0); - bool interpolationOn=flags.getBool("interpolationOn",true); + bool interpolationOff=flags.getBool("interpolationOff",false); ImGui::Text(_("Volume scale:")); if (CWSliderInt(_("Left##VolScaleL"),&vsL,0,127)) { @@ -2086,7 +2086,7 @@ bool FurnaceGUI::drawSysConf(int chan, int sysPos, DivSystem type, DivConfig& fl ImGui::Text(_("sum: %d"),filterSum); ImGui::PopStyleColor(); - if (ImGui::Checkbox(_("Gaussian interpolation"),&interpolationOn)) { + if (ImGui::Checkbox(_("Disable Gaussian interpolation"),&interpolationOff)) { altered=true; } @@ -2108,7 +2108,7 @@ bool FurnaceGUI::drawSysConf(int chan, int sysPos, DivSystem type, DivConfig& fl flags.set("echoFilter6",echoFilter[6]); flags.set("echoFilter7",echoFilter[7]); flags.set("echoMask",echoMask); - flags.set("interpolationOn",interpolationOn); + flags.set("interpolationOff",interpolationOff); }); } From 9b64bc104f208c96fc74a9341ffb790fb3a03bda Mon Sep 17 00:00:00 2001 From: tildearrow Date: Fri, 23 Aug 2024 02:22:44 -0500 Subject: [PATCH 5/6] pont of noreturn cover by leejh20 --- demos/multichip/pont of noreturn.fur | Bin 0 -> 7615 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 demos/multichip/pont of noreturn.fur diff --git a/demos/multichip/pont of noreturn.fur b/demos/multichip/pont of noreturn.fur new file mode 100644 index 0000000000000000000000000000000000000000..0f3d34857a4402a50a37b383ce72d3ac56e9d7da GIT binary patch literal 7615 zcmV;w9YErEob5enbX-??-&;mAl13WIvaOM2>y0gEVM!A^VM!p7oyFNu+mWQ)+|ls07xdnql2Qp%}&4&l(kIsMUv)0RUy(1o_boX`V>9ykYD zS}5vwzkA<%_bsz3QIy0=?pyBt_V2sjcki1w;~S2gKQ}uvHXb`0KYe~?{DyA;Kn(1^ z`yV>ecTEs4G+hB$xib&DKySI8#-7Bsv;-yp4wd;Ujs4>P&Bdo@ldb!A*t+Tg&S3i*wl_5ZdG=-UIN+ z5rEt81-SJ-)CJrBV*7{t0sia(w84V_zw;J=kM;t*^C5sseE{#lcJEPuYaRxO^aK14 zwx2$N@*V^D=i>n196;XK+6Iv&whXqAqHFJk*Xwp~L21K6I%_El_6 zZv%J$+bXtCoxo}ED8Tp#z+a5vJedHvIE8p;Q1`PaUmW0{u%+h#u1f%XJqeIpK>MWd z`f03A8>X&&IV0?LK+=&zTN_6oqeE&_bv62Nn-0N3IqdkotJ*4_zl z_E#|`e+}R>PXVaEjxq8s^cA-KzX@>P(>V590H1p|>Wyvxd(hX|ZhSAmp7&vlVfzZU zKYc&O(KBcxY`Z>)w*L_N7Tb5Q{TH_IhXLM)?Oh)M`0z&o{_SH(>*FjhDEObM=~}?P zsteWyW6$r%da;r9=Xazg*@zy$x2}Sr`i92hBMb?9R87_Et*gL#T`;5)b)WxKz1WCu zr4%#0DDDkHHZHf5kZ2~FZW3#fa_nQh5ixxa$ zDub`CE7(+Q8a5qU09zflAhr;;dTb5Y8nK13HDPPU7QqIvhWKlUzlQj0h`)yTYly#w z_-ly2hWKlUzlQj0h`)yTYly#w_zYM4p;PM|f6$9beFfXo*bd))fB%gnI{smeRCP^3 zF9%w;wQX-`+|eH0wX?HhcX&^i(bUqscVGAZYw9D{UKe9%K@*KrF}-~MLysK93<=+W zz3|ZC0Gy7;lW?SWKl}u9=~r(3dc$=tk=y%*{8q^YdHoMyj#E(ZH9L zdmdtx?zJd25T)4o*i_smS0~85L6D0e8PwwDZhrQVyW1ic1SE9sbb`~u^nU9;qxo($ z#eoi^{t&wMK)Vq-gl;&n!w4NQ%7~Vj8JUZXjwA#*v_;Pz6baF9+G(^ga<{+MXrg=6 z*q7X07P&f@o52XQv^>ydG#|pEc3=-`#U!gY8W^dA+xfYqmXqhFlOyLitv6t?iXbg4 zx{vHO^hf_2{k`2#5B&_FuF=rh*+c7;B-X_AL~_b9*w_x#5NnGn&RWh0GI2(?@pJFt z4hXS%$5M-ydpxZ3D^*jpbq}8rN#=?8`EwGZ(^t2xp#pb3) z662>gtd~E#DT`gR(96xQR`vYtIBM|=LGs*mGCn(QaT?_uLZ)Ua=M<_Dk!p zC6`SJ4gqlv2@c~m>GYV)Y2=K9)40oefo*Q9Helhb%BcbGq?$8#np#;S}Nk&~>`gv()dro-AwnDHQ z=2chB`$wXr7zT)!i(GCVo0c-?!*!T^F{j@dG@`6NC}3>w!zJti71{p0OcGAaj+`5} zNcA^SK5w}Nkkn@}qQMCFVIDsSM&xaN`P}yF4j7w>>|q16Co;MErD)+-wY@`I=lC97`d5o8}h1er|33_&yCOe@xdZ_hu{+iuF1IIa}tbg zeG!{aLoq%lB;%Z$PK=AH(jJ6hE0O|;M%oN`^heN=*+ut|2n66!a_0^ttuYnQ30hEG z{GFG_+vPGaGBZ;N6V+(A?>c`bsK_@<$IHz4h?oV}LF|@xqmiu}w#SURL!SgV6*B^? zDysEH-92yhadKQ*129U`@FK*htYbz=<*PIKq~rz znB=Nb6n7M%SYnN(H5-vbxXJHtH@30tGun#lHoR8?M$^51Hk*>1z-c*!GYKAZ6KvuH zdk=Toain1!l?k6?HOSs#vSLXhY{sdVcCi&UCZOpk#tzaP*=B@^<~|J0bqY@Z6?RP_ z&{)J_k4kf9bbMxpQ$lgaTQIb-C9nH|BC6X0bRXDOuh+be-({$db$kmyduUyh6YJSA+^^V)wMit_og%SzqMzmf zGFTXR_I?d345%%u`2Y7ypG4lQ@qoa;^}bu05nL5LJKMH-jr9Bp^NZ?)+3phN=;31z zC213j`zzy^Hr4P)`Mu%GKUB3-n)7_jy3d;(c{fD97>EaU15{-xx1z)j`A)HG*o_Cz z*gCWQXUxYGewrZmoCDDuwFy?h-6iH#Ms7x&Xl1;}Y0vVH3eai263CF?JY;k3wK)&T zoO?AFjzkCXZJH*a(I<5d3#4J2QJ>9dSZ36xxo{*ph;P&EdvTm5%?!y2HSog@H?0!0 z?pg6b^r{0l;J|*Dkxy#UrNyt`=66!&*KhJWshJ&aTGD;LZ`#z*fk!3LP6*LY*zAwm z>`%z-k7_O)i4Nl1G)=%-8M*b8RpDypoq#XjwE0DHn*OqM+UDjFX=V&-(q+ZzL_)(p ziQJ@%yp(Pv9|ktlhnr^F0jYCTAdT9L25d&7GNS>_g(J~He4FOLCi!r!A!MipZx(=tX82Ho-DzoHmkNz%sb_)p zWI0TVV=VCTd488-V~nQY(_#X$KE=VO#luJO@M&@IQJ^O>52h9=HvCf3%2;5sn~L>B zQbLuU$b!PIyy}q$f24@d{EO&{-55qhalyi#;nqrs4zJR(Fp4CMuj)?DmiB_P;^y4q z$GNN-go|a)Mg9Ad(YYs*6`j?nO@9A5`CakzdlD#Y<`vTjHnAk%+ z_;L14Z^^4!ojLxSRv~cN^M@1Vs*(|Wvi=IJ&~N*xyUkf&Z3yM zC@xxcJ7G~wo0Ghiy+f_kG2A#Gr40$MZnS6Md53x#g*g*Ov7{Cl87McvE2|eg=Kx=^ z2Uh(DiqV;MfY00D3$_OH4h4Ky+K(8LIWz1*$YDcNF9$@&^ITY*!a ztiUPRVqsOiQ!>SzQsvZMDi&7$9+Bw0^nD;t3@a6ju|?O|T#+%y^e8e=bb2@jmL2>r zIruM^m{ZP4@>=?!I0mqX)imwC{hw!BhXOl%&bk8YKsdiGK3s;LU|hvceVMi^Z;r6* zM+*FW{Gx?UR~*LK$FDX(rJ%)CTeyOW8w=~lNz$*AqzaRC-iHUq@Gf@M?~uk1Qb<$i z*5_5d;9*v%Mh7l%PjHENgRPN+Vz<7qO9!X*O~QO}Pr9jFM>mtYL*6+C%x@Smu4uO& zSM_BAS z=1XG9aak1Ko~GdEYDxD%?YfVb#2Vkqy7LHU3->Zn7cU~uY)x8}j@4ultVBtyg-Rkk zNU7=tkhz$BwuF~&q!)S20^1$FZ~t@esG!FFo_PO<(|T^HTTiI^(uV3RJJd?1pe0Hc z+Ha7!SZFzuWHBZ^kriH*%#x8PS&$OG1*s}U+>Y!C=12lg7wK`LW>HS;a(bV%`xa@Z zZZYk8g2{^O?R;hRR-<}b+icrRtkT&iUO_g}^v%{Zxq-Y}J{u*fsJB|6cHL`RA8iTU zd4$)M*F8~FJz1zp_f!$Ag_2n5N+O)`{3>Rj+IT(BUZ#Rt zXBX7{;+slfjMY8SmV;*J}2Rg?a+S;DtN2G9p zcN6qMf>z5ze}DmCx5ejmgo(Mf^8^iuV+%X>H?!lZI{P?gT}#M%3FPsReSEaRJW9v` z7xGZZK9)sBTRH^mZzSX}I}XzERFEA{((#N_>>#%m;~wFHC>A`xm(1N9C8H z6^#2zX(^5R=uRQ>Fog(|3=tff^HQwBsug0D_uy5DHbEl)0IEVL3aqzLV6k6e8L|<2 zb;lWpED?J>P$dwxA-x)`As5?W8>CNnoN>sKsLumc0#O^*tHBy}vE9mnC1(*wLfM#H z7N~EMsvvdo2ve^{*h@6R`fU#%@xAP~<+6LVBOY|K%R2Wv@0~RLIk{;`#gYAv%?TUe zsO~u9kR|0&4^#<6?Sx(p)(H>W=T9QjUMIb#6+^~JPnQX8fo#19+p@*+?G#x0)xfGK zu(on~m$I>ZS!W(uGSrR?y zfhvKh4eHfk4Z7G~&0aNSuUE6DtM&AN^cn3LaTiawD(7We`C zZu7AKsw1wZ=t>MZ0VVkIP_J+v_HadP$UmPT|IlM60Wri$4Ou*gEK)S&1eD;*Lm9)O zbC}}{TRes>>|rmU1YaI%^ZX;;cXSxN8eSfj{$xGQQm;CzDrfb}R_(W()o=0Yx2W{n z2nBKHJlVkhWI33W`RGS|1-+x3!cmLyQ45QPoPZL1d8q1n_-j?l1TVA9_et`P{xb4U zujuUMIK38+UJJX|3n;;thcf!)sPD6k-e>XZv#9jh2nBKH8MZt8DRVH%Ux7{X*Jjvq zKy(gpoB@l+fQ3Ea1(e{+L%oRp;`y&`lU9C?2~llwuW){CM%;PKU!|YQ0D9(AaFZ4j zgQ9bg;|y9n1}*GCFQ5cp9%@tO)36-%!%Md(bs)>1Ii?Md_9HRUoG2{w9>zmI#Iz8Z6p9hP?|&DV6*mV8Xtdx8Y1 zF(hriz0eck_egPpU7!{zqMu@S>{qGqF0WiRGERQ!3iu(rd{2)?;p&btw+EMc? zXGzpzVO8taGwrHHTg$eS?rWqw+qPtdEIA=d-japgrTj%HAY~>3lSsKN^j1;fMdBVq zR4vnvRI}|u6y`M**a|wBSyvz(Oetw})jc{Vw$DE#J=L;$=F02I zUce+ZxmNj}NX}L^%eF{4i>C9WOPzQ z+yu-s#B3Kb%Q0r67nRL-Y3px74nI(}^`2msBQd^tMkFmH%*Ya^T@q4^*@%`*{5&X4 z56ei)JnBp-nG=Y0LC7cGKD?D|rN7{|%6Vs!VkB~lqdDkYRlcWEIxU_hF4mOZ&CG4?|&_N8D`y}@=b z88EOV49J{(iNUQfj7vhCRUys<>wMBF&IF3H%Ecj)mn>N(V&QKej)kurW>_m$>`hS6 zE_-I)1o#Q6v=qAaC%Y6724!H}oU0xRgJjO9DPhrz?VKqF#U=C^(qn=Tf-^_(D_#>6 z*9>r_ld49St=vK@&v`RDPtgKK)Falh+rnHYdh1BOz?1c|RF!#+=CD~RRP35}S=qgSMcB+L z`^Z!wEIXv)aw**wusrjHfhky8sEEQ?`jsS+A`)qdglQ#I(#J$S5vqPy_Ij*@*}DD8 z-h$IY%z8^`7Xku?OcMso3MiE_@kJ#wpbB;g6C#@{k(jPZK~;Y>sLY_s6%8t0sv0T^ zs8MBp zPJ6i6ZDddJb5d9Z@UdZaHJ3@36sc51i|s4^9a5*PJ(1L&Ir9gP>56TEGkcP*KKj9W z`Uz#LBff`znR%A~ko_5cH@Sxhj9Ek{Euv?vzF7wi{w)!fiW+H$v0%_l5?=tz8%e$d zG_)4Se9sdY|M4iyDuyPzIB!S`LUSKkQTUt0U(UzG|SMD_DXUgEvTE>v(4^CMIOPdlyY)XW}X+vyE zTqYK4Ue7AR+Lqwz$>3RNkc=8|7zAa_g~`HSfag&kZV-};`@E@Xi59Pc%knDg()DV^K5;->H z*p5qSjyS2x3%4`bL(UI6rAwK0*sK6zm4IswTI5Le#aiX2qGlP%6e%M`h@>PU8H-3( z5b-I8IkOz*qSn$e>HuMd)VyCOTI-CoK_!D5fLHh>v((#Fkqdy}j7~aAM%qnA3JD|O z`oUI@h!xRn0X4(2V~drJ%G8B!r6{C`g1s)W41^l`TL-ro?E1=Hhk-DqNA1-mGY{`K zmZDaEK)Z5cc~MSrZb!u&5_2@^S=`yBJw`UF2XnVlppDAaSVCXr#tO~sQP zwk_!iUZmwR?kdp0KBO?8MtMH%qI}v2W<}uK39-fg?*BauDjWm&Lu0OULcKmX*Leop zEZ|{oS)1;J$f@lY)Q=f6opb8-pv`t_@lI{76R;Ju8PTRYiCB<`;l|~c_NO0V`t&2) zF~>JUxem6I$aXkBjaXo#6@B_ako?n+^Bov({GM%q*ah376a7qwi0BRxzD|DG3i$C| z3Xx@>exy5C@OQ9j&sh>RzD>z>NS}V>J4pBMlJ4x&kGzm&NyxHd$wJZOFN*6^fgFi} z*{Op*6(A)3sX(4tA!prl%?o5_`cxn*xHG#8gKYFu0iUF{leESC%8gCQ?vx&C{fxHI z{gjsKrqOrMC@$r-WH%p}@BWaM=w3EA18fWM82v+73g18QeTCVv$afM6zLQuKD7dEM z9a#e8dy^^iA9}I+Y%=ra*5dmlk52M@2xVbEjT4)b9{m<@eHPPWVf(Rf!B}Dt2uWwQ z_KHc5d@sd3k9=2RW_rNITFm#6Z=N%?9{J|z-nB>)Pbg#o>5=cHn9n2M6%PgJk#CqD zfpMlR9%EbLk?(JiXzbyBgq}vzzokQuqot1x1~<&QdcpRx0u-jlA&DUwu%D(t$W<#o{X7(8`r(r%_M0>3cdGgamCK!{b|`i4Z#=(KDLA?ax{;tk zKvP#Ubt&wZRQ{#&*bXH`y(_G@nZ1`c-ptx z|L)G2&Qb~#BB!=pP$d?Pr?#n}o!SPS^R4Pvv4{Tyxg-lXWnnidfTS8Q2sR6iC<}lERDZHFr$#NOJEGvrW)x5kim>06 zIn|b9hdFjg@muXwo1<&HqicIk0yV)dm=Lc3V*G;(GN9r#;P$kKGIf=w%rP&#a;Qm0 hRGmh=Hs>KtT~5;1v94<`_+a|=y-caC|39BPa`Bc#&`SUS literal 0 HcmV?d00001 From bae45e0b8666ba557b1e897e314ae5a7eeb3e596 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Fri, 23 Aug 2024 02:25:40 -0500 Subject: [PATCH 6/6] SN: fix arp macro with easy period --- src/engine/platform/sms.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/engine/platform/sms.cpp b/src/engine/platform/sms.cpp index 7be834bda..569862864 100644 --- a/src/engine/platform/sms.cpp +++ b/src/engine/platform/sms.cpp @@ -165,8 +165,12 @@ int DivPlatformSMS::snCalcFreq(int ch) { if (ch==3) CHIP_DIVIDER=noiseDivider; int easyStartingPeriod=16; int easyThreshold=round(128.0*12.0*log((chipClock/(easyStartingPeriod*CHIP_DIVIDER))/(0.0625*parent->song.tuning))/log(2.0))-384+64; - if (parent->song.linearPitch==2 && easyNoise && chan[ch].baseFreq+chan[ch].pitch+chan[ch].pitch2>(easyThreshold)) { - int ret=(((easyStartingPeriod<<7))-(chan[ch].baseFreq+chan[ch].pitch+chan[ch].pitch2-(easyThreshold)))>>7; + int curFreq=chan[ch].baseFreq+chan[ch].pitch+chan[ch].pitch2+(chan[ch].arpOff<<7); + if (chan[ch].fixedArp) { + curFreq=chan[ch].baseNoteOverride<<7; + } + if (parent->song.linearPitch==2 && easyNoise && curFreq>easyThreshold) { + int ret=(((easyStartingPeriod<<7))-(curFreq-(easyThreshold)))>>7; if (ret<0) ret=0; return ret; }