VGM export: bake SegaPCM samples

after this, the following has to be done:
- PCM playback
- PCM playback on PCE and NES (let's hope this is possible)
This commit is contained in:
tildearrow 2022-01-24 12:39:05 -05:00
parent ea796c2d6b
commit e221bcb023
3 changed files with 59 additions and 6 deletions

View file

@ -1973,9 +1973,18 @@ void DivEngine::performVGMWrite(SafeWriter* w, DivSystem sys, DivRegWrite& write
break;
case DIV_SYSTEM_ARCADE:
case DIV_SYSTEM_YM2151:
w->writeC(0x54);
w->writeC(write.addr&0xff);
w->writeC(write.val);
switch (write.addr>>16) {
case 0: // YM2151
w->writeC(0x54);
w->writeC(write.addr&0xff);
w->writeC(write.val);
break;
case 1: // SegaPCM
w->writeC(0xc0);
w->writeS(write.addr&0xffff);
w->writeC(write.val);
break;
}
break;
case DIV_SYSTEM_YM2610:
switch (write.addr>>8) {
@ -2267,14 +2276,52 @@ SafeWriter* DivEngine::saveVGM() {
}
if (writeSegaPCM) {
// TODO
unsigned char* pcmMem=new unsigned char[16777216];
size_t memPos=0;
for (int i=0; i<song.sampleLen; i++) {
DivSample* sample=song.sample[i];
sample->rendOffP=memPos;
unsigned int alignedSize=(sample->rendLength+0xff)&(~0xff);
if (alignedSize>65536) alignedSize=65536;
if (sample->depth==8) {
for (unsigned int j=0; j<alignedSize; j++) {
if (j>=sample->rendLength) {
pcmMem[memPos++]=0;
} else {
pcmMem[memPos++]=((unsigned char)sample->rendData[j]);
}
if (memPos>=16777216) break;
}
} else {
for (unsigned int j=0; j<alignedSize; j++) {
if (j>=sample->rendLength) {
pcmMem[memPos++]=0;
} else {
pcmMem[memPos++]=(((unsigned short)sample->rendData[j])>>8);
}
if (memPos>=16777216) break;
}
}
if (memPos>=16777216) break;
}
w->writeC(0x67);
w->writeC(0x66);
w->writeC(0x80);
w->writeI(memPos+8);
w->writeI(memPos);
w->writeI(0);
w->write(pcmMem,memPos);
delete[] pcmMem;
}
if (writeADPCM && adpcmMemLen>0) {
w->writeC(0x67);
w->writeC(0x66);
w->writeC(0x82);
w->writeI(adpcmMemLen);
w->writeI(adpcmMemLen+8);
w->writeI(adpcmMemLen);
w->writeI(0);
w->write(adpcmMem,adpcmMemLen);

View file

@ -241,6 +241,11 @@ int DivPlatformArcade::dispatch(DivCommand c) {
chan[c.chan].baseFreq=c.value<<6;
chan[c.chan].freqChanged=true;
chan[c.chan].furnacePCM=true;
if (dumpWrites) { // Sega PCM writes
DivSample* s=parent->song.sample[chan[c.chan].pcm.sample];
// TODO: THIS!!!
addWrite(0x10084,s->rendOffP);
}
} else {
chan[c.chan].pcm.sample=12*sampleBank+c.value%12;
if (chan[c.chan].pcm.sample>=parent->song.sampleLen) {

View file

@ -6,7 +6,7 @@ struct DivSample {
signed char vol, pitch;
unsigned char depth;
short* data;
unsigned int rendLength, adpcmRendLength, rendOff;
unsigned int rendLength, adpcmRendLength, rendOff, rendOffP;
short* rendData;
unsigned char* adpcmRendData;
@ -23,6 +23,7 @@ struct DivSample {
rendLength(0),
adpcmRendLength(0),
rendOff(0),
rendOffP(0),
rendData(NULL),
adpcmRendData(NULL) {}
~DivSample();