VGM export: add speed drift compensation setting
it appears this is the only way to get exports to play at the correct speed in DeadFish's VGM player for Genesis
This commit is contained in:
parent
41dcfe8462
commit
fe454ee2df
|
@ -583,7 +583,7 @@ class DivEngine {
|
||||||
void processRow(int i, bool afterDelay);
|
void processRow(int i, bool afterDelay);
|
||||||
void nextOrder();
|
void nextOrder();
|
||||||
void nextRow();
|
void nextRow();
|
||||||
void performVGMWrite(SafeWriter* w, DivSystem sys, DivRegWrite& write, int streamOff, double* loopTimer, double* loopFreq, int* loopSample, bool* sampleDir, bool isSecond, int* pendingFreq, int* playingSample, int* setPos, unsigned int* sampleOff8, unsigned int* sampleLen8, size_t bankOffset, bool directStream, bool* sampleStoppable, bool dpcm07, DivDispatch** writeNES);
|
void performVGMWrite(SafeWriter* w, DivSystem sys, DivRegWrite& write, int streamOff, double* loopTimer, double* loopFreq, int* loopSample, bool* sampleDir, bool isSecond, int* pendingFreq, int* playingSample, int* setPos, unsigned int* sampleOff8, unsigned int* sampleLen8, size_t bankOffset, bool directStream, bool* sampleStoppable, bool dpcm07, DivDispatch** writeNES, int rateCorrection);
|
||||||
// returns true if end of song.
|
// returns true if end of song.
|
||||||
bool nextTick(bool noAccum=false, bool inhibitLowLat=false);
|
bool nextTick(bool noAccum=false, bool inhibitLowLat=false);
|
||||||
bool perSystemEffect(int ch, unsigned char effect, unsigned char effectVal);
|
bool perSystemEffect(int ch, unsigned char effect, unsigned char effectVal);
|
||||||
|
@ -726,7 +726,7 @@ class DivEngine {
|
||||||
// - x to add x+1 ticks of trailing
|
// - x to add x+1 ticks of trailing
|
||||||
// - -1 to auto-determine trailing
|
// - -1 to auto-determine trailing
|
||||||
// - -2 to add a whole loop of trailing
|
// - -2 to add a whole loop of trailing
|
||||||
SafeWriter* saveVGM(bool* sysToExport=NULL, bool loop=true, int version=0x171, bool patternHints=false, bool directStream=false, int trailingTicks=-1, bool dpcm07=false);
|
SafeWriter* saveVGM(bool* sysToExport=NULL, bool loop=true, int version=0x171, bool patternHints=false, bool directStream=false, int trailingTicks=-1, bool dpcm07=false, int correctedRate=44100);
|
||||||
// dump to TIunA.
|
// dump to TIunA.
|
||||||
SafeWriter* saveTiuna(const bool* sysToExport, const char* baseLabel, int firstBankSize, int otherBankSize);
|
SafeWriter* saveTiuna(const bool* sysToExport, const char* baseLabel, int firstBankSize, int otherBankSize);
|
||||||
// dump command stream.
|
// dump command stream.
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
|
|
||||||
// this function is so long
|
// this function is so long
|
||||||
// may as well make it something else
|
// may as well make it something else
|
||||||
void DivEngine::performVGMWrite(SafeWriter* w, DivSystem sys, DivRegWrite& write, int streamOff, double* loopTimer, double* loopFreq, int* loopSample, bool* sampleDir, bool isSecond, int* pendingFreq, int* playingSample, int* setPos, unsigned int* sampleOff8, unsigned int* sampleLen8, size_t bankOffset, bool directStream, bool* sampleStoppable, bool dpcm07, DivDispatch** writeNES) {
|
void DivEngine::performVGMWrite(SafeWriter* w, DivSystem sys, DivRegWrite& write, int streamOff, double* loopTimer, double* loopFreq, int* loopSample, bool* sampleDir, bool isSecond, int* pendingFreq, int* playingSample, int* setPos, unsigned int* sampleOff8, unsigned int* sampleLen8, size_t bankOffset, bool directStream, bool* sampleStoppable, bool dpcm07, DivDispatch** writeNES, int rateCorrection) {
|
||||||
unsigned char baseAddr1=isSecond?0xa0:0x50;
|
unsigned char baseAddr1=isSecond?0xa0:0x50;
|
||||||
unsigned char baseAddr2=isSecond?0x80:0;
|
unsigned char baseAddr2=isSecond?0x80:0;
|
||||||
unsigned short baseAddr2S=isSecond?0x8000:0;
|
unsigned short baseAddr2S=isSecond?0x8000:0;
|
||||||
|
@ -795,7 +795,7 @@ void DivEngine::performVGMWrite(SafeWriter* w, DivSystem sys, DivRegWrite& write
|
||||||
break;
|
break;
|
||||||
case 1: { // set sample freq
|
case 1: { // set sample freq
|
||||||
sampleStoppable[streamID]=true;
|
sampleStoppable[streamID]=true;
|
||||||
int realFreq=write.val;
|
int realFreq=(write.val*44100)/rateCorrection;
|
||||||
if (realFreq<0) realFreq=0;
|
if (realFreq<0) realFreq=0;
|
||||||
if (realFreq>44100) realFreq=44100;
|
if (realFreq>44100) realFreq=44100;
|
||||||
w->writeC(0x92);
|
w->writeC(0x92);
|
||||||
|
@ -1233,7 +1233,7 @@ void DivEngine::performVGMWrite(SafeWriter* w, DivSystem sys, DivRegWrite& write
|
||||||
chipVol.push_back((_id)|(0x80000100)|(((unsigned int)_vol)<<16)); \
|
chipVol.push_back((_id)|(0x80000100)|(((unsigned int)_vol)<<16)); \
|
||||||
}
|
}
|
||||||
|
|
||||||
SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version, bool patternHints, bool directStream, int trailingTicks, bool dpcm07) {
|
SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version, bool patternHints, bool directStream, int trailingTicks, bool dpcm07, int correctedRate) {
|
||||||
if (version<0x150) {
|
if (version<0x150) {
|
||||||
lastError="VGM version is too low";
|
lastError="VGM version is too low";
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -1243,7 +1243,7 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version, bool p
|
||||||
setOrder(0);
|
setOrder(0);
|
||||||
BUSY_BEGIN_SOFT;
|
BUSY_BEGIN_SOFT;
|
||||||
double origRate=got.rate;
|
double origRate=got.rate;
|
||||||
got.rate=44100;
|
got.rate=correctedRate;
|
||||||
// determine loop point
|
// determine loop point
|
||||||
int loopOrder=0;
|
int loopOrder=0;
|
||||||
int loopRow=0;
|
int loopRow=0;
|
||||||
|
@ -2840,7 +2840,7 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version, bool p
|
||||||
lastOne=i.second.time;
|
lastOne=i.second.time;
|
||||||
}
|
}
|
||||||
// write write
|
// write write
|
||||||
performVGMWrite(w,song.system[i.first],i.second.write,streamIDs[i.first],loopTimer,loopFreq,loopSample,sampleDir,isSecond[i.first],pendingFreq,playingSample,setPos,sampleOff8,sampleLen8,bankOffset[i.first],directStream,sampleStoppable,dpcm07,writeNES);
|
performVGMWrite(w,song.system[i.first],i.second.write,streamIDs[i.first],loopTimer,loopFreq,loopSample,sampleDir,isSecond[i.first],pendingFreq,playingSample,setPos,sampleOff8,sampleLen8,bankOffset[i.first],directStream,sampleStoppable,dpcm07,writeNES,correctedRate);
|
||||||
writeCount++;
|
writeCount++;
|
||||||
}
|
}
|
||||||
sortedWrites.clear();
|
sortedWrites.clear();
|
||||||
|
|
|
@ -239,6 +239,16 @@ void FurnaceGUI::drawExportVGM(bool onWindow) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ImGui::Text(_("speed drift compensation:"));
|
||||||
|
if (ImGui::RadioButton(_("none"),vgmExportCorrectedRate==44100)) {
|
||||||
|
vgmExportCorrectedRate=44100;
|
||||||
|
}
|
||||||
|
// as tested on a Model 1 Genesis (VA6, USA):
|
||||||
|
// 0.97841613336995507871 slower, 1.02206000687632131440 longer
|
||||||
|
if (ImGui::RadioButton(_("DeadFish VgmPlay (1.02×)"),vgmExportCorrectedRate==43148)) {
|
||||||
|
vgmExportCorrectedRate=43148;
|
||||||
|
}
|
||||||
|
|
||||||
if (hasOneAtLeast) {
|
if (hasOneAtLeast) {
|
||||||
if (onWindow) {
|
if (onWindow) {
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
|
|
|
@ -5654,7 +5654,7 @@ bool FurnaceGUI::loop() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case GUI_FILE_EXPORT_VGM: {
|
case GUI_FILE_EXPORT_VGM: {
|
||||||
SafeWriter* w=e->saveVGM(willExport,vgmExportLoop,vgmExportVersion,vgmExportPatternHints,vgmExportDirectStream,vgmExportTrailingTicks,vgmExportDPCM07);
|
SafeWriter* w=e->saveVGM(willExport,vgmExportLoop,vgmExportVersion,vgmExportPatternHints,vgmExportDirectStream,vgmExportTrailingTicks,vgmExportDPCM07,vgmExportCorrectedRate);
|
||||||
if (w!=NULL) {
|
if (w!=NULL) {
|
||||||
FILE* f=ps_fopen(copyOfName.c_str(),"wb");
|
FILE* f=ps_fopen(copyOfName.c_str(),"wb");
|
||||||
if (f!=NULL) {
|
if (f!=NULL) {
|
||||||
|
@ -8478,6 +8478,7 @@ FurnaceGUI::FurnaceGUI():
|
||||||
debugFFT(false),
|
debugFFT(false),
|
||||||
vgmExportVersion(0x171),
|
vgmExportVersion(0x171),
|
||||||
vgmExportTrailingTicks(-1),
|
vgmExportTrailingTicks(-1),
|
||||||
|
vgmExportCorrectedRate(44100),
|
||||||
drawHalt(10),
|
drawHalt(10),
|
||||||
macroPointSize(16),
|
macroPointSize(16),
|
||||||
waveEditStyle(0),
|
waveEditStyle(0),
|
||||||
|
|
|
@ -1687,6 +1687,7 @@ class FurnaceGUI {
|
||||||
bool willExport[DIV_MAX_CHIPS];
|
bool willExport[DIV_MAX_CHIPS];
|
||||||
int vgmExportVersion;
|
int vgmExportVersion;
|
||||||
int vgmExportTrailingTicks;
|
int vgmExportTrailingTicks;
|
||||||
|
int vgmExportCorrectedRate;
|
||||||
int cvHiScore;
|
int cvHiScore;
|
||||||
int drawHalt;
|
int drawHalt;
|
||||||
int macroPointSize;
|
int macroPointSize;
|
||||||
|
|
Loading…
Reference in a new issue