introduce a benchmark mode
This commit is contained in:
parent
a4741861ce
commit
cd7b333b2d
|
@ -0,0 +1,32 @@
|
||||||
|
macroState=$50 ; pointer to state
|
||||||
|
macroAddr=$52 ; pointer to address
|
||||||
|
|
||||||
|
; macro state takes 4 bytes
|
||||||
|
; macroPos bits:
|
||||||
|
; 7: had
|
||||||
|
; 6: will
|
||||||
|
|
||||||
|
; x: macro
|
||||||
|
macroIntRun:
|
||||||
|
lda macroAddr,x
|
||||||
|
ora macroAddr+1,x
|
||||||
|
beq :+
|
||||||
|
|
||||||
|
; do macro
|
||||||
|
: rts
|
||||||
|
|
||||||
|
; set the macro address, then call
|
||||||
|
; x: macro
|
||||||
|
macroIntInit:
|
||||||
|
lda #0
|
||||||
|
sta macroState,x
|
||||||
|
sta macroPos,x
|
||||||
|
txa
|
||||||
|
rol
|
||||||
|
tax
|
||||||
|
lda macroAddr,x
|
||||||
|
ora macroAddr+1,x
|
||||||
|
beq :+
|
||||||
|
lda #$40
|
||||||
|
sta macroState,x
|
||||||
|
: rts
|
|
@ -36,6 +36,7 @@
|
||||||
#include "../audio/jack.h"
|
#include "../audio/jack.h"
|
||||||
#endif
|
#endif
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
#include <float.h>
|
||||||
#ifdef HAVE_SNDFILE
|
#ifdef HAVE_SNDFILE
|
||||||
#include "sfWrapper.h"
|
#include "sfWrapper.h"
|
||||||
#endif
|
#endif
|
||||||
|
@ -181,6 +182,63 @@ void DivEngine::walkSong(int& loopOrder, int& loopRow, int& loopEnd) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define EXPORT_BUFSIZE 2048
|
||||||
|
|
||||||
|
double DivEngine::benchmarkPlayback() {
|
||||||
|
float* outBuf[2];
|
||||||
|
outBuf[0]=new float[EXPORT_BUFSIZE];
|
||||||
|
outBuf[1]=new float[EXPORT_BUFSIZE];
|
||||||
|
|
||||||
|
curOrder=0;
|
||||||
|
prevOrder=0;
|
||||||
|
remainingLoops=1;
|
||||||
|
playSub(false);
|
||||||
|
|
||||||
|
std::chrono::high_resolution_clock::time_point timeStart=std::chrono::high_resolution_clock::now();
|
||||||
|
|
||||||
|
// benchmark
|
||||||
|
while (playing) {
|
||||||
|
nextBuf(NULL,outBuf,0,2,EXPORT_BUFSIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::chrono::high_resolution_clock::time_point timeEnd=std::chrono::high_resolution_clock::now();
|
||||||
|
|
||||||
|
delete[] outBuf[0];
|
||||||
|
delete[] outBuf[1];
|
||||||
|
|
||||||
|
double t=(double)(std::chrono::duration_cast<std::chrono::microseconds>(timeEnd-timeStart).count())/1000000.0;
|
||||||
|
printf("[RESULT] %fs\n",t);
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
double DivEngine::benchmarkSeek() {
|
||||||
|
double t[20];
|
||||||
|
curOrder=curSubSong->ordersLen-1;
|
||||||
|
prevOrder=curSubSong->ordersLen-1;
|
||||||
|
|
||||||
|
// benchmark
|
||||||
|
for (int i=0; i<20; i++) {
|
||||||
|
std::chrono::high_resolution_clock::time_point timeStart=std::chrono::high_resolution_clock::now();
|
||||||
|
playSub(false);
|
||||||
|
std::chrono::high_resolution_clock::time_point timeEnd=std::chrono::high_resolution_clock::now();
|
||||||
|
t[i]=(double)(std::chrono::duration_cast<std::chrono::microseconds>(timeEnd-timeStart).count())/1000000.0;
|
||||||
|
printf("[#%d] %fs\n",i+1,t[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
double tMin=DBL_MAX;
|
||||||
|
double tMax=0.0;
|
||||||
|
double tAvg=0.0;
|
||||||
|
for (int i=0; i<20; i++) {
|
||||||
|
if (t[i]<tMin) tMin=t[i];
|
||||||
|
if (t[i]>tMax) tMax=t[i];
|
||||||
|
tAvg+=t[i];
|
||||||
|
}
|
||||||
|
tAvg/=20.0;
|
||||||
|
|
||||||
|
printf("[RESULT] min %fs max %fs average %fs\n",tMin,tMax,tAvg);
|
||||||
|
return tAvg;
|
||||||
|
}
|
||||||
|
|
||||||
void _runExportThread(DivEngine* caller) {
|
void _runExportThread(DivEngine* caller) {
|
||||||
caller->runExportThread();
|
caller->runExportThread();
|
||||||
}
|
}
|
||||||
|
@ -189,8 +247,6 @@ bool DivEngine::isExporting() {
|
||||||
return exporting;
|
return exporting;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define EXPORT_BUFSIZE 2048
|
|
||||||
|
|
||||||
#ifdef HAVE_SNDFILE
|
#ifdef HAVE_SNDFILE
|
||||||
void DivEngine::runExportThread() {
|
void DivEngine::runExportThread() {
|
||||||
size_t fadeOutSamples=got.rate*exportFadeOut;
|
size_t fadeOutSamples=got.rate*exportFadeOut;
|
||||||
|
|
|
@ -477,6 +477,10 @@ class DivEngine {
|
||||||
// notify wavetable change
|
// notify wavetable change
|
||||||
void notifyWaveChange(int wave);
|
void notifyWaveChange(int wave);
|
||||||
|
|
||||||
|
// benchmark (returns time in seconds)
|
||||||
|
double benchmarkPlayback();
|
||||||
|
double benchmarkSeek();
|
||||||
|
|
||||||
// returns the minimum VGM version which may carry the specified system, or 0 if none.
|
// returns the minimum VGM version which may carry the specified system, or 0 if none.
|
||||||
int minVGMVersion(DivSystem which);
|
int minVGMVersion(DivSystem which);
|
||||||
|
|
||||||
|
|
25
src/main.cpp
25
src/main.cpp
|
@ -49,6 +49,7 @@ FurnaceGUI g;
|
||||||
String outName;
|
String outName;
|
||||||
String vgmOutName;
|
String vgmOutName;
|
||||||
int loops=1;
|
int loops=1;
|
||||||
|
int benchMode=0;
|
||||||
DivAudioExportModes outMode=DIV_EXPORT_MODE_ONE;
|
DivAudioExportModes outMode=DIV_EXPORT_MODE_ONE;
|
||||||
|
|
||||||
#ifdef HAVE_GUI
|
#ifdef HAVE_GUI
|
||||||
|
@ -220,6 +221,19 @@ TAParamResult pOutMode(String val) {
|
||||||
return TA_PARAM_SUCCESS;
|
return TA_PARAM_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TAParamResult pBenchmark(String val) {
|
||||||
|
if (val=="render") {
|
||||||
|
benchMode=1;
|
||||||
|
} else if (val=="seek") {
|
||||||
|
benchMode=2;
|
||||||
|
} else {
|
||||||
|
logE("invalid value for benchmark! valid values are: render and seek.");
|
||||||
|
return TA_PARAM_ERROR;
|
||||||
|
}
|
||||||
|
e.setAudio(DIV_AUDIO_DUMMY);
|
||||||
|
return TA_PARAM_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
TAParamResult pOutput(String val) {
|
TAParamResult pOutput(String val) {
|
||||||
outName=val;
|
outName=val;
|
||||||
e.setAudio(DIV_AUDIO_DUMMY);
|
e.setAudio(DIV_AUDIO_DUMMY);
|
||||||
|
@ -254,6 +268,8 @@ void initParams() {
|
||||||
params.push_back(TAParam("l","loops",true,pLoops,"<count>","set number of loops (-1 means loop forever)"));
|
params.push_back(TAParam("l","loops",true,pLoops,"<count>","set number of loops (-1 means loop forever)"));
|
||||||
params.push_back(TAParam("o","outmode",true,pOutMode,"one|persys|perchan","set file output mode"));
|
params.push_back(TAParam("o","outmode",true,pOutMode,"one|persys|perchan","set file output mode"));
|
||||||
|
|
||||||
|
params.push_back(TAParam("B","benchmark",true,pBenchmark,"render|seek","run performance test"));
|
||||||
|
|
||||||
params.push_back(TAParam("V","version",false,pVersion,"","view information about Furnace."));
|
params.push_back(TAParam("V","version",false,pVersion,"","view information about Furnace."));
|
||||||
params.push_back(TAParam("W","warranty",false,pWarranty,"","view warranty disclaimer."));
|
params.push_back(TAParam("W","warranty",false,pWarranty,"","view warranty disclaimer."));
|
||||||
}
|
}
|
||||||
|
@ -414,6 +430,15 @@ int main(int argc, char** argv) {
|
||||||
displayEngineFailError=true;
|
displayEngineFailError=true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (benchMode) {
|
||||||
|
logI("starting benchmark!");
|
||||||
|
if (benchMode==2) {
|
||||||
|
e.benchmarkSeek();
|
||||||
|
} else {
|
||||||
|
e.benchmarkPlayback();
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
if (outName!="" || vgmOutName!="") {
|
if (outName!="" || vgmOutName!="") {
|
||||||
if (vgmOutName!="") {
|
if (vgmOutName!="") {
|
||||||
SafeWriter* w=e.saveVGM();
|
SafeWriter* w=e.saveVGM();
|
||||||
|
|
Loading…
Reference in New Issue