parent
0a114b1168
commit
1003d9fcb8
8 changed files with 223 additions and 104 deletions
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue