diff --git a/src/engine/engine.h b/src/engine/engine.h index 25add2069..f94cb3e1f 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -197,6 +197,10 @@ struct DivDispatchContainer { bool lowQuality, dcOffCompensation; double rateMemory; + // used in multi-thread + int cycles; + unsigned int size; + void setRates(double gotRate); void setQuality(bool lowQual); void grow(size_t size); @@ -215,7 +219,9 @@ struct DivDispatchContainer { lastAvail(0), lowQuality(false), dcOffCompensation(false), - rateMemory(0.0) { + rateMemory(0.0), + cycles(0), + size(0) { memset(bb,0,DIV_MAX_OUTPUTS*sizeof(blip_buffer_t*)); memset(temp,0,DIV_MAX_OUTPUTS*sizeof(int)); memset(prevSample,0,DIV_MAX_OUTPUTS*sizeof(int)); diff --git a/src/engine/playback.cpp b/src/engine/playback.cpp index 5f06d31aa..1cb7b62d8 100644 --- a/src/engine/playback.cpp +++ b/src/engine/playback.cpp @@ -1760,6 +1760,13 @@ void DivEngine::runMidiTime(int totalCycles) { } } +void _runDispatch1(void* d) { +} + +void _runDispatch2(void* d) { + +} + void DivEngine::nextBuf(float** in, float** out, int inChans, int outChans, unsigned int size) { lastNBIns=inChans; lastNBOuts=outChans; @@ -2066,9 +2073,11 @@ void DivEngine::nextBuf(float** in, float** out, int inChans, int outChans, unsi // 5. tick the clock and fill buffers as needed if (cyclespush([this,size](void* d) { + disCont[i].cycles=cycles; + disCont[i].size=size; + renderPool->push([](void* d) { DivDispatchContainer* dc=(DivDispatchContainer*)d; - int total=(cycles*dc->runtotal)/(size<cycles*dc->runtotal)/(dc->size<acquire(dc->runPos,total); dc->runLeft-=total; dc->runPos+=total; diff --git a/src/engine/workPool.cpp b/src/engine/workPool.cpp index 643e56f0c..fd1993aa1 100644 --- a/src/engine/workPool.cpp +++ b/src/engine/workPool.cpp @@ -71,7 +71,7 @@ void DivWorkThread::run() { } } -bool DivWorkThread::assign(const std::function& what, void* arg) { +bool DivWorkThread::assign(void (*what)(void*), void* arg) { lock.lock(); if (tasks.size()>=30) { lock.unlock(); @@ -105,7 +105,7 @@ void DivWorkThread::init(DivWorkPool* p) { thread=new std::thread(_workThread,this); } -void DivWorkPool::push(const std::function& what, void* arg) { +void DivWorkPool::push(void (*what)(void*), void* arg) { // if no work threads, just execute if (!threaded) { what(arg); diff --git a/src/engine/workPool.h b/src/engine/workPool.h index ef430f1ce..7b16d3339 100644 --- a/src/engine/workPool.h +++ b/src/engine/workPool.h @@ -31,9 +31,9 @@ class DivWorkPool; struct DivPendingTask { - std::function func; + void (*func)(void*); void* funcArg; - DivPendingTask(std::function f, void* arg): + DivPendingTask(void (*f)(void*), void* arg): func(f), funcArg(arg) {} DivPendingTask(): @@ -52,7 +52,7 @@ struct DivWorkThread { bool promiseAlreadySet; void run(); - bool assign(const std::function& what, void* arg); + bool assign(void (*what)(void*), void* arg); void wait(); bool busy(); void finish(); @@ -82,7 +82,7 @@ class DivWorkPool { * push a new job to this work pool. * if all work threads are busy, this will block until one is free. */ - void push(const std::function& what, void* arg); + void push(void (*what)(void*), void* arg); /** * check whether this work pool is busy. diff --git a/src/gui/chanOsc.cpp b/src/gui/chanOsc.cpp index 3496fe895..04908702e 100644 --- a/src/gui/chanOsc.cpp +++ b/src/gui/chanOsc.cpp @@ -60,7 +60,7 @@ float FurnaceGUI::computeGradPos(int type, int chan) { return 1.0f; break; case GUI_OSCREF_FREQUENCY: - return chanOscPitch[chan]; + return chanOscChan[chan].pitch; break; case GUI_OSCREF_VOLUME: return chanOscVol[chan]; @@ -416,10 +416,11 @@ void FurnaceGUI::drawChanOsc() { } if (fft_->ready && e->isRunning()) { - chanOscWorkPool->push([this](void* fft_v) { + fft_->windowSize=chanOscWindowSize; + fft_->waveCorr=chanOscWaveCorr; + chanOscWorkPool->push([](void* fft_v) { ChanOscStatus* fft=(ChanOscStatus*)fft_v; DivDispatchOscBuffer* buf=fft->relatedBuf; - int ch=fft->relatedCh; // the STRATEGY // 1. FFT of windowed signal @@ -433,7 +434,7 @@ void FurnaceGUI::drawChanOsc() { // initialization double phase=0.0; - int displaySize=(float)(buf->rate)*(chanOscWindowSize/1000.0f); + int displaySize=(float)(buf->rate)*(fft->windowSize/1000.0f); fft->loudEnough=false; fft->needle=buf->needle; @@ -493,7 +494,7 @@ void FurnaceGUI::drawChanOsc() { // did we find the period size? if (fft->waveLen<(FURNACE_FFT_SIZE-32)) { // we got pitch - chanOscPitch[ch]=pow(1.0-(fft->waveLen/(double)(FURNACE_FFT_SIZE>>1)),4.0); + fft->pitch=pow(1.0-(fft->waveLen/(double)(FURNACE_FFT_SIZE>>1)),4.0); fft->waveLen*=(double)displaySize*2.0/(double)FURNACE_FFT_SIZE; @@ -511,7 +512,7 @@ void FurnaceGUI::drawChanOsc() { // calculate and lock into phase phase=(0.5+(atan2(dft[1],dft[0])/(2.0*M_PI))); - if (chanOscWaveCorr) { + if (fft->waveCorr) { fft->needle-=phase*fft->waveLen; } } diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp index 2dbe3f670..497aecace 100644 --- a/src/gui/gui.cpp +++ b/src/gui/gui.cpp @@ -1097,7 +1097,9 @@ float FurnaceGUI::calcBPM(const DivGroovePattern& speeds, float hz, int vN, int void FurnaceGUI::play(int row) { memset(chanOscVol,0,DIV_MAX_CHANS*sizeof(float)); - memset(chanOscPitch,0,DIV_MAX_CHANS*sizeof(float)); + for (int i=0; iwalkSong(loopOrder,loopRow,loopEnd); memset(lastIns,-1,sizeof(int)*DIV_MAX_CHANS); @@ -3811,7 +3813,9 @@ bool FurnaceGUI::loop() { if (!e->isRunning()) { activeNotes.clear(); memset(chanOscVol,0,DIV_MAX_CHANS*sizeof(float)); - memset(chanOscPitch,0,DIV_MAX_CHANS*sizeof(float)); + for (int i=0; isynchronized([this]() { @@ -7417,7 +7421,9 @@ FurnaceGUI::FurnaceGUI(): memset(chanOscLP0,0,sizeof(float)*DIV_MAX_CHANS); memset(chanOscLP1,0,sizeof(float)*DIV_MAX_CHANS); memset(chanOscVol,0,sizeof(float)*DIV_MAX_CHANS); - memset(chanOscPitch,0,sizeof(float)*DIV_MAX_CHANS); + for (int i=0; i