From 9f105d92a8e254cd5ba46d71cc8c32780c91c2b8 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Sun, 9 Oct 2022 17:24:24 -0500 Subject: [PATCH] VGM export: why --- src/engine/vgmOps.cpp | 56 ++++++++++++++++++++++++++++++------------- 1 file changed, 39 insertions(+), 17 deletions(-) diff --git a/src/engine/vgmOps.cpp b/src/engine/vgmOps.cpp index 67817a5e..815436fd 100644 --- a/src/engine/vgmOps.cpp +++ b/src/engine/vgmOps.cpp @@ -807,6 +807,20 @@ void DivEngine::performVGMWrite(SafeWriter* w, DivSystem sys, DivRegWrite& write } } +#define CHIP_VOL(_id,_mult) { \ + double _vol=fabs(song.systemVol[i])*4.0*_mult; \ + if (_vol<0.0) _vol=0.0; \ + if (_vol>32767.0) _vol=32767.0; \ + chipVol.push_back((_id)|(0x80000000)|(((unsigned int)_vol)<<16)); \ +} + +#define CHIP_VOL_SECOND(_id,_mult) { \ + double _vol=fabs(song.systemVol[i])*4.0*_mult; \ + if (_vol<0.0) _vol=0.0; \ + if (_vol>32767.0) _vol=32767.0; \ + chipVol.push_back((_id)|(0x80000100)|(((unsigned int)_vol)<<16)); \ +} + SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version, bool patternHints) { if (version<0x150) { lastError="VGM version is too low"; @@ -910,6 +924,7 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version, bool p double loopFreq[DIV_MAX_CHANS]; int loopSample[DIV_MAX_CHANS]; bool sampleDir[DIV_MAX_CHANS]; + std::vector chipVol; for (int i=0; ichipClock; + CHIP_VOL(0,1.0); willExport[i]=true; switch (song.systemFlags[i].getInt("chipType",0)) { case 1: // real SN @@ -961,6 +977,7 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version, bool p } else if (!(hasSN&0x40000000)) { isSecond[i]=true; willExport[i]=true; + CHIP_VOL_SECOND(0,1.0); hasSN|=0x40000000; howManyChips++; } @@ -1353,14 +1370,6 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version, bool p } } - //bool wantsExtraHeader=false; - /*for (int i=0; iwriteI(hasSN); w->writeI(hasOPLL); @@ -1422,8 +1431,15 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version, bool p w->writeC(0); // OPN w->writeC(0); // OPNA } + if (version>=0x160) { + int calcVolume=32.0*(log(song.masterVol)/log(2.0)); + if (calcVolume<-63) calcVolume=-63; + if (calcVolume>192) calcVolume=192; + w->writeC(calcVolume&0xff); // volume + } else { + w->writeC(0); // volume + } // currently not used but is part of 1.60 - w->writeC(0); // volume w->writeC(0); // reserved w->writeC(0); // loop count // 1.51 @@ -1507,15 +1523,21 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version, bool p w->writeI(0); } - /* TODO unsigned int exHeaderOff=w->tell(); - if (wantsExtraHeader) { - w->writeI(4); + if (version>=0x170) { + logD("writing extended header..."); + w->writeI(8); + w->writeI(0); w->writeI(4); - // write clocks - w->writeC(howManyChips); - }*/ + // write chip volumes + logD("writing chip volumes (%ld)...",chipVol.size()); + w->writeC(chipVol.size()); + for (unsigned int& i: chipVol) { + logV("- %.8x",i); + w->writeI(i); + } + } unsigned int songOff=w->tell(); @@ -2015,10 +2037,10 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version, bool p } w->seek(0x34,SEEK_SET); w->writeI(songOff-0x34); - /*if (wantsExtraHeader) { + if (version>=0x170) { w->seek(0xbc,SEEK_SET); w->writeI(exHeaderOff-0xbc); - }*/ + } remainingLoops=-1; playing=false;