parent
0a114b1168
commit
1003d9fcb8
|
@ -584,6 +584,7 @@ void DivEngine::renderSamples() {
|
|||
void DivEngine::createNew(const int* description) {
|
||||
quitDispatch();
|
||||
isBusy.lock();
|
||||
saveLock.lock();
|
||||
song.unload();
|
||||
song=DivSong();
|
||||
if (description!=NULL) {
|
||||
|
@ -602,6 +603,7 @@ void DivEngine::createNew(const int* description) {
|
|||
}
|
||||
recalcChans();
|
||||
renderSamples();
|
||||
saveLock.unlock();
|
||||
isBusy.unlock();
|
||||
initDispatch();
|
||||
isBusy.lock();
|
||||
|
@ -1214,8 +1216,10 @@ int DivEngine::addInstrument(int refChan) {
|
|||
int insCount=(int)song.ins.size();
|
||||
ins->name=fmt::sprintf("Instrument %d",insCount);
|
||||
ins->type=getPreferInsType(refChan);
|
||||
saveLock.lock();
|
||||
song.ins.push_back(ins);
|
||||
song.insLen=insCount+1;
|
||||
saveLock.unlock();
|
||||
isBusy.unlock();
|
||||
return insCount;
|
||||
}
|
||||
|
@ -1230,6 +1234,9 @@ enum DivInsFormats {
|
|||
DIV_INSFORMAT_SBI,
|
||||
};
|
||||
|
||||
// TODO: re-organize this function to:
|
||||
// - support replacing instruments
|
||||
// - support instrument formats which contain multiple instruments
|
||||
bool DivEngine::addInstrumentFromFile(const char* path) {
|
||||
warnings="";
|
||||
|
||||
|
@ -1354,7 +1361,7 @@ bool DivEngine::addInstrumentFromFile(const char* path) {
|
|||
}
|
||||
}
|
||||
|
||||
// TDOO these really should be refactored to separate functions/cpp files per instrument file type.
|
||||
// TDOO these really should be re-organized to separate functions per instrument file type.
|
||||
switch (format) {
|
||||
case DIV_INSFORMAT_DMP: {
|
||||
// this is a ridiculous mess
|
||||
|
@ -1937,15 +1944,18 @@ bool DivEngine::addInstrumentFromFile(const char* path) {
|
|||
}
|
||||
|
||||
isBusy.lock();
|
||||
saveLock.lock();
|
||||
int insCount=(int)song.ins.size();
|
||||
song.ins.push_back(ins);
|
||||
song.insLen=insCount+1;
|
||||
saveLock.unlock();
|
||||
isBusy.unlock();
|
||||
return true;
|
||||
}
|
||||
|
||||
void DivEngine::delInstrument(int index) {
|
||||
isBusy.lock();
|
||||
saveLock.lock();
|
||||
if (index>=0 && index<(int)song.ins.size()) {
|
||||
for (int i=0; i<song.systemLen; i++) {
|
||||
disCont[i].dispatch->notifyInsDeletion(song.ins[index]);
|
||||
|
@ -1964,15 +1974,18 @@ void DivEngine::delInstrument(int index) {
|
|||
}
|
||||
}
|
||||
}
|
||||
saveLock.unlock();
|
||||
isBusy.unlock();
|
||||
}
|
||||
|
||||
int DivEngine::addWave() {
|
||||
isBusy.lock();
|
||||
saveLock.lock();
|
||||
DivWavetable* wave=new DivWavetable;
|
||||
int waveCount=(int)song.wave.size();
|
||||
song.wave.push_back(wave);
|
||||
song.waveLen=waveCount+1;
|
||||
saveLock.unlock();
|
||||
isBusy.unlock();
|
||||
return waveCount;
|
||||
}
|
||||
|
@ -2088,30 +2101,36 @@ bool DivEngine::addWaveFromFile(const char* path) {
|
|||
}
|
||||
|
||||
isBusy.lock();
|
||||
saveLock.lock();
|
||||
int waveCount=(int)song.wave.size();
|
||||
song.wave.push_back(wave);
|
||||
song.waveLen=waveCount+1;
|
||||
saveLock.unlock();
|
||||
isBusy.unlock();
|
||||
return true;
|
||||
}
|
||||
|
||||
void DivEngine::delWave(int index) {
|
||||
isBusy.lock();
|
||||
saveLock.lock();
|
||||
if (index>=0 && index<(int)song.wave.size()) {
|
||||
delete song.wave[index];
|
||||
song.wave.erase(song.wave.begin()+index);
|
||||
song.waveLen=song.wave.size();
|
||||
}
|
||||
saveLock.unlock();
|
||||
isBusy.unlock();
|
||||
}
|
||||
|
||||
int DivEngine::addSample() {
|
||||
isBusy.lock();
|
||||
saveLock.lock();
|
||||
DivSample* sample=new DivSample;
|
||||
int sampleCount=(int)song.sample.size();
|
||||
sample->name=fmt::sprintf("Sample %d",sampleCount);
|
||||
song.sample.push_back(sample);
|
||||
song.sampleLen=sampleCount+1;
|
||||
saveLock.unlock();
|
||||
renderSamples();
|
||||
isBusy.unlock();
|
||||
return sampleCount;
|
||||
|
@ -2189,8 +2208,10 @@ bool DivEngine::addSampleFromFile(const char* path) {
|
|||
if (sample->centerRate<4000) sample->centerRate=4000;
|
||||
if (sample->centerRate>64000) sample->centerRate=64000;
|
||||
sf_close(f);
|
||||
saveLock.lock();
|
||||
song.sample.push_back(sample);
|
||||
song.sampleLen=sampleCount+1;
|
||||
saveLock.unlock();
|
||||
renderSamples();
|
||||
isBusy.unlock();
|
||||
return sampleCount;
|
||||
|
@ -2198,12 +2219,14 @@ bool DivEngine::addSampleFromFile(const char* path) {
|
|||
|
||||
void DivEngine::delSample(int index) {
|
||||
isBusy.lock();
|
||||
saveLock.lock();
|
||||
if (index>=0 && index<(int)song.sample.size()) {
|
||||
delete song.sample[index];
|
||||
song.sample.erase(song.sample.begin()+index);
|
||||
song.sampleLen=song.sample.size();
|
||||
renderSamples();
|
||||
}
|
||||
saveLock.unlock();
|
||||
isBusy.unlock();
|
||||
}
|
||||
|
||||
|
@ -2232,11 +2255,14 @@ void DivEngine::addOrder(bool duplicate, bool where) {
|
|||
}
|
||||
}
|
||||
if (where) { // at the end
|
||||
saveLock.lock();
|
||||
for (int i=0; i<DIV_MAX_CHANS; i++) {
|
||||
song.orders.ord[i][song.ordersLen]=order[i];
|
||||
}
|
||||
song.ordersLen++;
|
||||
saveLock.unlock();
|
||||
} else { // after current order
|
||||
saveLock.lock();
|
||||
for (int i=0; i<DIV_MAX_CHANS; i++) {
|
||||
for (int j=song.ordersLen; j>curOrder; j--) {
|
||||
song.orders.ord[i][j]=song.orders.ord[i][j-1];
|
||||
|
@ -2244,6 +2270,7 @@ void DivEngine::addOrder(bool duplicate, bool where) {
|
|||
song.orders.ord[i][curOrder+1]=order[i];
|
||||
}
|
||||
song.ordersLen++;
|
||||
saveLock.unlock();
|
||||
curOrder++;
|
||||
if (playing && !freelance) {
|
||||
playSub(false);
|
||||
|
@ -2280,11 +2307,14 @@ void DivEngine::deepCloneOrder(bool where) {
|
|||
}
|
||||
}
|
||||
if (where) { // at the end
|
||||
saveLock.lock();
|
||||
for (int i=0; i<chans; i++) {
|
||||
song.orders.ord[i][song.ordersLen]=order[i];
|
||||
}
|
||||
song.ordersLen++;
|
||||
saveLock.unlock();
|
||||
} else { // after current order
|
||||
saveLock.lock();
|
||||
for (int i=0; i<chans; i++) {
|
||||
for (int j=song.ordersLen; j>curOrder; j--) {
|
||||
song.orders.ord[i][j]=song.orders.ord[i][j-1];
|
||||
|
@ -2292,6 +2322,7 @@ void DivEngine::deepCloneOrder(bool where) {
|
|||
song.orders.ord[i][curOrder+1]=order[i];
|
||||
}
|
||||
song.ordersLen++;
|
||||
saveLock.unlock();
|
||||
curOrder++;
|
||||
if (playing && !freelance) {
|
||||
playSub(false);
|
||||
|
@ -2303,12 +2334,14 @@ void DivEngine::deepCloneOrder(bool where) {
|
|||
void DivEngine::deleteOrder() {
|
||||
if (song.ordersLen<=1) return;
|
||||
isBusy.lock();
|
||||
saveLock.lock();
|
||||
for (int i=0; i<DIV_MAX_CHANS; i++) {
|
||||
for (int j=curOrder; j<song.ordersLen; j++) {
|
||||
song.orders.ord[i][j]=song.orders.ord[i][j+1];
|
||||
}
|
||||
}
|
||||
song.ordersLen--;
|
||||
saveLock.unlock();
|
||||
if (curOrder>=song.ordersLen) curOrder=song.ordersLen-1;
|
||||
if (playing && !freelance) {
|
||||
playSub(false);
|
||||
|
@ -2322,11 +2355,13 @@ void DivEngine::moveOrderUp() {
|
|||
isBusy.unlock();
|
||||
return;
|
||||
}
|
||||
saveLock.lock();
|
||||
for (int i=0; i<DIV_MAX_CHANS; i++) {
|
||||
song.orders.ord[i][curOrder]^=song.orders.ord[i][curOrder-1];
|
||||
song.orders.ord[i][curOrder-1]^=song.orders.ord[i][curOrder];
|
||||
song.orders.ord[i][curOrder]^=song.orders.ord[i][curOrder-1];
|
||||
}
|
||||
saveLock.unlock();
|
||||
curOrder--;
|
||||
if (playing && !freelance) {
|
||||
playSub(false);
|
||||
|
@ -2340,11 +2375,13 @@ void DivEngine::moveOrderDown() {
|
|||
isBusy.unlock();
|
||||
return;
|
||||
}
|
||||
saveLock.lock();
|
||||
for (int i=0; i<DIV_MAX_CHANS; i++) {
|
||||
song.orders.ord[i][curOrder]^=song.orders.ord[i][curOrder+1];
|
||||
song.orders.ord[i][curOrder+1]^=song.orders.ord[i][curOrder];
|
||||
song.orders.ord[i][curOrder]^=song.orders.ord[i][curOrder+1];
|
||||
}
|
||||
saveLock.unlock();
|
||||
curOrder++;
|
||||
if (playing && !freelance) {
|
||||
playSub(false);
|
||||
|
@ -2371,9 +2408,11 @@ bool DivEngine::moveInsUp(int which) {
|
|||
if (which<1 || which>=(int)song.ins.size()) return false;
|
||||
isBusy.lock();
|
||||
DivInstrument* prev=song.ins[which];
|
||||
saveLock.lock();
|
||||
song.ins[which]=song.ins[which-1];
|
||||
song.ins[which-1]=prev;
|
||||
exchangeIns(which,which-1);
|
||||
saveLock.unlock();
|
||||
isBusy.unlock();
|
||||
return true;
|
||||
}
|
||||
|
@ -2382,8 +2421,10 @@ bool DivEngine::moveWaveUp(int which) {
|
|||
if (which<1 || which>=(int)song.wave.size()) return false;
|
||||
isBusy.lock();
|
||||
DivWavetable* prev=song.wave[which];
|
||||
saveLock.lock();
|
||||
song.wave[which]=song.wave[which-1];
|
||||
song.wave[which-1]=prev;
|
||||
saveLock.unlock();
|
||||
isBusy.unlock();
|
||||
return true;
|
||||
}
|
||||
|
@ -2392,8 +2433,10 @@ bool DivEngine::moveSampleUp(int which) {
|
|||
if (which<1 || which>=(int)song.sample.size()) return false;
|
||||
isBusy.lock();
|
||||
DivSample* prev=song.sample[which];
|
||||
saveLock.lock();
|
||||
song.sample[which]=song.sample[which-1];
|
||||
song.sample[which-1]=prev;
|
||||
saveLock.unlock();
|
||||
isBusy.unlock();
|
||||
return true;
|
||||
}
|
||||
|
@ -2402,9 +2445,11 @@ bool DivEngine::moveInsDown(int which) {
|
|||
if (which<0 || which>=((int)song.ins.size())-1) return false;
|
||||
isBusy.lock();
|
||||
DivInstrument* prev=song.ins[which];
|
||||
saveLock.lock();
|
||||
song.ins[which]=song.ins[which+1];
|
||||
song.ins[which+1]=prev;
|
||||
exchangeIns(which,which+1);
|
||||
saveLock.unlock();
|
||||
isBusy.unlock();
|
||||
return true;
|
||||
}
|
||||
|
@ -2413,8 +2458,10 @@ bool DivEngine::moveWaveDown(int which) {
|
|||
if (which<0 || which>=((int)song.wave.size())-1) return false;
|
||||
isBusy.lock();
|
||||
DivWavetable* prev=song.wave[which];
|
||||
saveLock.lock();
|
||||
song.wave[which]=song.wave[which+1];
|
||||
song.wave[which+1]=prev;
|
||||
saveLock.unlock();
|
||||
isBusy.unlock();
|
||||
return true;
|
||||
}
|
||||
|
@ -2423,8 +2470,10 @@ bool DivEngine::moveSampleDown(int which) {
|
|||
if (which<0 || which>=((int)song.sample.size())-1) return false;
|
||||
isBusy.lock();
|
||||
DivSample* prev=song.sample[which];
|
||||
saveLock.lock();
|
||||
song.sample[which]=song.sample[which+1];
|
||||
song.sample[which+1]=prev;
|
||||
saveLock.unlock();
|
||||
isBusy.unlock();
|
||||
return true;
|
||||
}
|
||||
|
@ -2465,7 +2514,9 @@ void DivEngine::setOrder(unsigned char order) {
|
|||
|
||||
void DivEngine::setSysFlags(int system, unsigned int flags, bool restart) {
|
||||
isBusy.lock();
|
||||
saveLock.lock();
|
||||
song.systemFlags[system]=flags;
|
||||
saveLock.unlock();
|
||||
disCont[system].dispatch->setFlags(song.systemFlags[system]);
|
||||
disCont[system].setRates(got.rate);
|
||||
if (restart && isPlaying()) {
|
||||
|
@ -2476,6 +2527,7 @@ void DivEngine::setSysFlags(int system, unsigned int flags, bool restart) {
|
|||
|
||||
void DivEngine::setSongRate(float hz, bool pal) {
|
||||
isBusy.lock();
|
||||
saveLock.lock();
|
||||
song.pal=!pal;
|
||||
song.hz=hz;
|
||||
// what?
|
||||
|
@ -2490,6 +2542,7 @@ void DivEngine::setSongRate(float hz, bool pal) {
|
|||
divider=50;
|
||||
}
|
||||
}
|
||||
saveLock.unlock();
|
||||
isBusy.unlock();
|
||||
}
|
||||
|
||||
|
@ -2539,6 +2592,20 @@ void DivEngine::synchronized(const std::function<void()>& what) {
|
|||
isBusy.unlock();
|
||||
}
|
||||
|
||||
void DivEngine::lockSave(const std::function<void()>& what) {
|
||||
saveLock.lock();
|
||||
what();
|
||||
saveLock.unlock();
|
||||
}
|
||||
|
||||
void DivEngine::lockEngine(const std::function<void()>& what) {
|
||||
isBusy.lock();
|
||||
saveLock.lock();
|
||||
what();
|
||||
saveLock.unlock();
|
||||
isBusy.unlock();
|
||||
}
|
||||
|
||||
TAAudioDesc& DivEngine::getAudioDescWant() {
|
||||
return want;
|
||||
}
|
||||
|
|
|
@ -201,7 +201,7 @@ class DivEngine {
|
|||
std::map<String,String> conf;
|
||||
std::queue<DivNoteEvent> pendingNotes;
|
||||
bool isMuted[DIV_MAX_CHANS];
|
||||
std::mutex isBusy;
|
||||
std::mutex isBusy, saveLock;
|
||||
String configPath;
|
||||
String configFile;
|
||||
String lastError;
|
||||
|
@ -621,6 +621,12 @@ class DivEngine {
|
|||
// perform secure/sync operation
|
||||
void synchronized(const std::function<void()>& what);
|
||||
|
||||
// perform secure/sync song operation
|
||||
void lockSave(const std::function<void()>& what);
|
||||
|
||||
// perform secure/sync song operation (and lock audio too)
|
||||
void lockEngine(const std::function<void()>& what);
|
||||
|
||||
// get audio desc want
|
||||
TAAudioDesc& getAudioDescWant();
|
||||
|
||||
|
|
|
@ -733,10 +733,12 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
|
|||
|
||||
if (active) quitDispatch();
|
||||
isBusy.lock();
|
||||
saveLock.lock();
|
||||
song.unload();
|
||||
song=ds;
|
||||
recalcChans();
|
||||
renderSamples();
|
||||
saveLock.unlock();
|
||||
isBusy.unlock();
|
||||
if (active) {
|
||||
initDispatch();
|
||||
|
@ -1219,10 +1221,12 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) {
|
|||
|
||||
if (active) quitDispatch();
|
||||
isBusy.lock();
|
||||
saveLock.lock();
|
||||
song.unload();
|
||||
song=ds;
|
||||
recalcChans();
|
||||
renderSamples();
|
||||
saveLock.unlock();
|
||||
isBusy.unlock();
|
||||
if (active) {
|
||||
initDispatch();
|
||||
|
@ -1583,10 +1587,12 @@ bool DivEngine::loadMod(unsigned char* file, size_t len) {
|
|||
|
||||
if (active) quitDispatch();
|
||||
isBusy.lock();
|
||||
saveLock.lock();
|
||||
song.unload();
|
||||
song=ds;
|
||||
recalcChans();
|
||||
renderSamples();
|
||||
saveLock.unlock();
|
||||
isBusy.unlock();
|
||||
if (active) {
|
||||
initDispatch();
|
||||
|
@ -1729,6 +1735,7 @@ bool DivEngine::load(unsigned char* f, size_t slen) {
|
|||
}
|
||||
|
||||
SafeWriter* DivEngine::saveFur(bool notPrimary) {
|
||||
saveLock.lock();
|
||||
int insPtr[256];
|
||||
int wavePtr[256];
|
||||
int samplePtr[256];
|
||||
|
@ -1969,6 +1976,7 @@ SafeWriter* DivEngine::saveFur(bool notPrimary) {
|
|||
w->writeI(i);
|
||||
}
|
||||
|
||||
saveLock.unlock();
|
||||
return w;
|
||||
}
|
||||
|
||||
|
@ -2028,6 +2036,7 @@ SafeWriter* DivEngine::saveDMF(unsigned char version) {
|
|||
lastError="this system is not possible on .dmf";
|
||||
return NULL;
|
||||
}
|
||||
saveLock.lock();
|
||||
warnings="";
|
||||
song.version=version;
|
||||
song.isDMF=true;
|
||||
|
@ -2259,7 +2268,8 @@ SafeWriter* DivEngine::saveDMF(unsigned char version) {
|
|||
w->writeC(16);
|
||||
w->write(i->data16,i->length16);
|
||||
}
|
||||
|
||||
|
||||
saveLock.unlock();
|
||||
return w;
|
||||
}
|
||||
|
||||
|
|
|
@ -1004,13 +1004,17 @@ void FurnaceGUI::drawSongInfo() {
|
|||
ImGui::TableNextColumn();
|
||||
float avail=ImGui::GetContentRegionAvail().x;
|
||||
ImGui::SetNextItemWidth(avail);
|
||||
if (ImGui::InputText("##Name",&e->song.name)) updateWindowTitle();
|
||||
if (ImGui::InputText("##Name",&e->song.name)) { MARK_MODIFIED
|
||||
updateWindowTitle();
|
||||
}
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("Author");
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::SetNextItemWidth(avail);
|
||||
ImGui::InputText("##Author",&e->song.author);
|
||||
if (ImGui::InputText("##Author",&e->song.author)) {
|
||||
MARK_MODIFIED;
|
||||
}
|
||||
ImGui::EndTable();
|
||||
}
|
||||
|
||||
|
@ -1026,7 +1030,7 @@ void FurnaceGUI::drawSongInfo() {
|
|||
float avail=ImGui::GetContentRegionAvail().x;
|
||||
ImGui::SetNextItemWidth(avail);
|
||||
unsigned char realTB=e->song.timeBase+1;
|
||||
if (ImGui::InputScalar("##TimeBase",ImGuiDataType_U8,&realTB,&_ONE,&_THREE)) {
|
||||
if (ImGui::InputScalar("##TimeBase",ImGuiDataType_U8,&realTB,&_ONE,&_THREE)) { MARK_MODIFIED
|
||||
if (realTB<1) realTB=1;
|
||||
if (realTB>16) realTB=16;
|
||||
e->song.timeBase=realTB-1;
|
||||
|
@ -1039,13 +1043,13 @@ void FurnaceGUI::drawSongInfo() {
|
|||
ImGui::Text("Speed");
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::SetNextItemWidth(avail);
|
||||
if (ImGui::InputScalar("##Speed1",ImGuiDataType_U8,&e->song.speed1,&_ONE,&_THREE)) {
|
||||
if (ImGui::InputScalar("##Speed1",ImGuiDataType_U8,&e->song.speed1,&_ONE,&_THREE)) { MARK_MODIFIED
|
||||
if (e->song.speed1<1) e->song.speed1=1;
|
||||
if (e->isPlaying()) play();
|
||||
}
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::SetNextItemWidth(avail);
|
||||
if (ImGui::InputScalar("##Speed2",ImGuiDataType_U8,&e->song.speed2,&_ONE,&_THREE)) {
|
||||
if (ImGui::InputScalar("##Speed2",ImGuiDataType_U8,&e->song.speed2,&_ONE,&_THREE)) { MARK_MODIFIED
|
||||
if (e->song.speed2<1) e->song.speed2=1;
|
||||
if (e->isPlaying()) play();
|
||||
}
|
||||
|
@ -1055,10 +1059,14 @@ void FurnaceGUI::drawSongInfo() {
|
|||
ImGui::Text("Highlight");
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::SetNextItemWidth(avail);
|
||||
ImGui::InputScalar("##Highlight1",ImGuiDataType_U8,&e->song.hilightA,&_ONE,&_THREE);
|
||||
if (ImGui::InputScalar("##Highlight1",ImGuiDataType_U8,&e->song.hilightA,&_ONE,&_THREE)) {
|
||||
MARK_MODIFIED;
|
||||
}
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::SetNextItemWidth(avail);
|
||||
ImGui::InputScalar("##Highlight2",ImGuiDataType_U8,&e->song.hilightB,&_ONE,&_THREE);
|
||||
if (ImGui::InputScalar("##Highlight2",ImGuiDataType_U8,&e->song.hilightB,&_ONE,&_THREE)) {
|
||||
MARK_MODIFIED;
|
||||
}
|
||||
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
|
@ -1066,7 +1074,7 @@ void FurnaceGUI::drawSongInfo() {
|
|||
ImGui::TableNextColumn();
|
||||
ImGui::SetNextItemWidth(avail);
|
||||
int patLen=e->song.patLen;
|
||||
if (ImGui::InputInt("##PatLength",&patLen,1,3)) {
|
||||
if (ImGui::InputInt("##PatLength",&patLen,1,3)) { MARK_MODIFIED
|
||||
if (patLen<1) patLen=1;
|
||||
if (patLen>256) patLen=256;
|
||||
e->song.patLen=patLen;
|
||||
|
@ -1078,7 +1086,7 @@ void FurnaceGUI::drawSongInfo() {
|
|||
ImGui::TableNextColumn();
|
||||
ImGui::SetNextItemWidth(avail);
|
||||
int ordLen=e->song.ordersLen;
|
||||
if (ImGui::InputInt("##OrdLength",&ordLen,1,3)) {
|
||||
if (ImGui::InputInt("##OrdLength",&ordLen,1,3)) { MARK_MODIFIED
|
||||
if (ordLen<1) ordLen=1;
|
||||
if (ordLen>127) ordLen=127;
|
||||
e->song.ordersLen=ordLen;
|
||||
|
@ -1092,7 +1100,7 @@ void FurnaceGUI::drawSongInfo() {
|
|||
ImGui::TableNextColumn();
|
||||
ImGui::SetNextItemWidth(avail);
|
||||
float setHz=tempoView?e->song.hz*2.5:e->song.hz;
|
||||
if (ImGui::InputFloat("##Rate",&setHz,1.0f,1.0f,"%g")) {
|
||||
if (ImGui::InputFloat("##Rate",&setHz,1.0f,1.0f,"%g")) { MARK_MODIFIED
|
||||
if (tempoView) setHz/=2.5;
|
||||
if (setHz<10) setHz=10;
|
||||
if (setHz>999) setHz=999;
|
||||
|
@ -1118,7 +1126,7 @@ void FurnaceGUI::drawSongInfo() {
|
|||
ImGui::TableNextColumn();
|
||||
float tune=e->song.tuning;
|
||||
ImGui::SetNextItemWidth(avail);
|
||||
if (ImGui::InputFloat("##Tuning",&tune,1.0f,3.0f,"%g")) {
|
||||
if (ImGui::InputFloat("##Tuning",&tune,1.0f,3.0f,"%g")) { MARK_MODIFIED
|
||||
if (tune<220.0f) tune=220.0f;
|
||||
if (tune>880.0f) tune=880.0f;
|
||||
e->song.tuning=tune;
|
||||
|
@ -2713,7 +2721,7 @@ void FurnaceGUI::makeUndo(ActionType action) {
|
|||
break;
|
||||
}
|
||||
if (doPush) {
|
||||
modified=true;
|
||||
MARK_MODIFIED;
|
||||
undoHist.push_back(s);
|
||||
redoHist.clear();
|
||||
if (undoHist.size()>settings.maxUndoSteps) undoHist.pop_front();
|
||||
|
@ -3509,7 +3517,7 @@ void FurnaceGUI::doUndo() {
|
|||
if (undoHist.empty()) return;
|
||||
UndoStep& us=undoHist.back();
|
||||
redoHist.push_back(us);
|
||||
modified=true;
|
||||
MARK_MODIFIED;
|
||||
|
||||
switch (us.type) {
|
||||
case GUI_UNDO_CHANGE_ORDER:
|
||||
|
@ -3555,7 +3563,7 @@ void FurnaceGUI::doRedo() {
|
|||
if (redoHist.empty()) return;
|
||||
UndoStep& us=redoHist.back();
|
||||
undoHist.push_back(us);
|
||||
modified=true;
|
||||
MARK_MODIFIED;
|
||||
|
||||
switch (us.type) {
|
||||
case GUI_UNDO_CHANGE_ORDER:
|
||||
|
@ -4095,14 +4103,14 @@ void FurnaceGUI::doAction(int what) {
|
|||
|
||||
case GUI_ACTION_INS_LIST_ADD:
|
||||
curIns=e->addInstrument(cursor.xCoarse);
|
||||
modified=true;
|
||||
MARK_MODIFIED;
|
||||
break;
|
||||
case GUI_ACTION_INS_LIST_DUPLICATE:
|
||||
if (curIns>=0 && curIns<(int)e->song.ins.size()) {
|
||||
int prevIns=curIns;
|
||||
curIns=e->addInstrument(cursor.xCoarse);
|
||||
(*e->song.ins[curIns])=(*e->song.ins[prevIns]);
|
||||
modified=true;
|
||||
MARK_MODIFIED;
|
||||
}
|
||||
break;
|
||||
case GUI_ACTION_INS_LIST_OPEN:
|
||||
|
@ -4120,7 +4128,7 @@ void FurnaceGUI::doAction(int what) {
|
|||
case GUI_ACTION_INS_LIST_DELETE:
|
||||
if (curIns>=0 && curIns<(int)e->song.ins.size()) {
|
||||
e->delInstrument(curIns);
|
||||
modified=true;
|
||||
MARK_MODIFIED;
|
||||
if (curIns>=(int)e->song.ins.size()) {
|
||||
curIns--;
|
||||
}
|
||||
|
@ -4138,14 +4146,14 @@ void FurnaceGUI::doAction(int what) {
|
|||
|
||||
case GUI_ACTION_WAVE_LIST_ADD:
|
||||
curWave=e->addWave();
|
||||
modified=true;
|
||||
MARK_MODIFIED;
|
||||
break;
|
||||
case GUI_ACTION_WAVE_LIST_DUPLICATE:
|
||||
if (curWave>=0 && curWave<(int)e->song.wave.size()) {
|
||||
int prevWave=curWave;
|
||||
curWave=e->addWave();
|
||||
(*e->song.wave[curWave])=(*e->song.wave[prevWave]);
|
||||
modified=true;
|
||||
MARK_MODIFIED;
|
||||
}
|
||||
break;
|
||||
case GUI_ACTION_WAVE_LIST_OPEN:
|
||||
|
@ -4163,7 +4171,7 @@ void FurnaceGUI::doAction(int what) {
|
|||
case GUI_ACTION_WAVE_LIST_DELETE:
|
||||
if (curWave>=0 && curWave<(int)e->song.wave.size()) {
|
||||
e->delWave(curWave);
|
||||
modified=true;
|
||||
MARK_MODIFIED;
|
||||
if (curWave>=(int)e->song.wave.size()) {
|
||||
curWave--;
|
||||
}
|
||||
|
@ -4181,7 +4189,7 @@ void FurnaceGUI::doAction(int what) {
|
|||
|
||||
case GUI_ACTION_SAMPLE_LIST_ADD:
|
||||
curSample=e->addSample();
|
||||
modified=true;
|
||||
MARK_MODIFIED;
|
||||
break;
|
||||
case GUI_ACTION_SAMPLE_LIST_OPEN:
|
||||
openFileDialog(GUI_FILE_SAMPLE_OPEN);
|
||||
|
@ -4197,7 +4205,7 @@ void FurnaceGUI::doAction(int what) {
|
|||
break;
|
||||
case GUI_ACTION_SAMPLE_LIST_DELETE:
|
||||
e->delSample(curSample);
|
||||
modified=true;
|
||||
MARK_MODIFIED;
|
||||
if (curSample>=(int)e->song.sample.size()) {
|
||||
curSample--;
|
||||
}
|
||||
|
@ -4498,7 +4506,9 @@ void FurnaceGUI::keyDown(SDL_Event& ev) {
|
|||
int num=valueKeys.at(ev.key.keysym.sym);
|
||||
if (orderCursor>=0 && orderCursor<e->getTotalChannelCount()) {
|
||||
int curOrder=e->getOrder();
|
||||
e->song.orders.ord[orderCursor][curOrder]=((e->song.orders.ord[orderCursor][curOrder]<<4)|num)&0x7f;
|
||||
e->lockSave([this,curOrder,num]() {
|
||||
e->song.orders.ord[orderCursor][curOrder]=((e->song.orders.ord[orderCursor][curOrder]<<4)|num)&0x7f;
|
||||
});
|
||||
if (orderEditMode==2 || orderEditMode==3) {
|
||||
curNibble=!curNibble;
|
||||
if (!curNibble) {
|
||||
|
@ -4813,13 +4823,11 @@ void FurnaceGUI::openFileDialog(FurnaceGUIFileDialogs type) {
|
|||
|
||||
int FurnaceGUI::save(String path, int dmfVersion) {
|
||||
SafeWriter* w;
|
||||
backupLock.lock();
|
||||
if (dmfVersion) {
|
||||
w=e->saveDMF(dmfVersion);
|
||||
} else {
|
||||
w=e->saveFur();
|
||||
}
|
||||
backupLock.unlock();
|
||||
if (w==NULL) {
|
||||
lastError=e->getLastError();
|
||||
return 3;
|
||||
|
@ -5062,7 +5070,7 @@ void FurnaceGUI::processDrags(int dragX, int dragY) {
|
|||
if (y<waveDragMin) y=waveDragMin;
|
||||
waveDragTarget[x]=y;
|
||||
e->notifyWaveChange(curWave);
|
||||
modified=true;
|
||||
MARK_MODIFIED;
|
||||
}
|
||||
}
|
||||
if (sampleDragActive) {
|
||||
|
@ -5363,7 +5371,9 @@ bool FurnaceGUI::loop() {
|
|||
break;
|
||||
}
|
||||
case SDL_MOUSEBUTTONUP:
|
||||
if (macroDragActive || macroLoopDragActive || waveDragActive || (sampleDragActive && sampleDragMode)) modified=true;
|
||||
if (macroDragActive || macroLoopDragActive || waveDragActive || (sampleDragActive && sampleDragMode)) {
|
||||
MARK_MODIFIED;
|
||||
}
|
||||
macroDragActive=false;
|
||||
macroDragBitMode=false;
|
||||
macroDragInitialValue=false;
|
||||
|
@ -6272,7 +6282,7 @@ bool FurnaceGUI::loop() {
|
|||
break;
|
||||
case GUI_FILE_SAMPLE_OPEN:
|
||||
e->addSampleFromFile(copyOfName.c_str());
|
||||
modified=true;
|
||||
MARK_MODIFIED;
|
||||
break;
|
||||
case GUI_FILE_SAMPLE_SAVE:
|
||||
if (curSample>=0 && curSample<(int)e->song.sample.size()) {
|
||||
|
@ -6299,7 +6309,7 @@ bool FurnaceGUI::loop() {
|
|||
break;
|
||||
case GUI_FILE_WAVE_OPEN:
|
||||
e->addWaveFromFile(copyOfName.c_str());
|
||||
modified=true;
|
||||
MARK_MODIFIED;
|
||||
break;
|
||||
case GUI_FILE_EXPORT_VGM: {
|
||||
SafeWriter* w=e->saveVGM(willExport,vgmExportLoop);
|
||||
|
@ -6444,9 +6454,7 @@ bool FurnaceGUI::loop() {
|
|||
return true;
|
||||
}
|
||||
logD("saving backup...\n");
|
||||
backupLock.lock();
|
||||
SafeWriter* w=e->saveFur(true);
|
||||
backupLock.unlock();
|
||||
|
||||
if (w!=NULL) {
|
||||
FILE* outFile=ps_fopen(backupPath.c_str(),"wb");
|
||||
|
|
|
@ -36,6 +36,8 @@
|
|||
#define handleUnimportant if (settings.insFocusesPattern && patternOpen) {nextWindow=GUI_WINDOW_PATTERN;}
|
||||
#define unimportant(x) if (x) {handleUnimportant}
|
||||
|
||||
#define MARK_MODIFIED modified=true;
|
||||
|
||||
enum FurnaceGUIColors {
|
||||
GUI_COLOR_BACKGROUND=0,
|
||||
GUI_COLOR_FRAME_BACKGROUND,
|
||||
|
|
|
@ -669,11 +669,11 @@ void FurnaceGUI::drawFMEnv(unsigned char tl, unsigned char ar, unsigned char dr,
|
|||
}
|
||||
|
||||
#define P(x) if (x) { \
|
||||
modified=true; \
|
||||
MARK_MODIFIED; \
|
||||
e->notifyInsChange(curIns); \
|
||||
}
|
||||
|
||||
#define PARAMETER modified=true; e->notifyInsChange(curIns);
|
||||
#define PARAMETER MARK_MODIFIED; e->notifyInsChange(curIns);
|
||||
|
||||
#define NORMAL_MACRO(macro,macroLen,macroLoop,macroRel,macroMin,macroHeight,macroName,displayName,displayHeight,displayLoop,bitfield,bfVal,drawSlider,sliderVal,sliderLow,macroDispMin,bitOff,macroMode,macroColor,mmlStr,macroAMin,macroAMax,hoverFunc,blockMode) \
|
||||
ImGui::TableNextRow(); \
|
||||
|
@ -685,7 +685,7 @@ void FurnaceGUI::drawFMEnv(unsigned char tl, unsigned char ar, unsigned char dr,
|
|||
} \
|
||||
if (displayLoop) { \
|
||||
ImGui::SetNextItemWidth(lenAvail); \
|
||||
if (ImGui::InputScalar("##IMacroLen_" macroName,ImGuiDataType_U8,¯oLen,&_ONE,&_THREE)) { \
|
||||
if (ImGui::InputScalar("##IMacroLen_" macroName,ImGuiDataType_U8,¯oLen,&_ONE,&_THREE)) { MARK_MODIFIED \
|
||||
if (macroLen>127) macroLen=127; \
|
||||
} \
|
||||
if (macroMode!=NULL) { \
|
||||
|
@ -774,7 +774,7 @@ void FurnaceGUI::drawFMEnv(unsigned char tl, unsigned char ar, unsigned char dr,
|
|||
} \
|
||||
if (displayLoop) { \
|
||||
ImGui::SetNextItemWidth(lenAvail); \
|
||||
if (ImGui::InputScalar("##IOPMacroLen_" #op macroName,ImGuiDataType_U8,¯oLen,&_ONE,&_THREE)) { \
|
||||
if (ImGui::InputScalar("##IOPMacroLen_" #op macroName,ImGuiDataType_U8,¯oLen,&_ONE,&_THREE)) { MARK_MODIFIED \
|
||||
if (macroLen>127) macroLen=127; \
|
||||
} \
|
||||
} \
|
||||
|
@ -924,7 +924,9 @@ void FurnaceGUI::drawInsEdit() {
|
|||
ImGui::Text("no instrument selected");
|
||||
} else {
|
||||
DivInstrument* ins=e->song.ins[curIns];
|
||||
ImGui::InputText("Name",&ins->name);
|
||||
if (ImGui::InputText("Name",&ins->name)) {
|
||||
MARK_MODIFIED;
|
||||
}
|
||||
if (ins->type<0 || ins->type>=DIV_INS_MAX) ins->type=DIV_INS_FM;
|
||||
int insType=ins->type;
|
||||
if (ImGui::Combo("Type",&insType,insTypes,DIV_INS_MAX,DIV_INS_MAX)) {
|
||||
|
@ -2011,7 +2013,7 @@ void FurnaceGUI::drawWaveEdit() {
|
|||
if (wave->len<1) wave->len=1;
|
||||
e->notifyWaveChange(curWave);
|
||||
if (wavePreviewOn) e->previewWave(curWave,wavePreviewNote);
|
||||
modified=true;
|
||||
MARK_MODIFIED;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
ImGui::Text("Height");
|
||||
|
@ -2024,7 +2026,7 @@ void FurnaceGUI::drawWaveEdit() {
|
|||
if (wave->max>255) wave->max=255;
|
||||
if (wave->max<1) wave->max=1;
|
||||
e->notifyWaveChange(curWave);
|
||||
modified=true;
|
||||
MARK_MODIFIED;
|
||||
}
|
||||
for (int i=0; i<wave->len; i++) {
|
||||
if (wave->data[i]>wave->max) wave->data[i]=wave->max;
|
||||
|
|
|
@ -97,13 +97,15 @@ void FurnaceGUI::drawOrders() {
|
|||
if (curOrder==i) {
|
||||
if (orderEditMode==0) {
|
||||
prepareUndo(GUI_UNDO_CHANGE_ORDER);
|
||||
if (changeAllOrders) {
|
||||
for (int k=0; k<e->getTotalChannelCount(); k++) {
|
||||
if (e->song.orders.ord[k][i]<0x7f) e->song.orders.ord[k][i]++;
|
||||
e->lockSave([this,i,j]() {
|
||||
if (changeAllOrders) {
|
||||
for (int k=0; k<e->getTotalChannelCount(); k++) {
|
||||
if (e->song.orders.ord[k][i]<0x7f) e->song.orders.ord[k][i]++;
|
||||
}
|
||||
} else {
|
||||
if (e->song.orders.ord[j][i]<0x7f) e->song.orders.ord[j][i]++;
|
||||
}
|
||||
} else {
|
||||
if (e->song.orders.ord[j][i]<0x7f) e->song.orders.ord[j][i]++;
|
||||
}
|
||||
});
|
||||
e->walkSong(loopOrder,loopRow,loopEnd);
|
||||
makeUndo(GUI_UNDO_CHANGE_ORDER);
|
||||
} else {
|
||||
|
@ -130,13 +132,15 @@ void FurnaceGUI::drawOrders() {
|
|||
if (curOrder==i) {
|
||||
if (orderEditMode==0) {
|
||||
prepareUndo(GUI_UNDO_CHANGE_ORDER);
|
||||
if (changeAllOrders) {
|
||||
for (int k=0; k<e->getTotalChannelCount(); k++) {
|
||||
if (e->song.orders.ord[k][i]>0) e->song.orders.ord[k][i]--;
|
||||
e->lockSave([this,i,j]() {
|
||||
if (changeAllOrders) {
|
||||
for (int k=0; k<e->getTotalChannelCount(); k++) {
|
||||
if (e->song.orders.ord[k][i]>0) e->song.orders.ord[k][i]--;
|
||||
}
|
||||
} else {
|
||||
if (e->song.orders.ord[j][i]>0) e->song.orders.ord[j][i]--;
|
||||
}
|
||||
} else {
|
||||
if (e->song.orders.ord[j][i]>0) e->song.orders.ord[j][i]--;
|
||||
}
|
||||
});
|
||||
e->walkSong(loopOrder,loopRow,loopEnd);
|
||||
makeUndo(GUI_UNDO_CHANGE_ORDER);
|
||||
} else {
|
||||
|
|
|
@ -60,7 +60,9 @@ void FurnaceGUI::drawSampleEdit() {
|
|||
ImGui::Text("Name");
|
||||
ImGui::SameLine();
|
||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||
ImGui::InputText("##SampleName",&sample->name);
|
||||
if (ImGui::InputText("##SampleName",&sample->name)) {
|
||||
MARK_MODIFIED;
|
||||
}
|
||||
|
||||
if (ImGui::BeginTable("SampleProps",4,ImGuiTableFlags_SizingStretchSame)) {
|
||||
ImGui::TableNextRow();
|
||||
|
@ -75,6 +77,7 @@ void FurnaceGUI::drawSampleEdit() {
|
|||
sample->depth=i;
|
||||
e->renderSamplesP();
|
||||
updateSampleTex=true;
|
||||
MARK_MODIFIED;
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("no undo for sample type change operations!");
|
||||
|
@ -87,7 +90,7 @@ void FurnaceGUI::drawSampleEdit() {
|
|||
ImGui::Text("Rate (Hz)");
|
||||
ImGui::SameLine();
|
||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||
if (ImGui::InputInt("##SampleRate",&sample->rate,10,200)) {
|
||||
if (ImGui::InputInt("##SampleRate",&sample->rate,10,200)) { MARK_MODIFIED
|
||||
if (sample->rate<100) sample->rate=100;
|
||||
if (sample->rate>96000) sample->rate=96000;
|
||||
}
|
||||
|
@ -96,14 +99,14 @@ void FurnaceGUI::drawSampleEdit() {
|
|||
ImGui::Text("C-4 (Hz)");
|
||||
ImGui::SameLine();
|
||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||
if (ImGui::InputInt("##SampleCenter",&sample->centerRate,10,200)) {
|
||||
if (ImGui::InputInt("##SampleCenter",&sample->centerRate,10,200)) { MARK_MODIFIED
|
||||
if (sample->centerRate<100) sample->centerRate=100;
|
||||
if (sample->centerRate>65535) sample->centerRate=65535;
|
||||
}
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
bool doLoop=(sample->loopStart>=0);
|
||||
if (ImGui::Checkbox("Loop",&doLoop)) {
|
||||
if (ImGui::Checkbox("Loop",&doLoop)) { MARK_MODIFIED
|
||||
if (doLoop) {
|
||||
sample->loopStart=0;
|
||||
} else {
|
||||
|
@ -114,7 +117,7 @@ void FurnaceGUI::drawSampleEdit() {
|
|||
if (doLoop) {
|
||||
ImGui::SameLine();
|
||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||
if (ImGui::InputInt("##LoopPosition",&sample->loopStart,1,10)) {
|
||||
if (ImGui::InputInt("##LoopPosition",&sample->loopStart,1,10)) { MARK_MODIFIED
|
||||
if (sample->loopStart<0 || sample->loopStart>=(int)sample->samples) {
|
||||
sample->loopStart=0;
|
||||
}
|
||||
|
@ -161,13 +164,16 @@ void FurnaceGUI::drawSampleEdit() {
|
|||
if (resizeSize>16777215) resizeSize=16777215;
|
||||
}
|
||||
if (ImGui::Button("Resize")) {
|
||||
e->synchronized([this,sample]() {
|
||||
e->lockEngine([this,sample]() {
|
||||
if (!sample->resize(resizeSize)) {
|
||||
showError("couldn't resize! make sure your sample is 8 or 16-bit.");
|
||||
}
|
||||
e->renderSamples();
|
||||
});
|
||||
updateSampleTex=true;
|
||||
sampleSelStart=-1;
|
||||
sampleSelEnd=-1;
|
||||
MARK_MODIFIED;
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
ImGui::EndPopup();
|
||||
|
@ -208,13 +214,16 @@ void FurnaceGUI::drawSampleEdit() {
|
|||
}
|
||||
ImGui::Combo("Filter",&resampleStrat,resampleStrats,6);
|
||||
if (ImGui::Button("Resample")) {
|
||||
e->synchronized([this,sample]() {
|
||||
e->lockEngine([this,sample]() {
|
||||
if (!sample->resample(resampleTarget,resampleStrat)) {
|
||||
showError("couldn't resample! make sure your sample is 8 or 16-bit.");
|
||||
}
|
||||
e->renderSamples();
|
||||
});
|
||||
updateSampleTex=true;
|
||||
sampleSelStart=-1;
|
||||
sampleSelEnd=-1;
|
||||
MARK_MODIFIED;
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
ImGui::EndPopup();
|
||||
|
@ -237,7 +246,7 @@ void FurnaceGUI::drawSampleEdit() {
|
|||
ImGui::SameLine();
|
||||
ImGui::Text("(%.1fdB)",20.0*log10(amplifyVol/100.0f));
|
||||
if (ImGui::Button("Apply")) {
|
||||
e->synchronized([this,sample]() {
|
||||
e->lockEngine([this,sample]() {
|
||||
SAMPLE_OP_BEGIN;
|
||||
float vol=amplifyVol/100.0f;
|
||||
|
||||
|
@ -261,59 +270,61 @@ void FurnaceGUI::drawSampleEdit() {
|
|||
|
||||
e->renderSamples();
|
||||
});
|
||||
MARK_MODIFIED;
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button(ICON_FA_ARROWS_V "##SNormalize")) {
|
||||
e->synchronized([this,sample]() {
|
||||
SAMPLE_OP_BEGIN;
|
||||
float maxVal=0.0f;
|
||||
e->lockEngine([this,sample]() {
|
||||
SAMPLE_OP_BEGIN;
|
||||
float maxVal=0.0f;
|
||||
|
||||
if (sample->depth==16) {
|
||||
for (unsigned int i=start; i<end; i++) {
|
||||
float val=fabs((float)sample->data16[i]/32767.0f);
|
||||
if (val>maxVal) maxVal=val;
|
||||
}
|
||||
if (maxVal>1.0f) maxVal=1.0f;
|
||||
if (maxVal>0.0f) {
|
||||
float vol=1.0f/maxVal;
|
||||
if (sample->depth==16) {
|
||||
for (unsigned int i=start; i<end; i++) {
|
||||
float val=sample->data16[i]*vol;
|
||||
if (val<-32768) val=-32768;
|
||||
if (val>32767) val=32767;
|
||||
sample->data16[i]=val;
|
||||
float val=fabs((float)sample->data16[i]/32767.0f);
|
||||
if (val>maxVal) maxVal=val;
|
||||
}
|
||||
if (maxVal>1.0f) maxVal=1.0f;
|
||||
if (maxVal>0.0f) {
|
||||
float vol=1.0f/maxVal;
|
||||
for (unsigned int i=start; i<end; i++) {
|
||||
float val=sample->data16[i]*vol;
|
||||
if (val<-32768) val=-32768;
|
||||
if (val>32767) val=32767;
|
||||
sample->data16[i]=val;
|
||||
}
|
||||
}
|
||||
} else if (sample->depth==8) {
|
||||
for (unsigned int i=start; i<end; i++) {
|
||||
float val=fabs((float)sample->data8[i]/127.0f);
|
||||
if (val>maxVal) maxVal=val;
|
||||
}
|
||||
if (maxVal>1.0f) maxVal=1.0f;
|
||||
if (maxVal>0.0f) {
|
||||
float vol=1.0f/maxVal;
|
||||
for (unsigned int i=start; i<end; i++) {
|
||||
float val=sample->data8[i]*vol;
|
||||
if (val<-128) val=-128;
|
||||
if (val>127) val=127;
|
||||
sample->data8[i]=val;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (sample->depth==8) {
|
||||
for (unsigned int i=start; i<end; i++) {
|
||||
float val=fabs((float)sample->data8[i]/127.0f);
|
||||
if (val>maxVal) maxVal=val;
|
||||
}
|
||||
if (maxVal>1.0f) maxVal=1.0f;
|
||||
if (maxVal>0.0f) {
|
||||
float vol=1.0f/maxVal;
|
||||
for (unsigned int i=start; i<end; i++) {
|
||||
float val=sample->data8[i]*vol;
|
||||
if (val<-128) val=-128;
|
||||
if (val>127) val=127;
|
||||
sample->data8[i]=val;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
updateSampleTex=true;
|
||||
updateSampleTex=true;
|
||||
|
||||
e->renderSamples();
|
||||
});
|
||||
e->renderSamples();
|
||||
});
|
||||
MARK_MODIFIED;
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Normalize");
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button(ICON_FA_ARROW_UP "##SFadeIn")) {
|
||||
e->synchronized([this,sample]() {
|
||||
e->lockEngine([this,sample]() {
|
||||
SAMPLE_OP_BEGIN;
|
||||
|
||||
if (sample->depth==16) {
|
||||
|
@ -336,13 +347,14 @@ void FurnaceGUI::drawSampleEdit() {
|
|||
|
||||
e->renderSamples();
|
||||
});
|
||||
MARK_MODIFIED;
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Fade in");
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button(ICON_FA_ARROW_DOWN "##SFadeOut")) {
|
||||
e->synchronized([this,sample]() {
|
||||
e->lockEngine([this,sample]() {
|
||||
SAMPLE_OP_BEGIN;
|
||||
|
||||
if (sample->depth==16) {
|
||||
|
@ -365,13 +377,14 @@ void FurnaceGUI::drawSampleEdit() {
|
|||
|
||||
e->renderSamples();
|
||||
});
|
||||
MARK_MODIFIED;
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Fade out");
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button(ICON_FA_ERASER "##SSilence")) {
|
||||
e->synchronized([this,sample]() {
|
||||
e->lockEngine([this,sample]() {
|
||||
SAMPLE_OP_BEGIN;
|
||||
|
||||
if (sample->depth==16) {
|
||||
|
@ -388,13 +401,14 @@ void FurnaceGUI::drawSampleEdit() {
|
|||
|
||||
e->renderSamples();
|
||||
});
|
||||
MARK_MODIFIED;
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Apply silence");
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button(ICON_FA_TIMES "##SDelete")) {
|
||||
e->synchronized([this,sample]() {
|
||||
e->lockEngine([this,sample]() {
|
||||
SAMPLE_OP_BEGIN;
|
||||
|
||||
sample->strip(start,end);
|
||||
|
@ -404,13 +418,14 @@ void FurnaceGUI::drawSampleEdit() {
|
|||
});
|
||||
sampleSelStart=-1;
|
||||
sampleSelEnd=-1;
|
||||
MARK_MODIFIED;
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Delete");
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button(ICON_FA_CROP "##STrim")) {
|
||||
e->synchronized([this,sample]() {
|
||||
e->lockEngine([this,sample]() {
|
||||
SAMPLE_OP_BEGIN;
|
||||
|
||||
sample->trim(start,end);
|
||||
|
@ -420,6 +435,7 @@ void FurnaceGUI::drawSampleEdit() {
|
|||
});
|
||||
sampleSelStart=-1;
|
||||
sampleSelEnd=-1;
|
||||
MARK_MODIFIED;
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Trim");
|
||||
|
@ -428,7 +444,7 @@ void FurnaceGUI::drawSampleEdit() {
|
|||
ImGui::Dummy(ImVec2(4.0*dpiScale,dpiScale));
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button(ICON_FA_BACKWARD "##SReverse")) {
|
||||
e->synchronized([this,sample]() {
|
||||
e->lockEngine([this,sample]() {
|
||||
SAMPLE_OP_BEGIN;
|
||||
|
||||
if (sample->depth==16) {
|
||||
|
@ -453,13 +469,14 @@ void FurnaceGUI::drawSampleEdit() {
|
|||
|
||||
e->renderSamples();
|
||||
});
|
||||
MARK_MODIFIED;
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Reverse");
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button(ICON_FA_SORT_AMOUNT_ASC "##SInvert")) {
|
||||
e->synchronized([this,sample]() {
|
||||
e->lockEngine([this,sample]() {
|
||||
SAMPLE_OP_BEGIN;
|
||||
|
||||
if (sample->depth==16) {
|
||||
|
@ -478,13 +495,14 @@ void FurnaceGUI::drawSampleEdit() {
|
|||
|
||||
e->renderSamples();
|
||||
});
|
||||
MARK_MODIFIED;
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Invert");
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button(ICON_FA_LEVEL_DOWN "##SSign")) {
|
||||
e->synchronized([this,sample]() {
|
||||
e->lockEngine([this,sample]() {
|
||||
SAMPLE_OP_BEGIN;
|
||||
|
||||
if (sample->depth==16) {
|
||||
|
@ -501,6 +519,7 @@ void FurnaceGUI::drawSampleEdit() {
|
|||
|
||||
e->renderSamples();
|
||||
});
|
||||
MARK_MODIFIED;
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Signed/unsigned exchange");
|
||||
|
@ -561,7 +580,7 @@ void FurnaceGUI::drawSampleEdit() {
|
|||
}
|
||||
|
||||
if (ImGui::Button("Apply")) {
|
||||
e->synchronized([this,sample]() {
|
||||
e->lockEngine([this,sample]() {
|
||||
SAMPLE_OP_BEGIN;
|
||||
float res=1.0-pow(sampleFilterRes,0.5f);
|
||||
float low=0;
|
||||
|
@ -608,6 +627,7 @@ void FurnaceGUI::drawSampleEdit() {
|
|||
|
||||
e->renderSamples();
|
||||
});
|
||||
MARK_MODIFIED;
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
ImGui::EndPopup();
|
||||
|
|
Loading…
Reference in New Issue