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*
This commit is contained in:
cam900 2022-03-11 03:47:36 +09:00
parent 93b3e16213
commit f3e4810dda
4 changed files with 93 additions and 71 deletions

View File

@ -313,11 +313,22 @@ const char* DivPlatformYM2610::getEffectName(unsigned char effect) {
return NULL; 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) { double DivPlatformYM2610::NOTE_ADPCMB(int note) {
DivInstrument* ins=parent->getIns(chan[13].ins); if (chan[13].sample>=0&&chan[13].sample<parent->song.sampleLen) {
if (ins->type!=DIV_INS_AMIGA) return 0; double off=(double)(parent->getSample(chan[13].sample)->centerRate)/8363.0;
double off=(double)(parent->getSample(ins->amiga.initSample)->centerRate)/8363.0;
return off*parent->calcBaseFreq((double)chipClock/144,65535,note,false); 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) { void DivPlatformYM2610::acquire(short* bufL, short* bufR, size_t start, size_t len) {
@ -691,7 +702,9 @@ int DivPlatformYM2610::dispatch(DivCommand c) {
chan[c.chan].outVol=chan[c.chan].vol; 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); chan[c.chan].sample=ins->amiga.initSample;
if (chan[c.chan].sample>=0&&chan[c.chan].sample<parent->song.sampleLen) {
DivSample* s=parent->getSample(chan[c.chan].sample);
immWrite(0x12,(s->offB>>8)&0xff); immWrite(0x12,(s->offB>>8)&0xff);
immWrite(0x13,s->offB>>16); immWrite(0x13,s->offB>>16);
int end=s->offB+s->lengthB-1; int end=s->offB+s->lengthB-1;
@ -707,6 +720,15 @@ int DivPlatformYM2610::dispatch(DivCommand c) {
chan[c.chan].active=true; chan[c.chan].active=true;
chan[c.chan].keyOn=true; chan[c.chan].keyOn=true;
} else { } else {
immWrite(0x10,0x01); // reset
immWrite(0x12,0);
immWrite(0x13,0);
immWrite(0x14,0);
immWrite(0x15,0);
break;
}
} else {
chan[c.chan].sample=-1;
chan[c.chan].std.init(NULL); chan[c.chan].std.init(NULL);
chan[c.chan].outVol=chan[c.chan].vol; chan[c.chan].outVol=chan[c.chan].vol;
if ((12*sampleBank+c.value%12)>=parent->song.sampleLen) { if ((12*sampleBank+c.value%12)>=parent->song.sampleLen) {
@ -915,8 +937,8 @@ int DivPlatformYM2610::dispatch(DivCommand c) {
break; break;
} }
case DIV_CMD_NOTE_PORTA: { case DIV_CMD_NOTE_PORTA: {
if (c.chan>3) { // PSG if (c.chan>3) { // PSG, ADPCM-B
int destFreq=NOTE_PERIODIC(c.value2); int destFreq=NOTE_OPNB(c.chan,c.value2);
bool return2=false; bool return2=false;
if (destFreq>chan[c.chan].baseFreq) { if (destFreq>chan[c.chan].baseFreq) {
chan[c.chan].baseFreq+=c.value; chan[c.chan].baseFreq+=c.value;
@ -975,11 +997,7 @@ int DivPlatformYM2610::dispatch(DivCommand c) {
iface.sampleBank=sampleBank; iface.sampleBank=sampleBank;
break; break;
case DIV_CMD_LEGATO: { case DIV_CMD_LEGATO: {
if (c.chan>3) { // PSG chan[c.chan].baseFreq=NOTE_OPNB(c.chan,c.value);
chan[c.chan].baseFreq=NOTE_PERIODIC(c.value);
} else {
chan[c.chan].baseFreq=NOTE_FREQUENCY(c.value);
}
chan[c.chan].freqChanged=true; chan[c.chan].freqChanged=true;
break; break;
} }
@ -1210,11 +1228,6 @@ void DivPlatformYM2610::reset() {
} }
lastBusy=60; lastBusy=60;
dacMode=0;
dacPeriod=0;
dacPos=0;
dacRate=0;
dacSample=-1;
sampleBank=0; sampleBank=0;
ayEnvPeriod=0; ayEnvPeriod=0;
ayEnvMode=0; ayEnvMode=0;

View File

@ -47,6 +47,7 @@ class DivPlatformYM2610: public DivDispatch {
signed char konCycles; signed char konCycles;
bool active, insChanged, freqChanged, keyOn, keyOff, portaPause, inPorta, furnacePCM; bool active, insChanged, freqChanged, keyOn, keyOff, portaPause, inPorta, furnacePCM;
int vol, outVol; int vol, outVol;
int sample;
unsigned char pan; unsigned char pan;
DivMacroInt std; DivMacroInt std;
Channel(): Channel():
@ -70,6 +71,7 @@ class DivPlatformYM2610: public DivDispatch {
furnacePCM(false), furnacePCM(false),
vol(0), vol(0),
outVol(15), outVol(15),
sample(-1),
pan(3) {} pan(3) {}
}; };
Channel chan[14]; Channel chan[14];
@ -87,11 +89,6 @@ class DivPlatformYM2610: public DivDispatch {
unsigned char regPool[512]; unsigned char regPool[512];
unsigned char lastBusy; unsigned char lastBusy;
bool dacMode;
int dacPeriod;
int dacRate;
int dacPos;
int dacSample;
int ayNoiseFreq; int ayNoiseFreq;
unsigned char sampleBank; unsigned char sampleBank;
@ -108,6 +105,7 @@ class DivPlatformYM2610: public DivDispatch {
int octave(int freq); int octave(int freq);
int toFreq(int freq); int toFreq(int freq);
double NOTE_OPNB(int ch, int note);
double NOTE_ADPCMB(int note); double NOTE_ADPCMB(int note);
friend void putDispatchChan(void*,int,int); friend void putDispatchChan(void*,int,int);

View File

@ -377,11 +377,22 @@ const char* DivPlatformYM2610B::getEffectName(unsigned char effect) {
return NULL; 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) { double DivPlatformYM2610B::NOTE_ADPCMB(int note) {
DivInstrument* ins=parent->getIns(chan[15].ins); if (chan[15].sample>=0&&chan[15].sample<parent->song.sampleLen) {
if (ins->type!=DIV_INS_AMIGA) return 0; double off=(double)(parent->getSample(chan[15].sample)->centerRate)/8363.0;
double off=(double)(parent->getSample(ins->amiga.initSample)->centerRate)/8363.0;
return off*parent->calcBaseFreq((double)chipClock/144,65535,note,false); 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) { void DivPlatformYM2610B::acquire(short* bufL, short* bufR, size_t start, size_t len) {
@ -754,7 +765,9 @@ int DivPlatformYM2610B::dispatch(DivCommand c) {
chan[c.chan].outVol=chan[c.chan].vol; 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); chan[c.chan].sample=ins->amiga.initSample;
if (chan[c.chan].sample>=0&&chan[c.chan].sample<parent->song.sampleLen) {
DivSample* s=parent->getSample(chan[c.chan].sample);
immWrite(0x12,(s->offB>>8)&0xff); immWrite(0x12,(s->offB>>8)&0xff);
immWrite(0x13,s->offB>>16); immWrite(0x13,s->offB>>16);
int end=s->offB+s->lengthB-1; int end=s->offB+s->lengthB-1;
@ -770,6 +783,15 @@ int DivPlatformYM2610B::dispatch(DivCommand c) {
chan[c.chan].active=true; chan[c.chan].active=true;
chan[c.chan].keyOn=true; chan[c.chan].keyOn=true;
} else { } else {
immWrite(0x10,0x01); // reset
immWrite(0x12,0);
immWrite(0x13,0);
immWrite(0x14,0);
immWrite(0x15,0);
break;
}
} else {
chan[c.chan].sample=-1;
chan[c.chan].std.init(NULL); chan[c.chan].std.init(NULL);
chan[c.chan].outVol=chan[c.chan].vol; chan[c.chan].outVol=chan[c.chan].vol;
if ((12*sampleBank+c.value%12)>=parent->song.sampleLen) { if ((12*sampleBank+c.value%12)>=parent->song.sampleLen) {
@ -978,8 +1000,8 @@ int DivPlatformYM2610B::dispatch(DivCommand c) {
break; break;
} }
case DIV_CMD_NOTE_PORTA: { case DIV_CMD_NOTE_PORTA: {
if (c.chan>5) { // PSG if (c.chan>5) { // PSG, ADPCM-B
int destFreq=NOTE_PERIODIC(c.value2); int destFreq=NOTE_OPNB(c.chan,c.value2);
bool return2=false; bool return2=false;
if (destFreq>chan[c.chan].baseFreq) { if (destFreq>chan[c.chan].baseFreq) {
chan[c.chan].baseFreq+=c.value; chan[c.chan].baseFreq+=c.value;
@ -1038,11 +1060,7 @@ int DivPlatformYM2610B::dispatch(DivCommand c) {
iface.sampleBank=sampleBank; iface.sampleBank=sampleBank;
break; break;
case DIV_CMD_LEGATO: { case DIV_CMD_LEGATO: {
if (c.chan>5) { // PSG chan[c.chan].baseFreq=NOTE_OPNB(c.chan,c.value);
chan[c.chan].baseFreq=NOTE_PERIODIC(c.value);
} else {
chan[c.chan].baseFreq=NOTE_FREQUENCY(c.value);
}
chan[c.chan].freqChanged=true; chan[c.chan].freqChanged=true;
break; break;
} }
@ -1273,11 +1291,6 @@ void DivPlatformYM2610B::reset() {
} }
lastBusy=60; lastBusy=60;
dacMode=0;
dacPeriod=0;
dacPos=0;
dacRate=0;
dacSample=-1;
sampleBank=0; sampleBank=0;
ayEnvPeriod=0; ayEnvPeriod=0;
ayEnvMode=0; ayEnvMode=0;

View File

@ -40,6 +40,7 @@ class DivPlatformYM2610B: public DivDispatch {
signed char konCycles; signed char konCycles;
bool active, insChanged, freqChanged, keyOn, keyOff, portaPause, inPorta, furnacePCM; bool active, insChanged, freqChanged, keyOn, keyOff, portaPause, inPorta, furnacePCM;
int vol, outVol; int vol, outVol;
int sample;
unsigned char pan; unsigned char pan;
DivMacroInt std; DivMacroInt std;
Channel(): Channel():
@ -63,6 +64,7 @@ class DivPlatformYM2610B: public DivDispatch {
furnacePCM(false), furnacePCM(false),
vol(0), vol(0),
outVol(15), outVol(15),
sample(-1),
pan(3) {} pan(3) {}
}; };
Channel chan[16]; Channel chan[16];
@ -80,11 +82,6 @@ class DivPlatformYM2610B: public DivDispatch {
unsigned char regPool[512]; unsigned char regPool[512];
unsigned char lastBusy; unsigned char lastBusy;
bool dacMode;
int dacPeriod;
int dacRate;
int dacPos;
int dacSample;
int ayNoiseFreq; int ayNoiseFreq;
unsigned char sampleBank; unsigned char sampleBank;
@ -101,6 +98,7 @@ class DivPlatformYM2610B: public DivDispatch {
int octave(int freq); int octave(int freq);
int toFreq(int freq); int toFreq(int freq);
double NOTE_OPNB(int ch, int note);
double NOTE_ADPCMB(int note); double NOTE_ADPCMB(int note);
friend void putDispatchChan(void*,int,int); friend void putDispatchChan(void*,int,int);