From eb70086234de1949c43c90efeeaa4216584099b5 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Fri, 15 Apr 2022 14:38:13 -0500 Subject: [PATCH 1/5] sample 8-bit blep resample fix --- src/engine/sample.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/engine/sample.cpp b/src/engine/sample.cpp index bd34daa5..3aec450b 100644 --- a/src/engine/sample.cpp +++ b/src/engine/sample.cpp @@ -587,8 +587,8 @@ bool DivSample::resampleSinc(double r) { result+=s[j]*t2[7-j]; result+=s[8+j]*t1[j]; } - if (result<-32768) result=-32768; - if (result>32767) result=32767; + if (result<-128) result=-128; + if (result>127) result=127; if (i>=8) { data8[i-8]=result; } From 45460df96d24c87fea90e58fe3d48a235c23e9f1 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Fri, 15 Apr 2022 14:38:25 -0500 Subject: [PATCH 2/5] improve low-latency mode strategy --- src/engine/engine.cpp | 2 ++ src/engine/macroInt.cpp | 25 ++++++++++++++++--------- src/engine/macroInt.h | 11 ++++++----- src/engine/playback.cpp | 2 +- 4 files changed, 25 insertions(+), 15 deletions(-) diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp index 81d7947a..6257ff53 100644 --- a/src/engine/engine.cpp +++ b/src/engine/engine.cpp @@ -2237,6 +2237,8 @@ bool DivEngine::initAudioBackend() { if (metroVol<0.0f) metroVol=0.0f; if (metroVol>2.0f) metroVol=2.0f; + if (lowLatency) logI("using low latency mode."); + switch (audioEngine) { case DIV_AUDIO_JACK: #ifndef HAVE_JACK diff --git a/src/engine/macroInt.cpp b/src/engine/macroInt.cpp index ae6caf5d..00fee080 100644 --- a/src/engine/macroInt.cpp +++ b/src/engine/macroInt.cpp @@ -21,14 +21,19 @@ #include "instrument.h" #include "engine.h" -void DivMacroStruct::doMacro(DivInstrumentMacro& source, bool released) { +void DivMacroStruct::doMacro(DivInstrumentMacro& source, bool released, bool tick) { + if (!tick) { + had=false; + return; + } if (finished) { finished=false; } - if (had!=has) { + if (actualHad!=has) { finished=true; } - had=has; + actualHad=has; + had=actualHad; if (has) { val=source.val[pos++]; if (source.rel>=0 && pos>source.rel && !released) { @@ -52,17 +57,18 @@ void DivMacroInt::next() { if (ins==NULL) return; // run macros // TODO: potentially get rid of list to avoid allocations - if (--subTick<=0) { + subTick--; + for (size_t i=0; idoMacro(*macroSource[i],released,subTick==0); + } + } + if (subTick<=0) { if (e==NULL) { subTick=1; } else { subTick=e->tickMult; } - for (size_t i=0; idoMacro(*macroSource[i],released); - } - } } } @@ -85,6 +91,7 @@ void DivMacroInt::init(DivInstrument* which) { if (macroList[i]!=NULL) macroList[i]->init(); } macroListLen=0; + subTick=1; released=false; diff --git a/src/engine/macroInt.h b/src/engine/macroInt.h index 886ecbe2..f1cd29a7 100644 --- a/src/engine/macroInt.h +++ b/src/engine/macroInt.h @@ -27,17 +27,17 @@ class DivEngine; struct DivMacroStruct { int pos; int val; - bool has, had, finished, will; + bool has, had, actualHad, finished, will; unsigned int mode; - void doMacro(DivInstrumentMacro& source, bool released); + void doMacro(DivInstrumentMacro& source, bool released, bool tick); void init() { pos=mode=0; - has=had=will=false; + has=had=actualHad=will=false; // TODO: test whether this breaks anything? val=0; } void prepare(DivInstrumentMacro& source) { - has=had=will=true; + has=had=actualHad=will=true; mode=source.mode; } DivMacroStruct(): @@ -45,6 +45,7 @@ struct DivMacroStruct { val(0), has(false), had(false), + actualHad(false), finished(false), will(false), mode(0) {} @@ -128,7 +129,7 @@ class DivMacroInt { e(NULL), ins(NULL), macroListLen(0), - subTick(0), + subTick(1), released(false), vol(), arp(), diff --git a/src/engine/playback.cpp b/src/engine/playback.cpp index ea221330..fe42c73a 100644 --- a/src/engine/playback.cpp +++ b/src/engine/playback.cpp @@ -1654,7 +1654,7 @@ bool DivEngine::nextTick(bool noAccum) { } } - if (consoleMode) fprintf(stderr,"\x1b[2K> %d:%.2d:%.2d.%.2d %.2x/%.2x:%.3d/%.3d %4dcmd/s\x1b[G",totalSeconds/3600,(totalSeconds/60)%60,totalSeconds%60,totalTicks/10000,curOrder,song.ordersLen,curRow,song.patLen,cmdsPerSecond); + if (consoleMode && subticks<=1) fprintf(stderr,"\x1b[2K> %d:%.2d:%.2d.%.2d %.2x/%.2x:%.3d/%.3d %4dcmd/s\x1b[G",totalSeconds/3600,(totalSeconds/60)%60,totalSeconds%60,totalTicks/10000,curOrder,song.ordersLen,curRow,song.patLen,cmdsPerSecond); } if (haltOn==DIV_HALT_TICK) halted=true; From fd3d57b1cba942ded63d532c5db4f0ca3d378ace Mon Sep 17 00:00:00 2001 From: tildearrow Date: Fri, 15 Apr 2022 15:01:11 -0500 Subject: [PATCH 3/5] even more improvements to low-latency mode --- src/engine/dispatch.h | 3 ++- src/engine/platform/abstract.cpp | 2 +- src/engine/platform/amiga.cpp | 2 +- src/engine/platform/amiga.h | 2 +- src/engine/platform/arcade.cpp | 2 +- src/engine/platform/arcade.h | 2 +- src/engine/platform/ay.cpp | 2 +- src/engine/platform/ay.h | 2 +- src/engine/platform/ay8930.cpp | 2 +- src/engine/platform/ay8930.h | 2 +- src/engine/platform/bubsyswsg.cpp | 2 +- src/engine/platform/bubsyswsg.h | 2 +- src/engine/platform/c64.cpp | 16 +++++++++------- src/engine/platform/c64.h | 2 +- src/engine/platform/dummy.cpp | 10 ++++++---- src/engine/platform/dummy.h | 2 +- src/engine/platform/fds.cpp | 2 +- src/engine/platform/fds.h | 2 +- src/engine/platform/gb.cpp | 2 +- src/engine/platform/gb.h | 2 +- src/engine/platform/genesis.cpp | 2 +- src/engine/platform/genesis.h | 2 +- src/engine/platform/genesisext.cpp | 4 ++-- src/engine/platform/genesisext.h | 2 +- src/engine/platform/lynx.cpp | 2 +- src/engine/platform/lynx.h | 2 +- src/engine/platform/mmc5.cpp | 2 +- src/engine/platform/mmc5.h | 2 +- src/engine/platform/n163.cpp | 2 +- src/engine/platform/n163.h | 2 +- src/engine/platform/nes.cpp | 2 +- src/engine/platform/nes.h | 2 +- src/engine/platform/opl.cpp | 2 +- src/engine/platform/opl.h | 2 +- src/engine/platform/opll.cpp | 2 +- src/engine/platform/opll.h | 2 +- src/engine/platform/pce.cpp | 2 +- src/engine/platform/pce.h | 2 +- src/engine/platform/pcspkr.cpp | 2 +- src/engine/platform/pcspkr.h | 2 +- src/engine/platform/pet.cpp | 2 +- src/engine/platform/pet.h | 2 +- src/engine/platform/qsound.cpp | 2 +- src/engine/platform/qsound.h | 2 +- src/engine/platform/saa.cpp | 2 +- src/engine/platform/saa.h | 2 +- src/engine/platform/segapcm.cpp | 2 +- src/engine/platform/segapcm.h | 2 +- src/engine/platform/sms.cpp | 2 +- src/engine/platform/sms.h | 2 +- src/engine/platform/swan.cpp | 2 +- src/engine/platform/swan.h | 2 +- src/engine/platform/tia.cpp | 2 +- src/engine/platform/tia.h | 2 +- src/engine/platform/tx81z.cpp | 2 +- src/engine/platform/tx81z.h | 2 +- src/engine/platform/vera.cpp | 2 +- src/engine/platform/vera.h | 2 +- src/engine/platform/vic20.cpp | 2 +- src/engine/platform/vic20.h | 2 +- src/engine/platform/vrc6.cpp | 2 +- src/engine/platform/vrc6.h | 2 +- src/engine/platform/x1_010.cpp | 2 +- src/engine/platform/x1_010.h | 2 +- src/engine/platform/ym2610.cpp | 4 ++-- src/engine/platform/ym2610.h | 2 +- src/engine/platform/ym2610b.cpp | 4 ++-- src/engine/platform/ym2610b.h | 2 +- src/engine/platform/ym2610bext.cpp | 4 ++-- src/engine/platform/ym2610bext.h | 2 +- src/engine/platform/ym2610ext.cpp | 4 ++-- src/engine/platform/ym2610ext.h | 2 +- src/engine/playback.cpp | 2 +- src/engine/waveSynth.cpp | 4 ++++ src/engine/waveSynth.h | 3 ++- 75 files changed, 98 insertions(+), 88 deletions(-) diff --git a/src/engine/dispatch.h b/src/engine/dispatch.h index 37e36a2b..c35ff919 100644 --- a/src/engine/dispatch.h +++ b/src/engine/dispatch.h @@ -245,8 +245,9 @@ class DivDispatch { /** * ticks this dispatch. + * @param sysTick whether the engine has ticked (if not then this may be a sub-tick used in low-latency mode). */ - virtual void tick(); + virtual void tick(bool sysTick=true); /** * get the state of a channel. diff --git a/src/engine/platform/abstract.cpp b/src/engine/platform/abstract.cpp index b860f680..343838e7 100644 --- a/src/engine/platform/abstract.cpp +++ b/src/engine/platform/abstract.cpp @@ -22,7 +22,7 @@ void DivDispatch::acquire(short* bufL, short* bufR, size_t start, size_t len) { } -void DivDispatch::tick() { +void DivDispatch::tick(bool sysTick) { } void* DivDispatch::getChanState(int chan) { diff --git a/src/engine/platform/amiga.cpp b/src/engine/platform/amiga.cpp index b8419d19..104e66d4 100644 --- a/src/engine/platform/amiga.cpp +++ b/src/engine/platform/amiga.cpp @@ -155,7 +155,7 @@ void DivPlatformAmiga::acquire(short* bufL, short* bufR, size_t start, size_t le } } -void DivPlatformAmiga::tick() { +void DivPlatformAmiga::tick(bool sysTick) { for (int i=0; i<4; i++) { chan[i].std.next(); if (chan[i].std.vol.had) { diff --git a/src/engine/platform/amiga.h b/src/engine/platform/amiga.h index 8fbe8fec..07c44ee7 100644 --- a/src/engine/platform/amiga.h +++ b/src/engine/platform/amiga.h @@ -88,7 +88,7 @@ class DivPlatformAmiga: public DivDispatch { void* getChanState(int chan); void reset(); void forceIns(); - void tick(); + void tick(bool sysTick=true); void muteChannel(int ch, bool mute); bool isStereo(); bool keyOffAffectsArp(int ch); diff --git a/src/engine/platform/arcade.cpp b/src/engine/platform/arcade.cpp index a7ab53ec..0bcb3b99 100644 --- a/src/engine/platform/arcade.cpp +++ b/src/engine/platform/arcade.cpp @@ -219,7 +219,7 @@ inline int hScale(int note) { return ((note/12)<<4)+(noteMap[note%12]); } -void DivPlatformArcade::tick() { +void DivPlatformArcade::tick(bool sysTick) { for (int i=0; i<8; i++) { chan[i].std.next(); diff --git a/src/engine/platform/arcade.h b/src/engine/platform/arcade.h index a6ec82c9..41af49e3 100644 --- a/src/engine/platform/arcade.h +++ b/src/engine/platform/arcade.h @@ -107,7 +107,7 @@ class DivPlatformArcade: public DivDispatch { int getRegisterPoolSize(); void reset(); void forceIns(); - void tick(); + void tick(bool sysTick=true); void muteChannel(int ch, bool mute); void notifyInsChange(int ins); void setFlags(unsigned int flags); diff --git a/src/engine/platform/ay.cpp b/src/engine/platform/ay.cpp index e8a61b9a..d3db4ba8 100644 --- a/src/engine/platform/ay.cpp +++ b/src/engine/platform/ay.cpp @@ -172,7 +172,7 @@ void DivPlatformAY8910::updateOutSel(bool immediate) { } } -void DivPlatformAY8910::tick() { +void DivPlatformAY8910::tick(bool sysTick) { // PSG for (int i=0; i<3; i++) { chan[i].std.next(); diff --git a/src/engine/platform/ay.h b/src/engine/platform/ay.h index b1a3ea12..a78f21bc 100644 --- a/src/engine/platform/ay.h +++ b/src/engine/platform/ay.h @@ -90,7 +90,7 @@ class DivPlatformAY8910: public DivDispatch { void flushWrites(); void reset(); void forceIns(); - void tick(); + void tick(bool sysTick=true); void muteChannel(int ch, bool mute); void setFlags(unsigned int flags); bool isStereo(); diff --git a/src/engine/platform/ay8930.cpp b/src/engine/platform/ay8930.cpp index 9f684a04..9fa39131 100644 --- a/src/engine/platform/ay8930.cpp +++ b/src/engine/platform/ay8930.cpp @@ -187,7 +187,7 @@ const unsigned char regMode[3]={ 0x0d, 0x14, 0x15 }; -void DivPlatformAY8930::tick() { +void DivPlatformAY8930::tick(bool sysTick) { // PSG for (int i=0; i<3; i++) { chan[i].std.next(); diff --git a/src/engine/platform/ay8930.h b/src/engine/platform/ay8930.h index 6bd51bdc..adbe0be8 100644 --- a/src/engine/platform/ay8930.h +++ b/src/engine/platform/ay8930.h @@ -78,7 +78,7 @@ class DivPlatformAY8930: public DivDispatch { int getRegisterPoolSize(); void reset(); void forceIns(); - void tick(); + void tick(bool sysTick=true); void muteChannel(int ch, bool mute); void setFlags(unsigned int flags); bool isStereo(); diff --git a/src/engine/platform/bubsyswsg.cpp b/src/engine/platform/bubsyswsg.cpp index 4a80bf41..91f50d46 100644 --- a/src/engine/platform/bubsyswsg.cpp +++ b/src/engine/platform/bubsyswsg.cpp @@ -81,7 +81,7 @@ void DivPlatformBubSysWSG::updateWave(int ch) { } } -void DivPlatformBubSysWSG::tick() { +void DivPlatformBubSysWSG::tick(bool sysTick) { for (int i=0; i<2; i++) { chan[i].std.next(); if (chan[i].std.vol.had) { diff --git a/src/engine/platform/bubsyswsg.h b/src/engine/platform/bubsyswsg.h index 6c0e2261..2efcc4d9 100644 --- a/src/engine/platform/bubsyswsg.h +++ b/src/engine/platform/bubsyswsg.h @@ -67,7 +67,7 @@ class DivPlatformBubSysWSG: public DivDispatch { int getRegisterPoolDepth(); void reset(); void forceIns(); - void tick(); + void tick(bool sysTick=true); void muteChannel(int ch, bool mute); bool isStereo(); bool keyOffAffectsArp(int ch); diff --git a/src/engine/platform/c64.cpp b/src/engine/platform/c64.cpp index db5ab46a..4c3cc32e 100644 --- a/src/engine/platform/c64.cpp +++ b/src/engine/platform/c64.cpp @@ -122,7 +122,7 @@ void DivPlatformC64::updateFilter() { rWrite(0x18,(filtControl<<4)|vol); } -void DivPlatformC64::tick() { +void DivPlatformC64::tick(bool sysTick) { for (int i=0; i<3; i++) { chan[i].std.next(); if (chan[i].std.vol.had) { @@ -166,12 +166,14 @@ void DivPlatformC64::tick() { rWrite(i*7+2,chan[i].duty&0xff); rWrite(i*7+3,chan[i].duty>>8); } - if (chan[i].testWhen>0) { - if (--chan[i].testWhen<1) { - if (!chan[i].resetMask) { - rWrite(i*7+5,0); - rWrite(i*7+6,0); - rWrite(i*7+4,(chan[i].wave<<4)|8|(chan[i].ring<<2)|(chan[i].sync<<1)); + if (sysTick) { + if (chan[i].testWhen>0) { + if (--chan[i].testWhen<1) { + if (!chan[i].resetMask) { + rWrite(i*7+5,0); + rWrite(i*7+6,0); + rWrite(i*7+4,(chan[i].wave<<4)|8|(chan[i].ring<<2)|(chan[i].sync<<1)); + } } } } diff --git a/src/engine/platform/c64.h b/src/engine/platform/c64.h index e288940e..f77e24b9 100644 --- a/src/engine/platform/c64.h +++ b/src/engine/platform/c64.h @@ -83,7 +83,7 @@ class DivPlatformC64: public DivDispatch { int getRegisterPoolSize(); void reset(); void forceIns(); - void tick(); + void tick(bool sysTick=true); void muteChannel(int ch, bool mute); void setFlags(unsigned int flags); void notifyInsChange(int ins); diff --git a/src/engine/platform/dummy.cpp b/src/engine/platform/dummy.cpp index 308b8372..e751e3b6 100644 --- a/src/engine/platform/dummy.cpp +++ b/src/engine/platform/dummy.cpp @@ -38,10 +38,12 @@ void DivPlatformDummy::muteChannel(int ch, bool mute) { isMuted[ch]=mute; } -void DivPlatformDummy::tick() { +void DivPlatformDummy::tick(bool sysTick) { for (unsigned char i=0; isampleAudio( bufL + start, bufR + start, len ); } -void DivPlatformLynx::tick() { +void DivPlatformLynx::tick(bool sysTick) { for (int i=0; i<4; i++) { chan[i].std.next(); if (chan[i].std.vol.had) { diff --git a/src/engine/platform/lynx.h b/src/engine/platform/lynx.h index 536a874a..61f6e67d 100644 --- a/src/engine/platform/lynx.h +++ b/src/engine/platform/lynx.h @@ -80,7 +80,7 @@ class DivPlatformLynx: public DivDispatch { int getRegisterPoolSize(); void reset(); void forceIns(); - void tick(); + void tick(bool sysTick=true); void muteChannel(int ch, bool mute); bool isStereo(); bool keyOffAffectsArp(int ch); diff --git a/src/engine/platform/mmc5.cpp b/src/engine/platform/mmc5.cpp index a9f9bb79..3c7f3dca 100644 --- a/src/engine/platform/mmc5.cpp +++ b/src/engine/platform/mmc5.cpp @@ -95,7 +95,7 @@ void DivPlatformMMC5::acquire(short* bufL, short* bufR, size_t start, size_t len } } -void DivPlatformMMC5::tick() { +void DivPlatformMMC5::tick(bool sysTick) { for (int i=0; i<2; i++) { chan[i].std.next(); if (chan[i].std.vol.had) { diff --git a/src/engine/platform/mmc5.h b/src/engine/platform/mmc5.h index 6b364d5a..02ca06e8 100644 --- a/src/engine/platform/mmc5.h +++ b/src/engine/platform/mmc5.h @@ -71,7 +71,7 @@ class DivPlatformMMC5: public DivDispatch { int getRegisterPoolSize(); void reset(); void forceIns(); - void tick(); + void tick(bool sysTick=true); void muteChannel(int ch, bool mute); bool keyOffAffectsArp(int ch); float getPostAmp(); diff --git a/src/engine/platform/n163.cpp b/src/engine/platform/n163.cpp index a66157d9..6a1eb60e 100644 --- a/src/engine/platform/n163.cpp +++ b/src/engine/platform/n163.cpp @@ -214,7 +214,7 @@ void DivPlatformN163::updateWaveCh(int ch) { } } -void DivPlatformN163::tick() { +void DivPlatformN163::tick(bool sysTick) { for (int i=0; i<=chanMax; i++) { chan[i].std.next(); if (chan[i].std.vol.had) { diff --git a/src/engine/platform/n163.h b/src/engine/platform/n163.h index 2f68d6c9..38ebeace 100644 --- a/src/engine/platform/n163.h +++ b/src/engine/platform/n163.h @@ -93,7 +93,7 @@ class DivPlatformN163: public DivDispatch { int getRegisterPoolSize(); void reset(); void forceIns(); - void tick(); + void tick(bool sysTick=true); void muteChannel(int ch, bool mute); void setFlags(unsigned int flags); void notifyWaveChange(int wave); diff --git a/src/engine/platform/nes.cpp b/src/engine/platform/nes.cpp index 4c65ce4f..7e291446 100644 --- a/src/engine/platform/nes.cpp +++ b/src/engine/platform/nes.cpp @@ -140,7 +140,7 @@ static unsigned char noiseTable[253]={ 15 }; -void DivPlatformNES::tick() { +void DivPlatformNES::tick(bool sysTick) { for (int i=0; i<4; i++) { chan[i].std.next(); if (chan[i].std.vol.had) { diff --git a/src/engine/platform/nes.h b/src/engine/platform/nes.h index 1dbb4411..2cf2a8a1 100644 --- a/src/engine/platform/nes.h +++ b/src/engine/platform/nes.h @@ -72,7 +72,7 @@ class DivPlatformNES: public DivDispatch { int getRegisterPoolSize(); void reset(); void forceIns(); - void tick(); + void tick(bool sysTick=true); void muteChannel(int ch, bool mute); bool keyOffAffectsArp(int ch); float getPostAmp(); diff --git a/src/engine/platform/opl.cpp b/src/engine/platform/opl.cpp index add3815c..e73ca41e 100644 --- a/src/engine/platform/opl.cpp +++ b/src/engine/platform/opl.cpp @@ -228,7 +228,7 @@ void DivPlatformOPL::acquire(short* bufL, short* bufR, size_t start, size_t len) //} } -void DivPlatformOPL::tick() { +void DivPlatformOPL::tick(bool sysTick) { for (int i=0; i>4))/15)|(((vol*(pan&15))/15)<<4); } -void DivPlatformSAA1099::tick() { +void DivPlatformSAA1099::tick(bool sysTick) { for (int i=0; i<6; i++) { chan[i].std.next(); if (chan[i].std.vol.had) { diff --git a/src/engine/platform/saa.h b/src/engine/platform/saa.h index 8df44f61..0542ff51 100644 --- a/src/engine/platform/saa.h +++ b/src/engine/platform/saa.h @@ -90,7 +90,7 @@ class DivPlatformSAA1099: public DivDispatch { int getRegisterPoolSize(); void reset(); void forceIns(); - void tick(); + void tick(bool sysTick=true); void muteChannel(int ch, bool mute); void setCore(DivSAACores core); void setFlags(unsigned int flags); diff --git a/src/engine/platform/segapcm.cpp b/src/engine/platform/segapcm.cpp index b2a8b3db..97ff900a 100644 --- a/src/engine/platform/segapcm.cpp +++ b/src/engine/platform/segapcm.cpp @@ -76,7 +76,7 @@ void DivPlatformSegaPCM::acquire(short* bufL, short* bufR, size_t start, size_t } } -void DivPlatformSegaPCM::tick() { +void DivPlatformSegaPCM::tick(bool sysTick) { for (int i=0; i<16; i++) { chan[i].std.next(); diff --git a/src/engine/platform/segapcm.h b/src/engine/platform/segapcm.h index b3c84cd3..4b05c160 100644 --- a/src/engine/platform/segapcm.h +++ b/src/engine/platform/segapcm.h @@ -78,7 +78,7 @@ class DivPlatformSegaPCM: public DivDispatch { int getRegisterPoolSize(); void reset(); void forceIns(); - void tick(); + void tick(bool sysTick=true); void muteChannel(int ch, bool mute); void notifyInsChange(int ins); void setFlags(unsigned int flags); diff --git a/src/engine/platform/sms.cpp b/src/engine/platform/sms.cpp index a0f8abdd..acd2c072 100644 --- a/src/engine/platform/sms.cpp +++ b/src/engine/platform/sms.cpp @@ -53,7 +53,7 @@ int DivPlatformSMS::acquireOne() { return v; } -void DivPlatformSMS::tick() { +void DivPlatformSMS::tick(bool sysTick) { for (int i=0; i<4; i++) { chan[i].std.next(); if (chan[i].std.vol.had) { diff --git a/src/engine/platform/sms.h b/src/engine/platform/sms.h index b49a5e27..0aeb9e81 100644 --- a/src/engine/platform/sms.h +++ b/src/engine/platform/sms.h @@ -63,7 +63,7 @@ class DivPlatformSMS: public DivDispatch { void* getChanState(int chan); void reset(); void forceIns(); - void tick(); + void tick(bool sysTick=true); void muteChannel(int ch, bool mute); bool keyOffAffectsArp(int ch); bool keyOffAffectsPorta(int ch); diff --git a/src/engine/platform/swan.cpp b/src/engine/platform/swan.cpp index 30be897b..99d819b1 100644 --- a/src/engine/platform/swan.cpp +++ b/src/engine/platform/swan.cpp @@ -141,7 +141,7 @@ void DivPlatformSwan::writeOutVol(int ch) { } } -void DivPlatformSwan::tick() { +void DivPlatformSwan::tick(bool sysTick) { unsigned char sndCtrl=(pcm?0x20:0)|(sweep?0x40:0)|((noise>0)?0x80:0); for (int i=0; i<4; i++) { chan[i].std.next(); diff --git a/src/engine/platform/swan.h b/src/engine/platform/swan.h index 610884b0..0f1643c5 100644 --- a/src/engine/platform/swan.h +++ b/src/engine/platform/swan.h @@ -77,7 +77,7 @@ class DivPlatformSwan: public DivDispatch { int getRegisterPoolSize(); void reset(); void forceIns(); - void tick(); + void tick(bool sysTick=true); void muteChannel(int ch, bool mute); void notifyWaveChange(int wave); void notifyInsDeletion(void* ins); diff --git a/src/engine/platform/tia.cpp b/src/engine/platform/tia.cpp index 474cd00e..dc6c607f 100644 --- a/src/engine/platform/tia.cpp +++ b/src/engine/platform/tia.cpp @@ -84,7 +84,7 @@ unsigned char DivPlatformTIA::dealWithFreq(unsigned char shape, int base, int pi return 0; } -void DivPlatformTIA::tick() { +void DivPlatformTIA::tick(bool sysTick) { for (int i=0; i<2; i++) { chan[i].std.next(); if (chan[i].std.vol.had) { diff --git a/src/engine/platform/tia.h b/src/engine/platform/tia.h index ea149ec3..3ec3c7f3 100644 --- a/src/engine/platform/tia.h +++ b/src/engine/platform/tia.h @@ -51,7 +51,7 @@ class DivPlatformTIA: public DivDispatch { int getRegisterPoolSize(); void reset(); void forceIns(); - void tick(); + void tick(bool sysTick=true); void muteChannel(int ch, bool mute); void setFlags(unsigned int flags); bool isStereo(); diff --git a/src/engine/platform/tx81z.cpp b/src/engine/platform/tx81z.cpp index 34b975dd..6f71be75 100644 --- a/src/engine/platform/tx81z.cpp +++ b/src/engine/platform/tx81z.cpp @@ -183,7 +183,7 @@ inline int hScale(int note) { return ((note/12)<<4)+(noteMap[note%12]); } -void DivPlatformTX81Z::tick() { +void DivPlatformTX81Z::tick(bool sysTick) { for (int i=0; i<8; i++) { chan[i].std.next(); diff --git a/src/engine/platform/tx81z.h b/src/engine/platform/tx81z.h index 363d5c23..c61b4bfe 100644 --- a/src/engine/platform/tx81z.h +++ b/src/engine/platform/tx81z.h @@ -102,7 +102,7 @@ class DivPlatformTX81Z: public DivDispatch { int getRegisterPoolSize(); void reset(); void forceIns(); - void tick(); + void tick(bool sysTick=true); void muteChannel(int ch, bool mute); void notifyInsChange(int ins); void setFlags(unsigned int flags); diff --git a/src/engine/platform/vera.cpp b/src/engine/platform/vera.cpp index 7e887be8..31d52569 100644 --- a/src/engine/platform/vera.cpp +++ b/src/engine/platform/vera.cpp @@ -156,7 +156,7 @@ int DivPlatformVERA::calcNoteFreq(int ch, int note) { } } -void DivPlatformVERA::tick() { +void DivPlatformVERA::tick(bool sysTick) { for (int i=0; i<16; i++) { chan[i].std.next(); if (chan[i].std.vol.had) { diff --git a/src/engine/platform/vera.h b/src/engine/platform/vera.h index 2b47f99a..ec6dcde1 100644 --- a/src/engine/platform/vera.h +++ b/src/engine/platform/vera.h @@ -63,7 +63,7 @@ class DivPlatformVERA: public DivDispatch { unsigned char* getRegisterPool(); int getRegisterPoolSize(); void reset(); - void tick(); + void tick(bool sysTick=true); void muteChannel(int ch, bool mute); void notifyInsDeletion(void* ins); float getPostAmp(); diff --git a/src/engine/platform/vic20.cpp b/src/engine/platform/vic20.cpp index b3062a63..7817cd83 100644 --- a/src/engine/platform/vic20.cpp +++ b/src/engine/platform/vic20.cpp @@ -91,7 +91,7 @@ void DivPlatformVIC20::writeOutVol(int ch) { } } -void DivPlatformVIC20::tick() { +void DivPlatformVIC20::tick(bool sysTick) { for (int i=0; i<4; i++) { chan[i].std.next(); if (chan[i].std.vol.had) { diff --git a/src/engine/platform/vic20.h b/src/engine/platform/vic20.h index 1c4d384b..7948c5ef 100644 --- a/src/engine/platform/vic20.h +++ b/src/engine/platform/vic20.h @@ -66,7 +66,7 @@ class DivPlatformVIC20: public DivDispatch { int getRegisterPoolSize(); void reset(); void forceIns(); - void tick(); + void tick(bool sysTick=true); void muteChannel(int ch, bool mute); void setFlags(unsigned int flags); void notifyInsDeletion(void* ins); diff --git a/src/engine/platform/vrc6.cpp b/src/engine/platform/vrc6.cpp index b126deb6..048b42cd 100644 --- a/src/engine/platform/vrc6.cpp +++ b/src/engine/platform/vrc6.cpp @@ -135,7 +135,7 @@ void DivPlatformVRC6::acquire(short* bufL, short* bufR, size_t start, size_t len } } -void DivPlatformVRC6::tick() { +void DivPlatformVRC6::tick(bool sysTick) { for (int i=0; i<3; i++) { // 16 for pulse; 14 for saw int CHIP_DIVIDER=(i==2)?14:16; diff --git a/src/engine/platform/vrc6.h b/src/engine/platform/vrc6.h index 05cd8941..d28265a4 100644 --- a/src/engine/platform/vrc6.h +++ b/src/engine/platform/vrc6.h @@ -82,7 +82,7 @@ class DivPlatformVRC6: public DivDispatch { int getRegisterPoolSize(); void reset(); void forceIns(); - void tick(); + void tick(bool sysTick=true); void muteChannel(int ch, bool mute); bool keyOffAffectsArp(int ch); void setFlags(unsigned int flags); diff --git a/src/engine/platform/x1_010.cpp b/src/engine/platform/x1_010.cpp index 1bbd2a80..df6682ad 100644 --- a/src/engine/platform/x1_010.cpp +++ b/src/engine/platform/x1_010.cpp @@ -336,7 +336,7 @@ void DivPlatformX1_010::updateEnvelope(int ch) { } } -void DivPlatformX1_010::tick() { +void DivPlatformX1_010::tick(bool sysTick) { for (int i=0; i<16; i++) { chan[i].std.next(); if (chan[i].std.vol.had) { diff --git a/src/engine/platform/x1_010.h b/src/engine/platform/x1_010.h index 2bfb78cc..bee54647 100644 --- a/src/engine/platform/x1_010.h +++ b/src/engine/platform/x1_010.h @@ -126,7 +126,7 @@ class DivPlatformX1_010: public DivDispatch { int getRegisterPoolSize(); void reset(); void forceIns(); - void tick(); + void tick(bool sysTick=true); void muteChannel(int ch, bool mute); bool isStereo(); bool keyOffAffectsArp(int ch); diff --git a/src/engine/platform/ym2610.cpp b/src/engine/platform/ym2610.cpp index a1f5ea65..3d6c8ed2 100644 --- a/src/engine/platform/ym2610.cpp +++ b/src/engine/platform/ym2610.cpp @@ -365,9 +365,9 @@ void DivPlatformYM2610::acquire(short* bufL, short* bufR, size_t start, size_t l } } -void DivPlatformYM2610::tick() { +void DivPlatformYM2610::tick(bool sysTick) { // PSG - ay->tick(); + ay->tick(sysTick); ay->flushWrites(); for (DivRegWrite& i: ay->getRegisterWrites()) { immWrite(i.addr&15,i.val); diff --git a/src/engine/platform/ym2610.h b/src/engine/platform/ym2610.h index 2fd525b0..e75e24d7 100644 --- a/src/engine/platform/ym2610.h +++ b/src/engine/platform/ym2610.h @@ -116,7 +116,7 @@ class DivPlatformYM2610: public DivDispatch { int getRegisterPoolSize(); void reset(); void forceIns(); - void tick(); + void tick(bool sysTick=true); void muteChannel(int ch, bool mute); bool isStereo(); bool keyOffAffectsArp(int ch); diff --git a/src/engine/platform/ym2610b.cpp b/src/engine/platform/ym2610b.cpp index 130eb29a..aeadeae4 100644 --- a/src/engine/platform/ym2610b.cpp +++ b/src/engine/platform/ym2610b.cpp @@ -429,9 +429,9 @@ void DivPlatformYM2610B::acquire(short* bufL, short* bufR, size_t start, size_t } } -void DivPlatformYM2610B::tick() { +void DivPlatformYM2610B::tick(bool sysTick) { // PSG - ay->tick(); + ay->tick(sysTick); ay->flushWrites(); for (DivRegWrite& i: ay->getRegisterWrites()) { immWrite(i.addr&15,i.val); diff --git a/src/engine/platform/ym2610b.h b/src/engine/platform/ym2610b.h index d6b616c5..6d46ecb2 100644 --- a/src/engine/platform/ym2610b.h +++ b/src/engine/platform/ym2610b.h @@ -107,7 +107,7 @@ class DivPlatformYM2610B: public DivDispatch { int getRegisterPoolSize(); void reset(); void forceIns(); - void tick(); + void tick(bool sysTick=true); void muteChannel(int ch, bool mute); bool isStereo(); bool keyOffAffectsArp(int ch); diff --git a/src/engine/platform/ym2610bext.cpp b/src/engine/platform/ym2610bext.cpp index 03e9f869..496a308e 100644 --- a/src/engine/platform/ym2610bext.cpp +++ b/src/engine/platform/ym2610bext.cpp @@ -212,7 +212,7 @@ static int opChanOffsH[4]={ 0xad, 0xae, 0xac, 0xa6 }; -void DivPlatformYM2610BExt::tick() { +void DivPlatformYM2610BExt::tick(bool sysTick) { if (extMode) { bool writeSomething=false; unsigned char writeMask=2; @@ -229,7 +229,7 @@ void DivPlatformYM2610BExt::tick() { } } - DivPlatformYM2610B::tick(); + DivPlatformYM2610B::tick(sysTick); bool writeNoteOn=false; unsigned char writeMask=2; diff --git a/src/engine/platform/ym2610bext.h b/src/engine/platform/ym2610bext.h index 25ca5919..e908916e 100644 --- a/src/engine/platform/ym2610bext.h +++ b/src/engine/platform/ym2610bext.h @@ -41,7 +41,7 @@ class DivPlatformYM2610BExt: public DivPlatformYM2610B { void* getChanState(int chan); void reset(); void forceIns(); - void tick(); + void tick(bool sysTick=true); void muteChannel(int ch, bool mute); bool keyOffAffectsArp(int ch); void notifyInsChange(int ins); diff --git a/src/engine/platform/ym2610ext.cpp b/src/engine/platform/ym2610ext.cpp index 40294733..dc462508 100644 --- a/src/engine/platform/ym2610ext.cpp +++ b/src/engine/platform/ym2610ext.cpp @@ -212,7 +212,7 @@ static int opChanOffsH[4]={ 0xad, 0xae, 0xac, 0xa6 }; -void DivPlatformYM2610Ext::tick() { +void DivPlatformYM2610Ext::tick(bool sysTick) { if (extMode) { bool writeSomething=false; unsigned char writeMask=2; @@ -229,7 +229,7 @@ void DivPlatformYM2610Ext::tick() { } } - DivPlatformYM2610::tick(); + DivPlatformYM2610::tick(sysTick); bool writeNoteOn=false; unsigned char writeMask=2; diff --git a/src/engine/platform/ym2610ext.h b/src/engine/platform/ym2610ext.h index 37c9e328..9fa44d0b 100644 --- a/src/engine/platform/ym2610ext.h +++ b/src/engine/platform/ym2610ext.h @@ -41,7 +41,7 @@ class DivPlatformYM2610Ext: public DivPlatformYM2610 { void* getChanState(int chan); void reset(); void forceIns(); - void tick(); + void tick(bool sysTick=true); void muteChannel(int ch, bool mute); bool keyOffAffectsArp(int ch); void notifyInsChange(int ins); diff --git a/src/engine/playback.cpp b/src/engine/playback.cpp index fe42c73a..0f378963 100644 --- a/src/engine/playback.cpp +++ b/src/engine/playback.cpp @@ -1638,7 +1638,7 @@ bool DivEngine::nextTick(bool noAccum) { firstTick=false; // system tick - for (int i=0; itick(); + for (int i=0; itick(subticks==tickMult); if (!freelance) { if (stepPlay!=1) { diff --git a/src/engine/waveSynth.cpp b/src/engine/waveSynth.cpp index 2b9946ee..7bae30d9 100644 --- a/src/engine/waveSynth.cpp +++ b/src/engine/waveSynth.cpp @@ -30,8 +30,11 @@ bool DivWaveSynth::activeChanged() { } bool DivWaveSynth::tick() { + if (--subDivCounter>0) return false; + bool updated=first; first=false; + subDivCounter=e->tickMult; if (!state.enabled) return updated; if (width<1) return false; @@ -167,6 +170,7 @@ void DivWaveSynth::init(DivInstrument* which, int w, int h, bool insChanged) { pos=0; stage=0; divCounter=1+state.rateDivider; + subDivCounter=0; first=true; changeWave1(state.wave1); diff --git a/src/engine/waveSynth.h b/src/engine/waveSynth.h index ecd6f8a8..f5c89e3a 100644 --- a/src/engine/waveSynth.h +++ b/src/engine/waveSynth.h @@ -28,7 +28,7 @@ class DivEngine; class DivWaveSynth { DivEngine* e; DivInstrumentWaveSynth state; - int pos, stage, divCounter, width, height; + int pos, stage, divCounter, width, height, subDivCounter; bool first, activeChangedB; unsigned char wave1[256]; unsigned char wave2[256]; @@ -78,6 +78,7 @@ class DivWaveSynth { divCounter(0), width(32), height(31), + subDivCounter(0), first(false), activeChangedB(false) { memset(wave1,0,256); From 55d821de6e99eb574cfcdf96fa917b871cc2d0e2 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Fri, 15 Apr 2022 16:00:21 -0500 Subject: [PATCH 4/5] potential to-do for Windows --- src/main.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main.cpp b/src/main.cpp index f8c749f7..8f41b10c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -239,6 +239,7 @@ void initParams() { params.push_back(TAParam("W","warranty",false,pWarranty,"","view warranty disclaimer.")); } +// TODO: CoInitializeEx on Windows? int main(int argc, char** argv) { initLog(); #if !(defined(__APPLE__) || defined(_WIN32)) From 98b9bd32b94b350b1fbca1bc558ddafb2b604f5b Mon Sep 17 00:00:00 2001 From: tildearrow Date: Fri, 15 Apr 2022 16:10:57 -0500 Subject: [PATCH 5/5] static_assert() on cmdName --- src/engine/playback.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/engine/playback.cpp b/src/engine/playback.cpp index 0f378963..2b22abd2 100644 --- a/src/engine/playback.cpp +++ b/src/engine/playback.cpp @@ -40,7 +40,7 @@ const char* notes[12]={ }; // update this when adding new commands. -const char* cmdName[DIV_CMD_MAX]={ +const char* cmdName[]={ "NOTE_ON", "NOTE_OFF", "NOTE_OFF_ENV", @@ -144,6 +144,7 @@ const char* cmdName[DIV_CMD_MAX]={ "N163_WAVE_LOAD", "N163_WAVE_LOADPOS", "N163_WAVE_LOADLEN", + "N163_WAVE_LOADMODE", "N163_CHANNEL_LIMIT", "N163_GLOBAL_WAVE_LOAD", "N163_GLOBAL_WAVE_LOADPOS", @@ -153,6 +154,8 @@ const char* cmdName[DIV_CMD_MAX]={ "ALWAYS_SET_VOLUME" }; +static_assert((sizeof(cmdName)/sizeof(void*))==DIV_CMD_MAX,"update cmdName!"); + const char* formatNote(unsigned char note, unsigned char octave) { static char ret[4]; if (note==100) {