VGM export: NES samples

This commit is contained in:
tildearrow 2022-01-24 17:48:58 -05:00
parent 92b5620497
commit cda191afee
2 changed files with 55 additions and 3 deletions

View file

@ -2084,6 +2084,8 @@ SafeWriter* DivEngine::saveVGM() {
int streamIDs[32]; int streamIDs[32];
bool writeDACSamples=false; bool writeDACSamples=false;
bool writeNESSamples=false;
bool writePCESamples=false;
bool writeADPCM=false; bool writeADPCM=false;
bool writeSegaPCM=false; bool writeSegaPCM=false;
@ -2119,14 +2121,14 @@ SafeWriter* DivEngine::saveVGM() {
if (!hasPCE) { if (!hasPCE) {
hasPCE=3579545; hasPCE=3579545;
willExport[i]=true; willExport[i]=true;
writeDACSamples=true; writePCESamples=true;
} }
break; break;
case DIV_SYSTEM_NES: case DIV_SYSTEM_NES:
if (!hasNES) { if (!hasNES) {
hasNES=1789773; hasNES=1789773;
willExport[i]=true; willExport[i]=true;
writeDACSamples=true; writeNESSamples=true;
} }
break; break;
case DIV_SYSTEM_ARCADE: case DIV_SYSTEM_ARCADE:
@ -2275,6 +2277,27 @@ SafeWriter* DivEngine::saveVGM() {
} }
} }
if (writeNESSamples) for (int i=0; i<song.sampleLen; i++) {
DivSample* sample=song.sample[i];
w->writeC(0x67);
w->writeC(0x66);
w->writeC(7);
w->writeI(sample->rendLength);
if (sample->depth==8) {
for (unsigned int j=0; j<sample->rendLength; j++) {
w->writeC(((unsigned char)sample->rendData[j]+0x80)>>1);
}
} else {
for (unsigned int j=0; j<sample->rendLength; j++) {
w->writeC(((unsigned short)sample->rendData[j]+0x8000)>>9);
}
}
}
if (writePCESamples) {
// TODO
}
if (writeSegaPCM) { if (writeSegaPCM) {
unsigned char* pcmMem=new unsigned char[16777216]; unsigned char* pcmMem=new unsigned char[16777216];
@ -2366,6 +2389,24 @@ SafeWriter* DivEngine::saveVGM() {
w->writeC(1); w->writeC(1);
w->writeC(0); w->writeC(0);
w->writeC(0x92);
w->writeC(streamID);
w->writeI(32000); // default
streamID++;
break;
case DIV_SYSTEM_NES:
w->writeC(0x90);
w->writeC(streamID);
w->writeC(20);
w->writeC(0); // port
w->writeC(0x11); // DAC
w->writeC(0x91);
w->writeC(streamID);
w->writeC(7);
w->writeC(1);
w->writeC(0);
w->writeC(0x92); w->writeC(0x92);
w->writeC(streamID); w->writeC(streamID);
w->writeI(32000); // default w->writeI(32000); // default

View file

@ -168,6 +168,7 @@ void DivPlatformNES::tick() {
chan[4].freq=parent->calcFreq(chan[4].baseFreq,chan[4].pitch,false); chan[4].freq=parent->calcFreq(chan[4].baseFreq,chan[4].pitch,false);
if (chan[4].furnaceDac) { if (chan[4].furnaceDac) {
dacRate=MIN(chan[4].freq,32000); dacRate=MIN(chan[4].freq,32000);
if (dumpWrites) addWrite(0xffff0001,dacRate);
} }
chan[4].freqChanged=false; chan[4].freqChanged=false;
} }
@ -182,7 +183,10 @@ int DivPlatformNES::dispatch(DivCommand c) {
dacSample=ins->amiga.initSample; dacSample=ins->amiga.initSample;
if (dacSample<0 || dacSample>=parent->song.sampleLen) { if (dacSample<0 || dacSample>=parent->song.sampleLen) {
dacSample=-1; dacSample=-1;
if (dumpWrites) addWrite(0xffff0002,0);
break; break;
} else {
if (dumpWrites) addWrite(0xffff0000,dacSample);
} }
dacPos=0; dacPos=0;
dacPeriod=0; dacPeriod=0;
@ -198,11 +202,15 @@ int DivPlatformNES::dispatch(DivCommand c) {
dacSample=12*sampleBank+c.value%12; dacSample=12*sampleBank+c.value%12;
if (dacSample>=parent->song.sampleLen) { if (dacSample>=parent->song.sampleLen) {
dacSample=-1; dacSample=-1;
if (dumpWrites) addWrite(0xffff0002,0);
break; break;
} else {
if (dumpWrites) addWrite(0xffff0000,dacSample);
} }
dacPos=0; dacPos=0;
dacPeriod=0; dacPeriod=0;
dacRate=parent->song.sample[dacSample]->rate; dacRate=parent->song.sample[dacSample]->rate;
if (dumpWrites) addWrite(0xffff0001,dacRate);
chan[c.chan].furnaceDac=false; chan[c.chan].furnaceDac=false;
} }
break; break;
@ -229,7 +237,10 @@ int DivPlatformNES::dispatch(DivCommand c) {
} }
break; break;
case DIV_CMD_NOTE_OFF: case DIV_CMD_NOTE_OFF:
if (c.chan==4) dacSample=-1; if (c.chan==4) {
dacSample=-1;
if (dumpWrites) addWrite(0xffff0002,0);
}
chan[c.chan].active=false; chan[c.chan].active=false;
chan[c.chan].keyOff=true; chan[c.chan].keyOff=true;
chan[c.chan].std.init(NULL); chan[c.chan].std.init(NULL);