This commit is contained in:
tildearrow 2024-08-24 17:41:41 -05:00
parent c06759b235
commit 0ab9f6c6fd
8 changed files with 163 additions and 239 deletions

View file

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

View file

@ -475,7 +475,7 @@ class DivEngine {
int midiOutTimeRate; int midiOutTimeRate;
float midiVolExp; float midiVolExp;
int softLockCount; int softLockCount;
int subticks, ticks, curRow, curOrder, prevRow, prevOrder, remainingLoops, totalLoops, lastLoopPos, exportLoopCount, curExportChan /*for per-channel export progress*/, nextSpeed, elapsedBars, elapsedBeats, curSpeed; int subticks, ticks, curRow, curOrder, prevRow, prevOrder, remainingLoops, totalLoops, lastLoopPos, exportLoopCount, curExportChan, nextSpeed, elapsedBars, elapsedBeats, curSpeed;
size_t curSubSongIndex; size_t curSubSongIndex;
size_t bufferPos; size_t bufferPos;
double divider; double divider;
@ -1015,19 +1015,19 @@ class DivEngine {
// get how many loops is left // get how many loops is left
void getLoopsLeft(int& loops); void getLoopsLeft(int& loops);
//get how many loops in total export needs to do // get how many loops in total export needs to do
void getTotalLoops(int& loops); void getTotalLoops(int& loops);
// get current position in song // get current position in song
void getCurSongPos(int& row, int& order); void getCurSongPos(int& row, int& order);
//get how many files export needs to create // get how many files export needs to create
void getTotalAudioFiles(int& files); void getTotalAudioFiles(int& files);
//get which file is processed right now (progress for e.g. per-channel export) // get which file is processed right now (progress for e.g. per-channel export)
void getCurFileIndex(int& file); void getCurFileIndex(int& file);
//get fadeout state // get fadeout state
bool getIsFadingOut(); bool getIsFadingOut();
// add instrument // add instrument

View file

@ -135,19 +135,12 @@ static short const gauss [512] =
1299,1300,1300,1301,1302,1302,1303,1303,1303,1304,1304,1304,1304,1304,1305,1305, 1299,1300,1300,1301,1302,1302,1303,1303,1303,1304,1304,1304,1304,1304,1305,1305,
}; };
void SPC_DSP::setupInterpolation(bool interpolate) void SPC_DSP::setupInterpolation(bool interpolate){for(int i=0;i<voice_count;i++){m.voices[i].interpolate=interpolate;}}
{
for(int i = 0; i < voice_count; i++)
{
m.voices[i].interpolate = interpolate;
}
}
inline int SPC_DSP::interpolate( voice_t const* v ) inline int SPC_DSP::interpolate( voice_t const* v )
{ {
// Make pointers into gaussian based on fractional position between samples // Make pointers into gaussian based on fractional position between samples
if(v->interpolate) if (v->interpolate) {
{
int offset = v->interp_pos >> 4 & 0xFF; int offset = v->interp_pos >> 4 & 0xFF;
short const* fwd = gauss + 255 - offset; short const* fwd = gauss + 255 - offset;
short const* rev = gauss + offset; // mirror left half of gaussian short const* rev = gauss + offset; // mirror left half of gaussian
@ -163,9 +156,7 @@ inline int SPC_DSP::interpolate( voice_t const* v )
CLAMP16( out ); CLAMP16( out );
out &= ~1; out &= ~1;
return out; return out;
} } else {
else
{
return v->buf [(v->interp_pos >> 12) + v->buf_pos]; //Furnace addition -- no interpolation return v->buf [(v->interp_pos >> 12) + v->buf_pos]; //Furnace addition -- no interpolation
} }
} }

View file

@ -102,9 +102,8 @@ bool DivSubSong::walk(int& loopOrder, int& loopRow, int& loopEnd, int chans, int
return false; return false;
} }
double calcRowLenInSeconds(const DivGroovePattern& speeds, float hz, int vN, int vD, int timeBaseFromSong) double calcRowLenInSeconds(const DivGroovePattern& speeds, float hz, int vN, int vD, int timeBaseFromSong) {
{ double hl=1; //count for 1 row
double hl=1; //count for 1 row
if (hl<=0.0) hl=4.0; if (hl<=0.0) hl=4.0;
double timeBase=timeBaseFromSong+1; double timeBase=timeBaseFromSong+1;
double speedSum=0; double speedSum=0;
@ -115,25 +114,23 @@ double calcRowLenInSeconds(const DivGroovePattern& speeds, float hz, int vN, int
if (timeBase<1.0) timeBase=1.0; if (timeBase<1.0) timeBase=1.0;
if (speedSum<1.0) speedSum=1.0; if (speedSum<1.0) speedSum=1.0;
if (vD<1) vD=1; 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);
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) 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;
length = 0; hasFFxx=false;
hasFFxx = false; rowsForFadeout=0;
rowsForFadeout = 0;
float secondsPerThisRow = 0.0f; float secondsPerThisRow=0.0f;
DivGroovePattern curSpeeds = speeds; //simulate that we are playing the song, track all speed/BPM/tempo/engine rate changes DivGroovePattern curSpeeds=speeds; //simulate that we are playing the song, track all speed/BPM/tempo/engine rate changes
short curVirtualTempoN = virtualTempoN; short curVirtualTempoN=virtualTempoN;
short curVirtualTempoD = virtualTempoD; short curVirtualTempoD=virtualTempoD;
float curHz = hz; float curHz=hz;
double curDivider = (double)timeBase; double curDivider=(double)timeBase;
double curLen = 0.0; //how many seconds passed since the start of song double curLen=0.0; //how many seconds passed since the start of song
int nextOrder=-1; int nextOrder=-1;
int nextRow=0; int nextRow=0;
@ -145,49 +142,39 @@ void DivSubSong::findLength(int loopOrder, int loopRow, double fadeoutLen, int&
if (firstPat>0) { if (firstPat>0) {
memset(wsWalked,255,32*firstPat); memset(wsWalked,255,32*firstPat);
} }
for (int i=firstPat; i<ordersLen; i++) for (int i=firstPat; i<ordersLen; i++) {
{ bool jumped=false;
bool jumped = false;
for (int j=0; j<chans; j++) for (int j=0; j<chans; j++) {
{
subPat[j]=pat[j].getPattern(orders.ord[j][i],false); subPat[j]=pat[j].getPattern(orders.ord[j][i],false);
} }
if (i>lastSuspectedLoopEnd) if (i>lastSuspectedLoopEnd) {
{
lastSuspectedLoopEnd=i; lastSuspectedLoopEnd=i;
} }
for (int j=nextRow; j<patLen; j++) for (int j=nextRow; j<patLen; j++) {
{
nextRow=0; nextRow=0;
bool changingOrder=false; bool changingOrder=false;
bool jumpingOrder=false; bool jumpingOrder=false;
if (wsWalked[((i<<5)+(j>>3))&8191]&(1<<(j&7))) if (wsWalked[((i<<5)+(j>>3))&8191]&(1<<(j&7))) {
{
return; return;
} }
for (int k=0; k<chans; k++) for (int k=0; k<chans; k++) {
{ for (int l=0; l<pat[k].effectCols; l++) {
for (int l=0; l<pat[k].effectCols; l++)
{
effectVal=subPat[k]->data[j][5+(l<<1)]; effectVal=subPat[k]->data[j][5+(l<<1)];
if (effectVal<0) effectVal=0; if (effectVal<0) effectVal=0;
if (subPat[k]->data[j][4+(l<<1)]==0xff) if (subPat[k]->data[j][4+(l<<1)]==0xff) {
{ hasFFxx=true;
hasFFxx = true;
//FFxx makes YOU SHALL NOT PASS!!! move // FFxx makes YOU SHALL NOT PASS!!! move
orders_vec.push_back(j + 1); //order len orders_vec.push_back(j+1); // order len
length += j + 1; //add length of order to song length length+=j+1; // add length of order to song length
return; return;
} }
switch(subPat[k]->data[j][4+(l<<1)]) //track speed/BMP/Hz/tempo changes switch (subPat[k]->data[j][4+(l<<1)]) {
{ case 0x09: { // select groove pattern/speed 1
case 0x09: // select groove pattern/speed 1
{
if (grooves.empty()) { if (grooves.empty()) {
if (effectVal>0) curSpeeds.val[0]=effectVal; if (effectVal>0) curSpeeds.val[0]=effectVal;
} else { } else {
@ -198,8 +185,7 @@ void DivSubSong::findLength(int loopOrder, int loopRow, double fadeoutLen, int&
} }
break; break;
} }
case 0x0f: // speed 1/speed 2 case 0x0f: { // speed 1/speed 2
{
if (curSpeeds.len==2 && grooves.empty()) { if (curSpeeds.len==2 && grooves.empty()) {
if (effectVal>0) curSpeeds.val[1]=effectVal; if (effectVal>0) curSpeeds.val[1]=effectVal;
} else { } else {
@ -207,68 +193,47 @@ void DivSubSong::findLength(int loopOrder, int loopRow, double fadeoutLen, int&
} }
break; break;
} }
case 0xfd: // virtual tempo num case 0xfd: { // virtual tempo num
{
if (effectVal>0) curVirtualTempoN=effectVal; if (effectVal>0) curVirtualTempoN=effectVal;
break; break;
} }
case 0xfe: // virtual tempo den case 0xfe: { // virtual tempo den
{
if (effectVal>0) curVirtualTempoD=effectVal; if (effectVal>0) curVirtualTempoD=effectVal;
break; break;
} }
case 0xf0: // set Hz by tempo (set bpm) case 0xf0: { // set Hz by tempo (set bpm)
{
curDivider=(double)effectVal*2.0/5.0; curDivider=(double)effectVal*2.0/5.0;
if (curDivider<1) curDivider=1; if (curDivider<1) curDivider=1;
//cycles=got.rate*pow(2,MASTER_CLOCK_PREC)/divider;
//clockDrift=0;
//subticks=0;
break; break;
} }
default: break;
} }
if (subPat[k]->data[j][4+(l<<1)]==0x0d) if (subPat[k]->data[j][4+(l<<1)]==0x0d) {
{ if (jumpTreatment==2) {
if (jumpTreatment==2) if ((i<ordersLen-1 || !ignoreJumpAtEnd)) {
{
if ((i<ordersLen-1 || !ignoreJumpAtEnd))
{
nextOrder=i+1; nextOrder=i+1;
nextRow=effectVal; nextRow=effectVal;
jumpingOrder=true; jumpingOrder=true;
} }
} } else if (jumpTreatment==1) {
else if (jumpTreatment==1) if (nextOrder==-1 && (i<ordersLen-1 || !ignoreJumpAtEnd)) {
{
if (nextOrder==-1 && (i<ordersLen-1 || !ignoreJumpAtEnd))
{
nextOrder=i+1; nextOrder=i+1;
nextRow=effectVal; nextRow=effectVal;
jumpingOrder=true; jumpingOrder=true;
} }
} } else {
else if ((i<ordersLen-1 || !ignoreJumpAtEnd)) {
{ if (!changingOrder) {
if ((i<ordersLen-1 || !ignoreJumpAtEnd))
{
if (!changingOrder)
{
nextOrder=i+1; nextOrder=i+1;
} }
jumpingOrder=true; jumpingOrder=true;
nextRow=effectVal; nextRow=effectVal;
} }
} }
} } else if (subPat[k]->data[j][4+(l<<1)]==0x0b) {
else if (subPat[k]->data[j][4+(l<<1)]==0x0b) if (nextOrder==-1 || jumpTreatment==0) {
{
if (nextOrder==-1 || jumpTreatment==0)
{
nextOrder=effectVal; nextOrder=effectVal;
if (jumpTreatment==1 || jumpTreatment==2 || !jumpingOrder) if (jumpTreatment==1 || jumpTreatment==2 || !jumpingOrder) {
{
nextRow=0; nextRow=0;
} }
changingOrder=true; changingOrder=true;
@ -277,32 +242,29 @@ void DivSubSong::findLength(int loopOrder, int loopRow, double fadeoutLen, int&
} }
} }
if(i > loopOrder || (i == loopOrder && j > loopRow)) if (i>loopOrder || (i==loopOrder && j>loopRow)) {
{ // we count each row fadeout lasts. When our time is greater than fadeout length we successfully counted the number of fadeout rows
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 if (curLen<=fadeoutLen && fadeoutLen>0.0) {
{ secondsPerThisRow=calcRowLenInSeconds(speeds,curHz,curVirtualTempoN,curVirtualTempoD,curDivider);
secondsPerThisRow = calcRowLenInSeconds(speeds, curHz, curVirtualTempoN, curVirtualTempoD, curDivider); curLen+=secondsPerThisRow;
curLen += secondsPerThisRow;
rowsForFadeout++; rowsForFadeout++;
} }
} }
wsWalked[((i<<5)+(j>>3))&8191]|=1<<(j&7); wsWalked[((i<<5)+(j>>3))&8191]|=1<<(j&7);
if (nextOrder!=-1) if (nextOrder!=-1) {
{
i=nextOrder-1; i=nextOrder-1;
orders_vec.push_back(j + 1); //order len orders_vec.push_back(j+1); // order len
length += j + 1; //add length of order to song length length+=j+1; // add length of order to song length
jumped = true; jumped=true;
nextOrder=-1; nextOrder=-1;
break; break;
} }
} }
if(!jumped) //if no jump occured we add full pattern length if (!jumped) { // if no jump occured we add full pattern length
{ orders_vec.push_back(patLen); // order len
orders_vec.push_back(patLen); //order len length+=patLen; // add length of order to song length
length += patLen; //add length of order to song length
} }
} }
} }

View file

@ -186,7 +186,7 @@ struct DivSubSong {
bool walk(int& loopOrder, int& loopRow, int& loopEnd, int chans, int jumpTreatment, int ignoreJumpAtEnd, int firstPat=0); bool walk(int& loopOrder, int& loopRow, int& loopEnd, int chans, int jumpTreatment, int ignoreJumpAtEnd, int firstPat=0);
/** /**
* find song length in rows (up to specified loop point). Also find length of every row * find song length in rows (up to specified loop point).
*/ */
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 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);

View file

@ -33,79 +33,70 @@ bool DivEngine::isExporting() {
return exporting; return exporting;
} }
void DivEngine::getLoopsLeft(int& loops) { void DivEngine::getLoopsLeft(int &loops) {
if(totalLoops < 0 || exportLoopCount == 0) if (totalLoops<0 || exportLoopCount==0) {
{ loops=0;
loops = 0;
return; return;
} }
loops = exportLoopCount - 1 - totalLoops; loops=exportLoopCount-1-totalLoops;
} }
void DivEngine::getTotalLoops(int& loops) { void DivEngine::getTotalLoops(int &loops) {
loops = exportLoopCount - 1; loops=exportLoopCount-1;
} }
void DivEngine::getCurSongPos(int& row, int& order) { void DivEngine::getCurSongPos(int &row, int &order) {
row = curRow; row=curRow;
order = curOrder; order=curOrder;
} }
void DivEngine::getTotalAudioFiles(int& files) void DivEngine::getTotalAudioFiles(int &files) {
{ files=0;
files = 0;
switch(exportMode) switch (exportMode) {
{ case DIV_EXPORT_MODE_ONE: {
case DIV_EXPORT_MODE_ONE: files=1;
{
files = 1;
break; break;
} }
case DIV_EXPORT_MODE_MANY_SYS: case DIV_EXPORT_MODE_MANY_SYS: {
{ files=1; // there actually are several files but they are processed in the same loop, so to correctly draw progress we think of them as one file
files = 1; //there actually are several files but they are processed in the same loop, so to correctly draw progress we think of them as one file
break; break;
} }
case DIV_EXPORT_MODE_MANY_CHAN: case DIV_EXPORT_MODE_MANY_CHAN: {
{ for (int i=0; i<chans; i++) {
for(int i = 0; i < chans; i++) if (exportChannelMask[i]) {
{ files++;
if (exportChannelMask[i]) files++; }
} }
break; break;
} }
default: break; default:
break;
} }
} }
void DivEngine::getCurFileIndex(int& file) void DivEngine::getCurFileIndex(int &file) {
{ file=0;
file = 0;
switch(exportMode) switch (exportMode) {
{ case DIV_EXPORT_MODE_ONE: {
case DIV_EXPORT_MODE_ONE: file=0;
{
file = 0;
break; break;
} }
case DIV_EXPORT_MODE_MANY_SYS: case DIV_EXPORT_MODE_MANY_SYS: {
{ file=0; // there actually are several files but they are processed in the same loop, so to correctly draw progress we think of them as one file
file = 0; //there actually are several files but they are processed in the same loop, so to correctly draw progress we think of them as one file
break; break;
} }
case DIV_EXPORT_MODE_MANY_CHAN: case DIV_EXPORT_MODE_MANY_CHAN: {
{ file=curExportChan;
file = curExportChan;
break; break;
} }
default: break; default:
break;
} }
} }
bool DivEngine::getIsFadingOut() bool DivEngine::getIsFadingOut() {
{
return isFadingOut; return isFadingOut;
} }
@ -327,7 +318,7 @@ void DivEngine::runExportThread() {
// take control of audio output // take control of audio output
deinitAudioBackend(); deinitAudioBackend();
curExportChan = 0; curExportChan=0;
float* outBuf[DIV_MAX_OUTPUTS]; float* outBuf[DIV_MAX_OUTPUTS];
float* outBufFinal; float* outBufFinal;
@ -463,7 +454,7 @@ void DivEngine::runExportThread() {
} }
logI("done!"); logI("done!");
exporting=false; exporting=false;
curExportChan = 0; curExportChan=0;
break; break;
} }
} }

View file

@ -2589,34 +2589,32 @@ void FurnaceGUI::exportAudio(String path, DivAudioExportModes mode) {
int loopEnd=0; int loopEnd=0;
e->walkSong(loopOrder,loopRow,loopEnd); e->walkSong(loopOrder,loopRow,loopEnd);
e->findSongLength(loopOrder, loopRow, audioExportOptions.fadeOut, songFadeoutSectionLength, songHasSongEndCommand, songOrdersLengths, songLength); //for progress estimation e->findSongLength(loopOrder,loopRow,audioExportOptions.fadeOut,songFadeoutSectionLength,songHasSongEndCommand,songOrdersLengths,songLength); // for progress estimation
songLoopedSectionLength = songLength; songLoopedSectionLength=songLength;
for(int i = 0; i < loopOrder; i++) for (int i=0; i<loopOrder; i++) {
{ songLoopedSectionLength-=songOrdersLengths[i];
songLoopedSectionLength -= songOrdersLengths[i];
} }
songLoopedSectionLength -= loopRow; songLoopedSectionLength-=loopRow;
e->saveAudio(path.c_str(),audioExportOptions); e->saveAudio(path.c_str(),audioExportOptions);
totalFiles = 0; totalFiles=0;
e->getTotalAudioFiles(totalFiles); e->getTotalAudioFiles(totalFiles);
int totalLoops = 0; int totalLoops=0;
lengthOfOneFile = songLength; lengthOfOneFile=songLength;
if(!songHasSongEndCommand) if (!songHasSongEndCommand) {
{
e->getTotalLoops(totalLoops); e->getTotalLoops(totalLoops);
lengthOfOneFile += songLoopedSectionLength * totalLoops; lengthOfOneFile+=songLoopedSectionLength*totalLoops;
lengthOfOneFile += songFadeoutSectionLength; //account for fadeout lengthOfOneFile+=songFadeoutSectionLength; // account for fadeout
} }
totalLength = lengthOfOneFile * totalFiles; totalLength=lengthOfOneFile*totalFiles;
curProgress = 0.0f; curProgress=0.0f;
displayExporting=true; displayExporting=true;
} }
@ -5861,69 +5859,53 @@ bool FurnaceGUI::loop() {
MEASURE_BEGIN(popup); MEASURE_BEGIN(popup);
centerNextWindow(_("Rendering..."),canvasW,canvasH); centerNextWindow(_("Rendering..."),canvasW,canvasH);
if (ImGui::BeginPopupModal(_("Rendering..."),NULL,ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove)) { if (ImGui::BeginPopupModal(_("Rendering..."),NULL,ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoMove)) {
// WHAT the HELL?!
WAKE_UP; WAKE_UP;
if(audioExportOptions.mode != DIV_EXPORT_MODE_MANY_CHAN) if (audioExportOptions.mode!=DIV_EXPORT_MODE_MANY_CHAN) {
{
ImGui::Text(_("Please wait...")); ImGui::Text(_("Please wait..."));
} }
float* progressLambda = &curProgress; float* progressLambda=&curProgress;
int curPosInRows = 0; int curPosInRows=0;
int* curPosInRowsLambda = &curPosInRows; int* curPosInRowsLambda=&curPosInRows;
int loopsLeft = 0; int loopsLeft=0;
int* loopsLeftLambda = &loopsLeft; int* loopsLeftLambda=&loopsLeft;
int totalLoops = 0; int totalLoops=0;
int* totalLoopsLambda = &totalLoops; int* totalLoopsLambda=&totalLoops;
int curFile = 0; int curFile=0;
int* curFileLambda = &curFile; int* curFileLambda=&curFile;
if(e->isExporting()) if (e->isExporting()) {
{ e->lockEngine([this, progressLambda, curPosInRowsLambda, curFileLambda,
e->lockEngine([this, progressLambda, curPosInRowsLambda, curFileLambda, loopsLeftLambda, totalLoopsLambda]() loopsLeftLambda, totalLoopsLambda] () {
{ int curRow=0; int curOrder=0;
int curRow = 0; e->getCurSongPos(curRow, curOrder); *curFileLambda=0;
int curOrder = 0; e->getCurFileIndex(*curFileLambda);
e->getCurSongPos(curRow, curOrder); *curPosInRowsLambda=curRow; for (int i=0; i<curOrder;
*curFileLambda = 0; i++) {
e->getCurFileIndex(*curFileLambda); *curPosInRowsLambda+=songOrdersLengths[i];}
*curPosInRowsLambda = curRow; if (!songHasSongEndCommand) {
e->getLoopsLeft(*loopsLeftLambda); e->getTotalLoops(*totalLoopsLambda); if ((*totalLoopsLambda)!=(*loopsLeftLambda)) //we are going 2nd, 3rd, etc. time through the song
for(int i = 0; i < curOrder; i++) {
{ *curPosInRowsLambda-=(songLength-songLoopedSectionLength); //a hack so progress bar does not jump?
*curPosInRowsLambda += songOrdersLengths[i]; }
} if (e->getIsFadingOut()) //we are in fadeout??? why it works like that bruh
{
if(!songHasSongEndCommand) // LIVE WITH IT damn it
{ *curPosInRowsLambda-=(songLength-songLoopedSectionLength); //a hack so progress bar does not jump?
e->getLoopsLeft(*loopsLeftLambda); }
e->getTotalLoops(*totalLoopsLambda); }
// this horrible indentation courtesy of `indent`
if((*totalLoopsLambda) != (*loopsLeftLambda)) //we are going 2nd, 3rd, etc. time through the song *progressLambda=(float) ((*curPosInRowsLambda) + ((*totalLoopsLambda)- (*loopsLeftLambda)) * songLength + lengthOfOneFile * (*curFileLambda)) / (float) totalLength;});
{
*curPosInRowsLambda -= (songLength - songLoopedSectionLength); //a hack so progress bar does not jump?
}
if(e->getIsFadingOut()) //we are in fadeout??? why it works like that bruh
{
*curPosInRowsLambda -= (songLength - songLoopedSectionLength); //a hack so progress bar does not jump?
}
}
*progressLambda = (float)((*curPosInRowsLambda) +
((*totalLoopsLambda) - (*loopsLeftLambda)) * songLength +
lengthOfOneFile * (*curFileLambda))
/ (float)totalLength;
});
} }
ImGui::Text(_("Row %d of %d"), curPosInRows + ImGui::Text(_("Row %d of %d"),curPosInRows+((totalLoops)-(loopsLeft))*songLength,lengthOfOneFile);
((totalLoops) - (loopsLeft)) * songLength, lengthOfOneFile);
if(audioExportOptions.mode == DIV_EXPORT_MODE_MANY_CHAN) if (audioExportOptions.mode==DIV_EXPORT_MODE_MANY_CHAN) {
{ ImGui::Text(_("Channel %d of %d"),curFile+1,totalFiles);
ImGui::Text(_("Channel %d of %d"), curFile + 1, totalFiles);
} }
ImGui::ProgressBar(curProgress,ImVec2(320.0f*dpiScale,0), fmt::sprintf("%.2f%%", curProgress * 100.0f).c_str()); ImGui::ProgressBar(curProgress,ImVec2(320.0f*dpiScale,0),fmt::sprintf("%.2f%%",curProgress*100.0f).c_str());
if (ImGui::Button(_("Abort"))) { if (ImGui::Button(_("Abort"))) {
if (e->haltAudioFile()) { if (e->haltAudioFile()) {

View file

@ -1723,13 +1723,13 @@ class FurnaceGUI {
char emptyLabel[32]; char emptyLabel[32];
char emptyLabel2[32]; char emptyLabel2[32];
std::vector<int> songOrdersLengths; //lengths of all orders (for drawing song export progress) std::vector<int> songOrdersLengths; // lengths of all orders (for drawing song export progress)
int songLength; //length of all the song in rows int songLength; // length of all the song in rows
int songLoopedSectionLength; //length of looped part of the song int songLoopedSectionLength; // length of looped part of the song
int songFadeoutSectionLength; //length of fading part of the song int songFadeoutSectionLength; // length of fading part of the song
bool songHasSongEndCommand; //song has "Song end" command (FFxx) bool songHasSongEndCommand; // song has "Song end" command (FFxx)
int lengthOfOneFile; //length of one rendering pass. song length times num of loops + fadeout int lengthOfOneFile; // length of one rendering pass. song length times num of loops + fadeout
int totalLength; //total length of render (lengthOfOneFile times num of files for per-channel export) int totalLength; // total length of render (lengthOfOneFile times num of files for per-channel export)
float curProgress; float curProgress;
int totalFiles; int totalFiles;