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,10 +203,8 @@ 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)
{
if (curSubSong!=NULL)
{
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

@ -475,7 +475,7 @@ class DivEngine {
int midiOutTimeRate;
float midiVolExp;
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 bufferPos;
double divider;

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,
};
void SPC_DSP::setupInterpolation(bool interpolate)
{
for(int i = 0; i < voice_count; i++)
{
m.voices[i].interpolate = interpolate;
}
}
void SPC_DSP::setupInterpolation(bool interpolate){for(int i=0;i<voice_count;i++){m.voices[i].interpolate=interpolate;}}
inline int SPC_DSP::interpolate( voice_t const* v )
{
// Make pointers into gaussian based on fractional position between samples
if(v->interpolate)
{
if (v->interpolate) {
int offset = v->interp_pos >> 4 & 0xFF;
short const* fwd = gauss + 255 - offset;
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 );
out &= ~1;
return out;
}
else
{
} else {
return v->buf [(v->interp_pos >> 12) + v->buf_pos]; //Furnace addition -- no interpolation
}
}

View file

@ -102,8 +102,7 @@ bool DivSubSong::walk(int& loopOrder, int& loopRow, int& loopEnd, int chans, int
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
if (hl<=0.0) hl=4.0;
double timeBase=timeBaseFromSong+1;
@ -115,12 +114,10 @@ double calcRowLenInSeconds(const DivGroovePattern& speeds, float hz, int vN, int
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)
{
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;
@ -145,36 +142,28 @@ void DivSubSong::findLength(int loopOrder, int loopRow, double fadeoutLen, int&
if (firstPat>0) {
memset(wsWalked,255,32*firstPat);
}
for (int i=firstPat; i<ordersLen; i++)
{
for (int i=firstPat; i<ordersLen; i++) {
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);
}
if (i>lastSuspectedLoopEnd)
{
if (i>lastSuspectedLoopEnd) {
lastSuspectedLoopEnd=i;
}
for (int j=nextRow; j<patLen; j++)
{
for (int j=nextRow; j<patLen; j++) {
nextRow=0;
bool changingOrder=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;
}
for (int k=0; k<chans; k++)
{
for (int l=0; l<pat[k].effectCols; l++)
{
for (int k=0; k<chans; k++) {
for (int l=0; l<pat[k].effectCols; l++) {
effectVal=subPat[k]->data[j][5+(l<<1)];
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;
// FFxx makes YOU SHALL NOT PASS!!! move
@ -184,10 +173,8 @@ void DivSubSong::findLength(int loopOrder, int loopRow, double fadeoutLen, int&
return;
}
switch(subPat[k]->data[j][4+(l<<1)]) //track speed/BMP/Hz/tempo changes
{
case 0x09: // select groove pattern/speed 1
{
switch (subPat[k]->data[j][4+(l<<1)]) {
case 0x09: { // select groove pattern/speed 1
if (grooves.empty()) {
if (effectVal>0) curSpeeds.val[0]=effectVal;
} else {
@ -198,8 +185,7 @@ void DivSubSong::findLength(int loopOrder, int loopRow, double fadeoutLen, int&
}
break;
}
case 0x0f: // speed 1/speed 2
{
case 0x0f: { // speed 1/speed 2
if (curSpeeds.len==2 && grooves.empty()) {
if (effectVal>0) curSpeeds.val[1]=effectVal;
} else {
@ -207,68 +193,47 @@ void DivSubSong::findLength(int loopOrder, int loopRow, double fadeoutLen, int&
}
break;
}
case 0xfd: // virtual tempo num
{
case 0xfd: { // virtual tempo num
if (effectVal>0) curVirtualTempoN=effectVal;
break;
}
case 0xfe: // virtual tempo den
{
case 0xfe: { // virtual tempo den
if (effectVal>0) curVirtualTempoD=effectVal;
break;
}
case 0xf0: // set Hz by tempo (set bpm)
{
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)
{
if ((i<ordersLen-1 || !ignoreJumpAtEnd))
{
if (subPat[k]->data[j][4+(l<<1)]==0x0d) {
if (jumpTreatment==2) {
if ((i<ordersLen-1 || !ignoreJumpAtEnd)) {
nextOrder=i+1;
nextRow=effectVal;
jumpingOrder=true;
}
}
else if (jumpTreatment==1)
{
if (nextOrder==-1 && (i<ordersLen-1 || !ignoreJumpAtEnd))
{
} else if (jumpTreatment==1) {
if (nextOrder==-1 && (i<ordersLen-1 || !ignoreJumpAtEnd)) {
nextOrder=i+1;
nextRow=effectVal;
jumpingOrder=true;
}
}
else
{
if ((i<ordersLen-1 || !ignoreJumpAtEnd))
{
if (!changingOrder)
{
} else {
if ((i<ordersLen-1 || !ignoreJumpAtEnd)) {
if (!changingOrder) {
nextOrder=i+1;
}
jumpingOrder=true;
nextRow=effectVal;
}
}
}
else if (subPat[k]->data[j][4+(l<<1)]==0x0b)
{
if (nextOrder==-1 || jumpTreatment==0)
{
} else if (subPat[k]->data[j][4+(l<<1)]==0x0b) {
if (nextOrder==-1 || jumpTreatment==0) {
nextOrder=effectVal;
if (jumpTreatment==1 || jumpTreatment==2 || !jumpingOrder)
{
if (jumpTreatment==1 || jumpTreatment==2 || !jumpingOrder) {
nextRow=0;
}
changingOrder=true;
@ -277,10 +242,9 @@ void DivSubSong::findLength(int loopOrder, int loopRow, double fadeoutLen, int&
}
}
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
{
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) {
secondsPerThisRow=calcRowLenInSeconds(speeds,curHz,curVirtualTempoN,curVirtualTempoD,curDivider);
curLen+=secondsPerThisRow;
rowsForFadeout++;
@ -289,8 +253,7 @@ void DivSubSong::findLength(int loopOrder, int loopRow, double fadeoutLen, int&
wsWalked[((i<<5)+(j>>3))&8191]|=1<<(j&7);
if (nextOrder!=-1)
{
if (nextOrder!=-1) {
i=nextOrder-1;
orders_vec.push_back(j+1); // order len
length+=j+1; // add length of order to song length
@ -299,8 +262,7 @@ void DivSubSong::findLength(int loopOrder, int loopRow, double fadeoutLen, int&
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
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);
/**
* 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);

View file

@ -34,8 +34,7 @@ bool DivEngine::isExporting() {
}
void DivEngine::getLoopsLeft(int &loops) {
if(totalLoops < 0 || exportLoopCount == 0)
{
if (totalLoops<0 || exportLoopCount==0) {
loops=0;
return;
}
@ -51,61 +50,53 @@ void DivEngine::getCurSongPos(int& row, int& order) {
order=curOrder;
}
void DivEngine::getTotalAudioFiles(int& files)
{
void DivEngine::getTotalAudioFiles(int &files) {
files=0;
switch(exportMode)
{
case DIV_EXPORT_MODE_ONE:
{
switch (exportMode) {
case DIV_EXPORT_MODE_ONE: {
files=1;
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
break;
}
case DIV_EXPORT_MODE_MANY_CHAN:
{
for(int i = 0; i < chans; i++)
{
if (exportChannelMask[i]) files++;
case DIV_EXPORT_MODE_MANY_CHAN: {
for (int i=0; i<chans; i++) {
if (exportChannelMask[i]) {
files++;
}
}
break;
}
default: break;
default:
break;
}
}
void DivEngine::getCurFileIndex(int& file)
{
void DivEngine::getCurFileIndex(int &file) {
file=0;
switch(exportMode)
{
case DIV_EXPORT_MODE_ONE:
{
switch (exportMode) {
case DIV_EXPORT_MODE_ONE: {
file=0;
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
break;
}
case DIV_EXPORT_MODE_MANY_CHAN:
{
case DIV_EXPORT_MODE_MANY_CHAN: {
file=curExportChan;
break;
}
default: break;
default:
break;
}
}
bool DivEngine::getIsFadingOut()
{
bool DivEngine::getIsFadingOut() {
return isFadingOut;
}

View file

@ -2592,8 +2592,7 @@ void FurnaceGUI::exportAudio(String path, DivAudioExportModes mode) {
e->findSongLength(loopOrder,loopRow,audioExportOptions.fadeOut,songFadeoutSectionLength,songHasSongEndCommand,songOrdersLengths,songLength); // for progress estimation
songLoopedSectionLength=songLength;
for(int i = 0; i < loopOrder; i++)
{
for (int i=0; i<loopOrder; i++) {
songLoopedSectionLength-=songOrdersLengths[i];
}
songLoopedSectionLength-=loopRow;
@ -2606,8 +2605,7 @@ void FurnaceGUI::exportAudio(String path, DivAudioExportModes mode) {
lengthOfOneFile=songLength;
if(!songHasSongEndCommand)
{
if (!songHasSongEndCommand) {
e->getTotalLoops(totalLoops);
lengthOfOneFile+=songLoopedSectionLength*totalLoops;
@ -5862,9 +5860,9 @@ bool FurnaceGUI::loop() {
centerNextWindow(_("Rendering..."),canvasW,canvasH);
if (ImGui::BeginPopupModal(_("Rendering..."),NULL,ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoMove)) {
// WHAT the HELL?!
WAKE_UP;
if(audioExportOptions.mode != DIV_EXPORT_MODE_MANY_CHAN)
{
if (audioExportOptions.mode!=DIV_EXPORT_MODE_MANY_CHAN) {
ImGui::Text(_("Please wait..."));
}
float* progressLambda=&curProgress;
@ -5876,50 +5874,34 @@ bool FurnaceGUI::loop() {
int* totalLoopsLambda=&totalLoops;
int curFile=0;
int* curFileLambda=&curFile;
if(e->isExporting())
{
e->lockEngine([this, progressLambda, curPosInRowsLambda, curFileLambda, loopsLeftLambda, totalLoopsLambda]()
{
int curRow = 0;
int curOrder = 0;
e->getCurSongPos(curRow, curOrder);
*curFileLambda = 0;
if (e->isExporting()) {
e->lockEngine([this, progressLambda, curPosInRowsLambda, curFileLambda,
loopsLeftLambda, totalLoopsLambda] () {
int curRow=0; int curOrder=0;
e->getCurSongPos(curRow, curOrder); *curFileLambda=0;
e->getCurFileIndex(*curFileLambda);
*curPosInRowsLambda=curRow; for (int i=0; i<curOrder;
i++) {
*curPosInRowsLambda+=songOrdersLengths[i];}
*curPosInRowsLambda = curRow;
for(int i = 0; i < curOrder; i++)
{
*curPosInRowsLambda += songOrdersLengths[i];
}
if(!songHasSongEndCommand)
{
e->getLoopsLeft(*loopsLeftLambda);
e->getTotalLoops(*totalLoopsLambda);
if((*totalLoopsLambda) != (*loopsLeftLambda)) //we are going 2nd, 3rd, etc. time through the song
if (!songHasSongEndCommand) {
e->getLoopsLeft(*loopsLeftLambda); e->getTotalLoops(*totalLoopsLambda); if ((*totalLoopsLambda)!=(*loopsLeftLambda)) //we are going 2nd, 3rd, etc. time through the song
{
*curPosInRowsLambda-=(songLength-songLoopedSectionLength); //a hack so progress bar does not jump?
}
if (e->getIsFadingOut()) //we are in fadeout??? why it works like that bruh
{
// LIVE WITH IT damn it
*curPosInRowsLambda-=(songLength-songLoopedSectionLength); //a hack so progress bar does not jump?
}
}
*progressLambda = (float)((*curPosInRowsLambda) +
((*totalLoopsLambda) - (*loopsLeftLambda)) * songLength +
lengthOfOneFile * (*curFileLambda))
/ (float)totalLength;
});
// this horrible indentation courtesy of `indent`
*progressLambda=(float) ((*curPosInRowsLambda) + ((*totalLoopsLambda)- (*loopsLeftLambda)) * songLength + lengthOfOneFile * (*curFileLambda)) / (float) totalLength;});
}
ImGui::Text(_("Row %d of %d"), curPosInRows +
((totalLoops) - (loopsLeft)) * songLength, lengthOfOneFile);
ImGui::Text(_("Row %d of %d"),curPosInRows+((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);
}