giga-refactor, part 13
get rid of time base
This commit is contained in:
parent
334d8708e2
commit
663f32d9d4
9 changed files with 43 additions and 35 deletions
|
|
@ -775,7 +775,7 @@ int DivEngine::duplicateSubSong(int index) {
|
|||
theCopy->notes=theOrig->notes;
|
||||
theCopy->hilightA=theOrig->hilightA;
|
||||
theCopy->hilightB=theOrig->hilightB;
|
||||
theCopy->timeBase=theOrig->timeBase;
|
||||
theCopy->effectDivider=theOrig->effectDivider;
|
||||
theCopy->arpLen=theOrig->arpLen;
|
||||
theCopy->speeds=theOrig->speeds;
|
||||
theCopy->virtualTempoN=theOrig->virtualTempoN;
|
||||
|
|
|
|||
|
|
@ -256,11 +256,11 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
|
|||
|
||||
bool customTempo=false;
|
||||
|
||||
ds.subsong[0]->timeBase=reader.readC();
|
||||
unsigned char oldTimeBase=reader.readC();
|
||||
ds.subsong[0]->speeds.len=2;
|
||||
ds.subsong[0]->speeds.val[0]=reader.readC();
|
||||
ds.subsong[0]->speeds.val[0]=(unsigned char)reader.readC();
|
||||
if (ds.version>0x07) {
|
||||
ds.subsong[0]->speeds.val[1]=reader.readC();
|
||||
ds.subsong[0]->speeds.val[1]=(unsigned char)reader.readC();
|
||||
bool pal=reader.readC();
|
||||
ds.subsong[0]->hz=pal?60:50;
|
||||
customTempo=reader.readC();
|
||||
|
|
@ -317,7 +317,7 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
|
|||
}
|
||||
|
||||
if (ds.system[0]==DIV_SYSTEM_YMU759) {
|
||||
switch (ds.subsong[0]->timeBase) {
|
||||
switch (oldTimeBase) {
|
||||
case 0:
|
||||
ds.subsong[0]->hz=248;
|
||||
break;
|
||||
|
|
@ -340,8 +340,10 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
|
|||
ds.subsong[0]->hz=248;
|
||||
break;
|
||||
}
|
||||
ds.subsong[0]->timeBase=0;
|
||||
addWarning("Yamaha YMU759 emulation is incomplete! please migrate your song to the OPL3 system.");
|
||||
} else {
|
||||
ds.subsong[0]->speeds.val[0]*=(oldTimeBase+1);
|
||||
ds.subsong[0]->speeds.val[1]*=(oldTimeBase+1);
|
||||
}
|
||||
|
||||
logV("%x",reader.tell());
|
||||
|
|
@ -1346,7 +1348,7 @@ SafeWriter* DivEngine::saveDMF(unsigned char version) {
|
|||
|
||||
int intHz=curSubSong->hz;
|
||||
|
||||
w->writeC(curSubSong->timeBase);
|
||||
w->writeC(0);
|
||||
w->writeC(curSubSong->speeds.val[0]);
|
||||
w->writeC((curSubSong->speeds.len>=2)?curSubSong->speeds.val[1]:curSubSong->speeds.val[0]);
|
||||
w->writeC((intHz<=53)?0:1);
|
||||
|
|
|
|||
|
|
@ -1077,7 +1077,7 @@ bool DivEngine::loadFur(unsigned char* file, size_t len, int variantID) {
|
|||
}
|
||||
reader.readI();
|
||||
|
||||
subSong->timeBase=reader.readC();
|
||||
unsigned char oldTimeBase=reader.readC();
|
||||
subSong->speeds.len=2;
|
||||
subSong->speeds.val[0]=(unsigned char)reader.readC();
|
||||
subSong->speeds.val[1]=(unsigned char)reader.readC();
|
||||
|
|
@ -1641,6 +1641,10 @@ bool DivEngine::loadFur(unsigned char* file, size_t len, int variantID) {
|
|||
}
|
||||
}
|
||||
|
||||
for (int i=0; i<16; i++) {
|
||||
subSong->speeds.val[i]*=(oldTimeBase+1);
|
||||
}
|
||||
|
||||
if (ds.version>=156) {
|
||||
assetDirPtr.push_back(reader.readI());
|
||||
assetDirPtr.push_back(reader.readI());
|
||||
|
|
|
|||
|
|
@ -296,7 +296,6 @@ SafeWriter* DivEngine::saveText(bool separatePatterns) {
|
|||
}
|
||||
w->writeText("\n");
|
||||
w->writeText(fmt::sprintf("- virtual tempo: %d/%d\n",s->virtualTempoN,s->virtualTempoD));
|
||||
w->writeText(fmt::sprintf("- time base: %d\n",s->timeBase));
|
||||
w->writeText(fmt::sprintf("- pattern length: %d\n",s->patLen));
|
||||
w->writeText(fmt::sprintf("\norders:\n```\n"));
|
||||
|
||||
|
|
|
|||
|
|
@ -705,12 +705,12 @@ void DivEngine::processRow(int i, bool afterDelay) {
|
|||
if (effectVal!=0) {
|
||||
// COMPAT FLAG: cut/delay effect policy (delayBehavior)
|
||||
// - 0: strict
|
||||
// - delays equal or greater to the speed * timeBase are ignored
|
||||
// - delays equal or greater to the speed are ignored (formerly time base was involved but that has been removed now)
|
||||
// - 1: strict old
|
||||
// - delays equal or greater to the speed are ignored
|
||||
// - delays greater to the speed are ignored
|
||||
// - 2: lax (default)
|
||||
// - no delay is ever ignored unless overridden by another
|
||||
bool comparison=(song.compatFlags.delayBehavior==1)?(effectVal<=nextSpeed):(effectVal<(nextSpeed*(curSubSong->timeBase+1)));
|
||||
bool comparison=(song.compatFlags.delayBehavior==1)?(effectVal<=nextSpeed):(effectVal<(nextSpeed));
|
||||
if (song.compatFlags.delayBehavior==2) comparison=true;
|
||||
if (comparison) {
|
||||
// set the delay row, order and timer
|
||||
|
|
@ -1868,16 +1868,16 @@ void DivEngine::nextRow() {
|
|||
|
||||
// if the pattern length is odd and the current order is odd, use speed 2 for even rows and speed 1 for odd ones
|
||||
if ((curSubSong->patLen&1) && curOrder&1) {
|
||||
ticks=((curRow&1)?speed2:speed1)*(curSubSong->timeBase+1);
|
||||
ticks=((curRow&1)?speed2:speed1);
|
||||
nextSpeed=(curRow&1)?speed1:speed2;
|
||||
} else {
|
||||
ticks=((curRow&1)?speed1:speed2)*(curSubSong->timeBase+1);
|
||||
ticks=((curRow&1)?speed1:speed2);
|
||||
nextSpeed=(curRow&1)?speed2:speed1;
|
||||
}
|
||||
} else {
|
||||
// normal speed alternation
|
||||
// set the number of ticks and cycle to the next speed
|
||||
ticks=speeds.val[curSpeed]*(curSubSong->timeBase+1);
|
||||
ticks=speeds.val[curSpeed];
|
||||
curSpeed++;
|
||||
if (curSpeed>=speeds.len) curSpeed=0;
|
||||
// cache the next speed for future operations
|
||||
|
|
@ -2633,20 +2633,18 @@ void DivEngine::runMidiClock(int totalCycles) {
|
|||
output->midiOut->send(TAMidiMessage(TA_MIDI_CLOCK,0,0));
|
||||
}
|
||||
|
||||
// calculate tempo using highlight, timeBase, tick rate, speeds and virtual tempo
|
||||
// calculate tempo using highlight, tick rate, speeds and virtual tempo
|
||||
double hl=curSubSong->hilightA;
|
||||
if (hl<=0.0) hl=4.0;
|
||||
double timeBase=curSubSong->timeBase+1;
|
||||
double speedSum=0;
|
||||
double vD=virtualTempoD;
|
||||
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;
|
||||
double bpm=((24.0*divider)/(timeBase*hl*speedSum))*(double)virtualTempoN/vD;
|
||||
double bpm=((24.0*divider)/(hl*speedSum))*(double)virtualTempoN/vD;
|
||||
// avoid a division by zer
|
||||
if (bpm<1.0) bpm=1.0;
|
||||
int increment=got.rate/(bpm);
|
||||
|
|
|
|||
|
|
@ -197,12 +197,12 @@ void DivSubSong::calcTimestamps(int chans, std::vector<DivGroovePattern>& groove
|
|||
if (effectVal!=0) {
|
||||
// COMPAT FLAG: cut/delay effect policy (delayBehavior)
|
||||
// - 0: strict
|
||||
// - delays equal or greater to the speed * timeBase are ignored
|
||||
// - delays equal or greater to the speed are ignored (formerly time base was involved but that has been removed now)
|
||||
// - 1: strict old
|
||||
// - delays equal or greater to the speed are ignored
|
||||
// - delays greater to the speed are ignored
|
||||
// - 2: lax (default)
|
||||
// - no delay is ever ignored unless overridden by another
|
||||
bool comparison=(delayBehavior==1)?(effectVal<=nextSpeed):(effectVal<(nextSpeed*(timeBase+1)));
|
||||
bool comparison=(delayBehavior==1)?(effectVal<=nextSpeed):(effectVal<(nextSpeed));
|
||||
if (delayBehavior==2) comparison=true;
|
||||
if (comparison) {
|
||||
// set the delay row, order and timer
|
||||
|
|
@ -327,16 +327,16 @@ void DivSubSong::calcTimestamps(int chans, std::vector<DivGroovePattern>& groove
|
|||
// we subtract firstPat from curOrder as firstPat is used by a function which finds sub-songs
|
||||
// (the beginning of a new sub-song will be in order 0)
|
||||
if ((patLen&1) && (curOrder-firstPat)&1) {
|
||||
ticks=((curRow&1)?speed2:speed1)*(timeBase+1);
|
||||
ticks=((curRow&1)?speed2:speed1);
|
||||
nextSpeed=(curRow&1)?speed1:speed2;
|
||||
} else {
|
||||
ticks=((curRow&1)?speed1:speed2)*(timeBase+1);
|
||||
ticks=((curRow&1)?speed1:speed2);
|
||||
nextSpeed=(curRow&1)?speed2:speed1;
|
||||
}
|
||||
} else {
|
||||
// normal speed alternation
|
||||
// set the number of ticks and cycle to the next speed
|
||||
ticks=curSpeeds.val[curSpeed]*(timeBase+1);
|
||||
ticks=curSpeeds.val[curSpeed];
|
||||
curSpeed++;
|
||||
if (curSpeed>=curSpeeds.len) curSpeed=0;
|
||||
// cache the next speed for future operations
|
||||
|
|
@ -465,7 +465,7 @@ bool DivSubSong::readData(SafeReader& reader, int version, int chans) {
|
|||
|
||||
hz=reader.readF();
|
||||
arpLen=reader.readC();
|
||||
timeBase=reader.readC();
|
||||
effectDivider=reader.readC();
|
||||
|
||||
patLen=reader.readS();
|
||||
ordersLen=reader.readS();
|
||||
|
|
@ -519,7 +519,7 @@ bool DivSubSong::readData(SafeReader& reader, int version, int chans) {
|
|||
}
|
||||
reader.readI();
|
||||
|
||||
timeBase=reader.readC();
|
||||
unsigned char oldTimeBase=reader.readC();
|
||||
speeds.len=2;
|
||||
speeds.val[0]=(unsigned char)reader.readC();
|
||||
speeds.val[1]=(unsigned char)reader.readC();
|
||||
|
|
@ -582,6 +582,10 @@ bool DivSubSong::readData(SafeReader& reader, int version, int chans) {
|
|||
speeds.val[i]=(unsigned char)reader.readC();
|
||||
}
|
||||
}
|
||||
|
||||
for (int i=0; i<16; i++) {
|
||||
speeds.val[i]*=(oldTimeBase+1);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
@ -595,7 +599,7 @@ void DivSubSong::putData(SafeWriter* w, int chans) {
|
|||
|
||||
w->writeF(hz);
|
||||
w->writeC(arpLen);
|
||||
w->writeC(timeBase);
|
||||
w->writeC(effectDivider);
|
||||
w->writeS(patLen);
|
||||
w->writeS(ordersLen);
|
||||
w->writeC(hilightA);
|
||||
|
|
@ -819,7 +823,7 @@ void DivSong::findSubSongs() {
|
|||
theCopy->notes=i->notes;
|
||||
theCopy->hilightA=i->hilightA;
|
||||
theCopy->hilightB=i->hilightB;
|
||||
theCopy->timeBase=i->timeBase;
|
||||
theCopy->effectDivider=i->effectDivider;
|
||||
theCopy->arpLen=i->arpLen;
|
||||
theCopy->speeds=i->speeds;
|
||||
theCopy->virtualTempoN=i->virtualTempoN;
|
||||
|
|
|
|||
|
|
@ -226,7 +226,7 @@ struct DivSongTimestamps {
|
|||
struct DivSubSong {
|
||||
String name, notes;
|
||||
unsigned char hilightA, hilightB;
|
||||
unsigned char timeBase, arpLen;
|
||||
unsigned char effectDivider, arpLen;
|
||||
DivGroovePattern speeds;
|
||||
short virtualTempoN, virtualTempoD;
|
||||
float hz;
|
||||
|
|
@ -269,7 +269,7 @@ struct DivSubSong {
|
|||
DivSubSong():
|
||||
hilightA(4),
|
||||
hilightB(16),
|
||||
timeBase(0),
|
||||
effectDivider(0),
|
||||
arpLen(1),
|
||||
virtualTempoN(150),
|
||||
virtualTempoD(150),
|
||||
|
|
|
|||
|
|
@ -1295,16 +1295,14 @@ void FurnaceGUI::prepareLayout() {
|
|||
float FurnaceGUI::calcBPM(const DivGroovePattern& speeds, float hz, int vN, int vD) {
|
||||
float hl=e->curSubSong->hilightA;
|
||||
if (hl<=0.0f) hl=4.0f;
|
||||
float timeBase=e->curSubSong->timeBase+1;
|
||||
float speedSum=0;
|
||||
for (int i=0; i<MIN(16,speeds.len); i++) {
|
||||
speedSum+=speeds.val[i];
|
||||
}
|
||||
speedSum/=MAX(1,speeds.len);
|
||||
if (timeBase<1.0f) timeBase=1.0f;
|
||||
if (speedSum<1.0f) speedSum=1.0f;
|
||||
if (vD<1) vD=1;
|
||||
return (60.0f*hz/(timeBase*hl*speedSum))*(float)vN/(float)vD;
|
||||
return (60.0f*hz/(hl*speedSum))*(float)vN/(float)vD;
|
||||
}
|
||||
|
||||
void FurnaceGUI::play(int row) {
|
||||
|
|
|
|||
|
|
@ -198,9 +198,11 @@ void FurnaceGUI::drawSpeed(bool asChild) {
|
|||
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
/*
|
||||
ImGui::AlignTextToFramePadding();
|
||||
ImGui::Text(_("Divider"));
|
||||
ImGui::Text(_("Divider"));*/
|
||||
ImGui::TableNextColumn();
|
||||
/*
|
||||
ImGui::SetNextItemWidth(halfAvail);
|
||||
unsigned char realTB=e->curSubSong->timeBase+1;
|
||||
if (ImGui::InputScalar("##TimeBase",ImGuiDataType_U8,&realTB,&_ONE,&_THREE)) { MARK_MODIFIED
|
||||
|
|
@ -210,6 +212,7 @@ void FurnaceGUI::drawSpeed(bool asChild) {
|
|||
recalcTimestamps=true;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
*/
|
||||
ImGui::Text("%.2f BPM",calcBPM(e->curSubSong->speeds,e->curSubSong->hz,e->curSubSong->virtualTempoN,e->curSubSong->virtualTempoD));
|
||||
|
||||
ImGui::TableNextRow();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue