From f3e4810dda918f0d0cb265fc3d8a0271596d69ba Mon Sep 17 00:00:00 2001 From: cam900 Date: Fri, 11 Mar 2022 03:47:36 +0900 Subject: [PATCH 1/2] Make some pitch command work in ADPCM-B, still partially and 01xx command is broken Fix sample check routine Remove dac* variables, No way to enable DAC mode in YM2610* --- src/engine/platform/ym2610.cpp | 73 +++++++++++++++++++------------- src/engine/platform/ym2610.h | 8 ++-- src/engine/platform/ym2610b.cpp | 75 +++++++++++++++++++-------------- src/engine/platform/ym2610b.h | 8 ++-- 4 files changed, 93 insertions(+), 71 deletions(-) diff --git a/src/engine/platform/ym2610.cpp b/src/engine/platform/ym2610.cpp index 1bd460fa1..5b2b19cc8 100644 --- a/src/engine/platform/ym2610.cpp +++ b/src/engine/platform/ym2610.cpp @@ -313,11 +313,22 @@ const char* DivPlatformYM2610::getEffectName(unsigned char effect) { return NULL; } +double DivPlatformYM2610::NOTE_OPNB(int ch, int note) { + if (ch>6) { // ADPCM + return NOTE_ADPCMB(note); + } else if (ch>3) { // PSG + return NOTE_PERIODIC(note); + } + // FM + return NOTE_FREQUENCY(note); +} + double DivPlatformYM2610::NOTE_ADPCMB(int note) { - DivInstrument* ins=parent->getIns(chan[13].ins); - if (ins->type!=DIV_INS_AMIGA) return 0; - double off=(double)(parent->getSample(ins->amiga.initSample)->centerRate)/8363.0; - return off*parent->calcBaseFreq((double)chipClock/144,65535,note,false); + if (chan[13].sample>=0&&chan[13].samplesong.sampleLen) { + double off=(double)(parent->getSample(chan[13].sample)->centerRate)/8363.0; + return off*parent->calcBaseFreq((double)chipClock/144,65535,note,false); + } + return 0; } void DivPlatformYM2610::acquire(short* bufL, short* bufR, size_t start, size_t len) { @@ -691,22 +702,33 @@ int DivPlatformYM2610::dispatch(DivCommand c) { chan[c.chan].outVol=chan[c.chan].vol; immWrite(0x1b,chan[c.chan].outVol); } - DivSample* s=parent->getSample(ins->amiga.initSample); - immWrite(0x12,(s->offB>>8)&0xff); - immWrite(0x13,s->offB>>16); - int end=s->offB+s->lengthB-1; - immWrite(0x14,(end>>8)&0xff); - immWrite(0x15,end>>16); - immWrite(0x11,isMuted[c.chan]?0:(chan[c.chan].pan<<6)); - immWrite(0x10,(s->loopStart>=0)?0x90:0x80); // start/repeat - if (c.value!=DIV_NOTE_NULL) { - chan[c.chan].note=c.value; - chan[c.chan].baseFreq=NOTE_ADPCMB(chan[c.chan].note); - chan[c.chan].freqChanged=true; + chan[c.chan].sample=ins->amiga.initSample; + if (chan[c.chan].sample>=0&&chan[c.chan].samplesong.sampleLen) { + DivSample* s=parent->getSample(chan[c.chan].sample); + immWrite(0x12,(s->offB>>8)&0xff); + immWrite(0x13,s->offB>>16); + int end=s->offB+s->lengthB-1; + immWrite(0x14,(end>>8)&0xff); + immWrite(0x15,end>>16); + immWrite(0x11,isMuted[c.chan]?0:(chan[c.chan].pan<<6)); + immWrite(0x10,(s->loopStart>=0)?0x90:0x80); // start/repeat + if (c.value!=DIV_NOTE_NULL) { + chan[c.chan].note=c.value; + chan[c.chan].baseFreq=NOTE_ADPCMB(chan[c.chan].note); + chan[c.chan].freqChanged=true; + } + chan[c.chan].active=true; + chan[c.chan].keyOn=true; + } else { + immWrite(0x10,0x01); // reset + immWrite(0x12,0); + immWrite(0x13,0); + immWrite(0x14,0); + immWrite(0x15,0); + break; } - chan[c.chan].active=true; - chan[c.chan].keyOn=true; } else { + chan[c.chan].sample=-1; chan[c.chan].std.init(NULL); chan[c.chan].outVol=chan[c.chan].vol; if ((12*sampleBank+c.value%12)>=parent->song.sampleLen) { @@ -915,8 +937,8 @@ int DivPlatformYM2610::dispatch(DivCommand c) { break; } case DIV_CMD_NOTE_PORTA: { - if (c.chan>3) { // PSG - int destFreq=NOTE_PERIODIC(c.value2); + if (c.chan>3) { // PSG, ADPCM-B + int destFreq=NOTE_OPNB(c.chan,c.value2); bool return2=false; if (destFreq>chan[c.chan].baseFreq) { chan[c.chan].baseFreq+=c.value; @@ -975,11 +997,7 @@ int DivPlatformYM2610::dispatch(DivCommand c) { iface.sampleBank=sampleBank; break; case DIV_CMD_LEGATO: { - if (c.chan>3) { // PSG - chan[c.chan].baseFreq=NOTE_PERIODIC(c.value); - } else { - chan[c.chan].baseFreq=NOTE_FREQUENCY(c.value); - } + chan[c.chan].baseFreq=NOTE_OPNB(c.chan,c.value); chan[c.chan].freqChanged=true; break; } @@ -1210,11 +1228,6 @@ void DivPlatformYM2610::reset() { } lastBusy=60; - dacMode=0; - dacPeriod=0; - dacPos=0; - dacRate=0; - dacSample=-1; sampleBank=0; ayEnvPeriod=0; ayEnvMode=0; diff --git a/src/engine/platform/ym2610.h b/src/engine/platform/ym2610.h index a0ee8b8d4..4e9b81f98 100644 --- a/src/engine/platform/ym2610.h +++ b/src/engine/platform/ym2610.h @@ -47,6 +47,7 @@ class DivPlatformYM2610: public DivDispatch { signed char konCycles; bool active, insChanged, freqChanged, keyOn, keyOff, portaPause, inPorta, furnacePCM; int vol, outVol; + int sample; unsigned char pan; DivMacroInt std; Channel(): @@ -70,6 +71,7 @@ class DivPlatformYM2610: public DivDispatch { furnacePCM(false), vol(0), outVol(15), + sample(-1), pan(3) {} }; Channel chan[14]; @@ -87,11 +89,6 @@ class DivPlatformYM2610: public DivDispatch { unsigned char regPool[512]; unsigned char lastBusy; - bool dacMode; - int dacPeriod; - int dacRate; - int dacPos; - int dacSample; int ayNoiseFreq; unsigned char sampleBank; @@ -108,6 +105,7 @@ class DivPlatformYM2610: public DivDispatch { int octave(int freq); int toFreq(int freq); + double NOTE_OPNB(int ch, int note); double NOTE_ADPCMB(int note); friend void putDispatchChan(void*,int,int); diff --git a/src/engine/platform/ym2610b.cpp b/src/engine/platform/ym2610b.cpp index a6bcf9ac7..02d120331 100644 --- a/src/engine/platform/ym2610b.cpp +++ b/src/engine/platform/ym2610b.cpp @@ -377,11 +377,22 @@ const char* DivPlatformYM2610B::getEffectName(unsigned char effect) { return NULL; } +double DivPlatformYM2610B::NOTE_OPNB(int ch, int note) { + if (ch>8) { // ADPCM-B + return NOTE_ADPCMB(note); + } else if (ch>5) { // PSG + return NOTE_PERIODIC(note); + } + // FM + return NOTE_FREQUENCY(note); +} + double DivPlatformYM2610B::NOTE_ADPCMB(int note) { - DivInstrument* ins=parent->getIns(chan[15].ins); - if (ins->type!=DIV_INS_AMIGA) return 0; - double off=(double)(parent->getSample(ins->amiga.initSample)->centerRate)/8363.0; - return off*parent->calcBaseFreq((double)chipClock/144,65535,note,false); + if (chan[15].sample>=0&&chan[15].samplesong.sampleLen) { + double off=(double)(parent->getSample(chan[15].sample)->centerRate)/8363.0; + return off*parent->calcBaseFreq((double)chipClock/144,65535,note,false); + } + return 0; } void DivPlatformYM2610B::acquire(short* bufL, short* bufR, size_t start, size_t len) { @@ -752,24 +763,35 @@ int DivPlatformYM2610B::dispatch(DivCommand c) { chan[c.chan].std.init(ins); if (!chan[c.chan].std.willVol) { chan[c.chan].outVol=chan[c.chan].vol; - immWrite(0x1b,chan[c.chan].outVol); + immWrite(0x1b,chan[c.chan].outVol); } - DivSample* s=parent->getSample(ins->amiga.initSample); - immWrite(0x12,(s->offB>>8)&0xff); - immWrite(0x13,s->offB>>16); - int end=s->offB+s->lengthB-1; - immWrite(0x14,(end>>8)&0xff); - immWrite(0x15,end>>16); - immWrite(0x11,isMuted[c.chan]?0:(chan[c.chan].pan<<6)); - immWrite(0x10,(s->loopStart>=0)?0x90:0x80); // start/repeat - if (c.value!=DIV_NOTE_NULL) { - chan[c.chan].note=c.value; - chan[c.chan].baseFreq=NOTE_ADPCMB(chan[c.chan].note); - chan[c.chan].freqChanged=true; + chan[c.chan].sample=ins->amiga.initSample; + if (chan[c.chan].sample>=0&&chan[c.chan].samplesong.sampleLen) { + DivSample* s=parent->getSample(chan[c.chan].sample); + immWrite(0x12,(s->offB>>8)&0xff); + immWrite(0x13,s->offB>>16); + int end=s->offB+s->lengthB-1; + immWrite(0x14,(end>>8)&0xff); + immWrite(0x15,end>>16); + immWrite(0x11,isMuted[c.chan]?0:(chan[c.chan].pan<<6)); + immWrite(0x10,(s->loopStart>=0)?0x90:0x80); // start/repeat + if (c.value!=DIV_NOTE_NULL) { + chan[c.chan].note=c.value; + chan[c.chan].baseFreq=NOTE_ADPCMB(chan[c.chan].note); + chan[c.chan].freqChanged=true; + } + chan[c.chan].active=true; + chan[c.chan].keyOn=true; + } else { + immWrite(0x10,0x01); // reset + immWrite(0x12,0); + immWrite(0x13,0); + immWrite(0x14,0); + immWrite(0x15,0); + break; } - chan[c.chan].active=true; - chan[c.chan].keyOn=true; } else { + chan[c.chan].sample=-1; chan[c.chan].std.init(NULL); chan[c.chan].outVol=chan[c.chan].vol; if ((12*sampleBank+c.value%12)>=parent->song.sampleLen) { @@ -978,8 +1000,8 @@ int DivPlatformYM2610B::dispatch(DivCommand c) { break; } case DIV_CMD_NOTE_PORTA: { - if (c.chan>5) { // PSG - int destFreq=NOTE_PERIODIC(c.value2); + if (c.chan>5) { // PSG, ADPCM-B + int destFreq=NOTE_OPNB(c.chan,c.value2); bool return2=false; if (destFreq>chan[c.chan].baseFreq) { chan[c.chan].baseFreq+=c.value; @@ -1038,11 +1060,7 @@ int DivPlatformYM2610B::dispatch(DivCommand c) { iface.sampleBank=sampleBank; break; case DIV_CMD_LEGATO: { - if (c.chan>5) { // PSG - chan[c.chan].baseFreq=NOTE_PERIODIC(c.value); - } else { - chan[c.chan].baseFreq=NOTE_FREQUENCY(c.value); - } + chan[c.chan].baseFreq=NOTE_OPNB(c.chan,c.value); chan[c.chan].freqChanged=true; break; } @@ -1273,11 +1291,6 @@ void DivPlatformYM2610B::reset() { } lastBusy=60; - dacMode=0; - dacPeriod=0; - dacPos=0; - dacRate=0; - dacSample=-1; sampleBank=0; ayEnvPeriod=0; ayEnvMode=0; diff --git a/src/engine/platform/ym2610b.h b/src/engine/platform/ym2610b.h index ca43e36b4..99c641a6e 100644 --- a/src/engine/platform/ym2610b.h +++ b/src/engine/platform/ym2610b.h @@ -40,6 +40,7 @@ class DivPlatformYM2610B: public DivDispatch { signed char konCycles; bool active, insChanged, freqChanged, keyOn, keyOff, portaPause, inPorta, furnacePCM; int vol, outVol; + int sample; unsigned char pan; DivMacroInt std; Channel(): @@ -63,6 +64,7 @@ class DivPlatformYM2610B: public DivDispatch { furnacePCM(false), vol(0), outVol(15), + sample(-1), pan(3) {} }; Channel chan[16]; @@ -80,11 +82,6 @@ class DivPlatformYM2610B: public DivDispatch { unsigned char regPool[512]; unsigned char lastBusy; - bool dacMode; - int dacPeriod; - int dacRate; - int dacPos; - int dacSample; int ayNoiseFreq; unsigned char sampleBank; @@ -101,6 +98,7 @@ class DivPlatformYM2610B: public DivDispatch { int octave(int freq); int toFreq(int freq); + double NOTE_OPNB(int ch, int note); double NOTE_ADPCMB(int note); friend void putDispatchChan(void*,int,int); From 36b336c7f49a257403a750ae1ecb625aa2884fde Mon Sep 17 00:00:00 2001 From: cam900 Date: Fri, 11 Mar 2022 04:11:23 +0900 Subject: [PATCH 2/2] A && B --- src/engine/platform/ym2610.cpp | 4 ++-- src/engine/platform/ym2610b.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/engine/platform/ym2610.cpp b/src/engine/platform/ym2610.cpp index 5b2b19cc8..8d7626632 100644 --- a/src/engine/platform/ym2610.cpp +++ b/src/engine/platform/ym2610.cpp @@ -324,7 +324,7 @@ double DivPlatformYM2610::NOTE_OPNB(int ch, int note) { } double DivPlatformYM2610::NOTE_ADPCMB(int note) { - if (chan[13].sample>=0&&chan[13].samplesong.sampleLen) { + if (chan[13].sample>=0 && chan[13].samplesong.sampleLen) { double off=(double)(parent->getSample(chan[13].sample)->centerRate)/8363.0; return off*parent->calcBaseFreq((double)chipClock/144,65535,note,false); } @@ -703,7 +703,7 @@ int DivPlatformYM2610::dispatch(DivCommand c) { immWrite(0x1b,chan[c.chan].outVol); } chan[c.chan].sample=ins->amiga.initSample; - if (chan[c.chan].sample>=0&&chan[c.chan].samplesong.sampleLen) { + if (chan[c.chan].sample>=0 && chan[c.chan].samplesong.sampleLen) { DivSample* s=parent->getSample(chan[c.chan].sample); immWrite(0x12,(s->offB>>8)&0xff); immWrite(0x13,s->offB>>16); diff --git a/src/engine/platform/ym2610b.cpp b/src/engine/platform/ym2610b.cpp index 02d120331..1d954ebe6 100644 --- a/src/engine/platform/ym2610b.cpp +++ b/src/engine/platform/ym2610b.cpp @@ -388,7 +388,7 @@ double DivPlatformYM2610B::NOTE_OPNB(int ch, int note) { } double DivPlatformYM2610B::NOTE_ADPCMB(int note) { - if (chan[15].sample>=0&&chan[15].samplesong.sampleLen) { + if (chan[15].sample>=0 && chan[15].samplesong.sampleLen) { double off=(double)(parent->getSample(chan[15].sample)->centerRate)/8363.0; return off*parent->calcBaseFreq((double)chipClock/144,65535,note,false); } @@ -766,7 +766,7 @@ int DivPlatformYM2610B::dispatch(DivCommand c) { immWrite(0x1b,chan[c.chan].outVol); } chan[c.chan].sample=ins->amiga.initSample; - if (chan[c.chan].sample>=0&&chan[c.chan].samplesong.sampleLen) { + if (chan[c.chan].sample>=0 && chan[c.chan].samplesong.sampleLen) { DivSample* s=parent->getSample(chan[c.chan].sample); immWrite(0x12,(s->offB>>8)&0xff); immWrite(0x13,s->offB>>16);