account for fadeout length, optimize some progress bar calc

This commit is contained in:
LTVA1 2024-08-21 15:11:11 +03:00 committed by tildearrow
parent 17f6ea5c6a
commit a4dae5302b
7 changed files with 180 additions and 28 deletions

View file

@ -199,9 +199,11 @@ void DivEngine::walkSong(int& loopOrder, int& loopRow, int& loopEnd) {
}
}
void DivEngine::findSongLength(bool& hasFFxx, std::vector<int>& orders, int& length, int loopOrder, int loopRow, int loopEnd) {
if (curSubSong!=NULL) {
curSubSong->findLength(hasFFxx, orders, length, loopOrder, loopRow, loopEnd, chans, song.jumpTreatment, song.ignoreJumpAtEnd);
void DivEngine::findSongLength(int loopOrder, int loopRow, double fadeoutLen, int& rowsForFadeout, bool& hasFFxx, std::vector<int>& orders, int& length)
{
if (curSubSong!=NULL)
{
curSubSong->findLength(loopOrder, loopRow, fadeoutLen, rowsForFadeout, hasFFxx, orders, song.grooves, length, chans, song.jumpTreatment, song.ignoreJumpAtEnd);
}
}

View file

@ -498,6 +498,7 @@ class DivEngine {
DivAudioExportModes exportMode;
DivAudioExportFormats exportFormat;
double exportFadeOut;
bool isFadingOut;
int exportOutputs;
bool exportChannelMask[DIV_MAX_CHANS];
DivConfig conf;
@ -817,7 +818,7 @@ class DivEngine {
void walkSong(int& loopOrder, int& loopRow, int& loopEnd);
// find song length in rows (up to specified loop point), and find length of every order
void findSongLength(bool& hasFFxx, std::vector<int>& orders, int& length, int loopOrder, int loopRow, int loopEnd);
void findSongLength(int loopOrder, int loopRow, double fadeoutLen, int& rowsForFadeout, bool& hasFFxx, std::vector<int>& orders, int& length);
// play (returns whether successful)
bool play();
@ -1025,6 +1026,9 @@ class DivEngine {
//get which file is processed right now (progress for e.g. per-channel export)
void getCurFileIndex(int& file);
//get fadeout state
bool getIsFadingOut();
// add instrument
int addInstrument(int refChan=0, DivInstrumentType fallbackType=DIV_INS_STD);
@ -1457,6 +1461,7 @@ class DivEngine {
exportMode(DIV_EXPORT_MODE_ONE),
exportFormat(DIV_EXPORT_FORMAT_S16),
exportFadeOut(0.0),
isFadingOut(false),
exportOutputs(2),
cmdStreamInt(NULL),
midiBaseChan(0),

View file

@ -102,14 +102,39 @@ bool DivSubSong::walk(int& loopOrder, int& loopRow, int& loopEnd, int chans, int
return false;
}
void DivSubSong::findLength(bool& hasFFxx, std::vector<int>& orders_vec, int& length, int& loopOrder, int& loopRow, int& loopEnd, int chans, int jumpTreatment, int ignoreJumpAtEnd, int firstPat)
double calcRowLenInSeconds(const DivGroovePattern& speeds, float hz, int vN, int vD, int timeBaseFromSong)
{
double hl=1; //count for 1 row
if (hl<=0.0) hl=4.0;
double timeBase=timeBaseFromSong+1;
double speedSum=0;
for (int i=0; i<MIN(16,speeds.len); i++) {
speedSum+=speeds.val[i];
}
speedSum/=MAX(1,speeds.len);
if (timeBase<1.0) timeBase=1.0;
if (speedSum<1.0) speedSum=1.0;
if (vD<1) vD=1;
//return (60.0 * hz / (timeBase * hl * speedSum)) * (double)vN / (double)vD;
return 1.0 / ((60.0*hz/(timeBase*hl*speedSum))*(double)vN/(double)vD / 60.0);
}
void DivSubSong::findLength(int loopOrder, int loopRow, double fadeoutLen, int& rowsForFadeout, bool& hasFFxx, std::vector<int>& orders_vec, std::vector<DivGroovePattern>& grooves, int& length, int chans, int jumpTreatment, int ignoreJumpAtEnd, int firstPat)
{
length = 0;
hasFFxx = false;
rowsForFadeout = 0;
float secondsPerThisRow = 0.0f;
DivGroovePattern curSpeeds = speeds; //simulate that we are playing the song, track all speed/BPM/tempo/engine rate changes
short curVirtualTempoN = virtualTempoN;
short curVirtualTempoD = virtualTempoD;
float curHz = hz;
double curDivider = (double)timeBase;
double curLen = 0.0; //how many seconds passed since the start of song
loopOrder=0;
loopRow=0;
loopEnd=-1;
int nextOrder=-1;
int nextRow=0;
int effectVal=0;
@ -139,9 +164,6 @@ void DivSubSong::findLength(bool& hasFFxx, std::vector<int>& orders_vec, int& le
bool jumpingOrder=false;
if (wsWalked[((i<<5)+(j>>3))&8191]&(1<<(j&7)))
{
loopOrder=i;
loopRow=j;
loopEnd=lastSuspectedLoopEnd;
return;
}
for (int k=0; k<chans; k++)
@ -162,6 +184,51 @@ void DivSubSong::findLength(bool& hasFFxx, std::vector<int>& orders_vec, int& le
return;
}
switch(subPat[k]->data[j][4+(l<<1)]) //track speed/BMP/Hz/tempo changes
{
case 0x09: // select groove pattern/speed 1
{
if (grooves.empty()) {
if (effectVal>0) curSpeeds.val[0]=effectVal;
} else {
if (effectVal<(short)grooves.size()) {
curSpeeds=grooves[effectVal];
//curSpeed=0;
}
}
break;
}
case 0x0f: // speed 1/speed 2
{
if (curSpeeds.len==2 && grooves.empty()) {
if (effectVal>0) curSpeeds.val[1]=effectVal;
} else {
if (effectVal>0) curSpeeds.val[0]=effectVal;
}
break;
}
case 0xfd: // virtual tempo num
{
if (effectVal>0) curVirtualTempoN=effectVal;
break;
}
case 0xfe: // virtual tempo den
{
if (effectVal>0) curVirtualTempoD=effectVal;
break;
}
case 0xf0: // set Hz by tempo (set bpm)
{
curDivider=(double)effectVal*2.0/5.0;
if (curDivider<1) curDivider=1;
//cycles=got.rate*pow(2,MASTER_CLOCK_PREC)/divider;
//clockDrift=0;
//subticks=0;
break;
}
default: break;
}
if (subPat[k]->data[j][4+(l<<1)]==0x0d)
{
if (jumpTreatment==2)
@ -210,6 +277,16 @@ void DivSubSong::findLength(bool& hasFFxx, std::vector<int>& orders_vec, int& le
}
}
if(i > loopOrder || (i == loopOrder && j > loopRow))
{
if(curLen <= fadeoutLen && fadeoutLen > 0.0) //we count each row fadeout lasts. When our time is greater than fadeout length we successfully counted the number of fadeout rows
{
secondsPerThisRow = calcRowLenInSeconds(speeds, curHz, curVirtualTempoN, curVirtualTempoD, curDivider);
curLen += secondsPerThisRow;
rowsForFadeout++;
}
}
wsWalked[((i<<5)+(j>>3))&8191]|=1<<(j&7);
if (nextOrder!=-1)

View file

@ -188,7 +188,7 @@ struct DivSubSong {
/**
* find song length in rows (up to specified loop point). Also find length of every row
*/
void findLength(bool& hasFFxx, std::vector<int>& orders, int& length, int& loopOrder, int& loopRow, int& loopEnd, int chans, int jumpTreatment, int ignoreJumpAtEnd, int firstPat=0);
void findLength(int loopOrder, int loopRow, double fadeoutLen, int& rowsForFadeout, bool& hasFFxx, std::vector<int>& orders, std::vector<DivGroovePattern>& grooves, int& length, int chans, int jumpTreatment, int ignoreJumpAtEnd, int firstPat=0);
void clearData();
void optimizePatterns();

View file

@ -104,11 +104,16 @@ void DivEngine::getCurFileIndex(int& file)
}
}
bool DivEngine::getIsFadingOut()
{
return isFadingOut;
}
#ifdef HAVE_SNDFILE
void DivEngine::runExportThread() {
size_t fadeOutSamples=got.rate*exportFadeOut;
size_t curFadeOutSample=0;
bool isFadingOut=false;
isFadingOut=false;
switch (exportMode) {
case DIV_EXPORT_MODE_ONE: {