From 6a58797669baa17375c518b1be9a7c86a8d8bbdc Mon Sep 17 00:00:00 2001 From: Natt Akuma Date: Wed, 18 Sep 2024 13:05:45 +0700 Subject: [PATCH 1/5] Use bsr() in frequency shift calculations --- src/engine/bsr.h | 59 +++++++++++++++++++-------- src/engine/platform/esfm.cpp | 17 ++++---- src/engine/platform/opl.cpp | 77 ++++++------------------------------ src/engine/platform/opll.cpp | 42 ++++---------------- src/engine/platform/saa.cpp | 20 ++-------- src/gui/fmPreview.cpp | 7 ++-- 6 files changed, 77 insertions(+), 145 deletions(-) diff --git a/src/engine/bsr.h b/src/engine/bsr.h index dcc865112..566125383 100644 --- a/src/engine/bsr.h +++ b/src/engine/bsr.h @@ -44,7 +44,7 @@ static inline int bsr32(unsigned int v) { static inline int bsr(unsigned short v) { if (v) { - return 32 - __builtin_clz(v); + return 32-__builtin_clz(v); } else { return -1; } @@ -52,7 +52,7 @@ static inline int bsr(unsigned short v) { static inline int bsr32(unsigned int v) { if (v) { - return 32 - __builtin_clz(v); + return 32-__builtin_clz(v); } else { return -1; } @@ -61,25 +61,52 @@ static inline int bsr32(unsigned int v) { #else static inline int bsr(unsigned short v) { - unsigned short mask = 0x8000; - for (int i = 16; i >= 0; --i) { - if (v&mask) - return i; - mask>>=1; + if (v==0) return -1; + if (v&0x8000) return 16; + int o=16; + if (!(v&0xff00)) { + o-=8; + v<<=8; + if (v&0x8000) return o; } - - return -1; + if (!(v&0xf000)) { + o-=4; + v<<=4; + if (v&0x8000) return o; + } + if (!(v&0xc000)) { + o-=2; + v<<=2; + if (v&0x8000) return o; + } + return (v&0x8000) ? o : o-1; } static inline int bsr32(unsigned int v) { - unsigned int mask = 0x80000000; - for (int i = 32; i >= 0; --i) { - if (v&mask) - return i; - mask>>=1; + if (v==0) return -1; + if (v&0x80000000) return 32; + int o=32; + if (!(v&0xffff0000)) { + o-=16; + v<<=16; + if (v&0x80000000) return o; } - - return -1; + if (!(v&0xff000000)) { + o-=8; + v<<=8; + if (v&0x80000000) return o; + } + if (!(v&0xf0000000)) { + o-=4; + v<<=4; + if (v&0x80000000) return o; + } + if (!(v&0xc0000000)) { + o-=2; + v<<=2; + if (v&0x80000000) return o; + } + return (v&0x80000000) ? o : o-1; } #endif diff --git a/src/engine/platform/esfm.cpp b/src/engine/platform/esfm.cpp index 3adab20f5..388fdf972 100644 --- a/src/engine/platform/esfm.cpp +++ b/src/engine/platform/esfm.cpp @@ -19,6 +19,7 @@ #include "esfm.h" #include "../engine.h" +#include "../bsr.h" #include "../../ta-log.h" #include #include @@ -366,21 +367,19 @@ void DivPlatformESFM::tick(bool sysTick) { } int DivPlatformESFM::octave(int freq) { - int result=1; - while (freq>0x3ff) { - freq>>=1; - result<<=1; + if (freq>0x3ff) { + return 1<<(bsr32(freq)-10); } - return result; + return 1; } int DivPlatformESFM::toFreq(int freq) { int block=0; - while (freq>0x3ff) { - freq>>=1; - block++; + if (freq>0x3ff) { + block=bsr32(freq)-10; + freq>>=block; } - return ((block&7)<<10)|(freq&0x3ff); + return (block<<10)|(freq&0x3ff); } void DivPlatformESFM::muteChannel(int ch, bool mute) { diff --git a/src/engine/platform/opl.cpp b/src/engine/platform/opl.cpp index 1204615dc..6ff60b69d 100644 --- a/src/engine/platform/opl.cpp +++ b/src/engine/platform/opl.cpp @@ -19,6 +19,7 @@ #include "opl.h" #include "../engine.h" +#include "../bsr.h" #include "../../ta-log.h" #include #include @@ -1386,39 +1387,12 @@ void DivPlatformOPL::tick(bool sysTick) { double off=(s->centerRate>=1)?((double)s->centerRate/8363.0):1.0; chan[i].freq=(int)(off*parent->calcFreq(chan[i].baseFreq,chan[i].pitch,chan[i].fixedArp?chan[i].baseNoteOverride:chan[i].arpOff,chan[i].fixedArp,false,2,chan[i].pitch2,chipClock,(524288*768))); if (chan[i].freq<0x400) chan[i].freq=0x400; - if (chan[i].freq>0x3ffffff) chan[i].freq=0x3ffffff; - if (chan[i].freq>=0x2000000) { + chan[i].freqH=0; + if (chan[i].freq>0x3ffffff) { + chan[i].freq=0x3ffffff; chan[i].freqH=15; - } else if (chan[i].freq>=0x1000000) { - chan[i].freqH=14; - } else if (chan[i].freq>=0x800000) { - chan[i].freqH=13; - } else if (chan[i].freq>=0x400000) { - chan[i].freqH=12; - } else if (chan[i].freq>=0x200000) { - chan[i].freqH=11; - } else if (chan[i].freq>=0x100000) { - chan[i].freqH=10; - } else if (chan[i].freq>=0x80000) { - chan[i].freqH=9; - } else if (chan[i].freq>=0x40000) { - chan[i].freqH=8; - } else if (chan[i].freq>=0x20000) { - chan[i].freqH=7; - } else if (chan[i].freq>=0x10000) { - chan[i].freqH=6; - } else if (chan[i].freq>=0x8000) { - chan[i].freqH=5; - } else if (chan[i].freq>=0x4000) { - chan[i].freqH=4; - } else if (chan[i].freq>=0x2000) { - chan[i].freqH=3; - } else if (chan[i].freq>=0x1000) { - chan[i].freqH=2; } else if (chan[i].freq>=0x800) { - chan[i].freqH=1; - } else { - chan[i].freqH=0; + chan[i].freqH=bsr32(chan[i].freq)-11; } chan[i].freqL=(chan[i].freq>>chan[i].freqH)&0x3ff; chan[i].freqH=8^chan[i].freqH; @@ -1528,44 +1502,15 @@ void DivPlatformOPL::tick(bool sysTick) { #define OPLL_C_NUM 686 int DivPlatformOPL::octave(int freq) { - if (freq>=OPLL_C_NUM*64) { - return 128; - } else if (freq>=OPLL_C_NUM*32) { - return 64; - } else if (freq>=OPLL_C_NUM*16) { - return 32; - } else if (freq>=OPLL_C_NUM*8) { - return 16; - } else if (freq>=OPLL_C_NUM*4) { - return 8; - } else if (freq>=OPLL_C_NUM*2) { - return 4; - } else if (freq>=OPLL_C_NUM) { - return 2; - } else { - return 1; - } - return 1; + freq/=OPLL_C_NUM; + if (freq==0) return 1; + return 1<=OPLL_C_NUM*64) { - return 0x1c00|((freq>>7)&0x3ff); - } else if (freq>=OPLL_C_NUM*32) { - return 0x1800|((freq>>6)&0x3ff); - } else if (freq>=OPLL_C_NUM*16) { - return 0x1400|((freq>>5)&0x3ff); - } else if (freq>=OPLL_C_NUM*8) { - return 0x1000|((freq>>4)&0x3ff); - } else if (freq>=OPLL_C_NUM*4) { - return 0xc00|((freq>>3)&0x3ff); - } else if (freq>=OPLL_C_NUM*2) { - return 0x800|((freq>>2)&0x3ff); - } else if (freq>=OPLL_C_NUM) { - return 0x400|((freq>>1)&0x3ff); - } else { - return freq&0x3ff; - } + int block=freq/OPLL_C_NUM; + if (block>0) block=bsr(block); + return (block<<10)|((freq>>block)&0x3ff); } void DivPlatformOPL::muteChannel(int ch, bool mute) { diff --git a/src/engine/platform/opll.cpp b/src/engine/platform/opll.cpp index fb3461622..a185d55bd 100644 --- a/src/engine/platform/opll.cpp +++ b/src/engine/platform/opll.cpp @@ -19,6 +19,7 @@ #include "opll.h" #include "../engine.h" +#include "../bsr.h" #include "../../ta-log.h" #include #include @@ -352,44 +353,15 @@ void DivPlatformOPLL::tick(bool sysTick) { #define OPLL_C_NUM 343 int DivPlatformOPLL::octave(int freq) { - if (freq>=OPLL_C_NUM*64) { - return 128; - } else if (freq>=OPLL_C_NUM*32) { - return 64; - } else if (freq>=OPLL_C_NUM*16) { - return 32; - } else if (freq>=OPLL_C_NUM*8) { - return 16; - } else if (freq>=OPLL_C_NUM*4) { - return 8; - } else if (freq>=OPLL_C_NUM*2) { - return 4; - } else if (freq>=OPLL_C_NUM) { - return 2; - } else { - return 1; - } - return 1; + freq/=OPLL_C_NUM; + if (freq==0) return 1; + return 1<=OPLL_C_NUM*64) { - return 0xe00|((freq>>7)&0x1ff); - } else if (freq>=OPLL_C_NUM*32) { - return 0xc00|((freq>>6)&0x1ff); - } else if (freq>=OPLL_C_NUM*16) { - return 0xa00|((freq>>5)&0x1ff); - } else if (freq>=OPLL_C_NUM*8) { - return 0x800|((freq>>4)&0x1ff); - } else if (freq>=OPLL_C_NUM*4) { - return 0x600|((freq>>3)&0x1ff); - } else if (freq>=OPLL_C_NUM*2) { - return 0x400|((freq>>2)&0x1ff); - } else if (freq>=OPLL_C_NUM) { - return 0x200|((freq>>1)&0x1ff); - } else { - return freq&0x1ff; - } + int block=freq/OPLL_C_NUM; + if (block>0) block=bsr(block); + return (block<<9)|((freq>>block)&0x1ff); } void DivPlatformOPLL::muteChannel(int ch, bool mute) { diff --git a/src/engine/platform/saa.cpp b/src/engine/platform/saa.cpp index f1e033b75..4f22cadde 100644 --- a/src/engine/platform/saa.cpp +++ b/src/engine/platform/saa.cpp @@ -19,6 +19,7 @@ #include "saa.h" #include "../engine.h" +#include "../bsr.h" #include "sound/saa1099.h" #include #include @@ -155,22 +156,9 @@ void DivPlatformSAA1099::tick(bool sysTick) { if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) { chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,chan[i].fixedArp?chan[i].baseNoteOverride:chan[i].arpOff,chan[i].fixedArp,true,0,chan[i].pitch2,chipClock,CHIP_DIVIDER); if (chan[i].freq>65535) chan[i].freq=65535; - if (chan[i].freq>=32768) { - chan[i].freqH=7; - } else if (chan[i].freq>=16384) { - chan[i].freqH=6; - } else if (chan[i].freq>=8192) { - chan[i].freqH=5; - } else if (chan[i].freq>=4096) { - chan[i].freqH=4; - } else if (chan[i].freq>=2048) { - chan[i].freqH=3; - } else if (chan[i].freq>=1024) { - chan[i].freqH=2; - } else if (chan[i].freq>=512) { - chan[i].freqH=1; - } else { - chan[i].freqH=0; + chan[i].freqH=0; + if (chan[i].freq>511) { + chan[i].freqH=bsr((unsigned short)chan[i].freq)-9; } chan[i].freqL=0xff-(chan[i].freq>>chan[i].freqH); chan[i].freqH=7-chan[i].freqH; diff --git a/src/gui/fmPreview.cpp b/src/gui/fmPreview.cpp index 4e11137b9..fc4eb0c6c 100644 --- a/src/gui/fmPreview.cpp +++ b/src/gui/fmPreview.cpp @@ -27,6 +27,7 @@ extern "C" { #include "../../extern/Nuked-OPLL/opll.h" } #include "../engine/platform/sound/ymfm/ymfm_opz.h" +#include "../engine/bsr.h" #define OPN_WRITE(addr,val) \ OPN2_Write((ym3438_t*)fmPreviewOPN,0,(addr)); \ @@ -388,9 +389,9 @@ void FurnaceGUI::renderFMPreviewESFM(const DivInstrumentFM& params, const DivIns double fbase=(mult0?2048.0:1024.0)*pow(2.0,(float)offset/(128.0*12.0)); int bf=round(fbase); int block=0; - while (bf>0x3ff) { - bf>>=1; - block++; + if (bf>0x3ff) { + block=bsr32(bf)-10; + bf>>=block; } freqL=bf&0xff; freqH=((block&7)<<2)|((bf>>8)&3); From cf3d08ca5a096ace951b6ee611dd0e7a64768dcf Mon Sep 17 00:00:00 2001 From: Natt Akuma Date: Wed, 18 Sep 2024 14:48:10 +0700 Subject: [PATCH 2/5] Add fixed octave for block+fnum systems This isn't implemented in SAA1099, despite also being block+fnum system, as there are no benefits from it --- papers/newIns.md | 1 + src/engine/dispatch.h | 2 +- src/engine/engine.cpp | 24 ++++++++++++++--- src/engine/engine.h | 8 +++--- src/engine/instrument.cpp | 6 +++++ src/engine/instrument.h | 3 ++- src/engine/platform/esfm.cpp | 36 +++++++++++++++++++------- src/engine/platform/esfm.h | 4 +-- src/engine/platform/fmshared_OPN.h | 2 +- src/engine/platform/genesis.cpp | 8 +++--- src/engine/platform/genesisext.cpp | 8 +++--- src/engine/platform/opl.cpp | 41 ++++++++++++++++++++++-------- src/engine/platform/opl.h | 4 +-- src/engine/platform/opll.cpp | 41 ++++++++++++++++++++++-------- src/engine/platform/opll.h | 4 +-- src/engine/platform/ym2203.cpp | 10 ++++---- src/engine/platform/ym2203ext.cpp | 8 +++--- src/engine/platform/ym2608.cpp | 8 +++--- src/engine/platform/ym2608ext.cpp | 8 +++--- src/engine/platform/ym2610.cpp | 6 ++--- src/engine/platform/ym2610b.cpp | 6 ++--- src/engine/platform/ym2610bext.cpp | 8 +++--- src/engine/platform/ym2610ext.cpp | 8 +++--- src/engine/platform/ym2610shared.h | 2 +- src/gui/insEdit.cpp | 35 +++++++++++++++++-------- 25 files changed, 194 insertions(+), 97 deletions(-) diff --git a/papers/newIns.md b/papers/newIns.md index d983a3d2e..32152bd32 100644 --- a/papers/newIns.md +++ b/papers/newIns.md @@ -192,6 +192,7 @@ size | description 1 | |x| ALG |x| FB | 1 | |FMS2 |AMS| FMS | 1 | |AM2|4| LLPatch | + 1 | |xxxxxxx| Block | (>=224) -----|------------------------------------ | **operator data × opCount** | /7 6 5 4 3 2 1 0| diff --git a/src/engine/dispatch.h b/src/engine/dispatch.h index 52e5c1c10..a3e203102 100644 --- a/src/engine/dispatch.h +++ b/src/engine/dispatch.h @@ -948,7 +948,7 @@ class DivDispatch { #define NOTE_FREQUENCY(x) parent->calcBaseFreq(chipClock,CHIP_FREQBASE,x,false) // this is a special case definition. only use it for f-num/block-based chips. -#define NOTE_FNUM_BLOCK(x,bits) parent->calcBaseFreqFNumBlock(chipClock,CHIP_FREQBASE,x,bits) +#define NOTE_FNUM_BLOCK(x,bits,ins) parent->calcBaseFreqFNumBlock(chipClock,CHIP_FREQBASE,x,bits,parent->getIns(ins)->fm.block) // this is for volume scaling calculation. #define VOL_SCALE_LINEAR(x,y,range) ((parent->song.ceilVolumeScaling)?((((x)*(y))+(range-1))/(range)):(((x)*(y))/(range))) diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp index f50bbc753..850dd98b4 100644 --- a/src/engine/engine.cpp +++ b/src/engine/engine.cpp @@ -1797,15 +1797,27 @@ double DivEngine::calcBaseFreq(double clock, double divider, int note, bool peri /* logV("f-num: %d block: %d",bf,block); */ \ return bf|(block<>=(block); \ + if (bf<0) bf=0; \ + if (bf>((1<<(bits))-1)) { \ + bf=(1<<(bits))-1; \ + } \ + return bf|((block)<<(bits)); + +int DivEngine::calcBaseFreqFNumBlock(double clock, double divider, int note, int bits, int fixedBlock) { if (song.linearPitch==2) { // full linear return (note<<7); } int bf=calcBaseFreq(clock,divider,note,false); - CONVERT_FNUM_BLOCK(bf,bits,note) + if (fixedBlock>0) { + CONVERT_FNUM_FIXEDBLOCK(bf,bits,fixedBlock-1); + } else { + CONVERT_FNUM_BLOCK(bf,bits,note); + } } -int DivEngine::calcFreq(int base, int pitch, int arp, bool arpFixed, bool period, int octave, int pitch2, double clock, double divider, int blockBits) { +int DivEngine::calcFreq(int base, int pitch, int arp, bool arpFixed, bool period, int octave, int pitch2, double clock, double divider, int blockBits, int fixedBlock) { if (song.linearPitch==2) { // do frequency calculation here int nbase=base+pitch+pitch2; @@ -1821,7 +1833,11 @@ int DivEngine::calcFreq(int base, int pitch, int arp, bool arpFixed, bool period round((clock/fbase)/divider): round(fbase*(divider/clock)); if (blockBits>0) { - CONVERT_FNUM_BLOCK(bf,blockBits,nbase>>7) + if (fixedBlock>0) { + CONVERT_FNUM_FIXEDBLOCK(bf,blockBits,fixedBlock-1); + } else { + CONVERT_FNUM_BLOCK(bf,blockBits,nbase>>7); + } } else { return bf; } diff --git a/src/engine/engine.h b/src/engine/engine.h index c64268dd8..5b6a83c51 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -54,8 +54,8 @@ class DivWorkPool; #define DIV_UNSTABLE -#define DIV_VERSION "dev223" -#define DIV_ENGINE_VERSION 223 +#define DIV_VERSION "dev224" +#define DIV_ENGINE_VERSION 224 // for imports #define DIV_VERSION_MOD 0xff01 #define DIV_VERSION_FC 0xff02 @@ -805,10 +805,10 @@ class DivEngine { double calcBaseFreq(double clock, double divider, int note, bool period); // calculate base frequency in f-num/block format - int calcBaseFreqFNumBlock(double clock, double divider, int note, int bits); + int calcBaseFreqFNumBlock(double clock, double divider, int note, int bits, int fixedBlock); // calculate frequency/period - int calcFreq(int base, int pitch, int arp, bool arpFixed, bool period=false, int octave=0, int pitch2=0, double clock=1.0, double divider=1.0, int blockBits=0); + int calcFreq(int base, int pitch, int arp, bool arpFixed, bool period=false, int octave=0, int pitch2=0, double clock=1.0, double divider=1.0, int blockBits=0, int fixedBlock=0); // calculate arpeggio int calcArp(int note, int arp, int offset=0); diff --git a/src/engine/instrument.cpp b/src/engine/instrument.cpp index 18ef4a31c..f068015cd 100644 --- a/src/engine/instrument.cpp +++ b/src/engine/instrument.cpp @@ -409,6 +409,7 @@ void DivInstrument::writeFeatureFM(SafeWriter* w, bool fui) { w->writeC(((fm.alg&7)<<4)|(fm.fb&7)); w->writeC(((fm.fms2&7)<<5)|((fm.ams&3)<<3)|(fm.fms&7)); w->writeC(((fm.ams2&3)<<6)|((fm.ops==4)?32:0)|(fm.opllPreset&31)); + w->writeC(fm.block&15); // operator data for (int i=0; i=224) { + next=reader.readC(); + fm.block=next&15; + } + // read operators for (int i=0; icalcFreq(chan[i].baseFreq,chan[i].pitch,chan[i].fixedArp?chan[i].baseNoteOverride:chan[i].arpOff,chan[i].fixedArp,false,octave(chan[i].baseFreq)*2,chan[i].pitch2,chipClock,CHIP_FREQBASE); + int mul=2; + int fixedBlock=parent->getIns(chan[i].ins)->fm.block; + if (parent->song.linearPitch!=2) { + mul=octave(chan[i].baseFreq,fixedBlock)*2; + } + chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,chan[i].fixedArp?chan[i].baseNoteOverride:chan[i].arpOff,chan[i].fixedArp,false,mul,chan[i].pitch2,chipClock,CHIP_FREQBASE); if (chan[i].freq<0) chan[i].freq=0; if (chan[i].freq>131071) chan[i].freq=131071; @@ -315,10 +320,10 @@ void DivPlatformESFM::tick(bool sysTick) { if(chan[i].opsState[o].hasOpPitch) { pitch2=chan[i].opsState[o].pitch2+dt; } - int opFreq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,arp,fixedArp,false,octave(chan[i].baseFreq)*2,pitch2,chipClock,CHIP_FREQBASE); + int opFreq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,arp,fixedArp,false,mul,pitch2,chipClock,CHIP_FREQBASE); if (opFreq<0) opFreq=0; if (opFreq>131071) opFreq=131071; - int freqt=toFreq(opFreq); + int freqt=toFreq(opFreq,fixedBlock); chan[i].freqL[o]=freqt&0xff; chan[i].freqH[o]=freqt>>8; } @@ -366,16 +371,23 @@ void DivPlatformESFM::tick(bool sysTick) { } } -int DivPlatformESFM::octave(int freq) { +int DivPlatformESFM::octave(int freq, int fixedBlock) { + if (fixedBlock>0) { + return 1<<(fixedBlock-1); + } if (freq>0x3ff) { return 1<<(bsr32(freq)-10); } return 1; } -int DivPlatformESFM::toFreq(int freq) { +int DivPlatformESFM::toFreq(int freq, int fixedBlock) { int block=0; - if (freq>0x3ff) { + if (fixedBlock>0) { + block=fixedBlock-1; + freq>>=block; + if (freq>0x3ff) freq=0x3ff; + } else if (freq>0x3ff) { block=bsr32(freq)-10; freq>>=block; } @@ -512,21 +524,27 @@ int DivPlatformESFM::dispatch(DivCommand c) { int destFreq=NOTE_FREQUENCY(c.value2); int newFreq; bool return2=false; + int mul=1; + int fixedBlock=0; + if (parent->song.linearPitch!=2) { + fixedBlock=parent->getIns(chan[c.chan].ins)->fm.block; + mul=octave(chan[c.chan].baseFreq,fixedBlock); + } if (destFreq>chan[c.chan].baseFreq) { - newFreq=chan[c.chan].baseFreq+c.value*((parent->song.linearPitch==2)?1:octave(chan[c.chan].baseFreq)); + newFreq=chan[c.chan].baseFreq+c.value*mul; if (newFreq>=destFreq) { newFreq=destFreq; return2=true; } } else { - newFreq=chan[c.chan].baseFreq-c.value*((parent->song.linearPitch==2)?1:octave(chan[c.chan].baseFreq)); + newFreq=chan[c.chan].baseFreq-c.value*mul; if (newFreq<=destFreq) { newFreq=destFreq; return2=true; } } if (!chan[c.chan].portaPause && parent->song.linearPitch!=2) { - if (octave(chan[c.chan].baseFreq)!=octave(newFreq)) { + if (mul!=octave(newFreq,fixedBlock)) { chan[c.chan].portaPause=true; break; } diff --git a/src/engine/platform/esfm.h b/src/engine/platform/esfm.h index 8321369bf..a46e12079 100644 --- a/src/engine/platform/esfm.h +++ b/src/engine/platform/esfm.h @@ -126,8 +126,8 @@ class DivPlatformESFM: public DivDispatch { short oldWrites[ESFM_REG_POOL_SIZE]; short pendingWrites[ESFM_REG_POOL_SIZE]; - int octave(int freq); - int toFreq(int freq); + int octave(int freq, int fixedBlock); + int toFreq(int freq, int fixedBlock); void commitState(int ch, DivInstrument* ins); friend void putDispatchChip(void*,int); diff --git a/src/engine/platform/fmshared_OPN.h b/src/engine/platform/fmshared_OPN.h index 6c29ecf93..64d121003 100644 --- a/src/engine/platform/fmshared_OPN.h +++ b/src/engine/platform/fmshared_OPN.h @@ -27,7 +27,7 @@ #define PLEASE_HELP_ME(_targetChan) \ int boundaryBottom=parent->calcBaseFreq(chipClock,CHIP_FREQBASE,0,false); \ int boundaryTop=parent->calcBaseFreq(chipClock,CHIP_FREQBASE,12,false); \ - int destFreq=NOTE_FNUM_BLOCK(c.value2,11); \ + int destFreq=NOTE_FNUM_BLOCK(c.value2,11,_targetChan.ins); \ int newFreq; \ bool return2=false; \ if (_targetChan.portaPause) { \ diff --git a/src/engine/platform/genesis.cpp b/src/engine/platform/genesis.cpp index a2cfc7fbb..ee246f50c 100644 --- a/src/engine/platform/genesis.cpp +++ b/src/engine/platform/genesis.cpp @@ -657,7 +657,7 @@ void DivPlatformGenesis::tick(bool sysTick) { chan[i].handleArp(); } else if (chan[i].std.arp.had) { if (!chan[i].inPorta) { - chan[i].baseFreq=NOTE_FNUM_BLOCK(parent->calcArp(chan[i].note,chan[i].std.arp.val),11); + chan[i].baseFreq=NOTE_FNUM_BLOCK(parent->calcArp(chan[i].note,chan[i].std.arp.val),11,chan[i].ins); } chan[i].freqChanged=true; } @@ -838,7 +838,7 @@ void DivPlatformGenesis::tick(bool sysTick) { if (i==2 && extMode) continue; if (chan[i].freqChanged) { if (parent->song.linearPitch==2) { - chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,chan[i].fixedArp?chan[i].baseNoteOverride:chan[i].arpOff,chan[i].fixedArp,false,2,chan[i].pitch2,chipClock,CHIP_FREQBASE,11); + chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,chan[i].fixedArp?chan[i].baseNoteOverride:chan[i].arpOff,chan[i].fixedArp,false,2,chan[i].pitch2,chipClock,CHIP_FREQBASE,11,parent->getIns(chan[i].ins)->fm.block); } else { int fNum=parent->calcFreq(chan[i].baseFreq&0x7ff,chan[i].pitch,chan[i].fixedArp?chan[i].baseNoteOverride:chan[i].arpOff,chan[i].fixedArp,false,2,chan[i].pitch2,chipClock,CHIP_FREQBASE,11); int block=(chan[i].baseFreq&0xf800)>>11; @@ -1084,7 +1084,7 @@ int DivPlatformGenesis::dispatch(DivCommand c) { chan[c.chan].insChanged=false; if (c.value!=DIV_NOTE_NULL) { - chan[c.chan].baseFreq=NOTE_FNUM_BLOCK(c.value,11); + chan[c.chan].baseFreq=NOTE_FNUM_BLOCK(c.value,11,chan[c.chan].ins); chan[c.chan].portaPause=false; chan[c.chan].note=c.value; chan[c.chan].freqChanged=true; @@ -1274,7 +1274,7 @@ int DivPlatformGenesis::dispatch(DivCommand c) { commitState(c.chan,ins); chan[c.chan].insChanged=false; } - chan[c.chan].baseFreq=NOTE_FNUM_BLOCK(c.value,11); + chan[c.chan].baseFreq=NOTE_FNUM_BLOCK(c.value,11,chan[c.chan].ins); } chan[c.chan].note=c.value; chan[c.chan].freqChanged=true; diff --git a/src/engine/platform/genesisext.cpp b/src/engine/platform/genesisext.cpp index 3ff9fc53c..fb63620e9 100644 --- a/src/engine/platform/genesisext.cpp +++ b/src/engine/platform/genesisext.cpp @@ -96,7 +96,7 @@ int DivPlatformGenesisExt::dispatch(DivCommand c) { opChan[ch].insChanged=false; if (c.value!=DIV_NOTE_NULL) { - opChan[ch].baseFreq=NOTE_FNUM_BLOCK(c.value,11); + opChan[ch].baseFreq=NOTE_FNUM_BLOCK(c.value,11,opChan[ch].ins); opChan[ch].portaPause=false; opChan[ch].note=c.value; opChan[ch].freqChanged=true; @@ -216,7 +216,7 @@ int DivPlatformGenesisExt::dispatch(DivCommand c) { commitStateExt(ch,ins); opChan[ch].insChanged=false; } - opChan[ch].baseFreq=NOTE_FNUM_BLOCK(c.value,11); + opChan[ch].baseFreq=NOTE_FNUM_BLOCK(c.value,11,opChan[ch].ins); opChan[ch].freqChanged=true; break; } @@ -517,7 +517,7 @@ void DivPlatformGenesisExt::tick(bool sysTick) { if (opChan[i].std.arp.had) { if (!opChan[i].inPorta) { - opChan[i].baseFreq=NOTE_FNUM_BLOCK(parent->calcArp(opChan[i].note,opChan[i].std.arp.val),11); + opChan[i].baseFreq=NOTE_FNUM_BLOCK(parent->calcArp(opChan[i].note,opChan[i].std.arp.val),11,opChan[i].ins); } opChan[i].freqChanged=true; } @@ -638,7 +638,7 @@ void DivPlatformGenesisExt::tick(bool sysTick) { if (extMode) for (int i=0; i<4; i++) { if (opChan[i].freqChanged) { if (parent->song.linearPitch==2) { - opChan[i].freq=parent->calcFreq(opChan[i].baseFreq,opChan[i].pitch,opChan[i].fixedArp?opChan[i].baseNoteOverride:opChan[i].arpOff,opChan[i].fixedArp,false,2,opChan[i].pitch2,chipClock,CHIP_FREQBASE,11); + opChan[i].freq=parent->calcFreq(opChan[i].baseFreq,opChan[i].pitch,opChan[i].fixedArp?opChan[i].baseNoteOverride:opChan[i].arpOff,opChan[i].fixedArp,false,2,opChan[i].pitch2,chipClock,CHIP_FREQBASE,11,parent->getIns(chan[i].ins)->fm.block); } else { int fNum=parent->calcFreq(opChan[i].baseFreq&0x7ff,opChan[i].pitch,opChan[i].fixedArp?opChan[i].baseNoteOverride:opChan[i].arpOff,opChan[i].fixedArp,false,2,opChan[i].pitch2); int block=(opChan[i].baseFreq&0xf800)>>11; diff --git a/src/engine/platform/opl.cpp b/src/engine/platform/opl.cpp index 6ff60b69d..56ae1f897 100644 --- a/src/engine/platform/opl.cpp +++ b/src/engine/platform/opl.cpp @@ -1433,11 +1433,16 @@ void DivPlatformOPL::tick(bool sysTick) { } } else { if (chan[i].freqChanged) { - chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,chan[i].fixedArp?chan[i].baseNoteOverride:chan[i].arpOff,chan[i].fixedArp,false,octave(chan[i].baseFreq)*2,chan[i].pitch2,chipClock,CHIP_FREQBASE); + int mul=2; + int fixedBlock=parent->getIns(chan[i].ins)->fm.block; + if (parent->song.linearPitch!=2) { + mul=octave(chan[i].baseFreq,fixedBlock)*2; + } + chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,chan[i].fixedArp?chan[i].baseNoteOverride:chan[i].arpOff,chan[i].fixedArp,false,mul,chan[i].pitch2,chipClock,CHIP_FREQBASE); if (chan[i].fixedFreq>0) chan[i].freq=chan[i].fixedFreq; if (chan[i].freq<0) chan[i].freq=0; if (chan[i].freq>131071) chan[i].freq=131071; - int freqt=toFreq(chan[i].freq); + int freqt=toFreq(chan[i].freq,fixedBlock); chan[i].freqH=freqt>>8; chan[i].freqL=freqt&0xff; immWrite(chanMap[i]+ADDR_FREQ,chan[i].freqL); @@ -1501,16 +1506,26 @@ void DivPlatformOPL::tick(bool sysTick) { #define OPLL_C_NUM 686 -int DivPlatformOPL::octave(int freq) { +int DivPlatformOPL::octave(int freq, int fixedBlock) { + if (fixedBlock>0) { + return 1<<(fixedBlock-1); + } freq/=OPLL_C_NUM; if (freq==0) return 1; return 1<0) block=bsr(block); - return (block<<10)|((freq>>block)&0x3ff); +int DivPlatformOPL::toFreq(int freq, int fixedBlock) { + int block=0; + if (fixedBlock>0) { + block=fixedBlock-1; + } else { + block=freq/OPLL_C_NUM; + if (block>0) block=bsr(block); + } + freq>>=block; + if (freq>0x3ff) freq=0x3ff; + return (block<<10)|freq; } void DivPlatformOPL::muteChannel(int ch, bool mute) { @@ -2020,21 +2035,27 @@ int DivPlatformOPL::dispatch(DivCommand c) { int destFreq=(c.chan==adpcmChan)?(NOTE_ADPCMB(c.value2)):(NOTE_FREQUENCY(c.value2)); int newFreq; bool return2=false; + int mul=1; + int fixedBlock=0; + if (parent->song.linearPitch!=2) { + fixedBlock=parent->getIns(chan[c.chan].ins)->fm.block; + mul=octave(chan[c.chan].baseFreq,fixedBlock); + } if (destFreq>chan[c.chan].baseFreq) { - newFreq=chan[c.chan].baseFreq+c.value*((parent->song.linearPitch==2)?1:octave(chan[c.chan].baseFreq)); + newFreq=chan[c.chan].baseFreq+c.value*mul; if (newFreq>=destFreq) { newFreq=destFreq; return2=true; } } else { - newFreq=chan[c.chan].baseFreq-c.value*((parent->song.linearPitch==2)?1:octave(chan[c.chan].baseFreq)); + newFreq=chan[c.chan].baseFreq-c.value*mul; if (newFreq<=destFreq) { newFreq=destFreq; return2=true; } } if (!chan[c.chan].portaPause && parent->song.linearPitch!=2) { - if (octave(chan[c.chan].baseFreq)!=octave(newFreq)) { + if (mul!=octave(newFreq,fixedBlock)) { chan[c.chan].portaPause=true; break; } diff --git a/src/engine/platform/opl.h b/src/engine/platform/opl.h index f976d0468..39b544daa 100644 --- a/src/engine/platform/opl.h +++ b/src/engine/platform/opl.h @@ -169,8 +169,8 @@ class DivPlatformOPL: public DivDispatch { DivMemoryComposition memCompo; - int octave(int freq); - int toFreq(int freq); + int octave(int freq, int fixedBlock); + int toFreq(int freq, int fixedBlock); double NOTE_ADPCMB(int note); void commitState(int ch, DivInstrument* ins); diff --git a/src/engine/platform/opll.cpp b/src/engine/platform/opll.cpp index a185d55bd..b5dbce83a 100644 --- a/src/engine/platform/opll.cpp +++ b/src/engine/platform/opll.cpp @@ -295,11 +295,16 @@ void DivPlatformOPLL::tick(bool sysTick) { for (int i=0; i<11; i++) { if (chan[i].freqChanged) { - chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,chan[i].fixedArp?chan[i].baseNoteOverride:chan[i].arpOff,chan[i].fixedArp,false,octave(chan[i].baseFreq)*2,chan[i].pitch2,chipClock,CHIP_FREQBASE); + int mul=2; + int fixedBlock=parent->getIns(chan[i].ins)->fm.block; + if (parent->song.linearPitch!=2) { + mul=octave(chan[i].baseFreq,fixedBlock)*2; + } + chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,chan[i].fixedArp?chan[i].baseNoteOverride:chan[i].arpOff,chan[i].fixedArp,false,mul,chan[i].pitch2,chipClock,CHIP_FREQBASE); if (chan[i].fixedFreq>0 && properDrums) chan[i].freq=chan[i].fixedFreq; if (chan[i].freq<0) chan[i].freq=0; if (chan[i].freq>65535) chan[i].freq=65535; - int freqt=toFreq(chan[i].freq); + int freqt=toFreq(chan[i].freq,fixedBlock); if (freqt>4095) freqt=4095; chan[i].freqL=freqt&0xff; if (i>=6 && properDrums && (i<9 || !noTopHatFreq)) { @@ -352,16 +357,26 @@ void DivPlatformOPLL::tick(bool sysTick) { #define OPLL_C_NUM 343 -int DivPlatformOPLL::octave(int freq) { +int DivPlatformOPLL::octave(int freq, int fixedBlock) { + if (fixedBlock>0) { + return 1<<(fixedBlock-1); + } freq/=OPLL_C_NUM; if (freq==0) return 1; return 1<0) block=bsr(block); - return (block<<9)|((freq>>block)&0x1ff); +int DivPlatformOPLL::toFreq(int freq, int fixedBlock) { + int block=0; + if (fixedBlock>0) { + block=fixedBlock-1; + } else { + block=freq/OPLL_C_NUM; + if (block>0) block=bsr(block); + } + freq>>=block; + if (freq>0x1ff) freq=0x1ff; + return (block<<9)|freq; } void DivPlatformOPLL::muteChannel(int ch, bool mute) { @@ -622,21 +637,27 @@ int DivPlatformOPLL::dispatch(DivCommand c) { int destFreq=NOTE_FREQUENCY(c.value2); int newFreq; bool return2=false; + int mul=1; + int fixedBlock=0; + if (parent->song.linearPitch!=2) { + fixedBlock=parent->getIns(chan[c.chan].ins)->fm.block; + mul=octave(chan[c.chan].baseFreq,fixedBlock); + } if (destFreq>chan[c.chan].baseFreq) { - newFreq=chan[c.chan].baseFreq+c.value*((parent->song.linearPitch==2)?1:octave(chan[c.chan].baseFreq)); + newFreq=chan[c.chan].baseFreq+c.value*mul; if (newFreq>=destFreq) { newFreq=destFreq; return2=true; } } else { - newFreq=chan[c.chan].baseFreq-c.value*((parent->song.linearPitch==2)?1:octave(chan[c.chan].baseFreq)); + newFreq=chan[c.chan].baseFreq-c.value*mul; if (newFreq<=destFreq) { newFreq=destFreq; return2=true; } } /*if (!chan[c.chan].portaPause) { - if (octave(chan[c.chan].baseFreq)!=octave(newFreq)) { + if (mul!=octave(newFreq,fixedBlock)) { chan[c.chan].portaPause=true; break; } diff --git a/src/engine/platform/opll.h b/src/engine/platform/opll.h index b1f6e56ac..58d2538b6 100644 --- a/src/engine/platform/opll.h +++ b/src/engine/platform/opll.h @@ -80,8 +80,8 @@ class DivPlatformOPLL: public DivDispatch { short oldWrites[256]; short pendingWrites[256]; - int octave(int freq); - int toFreq(int freq); + int octave(int freq, int fixedBlock); + int toFreq(int freq, int fixedBlock); void commitState(int ch, DivInstrument* ins); void switchMode(bool mode); diff --git a/src/engine/platform/ym2203.cpp b/src/engine/platform/ym2203.cpp index 58044e12d..fafbe036f 100644 --- a/src/engine/platform/ym2203.cpp +++ b/src/engine/platform/ym2203.cpp @@ -503,7 +503,7 @@ void DivPlatformYM2203::tick(bool sysTick) { chan[i].handleArp(); } else if (chan[i].std.arp.had) { if (!chan[i].inPorta) { - chan[i].baseFreq=NOTE_FNUM_BLOCK(parent->calcArp(chan[i].note,chan[i].std.arp.val),11); + chan[i].baseFreq=NOTE_FNUM_BLOCK(parent->calcArp(chan[i].note,chan[i].std.arp.val),11,chan[i].ins); } chan[i].freqChanged=true; } @@ -638,7 +638,7 @@ void DivPlatformYM2203::tick(bool sysTick) { if (i==2 && extMode) continue; if (chan[i].freqChanged) { if (parent->song.linearPitch==2) { - chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,chan[i].fixedArp?chan[i].baseNoteOverride:chan[i].arpOff,chan[i].fixedArp,false,4,chan[i].pitch2,chipClock,CHIP_FREQBASE,11); + chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,chan[i].fixedArp?chan[i].baseNoteOverride:chan[i].arpOff,chan[i].fixedArp,false,4,chan[i].pitch2,chipClock,CHIP_FREQBASE,11,parent->getIns(chan[i].ins)->fm.block); } else { int fNum=parent->calcFreq(chan[i].baseFreq&0x7ff,chan[i].pitch,chan[i].fixedArp?chan[i].baseNoteOverride:chan[i].arpOff,chan[i].fixedArp,false,4,chan[i].pitch2); int block=(chan[i].baseFreq&0xf800)>>11; @@ -760,7 +760,7 @@ int DivPlatformYM2203::dispatch(DivCommand c) { chan[c.chan].insChanged=false; if (c.value!=DIV_NOTE_NULL) { - chan[c.chan].baseFreq=NOTE_FNUM_BLOCK(c.value,11); + chan[c.chan].baseFreq=NOTE_FNUM_BLOCK(c.value,11,chan[c.chan].ins); chan[c.chan].portaPause=false; chan[c.chan].freqChanged=true; chan[c.chan].note=c.value; @@ -844,7 +844,7 @@ int DivPlatformYM2203::dispatch(DivCommand c) { break; } if (c.chan>(psgChanOffs-1) || parent->song.linearPitch==2) { // PSG - int destFreq=NOTE_FNUM_BLOCK(c.value2,11); + int destFreq=NOTE_FNUM_BLOCK(c.value2,11,chan[c.chan].ins); bool return2=false; if (destFreq>chan[c.chan].baseFreq) { chan[c.chan].baseFreq+=c.value; @@ -878,7 +878,7 @@ int DivPlatformYM2203::dispatch(DivCommand c) { commitState(c.chan,ins); chan[c.chan].insChanged=false; } - chan[c.chan].baseFreq=NOTE_FNUM_BLOCK(c.value,11); + chan[c.chan].baseFreq=NOTE_FNUM_BLOCK(c.value,11,chan[c.chan].ins); chan[c.chan].freqChanged=true; break; } diff --git a/src/engine/platform/ym2203ext.cpp b/src/engine/platform/ym2203ext.cpp index eeae96957..c954c93e5 100644 --- a/src/engine/platform/ym2203ext.cpp +++ b/src/engine/platform/ym2203ext.cpp @@ -89,7 +89,7 @@ int DivPlatformYM2203Ext::dispatch(DivCommand c) { opChan[ch].insChanged=false; if (c.value!=DIV_NOTE_NULL) { - opChan[ch].baseFreq=NOTE_FNUM_BLOCK(c.value,11); + opChan[ch].baseFreq=NOTE_FNUM_BLOCK(c.value,11,opChan[ch].ins); opChan[ch].portaPause=false; opChan[ch].note=c.value; opChan[ch].freqChanged=true; @@ -177,7 +177,7 @@ int DivPlatformYM2203Ext::dispatch(DivCommand c) { commitStateExt(ch,ins); opChan[ch].insChanged=false; } - opChan[ch].baseFreq=NOTE_FNUM_BLOCK(c.value,11); + opChan[ch].baseFreq=NOTE_FNUM_BLOCK(c.value,11,opChan[ch].ins); opChan[ch].freqChanged=true; break; } @@ -444,7 +444,7 @@ void DivPlatformYM2203Ext::tick(bool sysTick) { if (opChan[i].std.arp.had) { if (!opChan[i].inPorta) { - opChan[i].baseFreq=NOTE_FNUM_BLOCK(parent->calcArp(opChan[i].note,opChan[i].std.arp.val),11); + opChan[i].baseFreq=NOTE_FNUM_BLOCK(parent->calcArp(opChan[i].note,opChan[i].std.arp.val),11,opChan[i].ins); } opChan[i].freqChanged=true; } @@ -543,7 +543,7 @@ void DivPlatformYM2203Ext::tick(bool sysTick) { if (extMode) for (int i=0; i<4; i++) { if (opChan[i].freqChanged) { if (parent->song.linearPitch==2) { - opChan[i].freq=parent->calcFreq(opChan[i].baseFreq,opChan[i].pitch,opChan[i].fixedArp?opChan[i].baseNoteOverride:opChan[i].arpOff,opChan[i].fixedArp,false,4,opChan[i].pitch2,chipClock,CHIP_FREQBASE,11); + opChan[i].freq=parent->calcFreq(opChan[i].baseFreq,opChan[i].pitch,opChan[i].fixedArp?opChan[i].baseNoteOverride:opChan[i].arpOff,opChan[i].fixedArp,false,4,opChan[i].pitch2,chipClock,CHIP_FREQBASE,11,parent->getIns(chan[i].ins)->fm.block); } else { int fNum=parent->calcFreq(opChan[i].baseFreq&0x7ff,opChan[i].pitch,opChan[i].fixedArp?opChan[i].baseNoteOverride:opChan[i].arpOff,opChan[i].fixedArp,false,4,opChan[i].pitch2); int block=(opChan[i].baseFreq&0xf800)>>11; diff --git a/src/engine/platform/ym2608.cpp b/src/engine/platform/ym2608.cpp index 7e027db29..fb8ff1a73 100644 --- a/src/engine/platform/ym2608.cpp +++ b/src/engine/platform/ym2608.cpp @@ -284,7 +284,7 @@ double DivPlatformYM2608::NOTE_OPNB(int ch, int note) { return NOTE_PERIODIC(note); } // FM - return NOTE_FNUM_BLOCK(note,11); + return NOTE_FNUM_BLOCK(note,11,chan[ch].ins); } double DivPlatformYM2608::NOTE_ADPCMB(int note) { @@ -719,7 +719,7 @@ void DivPlatformYM2608::tick(bool sysTick) { chan[i].handleArp(); } else if (chan[i].std.arp.had) { if (!chan[i].inPorta) { - chan[i].baseFreq=NOTE_FNUM_BLOCK(parent->calcArp(chan[i].note,chan[i].std.arp.val),11); + chan[i].baseFreq=NOTE_FNUM_BLOCK(parent->calcArp(chan[i].note,chan[i].std.arp.val),11,chan[i].ins); } chan[i].freqChanged=true; } @@ -871,7 +871,7 @@ void DivPlatformYM2608::tick(bool sysTick) { if (i==2 && extMode) continue; if (chan[i].freqChanged) { if (parent->song.linearPitch==2) { - chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,chan[i].fixedArp?chan[i].baseNoteOverride:chan[i].arpOff,chan[i].fixedArp,false,4,chan[i].pitch2,chipClock,CHIP_FREQBASE,11); + chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,chan[i].fixedArp?chan[i].baseNoteOverride:chan[i].arpOff,chan[i].fixedArp,false,4,chan[i].pitch2,chipClock,CHIP_FREQBASE,11,parent->getIns(chan[i].ins)->fm.block); } else { int fNum=parent->calcFreq(chan[i].baseFreq&0x7ff,chan[i].pitch,chan[i].fixedArp?chan[i].baseNoteOverride:chan[i].arpOff,chan[i].fixedArp,false,4,chan[i].pitch2); int block=(chan[i].baseFreq&0xf800)>>11; @@ -1233,7 +1233,7 @@ int DivPlatformYM2608::dispatch(DivCommand c) { chan[c.chan].insChanged=false; if (c.value!=DIV_NOTE_NULL) { - chan[c.chan].baseFreq=NOTE_FNUM_BLOCK(c.value,11); + chan[c.chan].baseFreq=NOTE_FNUM_BLOCK(c.value,11,chan[c.chan].ins); chan[c.chan].portaPause=false; chan[c.chan].freqChanged=true; chan[c.chan].note=c.value; diff --git a/src/engine/platform/ym2608ext.cpp b/src/engine/platform/ym2608ext.cpp index 15038de14..28fe75cdd 100644 --- a/src/engine/platform/ym2608ext.cpp +++ b/src/engine/platform/ym2608ext.cpp @@ -93,7 +93,7 @@ int DivPlatformYM2608Ext::dispatch(DivCommand c) { opChan[ch].insChanged=false; if (c.value!=DIV_NOTE_NULL) { - opChan[ch].baseFreq=NOTE_FNUM_BLOCK(c.value,11); + opChan[ch].baseFreq=NOTE_FNUM_BLOCK(c.value,11,opChan[ch].ins); opChan[ch].portaPause=false; opChan[ch].note=c.value; opChan[ch].freqChanged=true; @@ -197,7 +197,7 @@ int DivPlatformYM2608Ext::dispatch(DivCommand c) { commitStateExt(ch,ins); opChan[ch].insChanged=false; } - opChan[ch].baseFreq=NOTE_FNUM_BLOCK(c.value,11); + opChan[ch].baseFreq=NOTE_FNUM_BLOCK(c.value,11,opChan[ch].ins); opChan[ch].freqChanged=true; break; } @@ -472,7 +472,7 @@ void DivPlatformYM2608Ext::tick(bool sysTick) { if (opChan[i].std.arp.had) { if (!opChan[i].inPorta) { - opChan[i].baseFreq=NOTE_FNUM_BLOCK(parent->calcArp(opChan[i].note,opChan[i].std.arp.val),11); + opChan[i].baseFreq=NOTE_FNUM_BLOCK(parent->calcArp(opChan[i].note,opChan[i].std.arp.val),11,opChan[i].ins); } opChan[i].freqChanged=true; } @@ -594,7 +594,7 @@ void DivPlatformYM2608Ext::tick(bool sysTick) { if (extMode) for (int i=0; i<4; i++) { if (opChan[i].freqChanged) { if (parent->song.linearPitch==2) { - opChan[i].freq=parent->calcFreq(opChan[i].baseFreq,opChan[i].pitch,opChan[i].fixedArp?opChan[i].baseNoteOverride:opChan[i].arpOff,opChan[i].fixedArp,false,4,opChan[i].pitch2,chipClock,CHIP_FREQBASE,11); + opChan[i].freq=parent->calcFreq(opChan[i].baseFreq,opChan[i].pitch,opChan[i].fixedArp?opChan[i].baseNoteOverride:opChan[i].arpOff,opChan[i].fixedArp,false,4,opChan[i].pitch2,chipClock,CHIP_FREQBASE,11,parent->getIns(chan[i].ins)->fm.block); } else { int fNum=parent->calcFreq(opChan[i].baseFreq&0x7ff,opChan[i].pitch,opChan[i].fixedArp?opChan[i].baseNoteOverride:opChan[i].arpOff,opChan[i].fixedArp,false,4,opChan[i].pitch2); int block=(opChan[i].baseFreq&0xf800)>>11; diff --git a/src/engine/platform/ym2610.cpp b/src/engine/platform/ym2610.cpp index afad156ce..1533eb995 100644 --- a/src/engine/platform/ym2610.cpp +++ b/src/engine/platform/ym2610.cpp @@ -647,7 +647,7 @@ void DivPlatformYM2610::tick(bool sysTick) { chan[i].handleArp(); } else if (chan[i].std.arp.had) { if (!chan[i].inPorta) { - chan[i].baseFreq=NOTE_FNUM_BLOCK(parent->calcArp(chan[i].note,chan[i].std.arp.val),11); + chan[i].baseFreq=NOTE_FNUM_BLOCK(parent->calcArp(chan[i].note,chan[i].std.arp.val),11,chan[i].ins); } chan[i].freqChanged=true; } @@ -799,7 +799,7 @@ void DivPlatformYM2610::tick(bool sysTick) { if (i==1 && extMode) continue; if (chan[i].freqChanged) { if (parent->song.linearPitch==2) { - chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,chan[i].fixedArp?chan[i].baseNoteOverride:chan[i].arpOff,chan[i].fixedArp,false,4,chan[i].pitch2,chipClock,CHIP_FREQBASE,11); + chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,chan[i].fixedArp?chan[i].baseNoteOverride:chan[i].arpOff,chan[i].fixedArp,false,4,chan[i].pitch2,chipClock,CHIP_FREQBASE,11,parent->getIns(chan[i].ins)->fm.block); } else { int fNum=parent->calcFreq(chan[i].baseFreq&0x7ff,chan[i].pitch,chan[i].fixedArp?chan[i].baseNoteOverride:chan[i].arpOff,chan[i].fixedArp,false,4,chan[i].pitch2,chipClock,CHIP_FREQBASE,11); int block=(chan[i].baseFreq&0xf800)>>11; @@ -1200,7 +1200,7 @@ int DivPlatformYM2610::dispatch(DivCommand c) { chan[c.chan].insChanged=false; if (c.value!=DIV_NOTE_NULL) { - chan[c.chan].baseFreq=NOTE_FNUM_BLOCK(c.value,11); + chan[c.chan].baseFreq=NOTE_FNUM_BLOCK(c.value,11,chan[c.chan].ins); chan[c.chan].portaPause=false; chan[c.chan].freqChanged=true; chan[c.chan].note=c.value; diff --git a/src/engine/platform/ym2610b.cpp b/src/engine/platform/ym2610b.cpp index 9874e7da1..20a4f973d 100644 --- a/src/engine/platform/ym2610b.cpp +++ b/src/engine/platform/ym2610b.cpp @@ -715,7 +715,7 @@ void DivPlatformYM2610B::tick(bool sysTick) { chan[i].handleArp(); } else if (chan[i].std.arp.had) { if (!chan[i].inPorta) { - chan[i].baseFreq=NOTE_FNUM_BLOCK(parent->calcArp(chan[i].note,chan[i].std.arp.val),11); + chan[i].baseFreq=NOTE_FNUM_BLOCK(parent->calcArp(chan[i].note,chan[i].std.arp.val),11,chan[i].ins); } chan[i].freqChanged=true; } @@ -867,7 +867,7 @@ void DivPlatformYM2610B::tick(bool sysTick) { if (i==2 && extMode) continue; if (chan[i].freqChanged) { if (parent->song.linearPitch==2) { - chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,chan[i].fixedArp?chan[i].baseNoteOverride:chan[i].arpOff,chan[i].fixedArp,false,4,chan[i].pitch2,chipClock,CHIP_FREQBASE,11); + chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,chan[i].fixedArp?chan[i].baseNoteOverride:chan[i].arpOff,chan[i].fixedArp,false,4,chan[i].pitch2,chipClock,CHIP_FREQBASE,11,parent->getIns(chan[i].ins)->fm.block); } else { int fNum=parent->calcFreq(chan[i].baseFreq&0x7ff,chan[i].pitch,chan[i].fixedArp?chan[i].baseNoteOverride:chan[i].arpOff,chan[i].fixedArp,false,4,chan[i].pitch2); int block=(chan[i].baseFreq&0xf800)>>11; @@ -1268,7 +1268,7 @@ int DivPlatformYM2610B::dispatch(DivCommand c) { chan[c.chan].insChanged=false; if (c.value!=DIV_NOTE_NULL) { - chan[c.chan].baseFreq=NOTE_FNUM_BLOCK(c.value,11); + chan[c.chan].baseFreq=NOTE_FNUM_BLOCK(c.value,11,chan[c.chan].ins); chan[c.chan].portaPause=false; chan[c.chan].freqChanged=true; chan[c.chan].note=c.value; diff --git a/src/engine/platform/ym2610bext.cpp b/src/engine/platform/ym2610bext.cpp index 035c87cf7..8f35fe183 100644 --- a/src/engine/platform/ym2610bext.cpp +++ b/src/engine/platform/ym2610bext.cpp @@ -89,7 +89,7 @@ int DivPlatformYM2610BExt::dispatch(DivCommand c) { opChan[ch].insChanged=false; if (c.value!=DIV_NOTE_NULL) { - opChan[ch].baseFreq=NOTE_FNUM_BLOCK(c.value,11); + opChan[ch].baseFreq=NOTE_FNUM_BLOCK(c.value,11,opChan[ch].ins); opChan[ch].portaPause=false; opChan[ch].note=c.value; opChan[ch].freqChanged=true; @@ -193,7 +193,7 @@ int DivPlatformYM2610BExt::dispatch(DivCommand c) { commitStateExt(ch,ins); opChan[ch].insChanged=false; } - opChan[ch].baseFreq=NOTE_FNUM_BLOCK(c.value,11); + opChan[ch].baseFreq=NOTE_FNUM_BLOCK(c.value,11,opChan[ch].ins); opChan[ch].freqChanged=true; break; } @@ -465,7 +465,7 @@ void DivPlatformYM2610BExt::tick(bool sysTick) { if (opChan[i].std.arp.had) { if (!opChan[i].inPorta) { - opChan[i].baseFreq=NOTE_FNUM_BLOCK(parent->calcArp(opChan[i].note,opChan[i].std.arp.val),11); + opChan[i].baseFreq=NOTE_FNUM_BLOCK(parent->calcArp(opChan[i].note,opChan[i].std.arp.val),11,opChan[i].ins); } opChan[i].freqChanged=true; } @@ -586,7 +586,7 @@ void DivPlatformYM2610BExt::tick(bool sysTick) { if (extMode) for (int i=0; i<4; i++) { if (opChan[i].freqChanged) { if (parent->song.linearPitch==2) { - opChan[i].freq=parent->calcFreq(opChan[i].baseFreq,opChan[i].pitch,opChan[i].fixedArp?opChan[i].baseNoteOverride:opChan[i].arpOff,opChan[i].fixedArp,false,4,opChan[i].pitch2,chipClock,CHIP_FREQBASE,11); + opChan[i].freq=parent->calcFreq(opChan[i].baseFreq,opChan[i].pitch,opChan[i].fixedArp?opChan[i].baseNoteOverride:opChan[i].arpOff,opChan[i].fixedArp,false,4,opChan[i].pitch2,chipClock,CHIP_FREQBASE,11,parent->getIns(chan[i].ins)->fm.block); } else { int fNum=parent->calcFreq(opChan[i].baseFreq&0x7ff,opChan[i].pitch,opChan[i].fixedArp?opChan[i].baseNoteOverride:opChan[i].arpOff,opChan[i].fixedArp,false,4,opChan[i].pitch2); int block=(opChan[i].baseFreq&0xf800)>>11; diff --git a/src/engine/platform/ym2610ext.cpp b/src/engine/platform/ym2610ext.cpp index c4472f597..df329738f 100644 --- a/src/engine/platform/ym2610ext.cpp +++ b/src/engine/platform/ym2610ext.cpp @@ -89,7 +89,7 @@ int DivPlatformYM2610Ext::dispatch(DivCommand c) { opChan[ch].insChanged=false; if (c.value!=DIV_NOTE_NULL) { - opChan[ch].baseFreq=NOTE_FNUM_BLOCK(c.value,11); + opChan[ch].baseFreq=NOTE_FNUM_BLOCK(c.value,11,opChan[ch].ins); opChan[ch].portaPause=false; opChan[ch].note=c.value; opChan[ch].freqChanged=true; @@ -193,7 +193,7 @@ int DivPlatformYM2610Ext::dispatch(DivCommand c) { commitStateExt(ch,ins); opChan[ch].insChanged=false; } - opChan[ch].baseFreq=NOTE_FNUM_BLOCK(c.value,11); + opChan[ch].baseFreq=NOTE_FNUM_BLOCK(c.value,11,opChan[ch].ins); opChan[ch].freqChanged=true; break; } @@ -465,7 +465,7 @@ void DivPlatformYM2610Ext::tick(bool sysTick) { if (opChan[i].std.arp.had) { if (!opChan[i].inPorta) { - opChan[i].baseFreq=NOTE_FNUM_BLOCK(parent->calcArp(opChan[i].note,opChan[i].std.arp.val),11); + opChan[i].baseFreq=NOTE_FNUM_BLOCK(parent->calcArp(opChan[i].note,opChan[i].std.arp.val),11,opChan[i].ins); } opChan[i].freqChanged=true; } @@ -586,7 +586,7 @@ void DivPlatformYM2610Ext::tick(bool sysTick) { if (extMode) for (int i=0; i<4; i++) { if (opChan[i].freqChanged) { if (parent->song.linearPitch==2) { - opChan[i].freq=parent->calcFreq(opChan[i].baseFreq,opChan[i].pitch,opChan[i].fixedArp?opChan[i].baseNoteOverride:opChan[i].arpOff,opChan[i].fixedArp,false,4,opChan[i].pitch2,chipClock,CHIP_FREQBASE,11); + opChan[i].freq=parent->calcFreq(opChan[i].baseFreq,opChan[i].pitch,opChan[i].fixedArp?opChan[i].baseNoteOverride:opChan[i].arpOff,opChan[i].fixedArp,false,4,opChan[i].pitch2,chipClock,CHIP_FREQBASE,11,parent->getIns(chan[i].ins)->fm.block); } else { int fNum=parent->calcFreq(opChan[i].baseFreq&0x7ff,opChan[i].pitch,opChan[i].fixedArp?opChan[i].baseNoteOverride:opChan[i].arpOff,opChan[i].fixedArp,false,4,opChan[i].pitch2); int block=(opChan[i].baseFreq&0xf800)>>11; diff --git a/src/engine/platform/ym2610shared.h b/src/engine/platform/ym2610shared.h index ea9d66031..03caf68f4 100644 --- a/src/engine/platform/ym2610shared.h +++ b/src/engine/platform/ym2610shared.h @@ -97,7 +97,7 @@ class DivPlatformYM2610Base: public DivPlatformOPN { return NOTE_PERIODIC(note); } // FM - return NOTE_FNUM_BLOCK(note,11); + return NOTE_FNUM_BLOCK(note,11,chan[ch].ins); } double NOTE_ADPCMB(int note) { if (chan[adpcmBChanOffs].sample>=0 && chan[adpcmBChanOffs].samplesong.sampleLen) { diff --git a/src/gui/insEdit.cpp b/src/gui/insEdit.cpp index 1879d7fd9..c934d4e89 100644 --- a/src/gui/insEdit.cpp +++ b/src/gui/insEdit.cpp @@ -49,8 +49,8 @@ const char* ssgEnvTypes[8]={ _N("Up DOWN") }; -const char* fmParamNames[3][32]={ - {_N("Algorithm"), _N("Feedback"), _N("LFO > Freq"), _N("LFO > Amp"), _N("Attack"), _N("Decay"), _N("Decay 2"), _N("Release"), _N("Sustain"), _N("Level"), _N("EnvScale"), _N("Multiplier"), _N("Detune"), _N("Detune 2"), _N("SSG-EG"), _N("AM"), _N("AM Depth"), _N("Vibrato Depth"), _N("Sustained"), _N("Sustained"), _N("Level Scaling"), _N("Sustain"), _N("Vibrato"), _N("Waveform"), _N("Scale Rate"), _N("OP2 Half Sine"), _N("OP1 Half Sine"), _N("EnvShift"), _N("Reverb"), _N("Fine"), _N("LFO2 > Freq"), _N("LFO2 > Amp")}, +const char* fmParamNames[3][33]={ + {_N("Algorithm"), _N("Feedback"), _N("LFO > Freq"), _N("LFO > Amp"), _N("Attack"), _N("Decay"), _N("Decay 2"), _N("Release"), _N("Sustain"), _N("Level"), _N("EnvScale"), _N("Multiplier"), _N("Detune"), _N("Detune 2"), _N("SSG-EG"), _N("AM"), _N("AM Depth"), _N("Vibrato Depth"), _N("Sustained"), _N("Sustained"), _N("Level Scaling"), _N("Sustain"), _N("Vibrato"), _N("Waveform"), _N("Scale Rate"), _N("OP2 Half Sine"), _N("OP1 Half Sine"), _N("EnvShift"), _N("Reverb"), _N("Fine"), _N("LFO2 > Freq"), _N("LFO2 > Amp"), _N("Block")}, {"ALG", "FB", "FMS/PMS", "AMS", "AR", "DR", "SR", "RR", "SL", "TL", "KS", "MULT", "DT", "DT2", "SSG-EG", "AM", "AMD", "FMD", "EGT", "EGT", "KSL", "SUS", "VIB", "WS", "KSR", "DC", "DM", "EGS", "REV", "Fine", "FMS/PMS2", "AMS2"}, {"ALG", "FB", "FMS/PMS", "AMS", "AR", "DR", "D2R", "RR", "SL", "TL", "RS", "MULT", "DT", "DT2", "SSG-EG", "AM", "DAM", "DVB", "EGT", "EGS", "KSL", "SUS", "VIB", "WS", "KSR", "DC", "DM", "EGS", "REV", "Fine", "FMS/PMS2", "AMS2"} }; @@ -388,7 +388,8 @@ enum FMParams { FM_REV=28, FM_FINE=29, FM_FMS2=30, - FM_AMS2=31 + FM_AMS2=31, + FM_BLOCK=32 }; enum ESFMParams { @@ -3909,8 +3910,13 @@ void FurnaceGUI::insTabFM(DivInstrument* ins) { } if (ImGui::BeginTable("fmDetails",3,(ins->type==DIV_INS_ESFM)?ImGuiTableFlags_SizingStretchProp:ImGuiTableFlags_SizingStretchSame)) { - ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthStretch,((ins->type==DIV_INS_ESFM)?0.50f:0.0f)); - ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthStretch,((ins->type==DIV_INS_ESFM)?0.15f:0.0f)); + String blockTxt=_("Any"); + if (ins->fm.block>=1) { + blockTxt=fmt::sprintf("%d",ins->fm.block-1); + } + + ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthStretch,((ins->type==DIV_INS_ESFM)?0.40f:0.0f)); + ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthStretch,((ins->type==DIV_INS_ESFM)?0.25f:0.0f)); ImGui::TableSetupColumn("c2",ImGuiTableColumnFlags_WidthStretch,((ins->type==DIV_INS_ESFM)?0.35f:0.0f)); ImGui::TableNextRow(); @@ -3920,6 +3926,9 @@ void FurnaceGUI::insTabFM(DivInstrument* ins) { ImGui::TableNextColumn(); P(CWSliderScalar(FM_NAME(FM_FB),ImGuiDataType_U8,&ins->fm.fb,&_ZERO,&_SEVEN)); rightClickable P(CWSliderScalar(FM_NAME(FM_FMS),ImGuiDataType_U8,&ins->fm.fms,&_ZERO,&_SEVEN)); rightClickable + if (ins->type==DIV_INS_FM) { + P(CWSliderScalar(FM_NAME(FM_BLOCK),ImGuiDataType_U8,&ins->fm.block,&_ZERO,&_EIGHT,blockTxt.c_str())); rightClickable + } ImGui::TableNextColumn(); P(CWSliderScalar(FM_NAME(FM_ALG),ImGuiDataType_U8,&ins->fm.alg,&_ZERO,&_SEVEN)); rightClickable P(CWSliderScalar(FM_NAME(FM_AMS),ImGuiDataType_U8,&ins->fm.ams,&_ZERO,&_THREE)); rightClickable @@ -3981,6 +3990,7 @@ void FurnaceGUI::insTabFM(DivInstrument* ins) { } ImGui::EndDisabled(); } + P(CWSliderScalar(FM_NAME(FM_BLOCK),ImGuiDataType_U8,&ins->fm.block,&_ZERO,&_EIGHT,blockTxt.c_str())); rightClickable ImGui::TableNextColumn(); P(CWSliderScalar(FM_NAME(FM_ALG),ImGuiDataType_U8,&ins->fm.alg,&_ZERO,&algMax)); rightClickable if (ins->type==DIV_INS_OPL) { @@ -4012,6 +4022,10 @@ void FurnaceGUI::insTabFM(DivInstrument* ins) { fmOrigin.fms=dc; } ImGui::EndDisabled(); + if (ins->fm.opllPreset!=0) { + ins->fm.op[1].tl&=15; + P(CWSliderScalar(_("Volume##TL"),ImGuiDataType_U8,&ins->fm.op[1].tl,&_FIFTEEN,&_ZERO)); rightClickable + } ImGui::TableNextColumn(); if (ImGui::Checkbox(FM_NAME(FM_SUS),&sus)) { PARAMETER ins->fm.alg=sus; @@ -4021,6 +4035,7 @@ void FurnaceGUI::insTabFM(DivInstrument* ins) { fmOrigin.ams=dm; } ImGui::EndDisabled(); + P(CWSliderScalar(FM_NAME(FM_BLOCK),ImGuiDataType_U8,&ins->fm.block,&_ZERO,&_EIGHT,blockTxt.c_str())); rightClickable ImGui::TableNextColumn(); if (fmPreviewOn) { drawFMPreview(ImVec2(ImGui::GetContentRegionAvail().x,24.0*dpiScale)); @@ -4074,6 +4089,7 @@ void FurnaceGUI::insTabFM(DivInstrument* ins) { P(CWSliderScalar(ESFM_LONG_NAME(ESFM_NOISE),ImGuiDataType_U8,&ins->esfm.noise,&_ZERO,&_THREE,_(esfmNoiseModeNames[ins->esfm.noise&3]))); rightClickable ImGui::TextUnformatted(_(esfmNoiseModeDescriptions[ins->esfm.noise&3])); ImGui::TableNextColumn(); + P(CWSliderScalar(FM_NAME(FM_BLOCK),ImGuiDataType_U8,&ins->fm.block,&_ZERO,&_EIGHT,blockTxt.c_str())); rightClickable ImGui::TableNextColumn(); if (fmPreviewOn) { drawFMPreview(ImVec2(ImGui::GetContentRegionAvail().x,48.0*dpiScale)); @@ -4091,6 +4107,9 @@ void FurnaceGUI::insTabFM(DivInstrument* ins) { } ImGui::EndTable(); } + if (ins->type==DIV_INS_OPLL && ins->fm.opllPreset==16) { + ImGui::Text(_("this volume slider only works in compatibility (non-drums) system.")); + } if (((ins->type==DIV_INS_OPLL || ins->type==DIV_INS_OPL) && ins->fm.opllPreset==16) || ins->type==DIV_INS_OPL_DRUMS) { ins->fm.ops=2; @@ -4121,12 +4140,6 @@ void FurnaceGUI::insTabFM(DivInstrument* ins) { bool willDisplayOps=true; if (ins->type==DIV_INS_OPLL && ins->fm.opllPreset!=0) willDisplayOps=false; if (!willDisplayOps && ins->type==DIV_INS_OPLL) { - ins->fm.op[1].tl&=15; - P(CWSliderScalar(_("Volume##TL"),ImGuiDataType_U8,&ins->fm.op[1].tl,&_FIFTEEN,&_ZERO)); rightClickable - if (ins->fm.opllPreset==16) { - ImGui::Text(_("this volume slider only works in compatibility (non-drums) system.")); - } - // update OPLL preset preview if (ins->fm.opllPreset>0 && ins->fm.opllPreset<16) { const opll_patch_t* patchROM=NULL; From 58a58bdd98107b0a3a4f7610d17a0487f47390fa Mon Sep 17 00:00:00 2001 From: tildearrow Date: Tue, 28 Jan 2025 03:52:17 -0500 Subject: [PATCH 3/5] GUI: fix crash in FM editor --- src/gui/insEdit.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gui/insEdit.cpp b/src/gui/insEdit.cpp index c934d4e89..f97bdb921 100644 --- a/src/gui/insEdit.cpp +++ b/src/gui/insEdit.cpp @@ -50,9 +50,9 @@ const char* ssgEnvTypes[8]={ }; const char* fmParamNames[3][33]={ - {_N("Algorithm"), _N("Feedback"), _N("LFO > Freq"), _N("LFO > Amp"), _N("Attack"), _N("Decay"), _N("Decay 2"), _N("Release"), _N("Sustain"), _N("Level"), _N("EnvScale"), _N("Multiplier"), _N("Detune"), _N("Detune 2"), _N("SSG-EG"), _N("AM"), _N("AM Depth"), _N("Vibrato Depth"), _N("Sustained"), _N("Sustained"), _N("Level Scaling"), _N("Sustain"), _N("Vibrato"), _N("Waveform"), _N("Scale Rate"), _N("OP2 Half Sine"), _N("OP1 Half Sine"), _N("EnvShift"), _N("Reverb"), _N("Fine"), _N("LFO2 > Freq"), _N("LFO2 > Amp"), _N("Block")}, - {"ALG", "FB", "FMS/PMS", "AMS", "AR", "DR", "SR", "RR", "SL", "TL", "KS", "MULT", "DT", "DT2", "SSG-EG", "AM", "AMD", "FMD", "EGT", "EGT", "KSL", "SUS", "VIB", "WS", "KSR", "DC", "DM", "EGS", "REV", "Fine", "FMS/PMS2", "AMS2"}, - {"ALG", "FB", "FMS/PMS", "AMS", "AR", "DR", "D2R", "RR", "SL", "TL", "RS", "MULT", "DT", "DT2", "SSG-EG", "AM", "DAM", "DVB", "EGT", "EGS", "KSL", "SUS", "VIB", "WS", "KSR", "DC", "DM", "EGS", "REV", "Fine", "FMS/PMS2", "AMS2"} + {_N("Algorithm"), _N("Feedback"), _N("LFO > Freq"), _N("LFO > Amp"), _N("Attack"), _N("Decay"), _N("Decay 2"), _N("Release"), _N("Sustain"), _N("Level"), _N("EnvScale"), _N("Multiplier"), _N("Detune"), _N("Detune 2"), _N("SSG-EG"), _N("AM"), _N("AM Depth"), _N("Vibrato Depth"), _N("Sustained"), _N("Sustained"), _N("Level Scaling"), _N("Sustain"), _N("Vibrato"), _N("Waveform"), _N("Scale Rate"), _N("OP2 Half Sine"), _N("OP1 Half Sine"), _N("EnvShift"), _N("Reverb"), _N("Fine"), _N("LFO2 > Freq"), _N("LFO2 > Amp"), _N("Octave")}, + {"ALG", "FB", "FMS/PMS", "AMS", "AR", "DR", "SR", "RR", "SL", "TL", "KS", "MULT", "DT", "DT2", "SSG-EG", "AM", "AMD", "FMD", "EGT", "EGT", "KSL", "SUS", "VIB", "WS", "KSR", "DC", "DM", "EGS", "REV", "Fine", "FMS/PMS2", "AMS2", "Block"}, + {"ALG", "FB", "FMS/PMS", "AMS", "AR", "DR", "D2R", "RR", "SL", "TL", "RS", "MULT", "DT", "DT2", "SSG-EG", "AM", "DAM", "DVB", "EGT", "EGS", "KSL", "SUS", "VIB", "WS", "KSR", "DC", "DM", "EGS", "REV", "Fine", "FMS/PMS2", "AMS2", "Block"} }; const char* esfmParamLongNames[9]={ From e713742985f79bd7bc9c83d4d77eb04bb30132f1 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Tue, 28 Jan 2025 04:04:01 -0500 Subject: [PATCH 4/5] GUI: some adjustments to FM block UI --- src/gui/insEdit.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/gui/insEdit.cpp b/src/gui/insEdit.cpp index f97bdb921..f7d2bb38c 100644 --- a/src/gui/insEdit.cpp +++ b/src/gui/insEdit.cpp @@ -3910,7 +3910,7 @@ void FurnaceGUI::insTabFM(DivInstrument* ins) { } if (ImGui::BeginTable("fmDetails",3,(ins->type==DIV_INS_ESFM)?ImGuiTableFlags_SizingStretchProp:ImGuiTableFlags_SizingStretchSame)) { - String blockTxt=_("Any"); + String blockTxt=_("Automatic"); if (ins->fm.block>=1) { blockTxt=fmt::sprintf("%d",ins->fm.block-1); } @@ -3983,17 +3983,16 @@ void FurnaceGUI::insTabFM(DivInstrument* ins) { ImGui::TableNextColumn(); ins->fm.alg&=algMax; P(CWSliderScalar(FM_NAME(FM_FB),ImGuiDataType_U8,&ins->fm.fb,&_ZERO,&_SEVEN)); rightClickable + P(CWSliderScalar(FM_NAME(FM_BLOCK),ImGuiDataType_U8,&ins->fm.block,&_ZERO,&_EIGHT,blockTxt.c_str())); rightClickable + ImGui::TableNextColumn(); + P(CWSliderScalar(FM_NAME(FM_ALG),ImGuiDataType_U8,&ins->fm.alg,&_ZERO,&algMax)); rightClickable if (ins->type==DIV_INS_OPL) { ImGui::BeginDisabled(ins->fm.opllPreset==16); if (ImGui::Checkbox("4-op",&fourOp)) { PARAMETER ins->fm.ops=fourOp?4:2; } ImGui::EndDisabled(); - } - P(CWSliderScalar(FM_NAME(FM_BLOCK),ImGuiDataType_U8,&ins->fm.block,&_ZERO,&_EIGHT,blockTxt.c_str())); rightClickable - ImGui::TableNextColumn(); - P(CWSliderScalar(FM_NAME(FM_ALG),ImGuiDataType_U8,&ins->fm.alg,&_ZERO,&algMax)); rightClickable - if (ins->type==DIV_INS_OPL) { + ImGui::SameLine(); if (ImGui::Checkbox(_("Drums"),&drums)) { PARAMETER ins->fm.opllPreset=drums?16:0; } @@ -4018,10 +4017,8 @@ void FurnaceGUI::insTabFM(DivInstrument* ins) { ImGui::TableNextColumn(); ImGui::BeginDisabled(ins->fm.opllPreset!=0); P(CWSliderScalar(FM_NAME(FM_FB),ImGuiDataType_U8,&fmOrigin.fb,&_ZERO,&_SEVEN)); rightClickable - if (ImGui::Checkbox(FM_NAME(FM_DC),&dc)) { PARAMETER - fmOrigin.fms=dc; - } ImGui::EndDisabled(); + P(CWSliderScalar(FM_NAME(FM_BLOCK),ImGuiDataType_U8,&ins->fm.block,&_ZERO,&_EIGHT,blockTxt.c_str())); rightClickable if (ins->fm.opllPreset!=0) { ins->fm.op[1].tl&=15; P(CWSliderScalar(_("Volume##TL"),ImGuiDataType_U8,&ins->fm.op[1].tl,&_FIFTEEN,&_ZERO)); rightClickable @@ -4031,11 +4028,14 @@ void FurnaceGUI::insTabFM(DivInstrument* ins) { ins->fm.alg=sus; } ImGui::BeginDisabled(ins->fm.opllPreset!=0); + if (ImGui::Checkbox(FM_NAME(FM_DC),&dc)) { PARAMETER + fmOrigin.fms=dc; + } + ImGui::SameLine(); if (ImGui::Checkbox(FM_NAME(FM_DM),&dm)) { PARAMETER fmOrigin.ams=dm; } ImGui::EndDisabled(); - P(CWSliderScalar(FM_NAME(FM_BLOCK),ImGuiDataType_U8,&ins->fm.block,&_ZERO,&_EIGHT,blockTxt.c_str())); rightClickable ImGui::TableNextColumn(); if (fmPreviewOn) { drawFMPreview(ImVec2(ImGui::GetContentRegionAvail().x,24.0*dpiScale)); From dd9d220f330a1673c4eded5b1879381a058c38ff Mon Sep 17 00:00:00 2001 From: tildearrow Date: Tue, 28 Jan 2025 04:24:10 -0500 Subject: [PATCH 5/5] use state instead of accessing ins for block --- src/engine/dispatch.h | 2 +- src/engine/platform/esfm.cpp | 4 ++-- src/engine/platform/fmshared_OPN.h | 4 ++-- src/engine/platform/genesis.cpp | 10 +++++----- src/engine/platform/genesisext.cpp | 10 +++++----- src/engine/platform/opl.cpp | 4 ++-- src/engine/platform/opll.cpp | 4 ++-- src/engine/platform/ym2203.cpp | 12 ++++++------ src/engine/platform/ym2203ext.cpp | 10 +++++----- src/engine/platform/ym2608.cpp | 10 +++++----- src/engine/platform/ym2608ext.cpp | 10 +++++----- src/engine/platform/ym2610.cpp | 8 ++++---- src/engine/platform/ym2610b.cpp | 8 ++++---- src/engine/platform/ym2610bext.cpp | 10 +++++----- src/engine/platform/ym2610ext.cpp | 10 +++++----- src/engine/platform/ym2610shared.h | 2 +- 16 files changed, 59 insertions(+), 59 deletions(-) diff --git a/src/engine/dispatch.h b/src/engine/dispatch.h index 47fb7b45d..fe1ac421a 100644 --- a/src/engine/dispatch.h +++ b/src/engine/dispatch.h @@ -948,7 +948,7 @@ class DivDispatch { #define NOTE_FREQUENCY(x) parent->calcBaseFreq(chipClock,CHIP_FREQBASE,x,false) // this is a special case definition. only use it for f-num/block-based chips. -#define NOTE_FNUM_BLOCK(x,bits,ins) parent->calcBaseFreqFNumBlock(chipClock,CHIP_FREQBASE,x,bits,parent->getIns(ins)->fm.block) +#define NOTE_FNUM_BLOCK(x,bits,blk) parent->calcBaseFreqFNumBlock(chipClock,CHIP_FREQBASE,x,bits,blk) // this is for volume scaling calculation. #define VOL_SCALE_LINEAR(x,y,range) ((parent->song.ceilVolumeScaling)?((((x)*(y))+(range-1))/(range)):(((x)*(y))/(range))) diff --git a/src/engine/platform/esfm.cpp b/src/engine/platform/esfm.cpp index bcdb4df55..8b3d48b75 100644 --- a/src/engine/platform/esfm.cpp +++ b/src/engine/platform/esfm.cpp @@ -293,7 +293,7 @@ void DivPlatformESFM::tick(bool sysTick) { for (int i=0; i<18; i++) { if (chan[i].freqChanged) { int mul=2; - int fixedBlock=parent->getIns(chan[i].ins)->fm.block; + int fixedBlock=chan[i].state.fm.block; if (parent->song.linearPitch!=2) { mul=octave(chan[i].baseFreq,fixedBlock)*2; } @@ -527,7 +527,7 @@ int DivPlatformESFM::dispatch(DivCommand c) { int mul=1; int fixedBlock=0; if (parent->song.linearPitch!=2) { - fixedBlock=parent->getIns(chan[c.chan].ins)->fm.block; + fixedBlock=chan[c.chan].state.fm.block; mul=octave(chan[c.chan].baseFreq,fixedBlock); } if (destFreq>chan[c.chan].baseFreq) { diff --git a/src/engine/platform/fmshared_OPN.h b/src/engine/platform/fmshared_OPN.h index 64d121003..7f4a21c01 100644 --- a/src/engine/platform/fmshared_OPN.h +++ b/src/engine/platform/fmshared_OPN.h @@ -24,10 +24,10 @@ #include "../../../extern/opn/ym3438.h" #include "sound/ymfm/ymfm_opn.h" -#define PLEASE_HELP_ME(_targetChan) \ +#define PLEASE_HELP_ME(_targetChan,blk) \ int boundaryBottom=parent->calcBaseFreq(chipClock,CHIP_FREQBASE,0,false); \ int boundaryTop=parent->calcBaseFreq(chipClock,CHIP_FREQBASE,12,false); \ - int destFreq=NOTE_FNUM_BLOCK(c.value2,11,_targetChan.ins); \ + int destFreq=NOTE_FNUM_BLOCK(c.value2,11,blk); \ int newFreq; \ bool return2=false; \ if (_targetChan.portaPause) { \ diff --git a/src/engine/platform/genesis.cpp b/src/engine/platform/genesis.cpp index ee246f50c..836cbea0c 100644 --- a/src/engine/platform/genesis.cpp +++ b/src/engine/platform/genesis.cpp @@ -657,7 +657,7 @@ void DivPlatformGenesis::tick(bool sysTick) { chan[i].handleArp(); } else if (chan[i].std.arp.had) { if (!chan[i].inPorta) { - chan[i].baseFreq=NOTE_FNUM_BLOCK(parent->calcArp(chan[i].note,chan[i].std.arp.val),11,chan[i].ins); + chan[i].baseFreq=NOTE_FNUM_BLOCK(parent->calcArp(chan[i].note,chan[i].std.arp.val),11,chan[i].state.block); } chan[i].freqChanged=true; } @@ -838,7 +838,7 @@ void DivPlatformGenesis::tick(bool sysTick) { if (i==2 && extMode) continue; if (chan[i].freqChanged) { if (parent->song.linearPitch==2) { - chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,chan[i].fixedArp?chan[i].baseNoteOverride:chan[i].arpOff,chan[i].fixedArp,false,2,chan[i].pitch2,chipClock,CHIP_FREQBASE,11,parent->getIns(chan[i].ins)->fm.block); + chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,chan[i].fixedArp?chan[i].baseNoteOverride:chan[i].arpOff,chan[i].fixedArp,false,2,chan[i].pitch2,chipClock,CHIP_FREQBASE,11,chan[i].state.block); } else { int fNum=parent->calcFreq(chan[i].baseFreq&0x7ff,chan[i].pitch,chan[i].fixedArp?chan[i].baseNoteOverride:chan[i].arpOff,chan[i].fixedArp,false,2,chan[i].pitch2,chipClock,CHIP_FREQBASE,11); int block=(chan[i].baseFreq&0xf800)>>11; @@ -1084,7 +1084,7 @@ int DivPlatformGenesis::dispatch(DivCommand c) { chan[c.chan].insChanged=false; if (c.value!=DIV_NOTE_NULL) { - chan[c.chan].baseFreq=NOTE_FNUM_BLOCK(c.value,11,chan[c.chan].ins); + chan[c.chan].baseFreq=NOTE_FNUM_BLOCK(c.value,11,chan[c.chan].state.block); chan[c.chan].portaPause=false; chan[c.chan].note=c.value; chan[c.chan].freqChanged=true; @@ -1235,7 +1235,7 @@ int DivPlatformGenesis::dispatch(DivCommand c) { } break; } - PLEASE_HELP_ME(chan[c.chan]); + PLEASE_HELP_ME(chan[c.chan],chan[c.chan].state.block); break; } case DIV_CMD_SAMPLE_MODE: { @@ -1274,7 +1274,7 @@ int DivPlatformGenesis::dispatch(DivCommand c) { commitState(c.chan,ins); chan[c.chan].insChanged=false; } - chan[c.chan].baseFreq=NOTE_FNUM_BLOCK(c.value,11,chan[c.chan].ins); + chan[c.chan].baseFreq=NOTE_FNUM_BLOCK(c.value,11,chan[c.chan].state.block); } chan[c.chan].note=c.value; chan[c.chan].freqChanged=true; diff --git a/src/engine/platform/genesisext.cpp b/src/engine/platform/genesisext.cpp index fb63620e9..b8b5ac666 100644 --- a/src/engine/platform/genesisext.cpp +++ b/src/engine/platform/genesisext.cpp @@ -96,7 +96,7 @@ int DivPlatformGenesisExt::dispatch(DivCommand c) { opChan[ch].insChanged=false; if (c.value!=DIV_NOTE_NULL) { - opChan[ch].baseFreq=NOTE_FNUM_BLOCK(c.value,11,opChan[ch].ins); + opChan[ch].baseFreq=NOTE_FNUM_BLOCK(c.value,11,chan[extChanOffs].state.alg); opChan[ch].portaPause=false; opChan[ch].note=c.value; opChan[ch].freqChanged=true; @@ -191,7 +191,7 @@ int DivPlatformGenesisExt::dispatch(DivCommand c) { } break; } - PLEASE_HELP_ME(opChan[ch]); + PLEASE_HELP_ME(opChan[ch],chan[extChanOffs].state.block); break; } case DIV_CMD_SAMPLE_MODE: { @@ -216,7 +216,7 @@ int DivPlatformGenesisExt::dispatch(DivCommand c) { commitStateExt(ch,ins); opChan[ch].insChanged=false; } - opChan[ch].baseFreq=NOTE_FNUM_BLOCK(c.value,11,opChan[ch].ins); + opChan[ch].baseFreq=NOTE_FNUM_BLOCK(c.value,11,chan[extChanOffs].state.alg); opChan[ch].freqChanged=true; break; } @@ -517,7 +517,7 @@ void DivPlatformGenesisExt::tick(bool sysTick) { if (opChan[i].std.arp.had) { if (!opChan[i].inPorta) { - opChan[i].baseFreq=NOTE_FNUM_BLOCK(parent->calcArp(opChan[i].note,opChan[i].std.arp.val),11,opChan[i].ins); + opChan[i].baseFreq=NOTE_FNUM_BLOCK(parent->calcArp(opChan[i].note,opChan[i].std.arp.val),11,chan[extChanOffs].state.alg); } opChan[i].freqChanged=true; } @@ -638,7 +638,7 @@ void DivPlatformGenesisExt::tick(bool sysTick) { if (extMode) for (int i=0; i<4; i++) { if (opChan[i].freqChanged) { if (parent->song.linearPitch==2) { - opChan[i].freq=parent->calcFreq(opChan[i].baseFreq,opChan[i].pitch,opChan[i].fixedArp?opChan[i].baseNoteOverride:opChan[i].arpOff,opChan[i].fixedArp,false,2,opChan[i].pitch2,chipClock,CHIP_FREQBASE,11,parent->getIns(chan[i].ins)->fm.block); + opChan[i].freq=parent->calcFreq(opChan[i].baseFreq,opChan[i].pitch,opChan[i].fixedArp?opChan[i].baseNoteOverride:opChan[i].arpOff,opChan[i].fixedArp,false,2,opChan[i].pitch2,chipClock,CHIP_FREQBASE,11,chan[extChanOffs].state.block); } else { int fNum=parent->calcFreq(opChan[i].baseFreq&0x7ff,opChan[i].pitch,opChan[i].fixedArp?opChan[i].baseNoteOverride:opChan[i].arpOff,opChan[i].fixedArp,false,2,opChan[i].pitch2); int block=(opChan[i].baseFreq&0xf800)>>11; diff --git a/src/engine/platform/opl.cpp b/src/engine/platform/opl.cpp index 56ae1f897..5894ee98c 100644 --- a/src/engine/platform/opl.cpp +++ b/src/engine/platform/opl.cpp @@ -1434,7 +1434,7 @@ void DivPlatformOPL::tick(bool sysTick) { } else { if (chan[i].freqChanged) { int mul=2; - int fixedBlock=parent->getIns(chan[i].ins)->fm.block; + int fixedBlock=chan[i].state.block; if (parent->song.linearPitch!=2) { mul=octave(chan[i].baseFreq,fixedBlock)*2; } @@ -2038,7 +2038,7 @@ int DivPlatformOPL::dispatch(DivCommand c) { int mul=1; int fixedBlock=0; if (parent->song.linearPitch!=2) { - fixedBlock=parent->getIns(chan[c.chan].ins)->fm.block; + fixedBlock=chan[c.chan].state.block; mul=octave(chan[c.chan].baseFreq,fixedBlock); } if (destFreq>chan[c.chan].baseFreq) { diff --git a/src/engine/platform/opll.cpp b/src/engine/platform/opll.cpp index b5dbce83a..179103916 100644 --- a/src/engine/platform/opll.cpp +++ b/src/engine/platform/opll.cpp @@ -296,7 +296,7 @@ void DivPlatformOPLL::tick(bool sysTick) { for (int i=0; i<11; i++) { if (chan[i].freqChanged) { int mul=2; - int fixedBlock=parent->getIns(chan[i].ins)->fm.block; + int fixedBlock=chan[i].state.block; if (parent->song.linearPitch!=2) { mul=octave(chan[i].baseFreq,fixedBlock)*2; } @@ -640,7 +640,7 @@ int DivPlatformOPLL::dispatch(DivCommand c) { int mul=1; int fixedBlock=0; if (parent->song.linearPitch!=2) { - fixedBlock=parent->getIns(chan[c.chan].ins)->fm.block; + fixedBlock=chan[c.chan].state.block; mul=octave(chan[c.chan].baseFreq,fixedBlock); } if (destFreq>chan[c.chan].baseFreq) { diff --git a/src/engine/platform/ym2203.cpp b/src/engine/platform/ym2203.cpp index fafbe036f..6ddfbfdf5 100644 --- a/src/engine/platform/ym2203.cpp +++ b/src/engine/platform/ym2203.cpp @@ -503,7 +503,7 @@ void DivPlatformYM2203::tick(bool sysTick) { chan[i].handleArp(); } else if (chan[i].std.arp.had) { if (!chan[i].inPorta) { - chan[i].baseFreq=NOTE_FNUM_BLOCK(parent->calcArp(chan[i].note,chan[i].std.arp.val),11,chan[i].ins); + chan[i].baseFreq=NOTE_FNUM_BLOCK(parent->calcArp(chan[i].note,chan[i].std.arp.val),11,chan[i].state.block); } chan[i].freqChanged=true; } @@ -638,7 +638,7 @@ void DivPlatformYM2203::tick(bool sysTick) { if (i==2 && extMode) continue; if (chan[i].freqChanged) { if (parent->song.linearPitch==2) { - chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,chan[i].fixedArp?chan[i].baseNoteOverride:chan[i].arpOff,chan[i].fixedArp,false,4,chan[i].pitch2,chipClock,CHIP_FREQBASE,11,parent->getIns(chan[i].ins)->fm.block); + chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,chan[i].fixedArp?chan[i].baseNoteOverride:chan[i].arpOff,chan[i].fixedArp,false,4,chan[i].pitch2,chipClock,CHIP_FREQBASE,11,chan[i].state.block); } else { int fNum=parent->calcFreq(chan[i].baseFreq&0x7ff,chan[i].pitch,chan[i].fixedArp?chan[i].baseNoteOverride:chan[i].arpOff,chan[i].fixedArp,false,4,chan[i].pitch2); int block=(chan[i].baseFreq&0xf800)>>11; @@ -760,7 +760,7 @@ int DivPlatformYM2203::dispatch(DivCommand c) { chan[c.chan].insChanged=false; if (c.value!=DIV_NOTE_NULL) { - chan[c.chan].baseFreq=NOTE_FNUM_BLOCK(c.value,11,chan[c.chan].ins); + chan[c.chan].baseFreq=NOTE_FNUM_BLOCK(c.value,11,chan[c.chan].state.block); chan[c.chan].portaPause=false; chan[c.chan].freqChanged=true; chan[c.chan].note=c.value; @@ -844,7 +844,7 @@ int DivPlatformYM2203::dispatch(DivCommand c) { break; } if (c.chan>(psgChanOffs-1) || parent->song.linearPitch==2) { // PSG - int destFreq=NOTE_FNUM_BLOCK(c.value2,11,chan[c.chan].ins); + int destFreq=NOTE_FNUM_BLOCK(c.value2,11,chan[c.chan].state.block); bool return2=false; if (destFreq>chan[c.chan].baseFreq) { chan[c.chan].baseFreq+=c.value; @@ -866,7 +866,7 @@ int DivPlatformYM2203::dispatch(DivCommand c) { } break; } - PLEASE_HELP_ME(chan[c.chan]); + PLEASE_HELP_ME(chan[c.chan],chan[c.chan].state.block); break; } case DIV_CMD_LEGATO: { @@ -878,7 +878,7 @@ int DivPlatformYM2203::dispatch(DivCommand c) { commitState(c.chan,ins); chan[c.chan].insChanged=false; } - chan[c.chan].baseFreq=NOTE_FNUM_BLOCK(c.value,11,chan[c.chan].ins); + chan[c.chan].baseFreq=NOTE_FNUM_BLOCK(c.value,11,chan[c.chan].state.block); chan[c.chan].freqChanged=true; break; } diff --git a/src/engine/platform/ym2203ext.cpp b/src/engine/platform/ym2203ext.cpp index c954c93e5..c4b392880 100644 --- a/src/engine/platform/ym2203ext.cpp +++ b/src/engine/platform/ym2203ext.cpp @@ -89,7 +89,7 @@ int DivPlatformYM2203Ext::dispatch(DivCommand c) { opChan[ch].insChanged=false; if (c.value!=DIV_NOTE_NULL) { - opChan[ch].baseFreq=NOTE_FNUM_BLOCK(c.value,11,opChan[ch].ins); + opChan[ch].baseFreq=NOTE_FNUM_BLOCK(c.value,11,chan[extChanOffs].state.block); opChan[ch].portaPause=false; opChan[ch].note=c.value; opChan[ch].freqChanged=true; @@ -168,7 +168,7 @@ int DivPlatformYM2203Ext::dispatch(DivCommand c) { } break; } - PLEASE_HELP_ME(opChan[ch]); + PLEASE_HELP_ME(opChan[ch],chan[extChanOffs].state.block); break; } case DIV_CMD_LEGATO: { @@ -177,7 +177,7 @@ int DivPlatformYM2203Ext::dispatch(DivCommand c) { commitStateExt(ch,ins); opChan[ch].insChanged=false; } - opChan[ch].baseFreq=NOTE_FNUM_BLOCK(c.value,11,opChan[ch].ins); + opChan[ch].baseFreq=NOTE_FNUM_BLOCK(c.value,11,chan[extChanOffs].state.block); opChan[ch].freqChanged=true; break; } @@ -444,7 +444,7 @@ void DivPlatformYM2203Ext::tick(bool sysTick) { if (opChan[i].std.arp.had) { if (!opChan[i].inPorta) { - opChan[i].baseFreq=NOTE_FNUM_BLOCK(parent->calcArp(opChan[i].note,opChan[i].std.arp.val),11,opChan[i].ins); + opChan[i].baseFreq=NOTE_FNUM_BLOCK(parent->calcArp(opChan[i].note,opChan[i].std.arp.val),11,chan[extChanOffs].state.block); } opChan[i].freqChanged=true; } @@ -543,7 +543,7 @@ void DivPlatformYM2203Ext::tick(bool sysTick) { if (extMode) for (int i=0; i<4; i++) { if (opChan[i].freqChanged) { if (parent->song.linearPitch==2) { - opChan[i].freq=parent->calcFreq(opChan[i].baseFreq,opChan[i].pitch,opChan[i].fixedArp?opChan[i].baseNoteOverride:opChan[i].arpOff,opChan[i].fixedArp,false,4,opChan[i].pitch2,chipClock,CHIP_FREQBASE,11,parent->getIns(chan[i].ins)->fm.block); + opChan[i].freq=parent->calcFreq(opChan[i].baseFreq,opChan[i].pitch,opChan[i].fixedArp?opChan[i].baseNoteOverride:opChan[i].arpOff,opChan[i].fixedArp,false,4,opChan[i].pitch2,chipClock,CHIP_FREQBASE,11,chan[extChanOffs].state.block); } else { int fNum=parent->calcFreq(opChan[i].baseFreq&0x7ff,opChan[i].pitch,opChan[i].fixedArp?opChan[i].baseNoteOverride:opChan[i].arpOff,opChan[i].fixedArp,false,4,opChan[i].pitch2); int block=(opChan[i].baseFreq&0xf800)>>11; diff --git a/src/engine/platform/ym2608.cpp b/src/engine/platform/ym2608.cpp index fb8ff1a73..784bc7fb3 100644 --- a/src/engine/platform/ym2608.cpp +++ b/src/engine/platform/ym2608.cpp @@ -284,7 +284,7 @@ double DivPlatformYM2608::NOTE_OPNB(int ch, int note) { return NOTE_PERIODIC(note); } // FM - return NOTE_FNUM_BLOCK(note,11,chan[ch].ins); + return NOTE_FNUM_BLOCK(note,11,chan[ch].state.block); } double DivPlatformYM2608::NOTE_ADPCMB(int note) { @@ -719,7 +719,7 @@ void DivPlatformYM2608::tick(bool sysTick) { chan[i].handleArp(); } else if (chan[i].std.arp.had) { if (!chan[i].inPorta) { - chan[i].baseFreq=NOTE_FNUM_BLOCK(parent->calcArp(chan[i].note,chan[i].std.arp.val),11,chan[i].ins); + chan[i].baseFreq=NOTE_FNUM_BLOCK(parent->calcArp(chan[i].note,chan[i].std.arp.val),11,chan[i].state.block); } chan[i].freqChanged=true; } @@ -871,7 +871,7 @@ void DivPlatformYM2608::tick(bool sysTick) { if (i==2 && extMode) continue; if (chan[i].freqChanged) { if (parent->song.linearPitch==2) { - chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,chan[i].fixedArp?chan[i].baseNoteOverride:chan[i].arpOff,chan[i].fixedArp,false,4,chan[i].pitch2,chipClock,CHIP_FREQBASE,11,parent->getIns(chan[i].ins)->fm.block); + chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,chan[i].fixedArp?chan[i].baseNoteOverride:chan[i].arpOff,chan[i].fixedArp,false,4,chan[i].pitch2,chipClock,CHIP_FREQBASE,11,chan[i].state.block); } else { int fNum=parent->calcFreq(chan[i].baseFreq&0x7ff,chan[i].pitch,chan[i].fixedArp?chan[i].baseNoteOverride:chan[i].arpOff,chan[i].fixedArp,false,4,chan[i].pitch2); int block=(chan[i].baseFreq&0xf800)>>11; @@ -1233,7 +1233,7 @@ int DivPlatformYM2608::dispatch(DivCommand c) { chan[c.chan].insChanged=false; if (c.value!=DIV_NOTE_NULL) { - chan[c.chan].baseFreq=NOTE_FNUM_BLOCK(c.value,11,chan[c.chan].ins); + chan[c.chan].baseFreq=NOTE_FNUM_BLOCK(c.value,11,chan[c.chan].state.block); chan[c.chan].portaPause=false; chan[c.chan].freqChanged=true; chan[c.chan].note=c.value; @@ -1372,7 +1372,7 @@ int DivPlatformYM2608::dispatch(DivCommand c) { } break; } - PLEASE_HELP_ME(chan[c.chan]); + PLEASE_HELP_ME(chan[c.chan],chan[c.chan].state.block); break; } case DIV_CMD_SAMPLE_BANK: diff --git a/src/engine/platform/ym2608ext.cpp b/src/engine/platform/ym2608ext.cpp index 28fe75cdd..8a8784af8 100644 --- a/src/engine/platform/ym2608ext.cpp +++ b/src/engine/platform/ym2608ext.cpp @@ -93,7 +93,7 @@ int DivPlatformYM2608Ext::dispatch(DivCommand c) { opChan[ch].insChanged=false; if (c.value!=DIV_NOTE_NULL) { - opChan[ch].baseFreq=NOTE_FNUM_BLOCK(c.value,11,opChan[ch].ins); + opChan[ch].baseFreq=NOTE_FNUM_BLOCK(c.value,11,chan[extChanOffs].state.block); opChan[ch].portaPause=false; opChan[ch].note=c.value; opChan[ch].freqChanged=true; @@ -188,7 +188,7 @@ int DivPlatformYM2608Ext::dispatch(DivCommand c) { } break; } - PLEASE_HELP_ME(opChan[ch]); + PLEASE_HELP_ME(opChan[ch],chan[extChanOffs].state.block); break; } case DIV_CMD_LEGATO: { @@ -197,7 +197,7 @@ int DivPlatformYM2608Ext::dispatch(DivCommand c) { commitStateExt(ch,ins); opChan[ch].insChanged=false; } - opChan[ch].baseFreq=NOTE_FNUM_BLOCK(c.value,11,opChan[ch].ins); + opChan[ch].baseFreq=NOTE_FNUM_BLOCK(c.value,11,chan[extChanOffs].state.block); opChan[ch].freqChanged=true; break; } @@ -472,7 +472,7 @@ void DivPlatformYM2608Ext::tick(bool sysTick) { if (opChan[i].std.arp.had) { if (!opChan[i].inPorta) { - opChan[i].baseFreq=NOTE_FNUM_BLOCK(parent->calcArp(opChan[i].note,opChan[i].std.arp.val),11,opChan[i].ins); + opChan[i].baseFreq=NOTE_FNUM_BLOCK(parent->calcArp(opChan[i].note,opChan[i].std.arp.val),11,chan[extChanOffs].state.block); } opChan[i].freqChanged=true; } @@ -594,7 +594,7 @@ void DivPlatformYM2608Ext::tick(bool sysTick) { if (extMode) for (int i=0; i<4; i++) { if (opChan[i].freqChanged) { if (parent->song.linearPitch==2) { - opChan[i].freq=parent->calcFreq(opChan[i].baseFreq,opChan[i].pitch,opChan[i].fixedArp?opChan[i].baseNoteOverride:opChan[i].arpOff,opChan[i].fixedArp,false,4,opChan[i].pitch2,chipClock,CHIP_FREQBASE,11,parent->getIns(chan[i].ins)->fm.block); + opChan[i].freq=parent->calcFreq(opChan[i].baseFreq,opChan[i].pitch,opChan[i].fixedArp?opChan[i].baseNoteOverride:opChan[i].arpOff,opChan[i].fixedArp,false,4,opChan[i].pitch2,chipClock,CHIP_FREQBASE,11,chan[extChanOffs].state.block); } else { int fNum=parent->calcFreq(opChan[i].baseFreq&0x7ff,opChan[i].pitch,opChan[i].fixedArp?opChan[i].baseNoteOverride:opChan[i].arpOff,opChan[i].fixedArp,false,4,opChan[i].pitch2); int block=(opChan[i].baseFreq&0xf800)>>11; diff --git a/src/engine/platform/ym2610.cpp b/src/engine/platform/ym2610.cpp index 1533eb995..3c1d39700 100644 --- a/src/engine/platform/ym2610.cpp +++ b/src/engine/platform/ym2610.cpp @@ -647,7 +647,7 @@ void DivPlatformYM2610::tick(bool sysTick) { chan[i].handleArp(); } else if (chan[i].std.arp.had) { if (!chan[i].inPorta) { - chan[i].baseFreq=NOTE_FNUM_BLOCK(parent->calcArp(chan[i].note,chan[i].std.arp.val),11,chan[i].ins); + chan[i].baseFreq=NOTE_FNUM_BLOCK(parent->calcArp(chan[i].note,chan[i].std.arp.val),11,chan[i].state.block); } chan[i].freqChanged=true; } @@ -799,7 +799,7 @@ void DivPlatformYM2610::tick(bool sysTick) { if (i==1 && extMode) continue; if (chan[i].freqChanged) { if (parent->song.linearPitch==2) { - chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,chan[i].fixedArp?chan[i].baseNoteOverride:chan[i].arpOff,chan[i].fixedArp,false,4,chan[i].pitch2,chipClock,CHIP_FREQBASE,11,parent->getIns(chan[i].ins)->fm.block); + chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,chan[i].fixedArp?chan[i].baseNoteOverride:chan[i].arpOff,chan[i].fixedArp,false,4,chan[i].pitch2,chipClock,CHIP_FREQBASE,11,chan[i].state.block); } else { int fNum=parent->calcFreq(chan[i].baseFreq&0x7ff,chan[i].pitch,chan[i].fixedArp?chan[i].baseNoteOverride:chan[i].arpOff,chan[i].fixedArp,false,4,chan[i].pitch2,chipClock,CHIP_FREQBASE,11); int block=(chan[i].baseFreq&0xf800)>>11; @@ -1200,7 +1200,7 @@ int DivPlatformYM2610::dispatch(DivCommand c) { chan[c.chan].insChanged=false; if (c.value!=DIV_NOTE_NULL) { - chan[c.chan].baseFreq=NOTE_FNUM_BLOCK(c.value,11,chan[c.chan].ins); + chan[c.chan].baseFreq=NOTE_FNUM_BLOCK(c.value,11,chan[c.chan].state.block); chan[c.chan].portaPause=false; chan[c.chan].freqChanged=true; chan[c.chan].note=c.value; @@ -1339,7 +1339,7 @@ int DivPlatformYM2610::dispatch(DivCommand c) { } break; } - PLEASE_HELP_ME(chan[c.chan]); + PLEASE_HELP_ME(chan[c.chan],chan[c.chan].state.block); break; } case DIV_CMD_SAMPLE_BANK: diff --git a/src/engine/platform/ym2610b.cpp b/src/engine/platform/ym2610b.cpp index 20a4f973d..026ad1f3f 100644 --- a/src/engine/platform/ym2610b.cpp +++ b/src/engine/platform/ym2610b.cpp @@ -715,7 +715,7 @@ void DivPlatformYM2610B::tick(bool sysTick) { chan[i].handleArp(); } else if (chan[i].std.arp.had) { if (!chan[i].inPorta) { - chan[i].baseFreq=NOTE_FNUM_BLOCK(parent->calcArp(chan[i].note,chan[i].std.arp.val),11,chan[i].ins); + chan[i].baseFreq=NOTE_FNUM_BLOCK(parent->calcArp(chan[i].note,chan[i].std.arp.val),11,chan[i].state.block); } chan[i].freqChanged=true; } @@ -867,7 +867,7 @@ void DivPlatformYM2610B::tick(bool sysTick) { if (i==2 && extMode) continue; if (chan[i].freqChanged) { if (parent->song.linearPitch==2) { - chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,chan[i].fixedArp?chan[i].baseNoteOverride:chan[i].arpOff,chan[i].fixedArp,false,4,chan[i].pitch2,chipClock,CHIP_FREQBASE,11,parent->getIns(chan[i].ins)->fm.block); + chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,chan[i].fixedArp?chan[i].baseNoteOverride:chan[i].arpOff,chan[i].fixedArp,false,4,chan[i].pitch2,chipClock,CHIP_FREQBASE,11,chan[i].state.block); } else { int fNum=parent->calcFreq(chan[i].baseFreq&0x7ff,chan[i].pitch,chan[i].fixedArp?chan[i].baseNoteOverride:chan[i].arpOff,chan[i].fixedArp,false,4,chan[i].pitch2); int block=(chan[i].baseFreq&0xf800)>>11; @@ -1268,7 +1268,7 @@ int DivPlatformYM2610B::dispatch(DivCommand c) { chan[c.chan].insChanged=false; if (c.value!=DIV_NOTE_NULL) { - chan[c.chan].baseFreq=NOTE_FNUM_BLOCK(c.value,11,chan[c.chan].ins); + chan[c.chan].baseFreq=NOTE_FNUM_BLOCK(c.value,11,chan[c.chan].state.block); chan[c.chan].portaPause=false; chan[c.chan].freqChanged=true; chan[c.chan].note=c.value; @@ -1407,7 +1407,7 @@ int DivPlatformYM2610B::dispatch(DivCommand c) { } break; } - PLEASE_HELP_ME(chan[c.chan]); + PLEASE_HELP_ME(chan[c.chan],chan[c.chan].state.block); break; } case DIV_CMD_SAMPLE_BANK: diff --git a/src/engine/platform/ym2610bext.cpp b/src/engine/platform/ym2610bext.cpp index 8f35fe183..4988e1b6c 100644 --- a/src/engine/platform/ym2610bext.cpp +++ b/src/engine/platform/ym2610bext.cpp @@ -89,7 +89,7 @@ int DivPlatformYM2610BExt::dispatch(DivCommand c) { opChan[ch].insChanged=false; if (c.value!=DIV_NOTE_NULL) { - opChan[ch].baseFreq=NOTE_FNUM_BLOCK(c.value,11,opChan[ch].ins); + opChan[ch].baseFreq=NOTE_FNUM_BLOCK(c.value,11,chan[extChanOffs].state.block); opChan[ch].portaPause=false; opChan[ch].note=c.value; opChan[ch].freqChanged=true; @@ -184,7 +184,7 @@ int DivPlatformYM2610BExt::dispatch(DivCommand c) { } break; } - PLEASE_HELP_ME(opChan[ch]); + PLEASE_HELP_ME(opChan[ch],chan[extChanOffs].state.block); break; } case DIV_CMD_LEGATO: { @@ -193,7 +193,7 @@ int DivPlatformYM2610BExt::dispatch(DivCommand c) { commitStateExt(ch,ins); opChan[ch].insChanged=false; } - opChan[ch].baseFreq=NOTE_FNUM_BLOCK(c.value,11,opChan[ch].ins); + opChan[ch].baseFreq=NOTE_FNUM_BLOCK(c.value,11,chan[extChanOffs].state.block); opChan[ch].freqChanged=true; break; } @@ -465,7 +465,7 @@ void DivPlatformYM2610BExt::tick(bool sysTick) { if (opChan[i].std.arp.had) { if (!opChan[i].inPorta) { - opChan[i].baseFreq=NOTE_FNUM_BLOCK(parent->calcArp(opChan[i].note,opChan[i].std.arp.val),11,opChan[i].ins); + opChan[i].baseFreq=NOTE_FNUM_BLOCK(parent->calcArp(opChan[i].note,opChan[i].std.arp.val),11,chan[extChanOffs].state.block); } opChan[i].freqChanged=true; } @@ -586,7 +586,7 @@ void DivPlatformYM2610BExt::tick(bool sysTick) { if (extMode) for (int i=0; i<4; i++) { if (opChan[i].freqChanged) { if (parent->song.linearPitch==2) { - opChan[i].freq=parent->calcFreq(opChan[i].baseFreq,opChan[i].pitch,opChan[i].fixedArp?opChan[i].baseNoteOverride:opChan[i].arpOff,opChan[i].fixedArp,false,4,opChan[i].pitch2,chipClock,CHIP_FREQBASE,11,parent->getIns(chan[i].ins)->fm.block); + opChan[i].freq=parent->calcFreq(opChan[i].baseFreq,opChan[i].pitch,opChan[i].fixedArp?opChan[i].baseNoteOverride:opChan[i].arpOff,opChan[i].fixedArp,false,4,opChan[i].pitch2,chipClock,CHIP_FREQBASE,11,chan[extChanOffs].state.block); } else { int fNum=parent->calcFreq(opChan[i].baseFreq&0x7ff,opChan[i].pitch,opChan[i].fixedArp?opChan[i].baseNoteOverride:opChan[i].arpOff,opChan[i].fixedArp,false,4,opChan[i].pitch2); int block=(opChan[i].baseFreq&0xf800)>>11; diff --git a/src/engine/platform/ym2610ext.cpp b/src/engine/platform/ym2610ext.cpp index df329738f..a3b2455bc 100644 --- a/src/engine/platform/ym2610ext.cpp +++ b/src/engine/platform/ym2610ext.cpp @@ -89,7 +89,7 @@ int DivPlatformYM2610Ext::dispatch(DivCommand c) { opChan[ch].insChanged=false; if (c.value!=DIV_NOTE_NULL) { - opChan[ch].baseFreq=NOTE_FNUM_BLOCK(c.value,11,opChan[ch].ins); + opChan[ch].baseFreq=NOTE_FNUM_BLOCK(c.value,11,chan[extChanOffs].state.block); opChan[ch].portaPause=false; opChan[ch].note=c.value; opChan[ch].freqChanged=true; @@ -184,7 +184,7 @@ int DivPlatformYM2610Ext::dispatch(DivCommand c) { } break; } - PLEASE_HELP_ME(opChan[ch]); + PLEASE_HELP_ME(opChan[ch],chan[extChanOffs].state.block); break; } case DIV_CMD_LEGATO: { @@ -193,7 +193,7 @@ int DivPlatformYM2610Ext::dispatch(DivCommand c) { commitStateExt(ch,ins); opChan[ch].insChanged=false; } - opChan[ch].baseFreq=NOTE_FNUM_BLOCK(c.value,11,opChan[ch].ins); + opChan[ch].baseFreq=NOTE_FNUM_BLOCK(c.value,11,chan[extChanOffs].state.block); opChan[ch].freqChanged=true; break; } @@ -465,7 +465,7 @@ void DivPlatformYM2610Ext::tick(bool sysTick) { if (opChan[i].std.arp.had) { if (!opChan[i].inPorta) { - opChan[i].baseFreq=NOTE_FNUM_BLOCK(parent->calcArp(opChan[i].note,opChan[i].std.arp.val),11,opChan[i].ins); + opChan[i].baseFreq=NOTE_FNUM_BLOCK(parent->calcArp(opChan[i].note,opChan[i].std.arp.val),11,chan[extChanOffs].state.block); } opChan[i].freqChanged=true; } @@ -586,7 +586,7 @@ void DivPlatformYM2610Ext::tick(bool sysTick) { if (extMode) for (int i=0; i<4; i++) { if (opChan[i].freqChanged) { if (parent->song.linearPitch==2) { - opChan[i].freq=parent->calcFreq(opChan[i].baseFreq,opChan[i].pitch,opChan[i].fixedArp?opChan[i].baseNoteOverride:opChan[i].arpOff,opChan[i].fixedArp,false,4,opChan[i].pitch2,chipClock,CHIP_FREQBASE,11,parent->getIns(chan[i].ins)->fm.block); + opChan[i].freq=parent->calcFreq(opChan[i].baseFreq,opChan[i].pitch,opChan[i].fixedArp?opChan[i].baseNoteOverride:opChan[i].arpOff,opChan[i].fixedArp,false,4,opChan[i].pitch2,chipClock,CHIP_FREQBASE,11,chan[extChanOffs].state.block); } else { int fNum=parent->calcFreq(opChan[i].baseFreq&0x7ff,opChan[i].pitch,opChan[i].fixedArp?opChan[i].baseNoteOverride:opChan[i].arpOff,opChan[i].fixedArp,false,4,opChan[i].pitch2); int block=(opChan[i].baseFreq&0xf800)>>11; diff --git a/src/engine/platform/ym2610shared.h b/src/engine/platform/ym2610shared.h index 03caf68f4..d5e12df10 100644 --- a/src/engine/platform/ym2610shared.h +++ b/src/engine/platform/ym2610shared.h @@ -97,7 +97,7 @@ class DivPlatformYM2610Base: public DivPlatformOPN { return NOTE_PERIODIC(note); } // FM - return NOTE_FNUM_BLOCK(note,11,chan[ch].ins); + return NOTE_FNUM_BLOCK(note,11,chan[ch].state.block); } double NOTE_ADPCMB(int note) { if (chan[adpcmBChanOffs].sample>=0 && chan[adpcmBChanOffs].samplesong.sampleLen) {