mirror of
https://github.com/tildearrow/furnace.git
synced 2025-01-01 04:21:44 +00:00
VGM export: implement ADPCM storage
possibly first open-source Neo Geo tracker that exports to .vgm
This commit is contained in:
parent
a3a2e3ff47
commit
1b4081a044
2 changed files with 30 additions and 3 deletions
|
@ -2074,12 +2074,17 @@ SafeWriter* DivEngine::saveVGM() {
|
||||||
bool willExport[32];
|
bool willExport[32];
|
||||||
int streamIDs[32];
|
int streamIDs[32];
|
||||||
|
|
||||||
|
bool writeDACSamples=false;
|
||||||
|
bool writeADPCM=false;
|
||||||
|
bool writeSegaPCM=false;
|
||||||
|
|
||||||
for (int i=0; i<song.systemLen; i++) {
|
for (int i=0; i<song.systemLen; i++) {
|
||||||
willExport[i]=false;
|
willExport[i]=false;
|
||||||
streamIDs[i]=0;
|
streamIDs[i]=0;
|
||||||
switch (song.system[i]) {
|
switch (song.system[i]) {
|
||||||
case DIV_SYSTEM_GENESIS:
|
case DIV_SYSTEM_GENESIS:
|
||||||
case DIV_SYSTEM_GENESIS_EXT:
|
case DIV_SYSTEM_GENESIS_EXT:
|
||||||
|
writeDACSamples=true;
|
||||||
if (!hasOPN2) {
|
if (!hasOPN2) {
|
||||||
hasOPN2=7670454;
|
hasOPN2=7670454;
|
||||||
willExport[i]=true;
|
willExport[i]=true;
|
||||||
|
@ -2105,12 +2110,14 @@ SafeWriter* DivEngine::saveVGM() {
|
||||||
if (!hasPCE) {
|
if (!hasPCE) {
|
||||||
hasPCE=3579545;
|
hasPCE=3579545;
|
||||||
willExport[i]=true;
|
willExport[i]=true;
|
||||||
|
writeDACSamples=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;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DIV_SYSTEM_ARCADE:
|
case DIV_SYSTEM_ARCADE:
|
||||||
|
@ -2121,6 +2128,7 @@ SafeWriter* DivEngine::saveVGM() {
|
||||||
if (!hasSegaPCM) {
|
if (!hasSegaPCM) {
|
||||||
hasSegaPCM=4000000;
|
hasSegaPCM=4000000;
|
||||||
willExport[i]=true;
|
willExport[i]=true;
|
||||||
|
writeSegaPCM=true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DIV_SYSTEM_YM2610:
|
case DIV_SYSTEM_YM2610:
|
||||||
|
@ -2128,6 +2136,7 @@ SafeWriter* DivEngine::saveVGM() {
|
||||||
if (!hasOPNB) {
|
if (!hasOPNB) {
|
||||||
hasOPNB=8000000;
|
hasOPNB=8000000;
|
||||||
willExport[i]=true;
|
willExport[i]=true;
|
||||||
|
writeADPCM=true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DIV_SYSTEM_AY8910:
|
case DIV_SYSTEM_AY8910:
|
||||||
|
@ -2149,6 +2158,7 @@ SafeWriter* DivEngine::saveVGM() {
|
||||||
if (!hasOPN2) {
|
if (!hasOPN2) {
|
||||||
hasOPN2=7670454;
|
hasOPN2=7670454;
|
||||||
willExport[i]=true;
|
willExport[i]=true;
|
||||||
|
writeDACSamples=true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DIV_SYSTEM_YM2151:
|
case DIV_SYSTEM_YM2151:
|
||||||
|
@ -2239,11 +2249,11 @@ SafeWriter* DivEngine::saveVGM() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// write samples
|
// write samples
|
||||||
for (int i=0; i<song.sampleLen; i++) {
|
if (writeDACSamples) for (int i=0; i<song.sampleLen; i++) {
|
||||||
DivSample* sample=song.sample[i];
|
DivSample* sample=song.sample[i];
|
||||||
w->writeC(0x67);
|
w->writeC(0x67);
|
||||||
w->writeC(0x66);
|
w->writeC(0x66);
|
||||||
w->writeC(0); // for now!
|
w->writeC(0);
|
||||||
w->writeI(sample->rendLength);
|
w->writeI(sample->rendLength);
|
||||||
if (sample->depth==8) {
|
if (sample->depth==8) {
|
||||||
for (unsigned int j=0; j<sample->rendLength; j++) {
|
for (unsigned int j=0; j<sample->rendLength; j++) {
|
||||||
|
@ -2256,6 +2266,20 @@ SafeWriter* DivEngine::saveVGM() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (writeSegaPCM) {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
if (writeADPCM && adpcmMemLen>0) {
|
||||||
|
w->writeC(0x67);
|
||||||
|
w->writeC(0x66);
|
||||||
|
w->writeC(0x82);
|
||||||
|
w->writeI(adpcmMemLen);
|
||||||
|
w->writeI(adpcmMemLen);
|
||||||
|
w->writeI(0);
|
||||||
|
w->write(adpcmMem,adpcmMemLen);
|
||||||
|
}
|
||||||
|
|
||||||
// initialize streams
|
// initialize streams
|
||||||
int streamID=0;
|
int streamID=0;
|
||||||
for (int i=0; i<song.systemLen; i++) {
|
for (int i=0; i<song.systemLen; i++) {
|
||||||
|
@ -2901,6 +2925,7 @@ void DivEngine::renderSamples() {
|
||||||
s->rendOff=memPos;
|
s->rendOff=memPos;
|
||||||
memPos+=s->adpcmRendLength;
|
memPos+=s->adpcmRendLength;
|
||||||
}
|
}
|
||||||
|
adpcmMemLen=memPos;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DivEngine::createNew() {
|
void DivEngine::createNew() {
|
||||||
|
|
|
@ -485,6 +485,7 @@ class DivEngine {
|
||||||
bool quit();
|
bool quit();
|
||||||
|
|
||||||
unsigned char* adpcmMem;
|
unsigned char* adpcmMem;
|
||||||
|
size_t adpcmMemLen;
|
||||||
|
|
||||||
DivEngine():
|
DivEngine():
|
||||||
output(NULL),
|
output(NULL),
|
||||||
|
@ -532,6 +533,7 @@ class DivEngine {
|
||||||
metroAmp(0.0f),
|
metroAmp(0.0f),
|
||||||
totalProcessed(0),
|
totalProcessed(0),
|
||||||
jediTable(NULL),
|
jediTable(NULL),
|
||||||
adpcmMem(NULL) {}
|
adpcmMem(NULL),
|
||||||
|
adpcmMemLen(0) {}
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue