From 5a08e0d230786dc8442a624c1e2c552a611b16b1 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Wed, 23 Mar 2022 15:50:18 -0500 Subject: [PATCH 1/6] OPLL: add patch macro --- src/engine/platform/opll.cpp | 7 +++++++ src/gui/insEdit.cpp | 11 ++++++++--- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/engine/platform/opll.cpp b/src/engine/platform/opll.cpp index fd1d61d62..4f21ba212 100644 --- a/src/engine/platform/opll.cpp +++ b/src/engine/platform/opll.cpp @@ -138,6 +138,13 @@ void DivPlatformOPLL::tick() { } } + if (chan[i].std.hadWave && chan[i].state.opllPreset!=16) { + chan[i].state.opllPreset=chan[i].std.wave; + if (i<9) { + rWrite(0x30+i,((15-(chan[i].outVol*(15-chan[i].state.op[1].tl))/15)&15)|(chan[i].state.opllPreset<<4)); + } + } + if (chan[i].state.opllPreset==0) { if (chan[i].std.hadAlg) { // SUS chan[i].state.alg=chan[i].std.alg; diff --git a/src/gui/insEdit.cpp b/src/gui/insEdit.cpp index 21e7534bc..d77a4632e 100644 --- a/src/gui/insEdit.cpp +++ b/src/gui/insEdit.cpp @@ -1603,22 +1603,27 @@ void FurnaceGUI::drawInsEdit() { } bool dutyIsRel=(ins->type==DIV_INS_C64 && !ins->c64.dutyIsAbs); + const char* waveLabel="Waveform"; int waveMax=(ins->type==DIV_INS_AY || ins->type==DIV_INS_AY8930 || ins->type==DIV_INS_VERA)?3:63; bool bitMode=false; if (ins->type==DIV_INS_C64 || ins->type==DIV_INS_AY || ins->type==DIV_INS_AY8930 || ins->type==DIV_INS_SAA1099) { bitMode=true; } if (ins->type==DIV_INS_STD) waveMax=0; - if (ins->type==DIV_INS_TIA || ins->type==DIV_INS_VIC) waveMax=15; + if (ins->type==DIV_INS_TIA || ins->type==DIV_INS_VIC || ins->type==DIV_INS_OPLL) waveMax=15; if (ins->type==DIV_INS_C64) waveMax=4; if (ins->type==DIV_INS_SAA1099) waveMax=2; - if (ins->type==DIV_INS_FM || ins->type==DIV_INS_OPLL || ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPZ) waveMax=0; + if (ins->type==DIV_INS_FM || ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPZ) waveMax=0; if (ins->type==DIV_INS_MIKEY) waveMax=0; if (ins->type==DIV_INS_PET) { waveMax=8; bitMode=true; } + if (ins->type==DIV_INS_OPLL) { + waveLabel="Patch"; + } + const char** waveNames=NULL; if (ins->type==DIV_INS_AY || ins->type==DIV_INS_AY8930 || ins->type==DIV_INS_SAA1099) waveNames=ayShapeBits; if (ins->type==DIV_INS_C64) waveNames=c64ShapeBits; @@ -1654,7 +1659,7 @@ void FurnaceGUI::drawInsEdit() { } } if (waveMax>0) { - NORMAL_MACRO(ins->std.waveMacro,ins->std.waveMacroLen,ins->std.waveMacroLoop,ins->std.waveMacroRel,0,waveMax,"wave","Waveform",bitMode?64:160,ins->std.waveMacroOpen,bitMode,waveNames,false,NULL,0,0,((ins->type==DIV_INS_AY || ins->type==DIV_INS_AY8930)?1:0),NULL,uiColors[GUI_COLOR_MACRO_WAVE],mmlString[3],0,waveMax,NULL,false); + NORMAL_MACRO(ins->std.waveMacro,ins->std.waveMacroLen,ins->std.waveMacroLoop,ins->std.waveMacroRel,0,waveMax,"wave",waveLabel,bitMode?64:160,ins->std.waveMacroOpen,bitMode,waveNames,false,NULL,0,0,((ins->type==DIV_INS_AY || ins->type==DIV_INS_AY8930)?1:0),NULL,uiColors[GUI_COLOR_MACRO_WAVE],mmlString[3],0,waveMax,NULL,false); } if (ex1Max>0) { if (ins->type==DIV_INS_C64) { From 6492eeff569542aac183bb21a673ebdbca5dbbc8 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Wed, 23 Mar 2022 16:39:08 -0500 Subject: [PATCH 2/6] GUI: proper sample errors --- src/engine/engine.cpp | 10 ++++++---- src/engine/engine.h | 2 +- src/gui/gui.cpp | 7 +++++-- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp index fb11f1df6..a634bd3c2 100644 --- a/src/engine/engine.cpp +++ b/src/engine/engine.cpp @@ -2142,18 +2142,20 @@ int DivEngine::addSample() { return sampleCount; } -bool DivEngine::addSampleFromFile(const char* path) { +int DivEngine::addSampleFromFile(const char* path) { isBusy.lock(); SF_INFO si; SNDFILE* f=sf_open(path,SFM_READ,&si); if (f==NULL) { isBusy.unlock(); - return false; + lastError=fmt::sprintf("could not open file! (%s)",sf_error_number(sf_error(NULL))); + return -1; } - if (si.frames>1000000) { + if (si.frames>16777215) { + lastError="this sample is too big! max sample size is 16777215."; sf_close(f); isBusy.unlock(); - return false; + return -1; } short* buf=new short[si.channels*si.frames]; if (sf_readf_short(f,buf,si.frames)!=si.frames) { diff --git a/src/engine/engine.h b/src/engine/engine.h index 911a33c7c..af4793324 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -489,7 +489,7 @@ class DivEngine { int addSample(); // add sample from file - bool addSampleFromFile(const char* path); + int addSampleFromFile(const char* path); // delete sample void delSample(int index); diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp index 9f869e57d..7cbf10970 100644 --- a/src/gui/gui.cpp +++ b/src/gui/gui.cpp @@ -2269,8 +2269,11 @@ bool FurnaceGUI::loop() { } break; case GUI_FILE_SAMPLE_OPEN: - e->addSampleFromFile(copyOfName.c_str()); - MARK_MODIFIED; + if (e->addSampleFromFile(copyOfName.c_str())==-1) { + showError(e->getLastError()); + } else { + MARK_MODIFIED; + } break; case GUI_FILE_SAMPLE_SAVE: if (curSample>=0 && curSample<(int)e->song.sample.size()) { From 11d9ce3f87c97582536a7ea25d74d9c2ddfe5d1d Mon Sep 17 00:00:00 2001 From: tildearrow Date: Wed, 23 Mar 2022 17:00:40 -0500 Subject: [PATCH 3/6] what is going on --- src/engine/engine.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp index a634bd3c2..bb027ab63 100644 --- a/src/engine/engine.cpp +++ b/src/engine/engine.cpp @@ -2148,7 +2148,12 @@ int DivEngine::addSampleFromFile(const char* path) { SNDFILE* f=sf_open(path,SFM_READ,&si); if (f==NULL) { isBusy.unlock(); - lastError=fmt::sprintf("could not open file! (%s)",sf_error_number(sf_error(NULL))); + int err=sf_error(NULL); + if (err==SF_ERR_SYSTEM) { + lastError=fmt::sprintf("could not open file! (%s %s)",sf_error_number(err),strerror(errno)); + } else { + lastError=fmt::sprintf("could not open file! (%s)",sf_error_number(err)); + } return -1; } if (si.frames>16777215) { From 711b60d454009263e79fe50a7fdf2adae2053753 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Wed, 23 Mar 2022 21:38:28 -0500 Subject: [PATCH 4/6] improved mutex locking - less xruns when seeking especially in JACK and macOS --- src/engine/engine.cpp | 252 ++++++++++++++++++++-------------------- src/engine/engine.h | 5 + src/engine/fileOps.cpp | 12 +- src/engine/playback.cpp | 8 +- src/engine/vgmOps.cpp | 4 +- 5 files changed, 147 insertions(+), 134 deletions(-) diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp index bb027ab63..e0c149752 100644 --- a/src/engine/engine.cpp +++ b/src/engine/engine.cpp @@ -437,25 +437,25 @@ bool DivEngine::haltAudioFile() { } void DivEngine::notifyInsChange(int ins) { - isBusy.lock(); + BUSY_BEGIN; for (int i=0; inotifyInsChange(ins); } - isBusy.unlock(); + BUSY_END; } void DivEngine::notifyWaveChange(int wave) { - isBusy.lock(); + BUSY_BEGIN; for (int i=0; inotifyWaveChange(wave); } - isBusy.unlock(); + BUSY_END; } void DivEngine::renderSamplesP() { - isBusy.lock(); + BUSY_BEGIN; renderSamples(); - isBusy.unlock(); + BUSY_END; } void DivEngine::renderSamples() { @@ -583,7 +583,7 @@ void DivEngine::renderSamples() { void DivEngine::createNew(const int* description) { quitDispatch(); - isBusy.lock(); + BUSY_BEGIN; saveLock.lock(); song.unload(); song=DivSong(); @@ -604,27 +604,27 @@ void DivEngine::createNew(const int* description) { recalcChans(); renderSamples(); saveLock.unlock(); - isBusy.unlock(); + BUSY_END; initDispatch(); - isBusy.lock(); + BUSY_BEGIN; reset(); - isBusy.unlock(); + BUSY_END; } void DivEngine::changeSystem(int index, DivSystem which) { quitDispatch(); - isBusy.lock(); + BUSY_BEGIN; saveLock.lock(); song.system[index]=which; song.systemFlags[index]=0; recalcChans(); saveLock.unlock(); - isBusy.unlock(); + BUSY_END; initDispatch(); - isBusy.lock(); + BUSY_BEGIN; renderSamples(); reset(); - isBusy.unlock(); + BUSY_END; } bool DivEngine::addSystem(DivSystem which) { @@ -638,7 +638,7 @@ bool DivEngine::addSystem(DivSystem which) { return false; } quitDispatch(); - isBusy.lock(); + BUSY_BEGIN; saveLock.lock(); song.system[song.systemLen]=which; song.systemVol[song.systemLen]=64; @@ -646,12 +646,12 @@ bool DivEngine::addSystem(DivSystem which) { song.systemFlags[song.systemLen++]=0; recalcChans(); saveLock.unlock(); - isBusy.unlock(); + BUSY_END; initDispatch(); - isBusy.lock(); + BUSY_BEGIN; renderSamples(); reset(); - isBusy.unlock(); + BUSY_END; return true; } @@ -665,7 +665,7 @@ bool DivEngine::removeSystem(int index) { return false; } quitDispatch(); - isBusy.lock(); + BUSY_BEGIN; saveLock.lock(); song.system[index]=DIV_SYSTEM_NULL; song.systemLen--; @@ -674,27 +674,27 @@ bool DivEngine::removeSystem(int index) { } recalcChans(); saveLock.unlock(); - isBusy.unlock(); + BUSY_END; initDispatch(); - isBusy.lock(); + BUSY_BEGIN; renderSamples(); reset(); - isBusy.unlock(); + BUSY_END; return true; } void DivEngine::poke(int sys, unsigned int addr, unsigned short val) { if (sys<0 || sys>=song.systemLen) return; - isBusy.lock(); + BUSY_BEGIN; disCont[sys].dispatch->poke(addr,val); - isBusy.unlock(); + BUSY_END; } void DivEngine::poke(int sys, std::vector& wlist) { if (sys<0 || sys>=song.systemLen) return; - isBusy.lock(); + BUSY_BEGIN; disCont[sys].dispatch->poke(wlist); - isBusy.unlock(); + BUSY_END; } String DivEngine::getLastError() { @@ -753,13 +753,13 @@ void DivEngine::enableCommandStream(bool enable) { } void DivEngine::getCommandStream(std::vector& where) { - isBusy.lock(); + BUSY_BEGIN; where.clear(); for (DivCommand& i: cmdStream) { where.push_back(i); } cmdStream.clear(); - isBusy.unlock(); + BUSY_END; } void DivEngine::playSub(bool preserveDrift, int goalRow) { @@ -834,7 +834,7 @@ int DivEngine::calcFreq(int base, int pitch, bool period, int octave) { } void DivEngine::play() { - isBusy.lock(); + BUSY_BEGIN_SOFT; sPreview.sample=-1; sPreview.wave=-1; sPreview.pos=0; @@ -847,11 +847,11 @@ void DivEngine::play() { for (int i=0; inotifyPlaybackStop(); } - isBusy.unlock(); + BUSY_END; } void DivEngine::halt() { - isBusy.lock(); + BUSY_BEGIN; halted=true; - isBusy.unlock(); + BUSY_END; } void DivEngine::resume() { - isBusy.lock(); + BUSY_BEGIN; halted=false; haltOn=DIV_HALT_NONE; - isBusy.unlock(); + BUSY_END; } void DivEngine::haltWhen(DivHaltPositions when) { - isBusy.lock(); + BUSY_BEGIN; halted=false; haltOn=when; - isBusy.unlock(); + BUSY_END; } bool DivEngine::isHalted() { @@ -966,9 +968,9 @@ void DivEngine::reset() { } void DivEngine::syncReset() { - isBusy.lock(); + BUSY_BEGIN; reset(); - isBusy.unlock(); + BUSY_END; } const int sampleRates[6]={ @@ -1024,11 +1026,11 @@ int DivEngine::getEffectiveSampleRate(int rate) { } void DivEngine::previewSample(int sample, int note) { - isBusy.lock(); + BUSY_BEGIN; if (sample<0 || sample>=(int)song.sample.size()) { sPreview.sample=-1; sPreview.pos=0; - isBusy.unlock(); + BUSY_END; return; } blip_clear(samp_bb); @@ -1043,26 +1045,26 @@ void DivEngine::previewSample(int sample, int note) { sPreview.pos=0; sPreview.sample=sample; sPreview.wave=-1; - isBusy.unlock(); + BUSY_END; } void DivEngine::stopSamplePreview() { - isBusy.lock(); + BUSY_BEGIN; sPreview.sample=-1; sPreview.pos=0; - isBusy.unlock(); + BUSY_END; } void DivEngine::previewWave(int wave, int note) { - isBusy.lock(); + BUSY_BEGIN; if (wave<0 || wave>=(int)song.wave.size()) { sPreview.wave=-1; sPreview.pos=0; - isBusy.unlock(); + BUSY_END; return; } if (song.wave[wave]->len<=0) { - isBusy.unlock(); + BUSY_END; return; } blip_clear(samp_bb); @@ -1073,14 +1075,14 @@ void DivEngine::previewWave(int wave, int note) { sPreview.pos=0; sPreview.sample=-1; sPreview.wave=wave; - isBusy.unlock(); + BUSY_END; } void DivEngine::stopWavePreview() { - isBusy.lock(); + BUSY_BEGIN; sPreview.wave=-1; sPreview.pos=0; - isBusy.unlock(); + BUSY_END; } String DivEngine::getConfigPath() { @@ -1135,9 +1137,9 @@ bool DivEngine::getRepeatPattern() { } void DivEngine::setRepeatPattern(bool value) { - isBusy.lock(); + BUSY_BEGIN; repeatPattern=value; - isBusy.unlock(); + BUSY_END; } bool DivEngine::hasExtValue() { @@ -1177,7 +1179,7 @@ void DivEngine::toggleSolo(int chan) { } } } - isBusy.lock(); + BUSY_BEGIN; if (!solo) { for (int i=0; imuteChannel(dispatchChanOfChan[chan],isMuted[chan]); } - isBusy.unlock(); + BUSY_END; } void DivEngine::unmuteAll() { - isBusy.lock(); + BUSY_BEGIN; for (int i=0; imuteChannel(dispatchChanOfChan[i],isMuted[i]); } } - isBusy.unlock(); + BUSY_END; } int DivEngine::addInstrument(int refChan) { - isBusy.lock(); + BUSY_BEGIN; DivInstrument* ins=new DivInstrument; int insCount=(int)song.ins.size(); ins->name=fmt::sprintf("Instrument %d",insCount); @@ -1226,7 +1228,7 @@ int DivEngine::addInstrument(int refChan) { song.ins.push_back(ins); song.insLen=insCount+1; saveLock.unlock(); - isBusy.unlock(); + BUSY_END; return insCount; } @@ -1949,18 +1951,18 @@ bool DivEngine::addInstrumentFromFile(const char* path) { } } - isBusy.lock(); + BUSY_BEGIN; saveLock.lock(); int insCount=(int)song.ins.size(); song.ins.push_back(ins); song.insLen=insCount+1; saveLock.unlock(); - isBusy.unlock(); + BUSY_END; return true; } void DivEngine::delInstrument(int index) { - isBusy.lock(); + BUSY_BEGIN; saveLock.lock(); if (index>=0 && index<(int)song.ins.size()) { for (int i=0; i=0 && index<(int)song.wave.size()) { delete song.wave[index]; @@ -2125,11 +2127,11 @@ void DivEngine::delWave(int index) { song.waveLen=song.wave.size(); } saveLock.unlock(); - isBusy.unlock(); + BUSY_END; } int DivEngine::addSample() { - isBusy.lock(); + BUSY_BEGIN; saveLock.lock(); DivSample* sample=new DivSample; int sampleCount=(int)song.sample.size(); @@ -2138,16 +2140,16 @@ int DivEngine::addSample() { song.sampleLen=sampleCount+1; saveLock.unlock(); renderSamples(); - isBusy.unlock(); + BUSY_END; return sampleCount; } int DivEngine::addSampleFromFile(const char* path) { - isBusy.lock(); + BUSY_BEGIN; SF_INFO si; SNDFILE* f=sf_open(path,SFM_READ,&si); if (f==NULL) { - isBusy.unlock(); + BUSY_END; int err=sf_error(NULL); if (err==SF_ERR_SYSTEM) { lastError=fmt::sprintf("could not open file! (%s %s)",sf_error_number(err),strerror(errno)); @@ -2159,7 +2161,7 @@ int DivEngine::addSampleFromFile(const char* path) { if (si.frames>16777215) { lastError="this sample is too big! max sample size is 16777215."; sf_close(f); - isBusy.unlock(); + BUSY_END; return -1; } short* buf=new short[si.channels*si.frames]; @@ -2226,12 +2228,12 @@ int DivEngine::addSampleFromFile(const char* path) { song.sampleLen=sampleCount+1; saveLock.unlock(); renderSamples(); - isBusy.unlock(); + BUSY_END; return sampleCount; } void DivEngine::delSample(int index) { - isBusy.lock(); + BUSY_BEGIN; saveLock.lock(); if (index>=0 && index<(int)song.sample.size()) { delete song.sample[index]; @@ -2240,13 +2242,13 @@ void DivEngine::delSample(int index) { renderSamples(); } saveLock.unlock(); - isBusy.unlock(); + BUSY_END; } void DivEngine::addOrder(bool duplicate, bool where) { unsigned char order[DIV_MAX_CHANS]; if (song.ordersLen>=0x7e) return; - isBusy.lock(); + BUSY_BEGIN_SOFT; if (duplicate) { for (int i=0; i=0x7e) return; warnings=""; - isBusy.lock(); + BUSY_BEGIN_SOFT; for (int i=0; i=song.ordersLen-1) { - isBusy.unlock(); + BUSY_END; return; } saveLock.lock(); @@ -2399,7 +2401,7 @@ void DivEngine::moveOrderDown() { if (playing && !freelance) { playSub(false); } - isBusy.unlock(); + BUSY_END; } void DivEngine::exchangeIns(int one, int two) { @@ -2419,114 +2421,114 @@ void DivEngine::exchangeIns(int one, int two) { bool DivEngine::moveInsUp(int which) { if (which<1 || which>=(int)song.ins.size()) return false; - isBusy.lock(); + BUSY_BEGIN; 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(); + BUSY_END; return true; } bool DivEngine::moveWaveUp(int which) { if (which<1 || which>=(int)song.wave.size()) return false; - isBusy.lock(); + BUSY_BEGIN; DivWavetable* prev=song.wave[which]; saveLock.lock(); song.wave[which]=song.wave[which-1]; song.wave[which-1]=prev; saveLock.unlock(); - isBusy.unlock(); + BUSY_END; return true; } bool DivEngine::moveSampleUp(int which) { if (which<1 || which>=(int)song.sample.size()) return false; - isBusy.lock(); + BUSY_BEGIN; DivSample* prev=song.sample[which]; saveLock.lock(); song.sample[which]=song.sample[which-1]; song.sample[which-1]=prev; saveLock.unlock(); - isBusy.unlock(); + BUSY_END; return true; } bool DivEngine::moveInsDown(int which) { if (which<0 || which>=((int)song.ins.size())-1) return false; - isBusy.lock(); + BUSY_BEGIN; 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(); + BUSY_END; return true; } bool DivEngine::moveWaveDown(int which) { if (which<0 || which>=((int)song.wave.size())-1) return false; - isBusy.lock(); + BUSY_BEGIN; DivWavetable* prev=song.wave[which]; saveLock.lock(); song.wave[which]=song.wave[which+1]; song.wave[which+1]=prev; saveLock.unlock(); - isBusy.unlock(); + BUSY_END; return true; } bool DivEngine::moveSampleDown(int which) { if (which<0 || which>=((int)song.sample.size())-1) return false; - isBusy.lock(); + BUSY_BEGIN; DivSample* prev=song.sample[which]; saveLock.lock(); song.sample[which]=song.sample[which+1]; song.sample[which+1]=prev; saveLock.unlock(); - isBusy.unlock(); + BUSY_END; return true; } void DivEngine::noteOn(int chan, int ins, int note, int vol) { if (chan<0 || chan>=chans) return; - isBusy.lock(); + BUSY_BEGIN; pendingNotes.push(DivNoteEvent(chan,ins,note,vol,true)); if (!playing) { reset(); freelance=true; playing=true; } - isBusy.unlock(); + BUSY_END; } void DivEngine::noteOff(int chan) { if (chan<0 || chan>=chans) return; - isBusy.lock(); + BUSY_BEGIN; pendingNotes.push(DivNoteEvent(chan,-1,-1,-1,false)); if (!playing) { reset(); freelance=true; playing=true; } - isBusy.unlock(); + BUSY_END; } void DivEngine::setOrder(unsigned char order) { - isBusy.lock(); + BUSY_BEGIN_SOFT; curOrder=order; if (order>=song.ordersLen) curOrder=0; if (playing && !freelance) { playSub(false); } - isBusy.unlock(); + BUSY_END; } void DivEngine::setSysFlags(int system, unsigned int flags, bool restart) { - isBusy.lock(); + BUSY_BEGIN_SOFT; saveLock.lock(); song.systemFlags[system]=flags; saveLock.unlock(); @@ -2535,11 +2537,11 @@ void DivEngine::setSysFlags(int system, unsigned int flags, bool restart) { if (restart && isPlaying()) { playSub(false); } - isBusy.unlock(); + BUSY_END; } void DivEngine::setSongRate(float hz, bool pal) { - isBusy.lock(); + BUSY_BEGIN; saveLock.lock(); song.pal=!pal; song.hz=hz; @@ -2556,7 +2558,7 @@ void DivEngine::setSongRate(float hz, bool pal) { } } saveLock.unlock(); - isBusy.unlock(); + BUSY_END; } void DivEngine::setAudio(DivAudioEngines which) { @@ -2600,9 +2602,9 @@ bool DivEngine::switchMaster() { } void DivEngine::synchronized(const std::function& what) { - isBusy.lock(); + BUSY_BEGIN; what(); - isBusy.unlock(); + BUSY_END; } void DivEngine::lockSave(const std::function& what) { @@ -2612,11 +2614,11 @@ void DivEngine::lockSave(const std::function& what) { } void DivEngine::lockEngine(const std::function& what) { - isBusy.lock(); + BUSY_BEGIN; saveLock.lock(); what(); saveLock.unlock(); - isBusy.unlock(); + BUSY_END; } TAAudioDesc& DivEngine::getAudioDescWant() { @@ -2639,18 +2641,18 @@ void DivEngine::rescanAudioDevices() { } void DivEngine::initDispatch() { - isBusy.lock(); + BUSY_BEGIN; for (int i=0; i=0 && sPreview.sample<(int)song.sample.size()) || (sPreview.wave>=0 && sPreview.wave<(int)song.wave.size()))) { diff --git a/src/engine/vgmOps.cpp b/src/engine/vgmOps.cpp index 6133fff62..c2356dbcd 100644 --- a/src/engine/vgmOps.cpp +++ b/src/engine/vgmOps.cpp @@ -477,7 +477,7 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop) { stop(); repeatPattern=false; setOrder(0); - isBusy.lock(); + BUSY_BEGIN_SOFT; double origRate=got.rate; got.rate=44100; // determine loop point @@ -1305,6 +1305,6 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop) { logI("%d register writes total.\n",writeCount); - isBusy.unlock(); + BUSY_END; return w; } From 47d7722f6e6fc5248db0698c174845602367b0ec Mon Sep 17 00:00:00 2001 From: tildearrow Date: Wed, 23 Mar 2022 22:05:09 -0500 Subject: [PATCH 5/6] add a new log level (trace) --- src/engine/engine.h | 3 +++ src/engine/playback.cpp | 1 + src/log.cpp | 18 ++++++++++++++++++ src/main.cpp | 6 ++++-- src/ta-log.h | 2 ++ 5 files changed, 28 insertions(+), 2 deletions(-) diff --git a/src/engine/engine.h b/src/engine/engine.h index 7c8c90976..1aa2b0c53 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -190,6 +190,7 @@ class DivEngine { bool forceMono; bool cmdStreamEnabled; bool softLocked; + int softLockCount; int ticks, curRow, curOrder, remainingLoops, nextSpeed; double divider; int cycles; @@ -681,6 +682,8 @@ class DivEngine { halted(false), forceMono(false), cmdStreamEnabled(false), + softLocked(0), + softLockCount(0), ticks(0), curRow(0), curOrder(0), diff --git a/src/engine/playback.cpp b/src/engine/playback.cpp index 5443faa51..1d7f24175 100644 --- a/src/engine/playback.cpp +++ b/src/engine/playback.cpp @@ -1410,6 +1410,7 @@ void DivEngine::nextBuf(float** in, float** out, int inChans, int outChans, unsi if (softLocked) { if (!isBusy.try_lock()) { + logV("audio is soft-locked (%d)\n",softLockCount++); return; } } else { diff --git a/src/log.cpp b/src/log.cpp index c8dd030e7..1f77925b4 100644 --- a/src/log.cpp +++ b/src/log.cpp @@ -17,10 +17,28 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +// TODO: improve these routines to allow logging to memory for eventual log window! + #include "ta-log.h" int logLevel=LOGLEVEL_INFO; +int logV(const char* format, ...) { + va_list va; + int ret; + if (logLevel Date: Wed, 23 Mar 2022 22:16:25 -0500 Subject: [PATCH 6/6] YM2151: implement song tuning --- src/engine/platform/arcade.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/engine/platform/arcade.cpp b/src/engine/platform/arcade.cpp index 0f13be178..1eb950183 100644 --- a/src/engine/platform/arcade.cpp +++ b/src/engine/platform/arcade.cpp @@ -52,6 +52,8 @@ static int orderedOps[4]={ #define rWrite(a,v) if (!skipRegisterWrites) {pendingWrites[a]=v;} #define immWrite(a,v) if (!skipRegisterWrites) {writes.emplace(a,v); if (dumpWrites) {addWrite(a,v);} } +#define NOTE_LINEAR(x) (((x)<<6)+baseFreqOff+log2(parent->song.tuning/440.0)*12.0*64.0) + const char* regCheatSheetOPM[]={ "Test", "00", "NoteCtl", "08", @@ -234,15 +236,15 @@ void DivPlatformArcade::tick() { if (chan[i].std.hadArp) { if (!chan[i].inPorta) { if (chan[i].std.arpMode) { - chan[i].baseFreq=(chan[i].std.arp<<6)+baseFreqOff; + chan[i].baseFreq=NOTE_LINEAR(chan[i].std.arp); } else { - chan[i].baseFreq=((chan[i].note+(signed char)chan[i].std.arp)<<6)+baseFreqOff; + chan[i].baseFreq=NOTE_LINEAR(chan[i].note+(signed char)chan[i].std.arp); } } chan[i].freqChanged=true; } else { if (chan[i].std.arpMode && chan[i].std.finishedArp) { - chan[i].baseFreq=(chan[i].note<<6)+baseFreqOff; + chan[i].baseFreq=NOTE_LINEAR(chan[i].note); chan[i].freqChanged=true; } } @@ -446,7 +448,7 @@ int DivPlatformArcade::dispatch(DivCommand c) { chan[c.chan].insChanged=false; if (c.value!=DIV_NOTE_NULL) { - chan[c.chan].baseFreq=(c.value<<6)+baseFreqOff; + chan[c.chan].baseFreq=NOTE_LINEAR(c.value); chan[c.chan].note=c.value; chan[c.chan].freqChanged=true; } @@ -510,7 +512,7 @@ int DivPlatformArcade::dispatch(DivCommand c) { break; } case DIV_CMD_NOTE_PORTA: { - int destFreq=(c.value2<<6)+baseFreqOff; + int destFreq=NOTE_LINEAR(c.value2); int newFreq; bool return2=false; if (destFreq>chan[c.chan].baseFreq) { @@ -535,7 +537,7 @@ int DivPlatformArcade::dispatch(DivCommand c) { break; } case DIV_CMD_LEGATO: { - chan[c.chan].baseFreq=(c.value<<6)+baseFreqOff; + chan[c.chan].baseFreq=NOTE_LINEAR(c.value); chan[c.chan].freqChanged=true; break; }