workPool: don't use std::function
it's kinda slow
This commit is contained in:
parent
084cbcb168
commit
9b276e80f8
|
@ -197,6 +197,10 @@ struct DivDispatchContainer {
|
||||||
bool lowQuality, dcOffCompensation;
|
bool lowQuality, dcOffCompensation;
|
||||||
double rateMemory;
|
double rateMemory;
|
||||||
|
|
||||||
|
// used in multi-thread
|
||||||
|
int cycles;
|
||||||
|
unsigned int size;
|
||||||
|
|
||||||
void setRates(double gotRate);
|
void setRates(double gotRate);
|
||||||
void setQuality(bool lowQual);
|
void setQuality(bool lowQual);
|
||||||
void grow(size_t size);
|
void grow(size_t size);
|
||||||
|
@ -215,7 +219,9 @@ struct DivDispatchContainer {
|
||||||
lastAvail(0),
|
lastAvail(0),
|
||||||
lowQuality(false),
|
lowQuality(false),
|
||||||
dcOffCompensation(false),
|
dcOffCompensation(false),
|
||||||
rateMemory(0.0) {
|
rateMemory(0.0),
|
||||||
|
cycles(0),
|
||||||
|
size(0) {
|
||||||
memset(bb,0,DIV_MAX_OUTPUTS*sizeof(blip_buffer_t*));
|
memset(bb,0,DIV_MAX_OUTPUTS*sizeof(blip_buffer_t*));
|
||||||
memset(temp,0,DIV_MAX_OUTPUTS*sizeof(int));
|
memset(temp,0,DIV_MAX_OUTPUTS*sizeof(int));
|
||||||
memset(prevSample,0,DIV_MAX_OUTPUTS*sizeof(int));
|
memset(prevSample,0,DIV_MAX_OUTPUTS*sizeof(int));
|
||||||
|
|
|
@ -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) {
|
void DivEngine::nextBuf(float** in, float** out, int inChans, int outChans, unsigned int size) {
|
||||||
lastNBIns=inChans;
|
lastNBIns=inChans;
|
||||||
lastNBOuts=outChans;
|
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
|
// 5. tick the clock and fill buffers as needed
|
||||||
if (cycles<runLeftG) {
|
if (cycles<runLeftG) {
|
||||||
for (int i=0; i<song.systemLen; i++) {
|
for (int i=0; i<song.systemLen; i++) {
|
||||||
renderPool->push([this,size](void* d) {
|
disCont[i].cycles=cycles;
|
||||||
|
disCont[i].size=size;
|
||||||
|
renderPool->push([](void* d) {
|
||||||
DivDispatchContainer* dc=(DivDispatchContainer*)d;
|
DivDispatchContainer* dc=(DivDispatchContainer*)d;
|
||||||
int total=(cycles*dc->runtotal)/(size<<MASTER_CLOCK_PREC);
|
int total=(dc->cycles*dc->runtotal)/(dc->size<<MASTER_CLOCK_PREC);
|
||||||
dc->acquire(dc->runPos,total);
|
dc->acquire(dc->runPos,total);
|
||||||
dc->runLeft-=total;
|
dc->runLeft-=total;
|
||||||
dc->runPos+=total;
|
dc->runPos+=total;
|
||||||
|
|
|
@ -71,7 +71,7 @@ void DivWorkThread::run() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DivWorkThread::assign(const std::function<void(void*)>& what, void* arg) {
|
bool DivWorkThread::assign(void (*what)(void*), void* arg) {
|
||||||
lock.lock();
|
lock.lock();
|
||||||
if (tasks.size()>=30) {
|
if (tasks.size()>=30) {
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
|
@ -105,7 +105,7 @@ void DivWorkThread::init(DivWorkPool* p) {
|
||||||
thread=new std::thread(_workThread,this);
|
thread=new std::thread(_workThread,this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DivWorkPool::push(const std::function<void(void*)>& what, void* arg) {
|
void DivWorkPool::push(void (*what)(void*), void* arg) {
|
||||||
// if no work threads, just execute
|
// if no work threads, just execute
|
||||||
if (!threaded) {
|
if (!threaded) {
|
||||||
what(arg);
|
what(arg);
|
||||||
|
|
|
@ -31,9 +31,9 @@
|
||||||
class DivWorkPool;
|
class DivWorkPool;
|
||||||
|
|
||||||
struct DivPendingTask {
|
struct DivPendingTask {
|
||||||
std::function<void(void*)> func;
|
void (*func)(void*);
|
||||||
void* funcArg;
|
void* funcArg;
|
||||||
DivPendingTask(std::function<void(void*)> f, void* arg):
|
DivPendingTask(void (*f)(void*), void* arg):
|
||||||
func(f),
|
func(f),
|
||||||
funcArg(arg) {}
|
funcArg(arg) {}
|
||||||
DivPendingTask():
|
DivPendingTask():
|
||||||
|
@ -52,7 +52,7 @@ struct DivWorkThread {
|
||||||
bool promiseAlreadySet;
|
bool promiseAlreadySet;
|
||||||
|
|
||||||
void run();
|
void run();
|
||||||
bool assign(const std::function<void(void*)>& what, void* arg);
|
bool assign(void (*what)(void*), void* arg);
|
||||||
void wait();
|
void wait();
|
||||||
bool busy();
|
bool busy();
|
||||||
void finish();
|
void finish();
|
||||||
|
@ -82,7 +82,7 @@ class DivWorkPool {
|
||||||
* push a new job to this work pool.
|
* push a new job to this work pool.
|
||||||
* if all work threads are busy, this will block until one is free.
|
* if all work threads are busy, this will block until one is free.
|
||||||
*/
|
*/
|
||||||
void push(const std::function<void(void*)>& what, void* arg);
|
void push(void (*what)(void*), void* arg);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* check whether this work pool is busy.
|
* check whether this work pool is busy.
|
||||||
|
|
|
@ -60,7 +60,7 @@ float FurnaceGUI::computeGradPos(int type, int chan) {
|
||||||
return 1.0f;
|
return 1.0f;
|
||||||
break;
|
break;
|
||||||
case GUI_OSCREF_FREQUENCY:
|
case GUI_OSCREF_FREQUENCY:
|
||||||
return chanOscPitch[chan];
|
return chanOscChan[chan].pitch;
|
||||||
break;
|
break;
|
||||||
case GUI_OSCREF_VOLUME:
|
case GUI_OSCREF_VOLUME:
|
||||||
return chanOscVol[chan];
|
return chanOscVol[chan];
|
||||||
|
@ -416,10 +416,11 @@ void FurnaceGUI::drawChanOsc() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fft_->ready && e->isRunning()) {
|
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;
|
ChanOscStatus* fft=(ChanOscStatus*)fft_v;
|
||||||
DivDispatchOscBuffer* buf=fft->relatedBuf;
|
DivDispatchOscBuffer* buf=fft->relatedBuf;
|
||||||
int ch=fft->relatedCh;
|
|
||||||
|
|
||||||
// the STRATEGY
|
// the STRATEGY
|
||||||
// 1. FFT of windowed signal
|
// 1. FFT of windowed signal
|
||||||
|
@ -433,7 +434,7 @@ void FurnaceGUI::drawChanOsc() {
|
||||||
|
|
||||||
// initialization
|
// initialization
|
||||||
double phase=0.0;
|
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->loudEnough=false;
|
||||||
fft->needle=buf->needle;
|
fft->needle=buf->needle;
|
||||||
|
|
||||||
|
@ -493,7 +494,7 @@ void FurnaceGUI::drawChanOsc() {
|
||||||
// did we find the period size?
|
// did we find the period size?
|
||||||
if (fft->waveLen<(FURNACE_FFT_SIZE-32)) {
|
if (fft->waveLen<(FURNACE_FFT_SIZE-32)) {
|
||||||
// we got pitch
|
// 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;
|
fft->waveLen*=(double)displaySize*2.0/(double)FURNACE_FFT_SIZE;
|
||||||
|
|
||||||
|
@ -511,7 +512,7 @@ void FurnaceGUI::drawChanOsc() {
|
||||||
// calculate and lock into phase
|
// calculate and lock into phase
|
||||||
phase=(0.5+(atan2(dft[1],dft[0])/(2.0*M_PI)));
|
phase=(0.5+(atan2(dft[1],dft[0])/(2.0*M_PI)));
|
||||||
|
|
||||||
if (chanOscWaveCorr) {
|
if (fft->waveCorr) {
|
||||||
fft->needle-=phase*fft->waveLen;
|
fft->needle-=phase*fft->waveLen;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1097,7 +1097,9 @@ float FurnaceGUI::calcBPM(const DivGroovePattern& speeds, float hz, int vN, int
|
||||||
|
|
||||||
void FurnaceGUI::play(int row) {
|
void FurnaceGUI::play(int row) {
|
||||||
memset(chanOscVol,0,DIV_MAX_CHANS*sizeof(float));
|
memset(chanOscVol,0,DIV_MAX_CHANS*sizeof(float));
|
||||||
memset(chanOscPitch,0,DIV_MAX_CHANS*sizeof(float));
|
for (int i=0; i<DIV_MAX_CHANS; i++) {
|
||||||
|
chanOscChan[i].pitch=0.0f;
|
||||||
|
}
|
||||||
memset(chanOscBright,0,DIV_MAX_CHANS*sizeof(float));
|
memset(chanOscBright,0,DIV_MAX_CHANS*sizeof(float));
|
||||||
e->walkSong(loopOrder,loopRow,loopEnd);
|
e->walkSong(loopOrder,loopRow,loopEnd);
|
||||||
memset(lastIns,-1,sizeof(int)*DIV_MAX_CHANS);
|
memset(lastIns,-1,sizeof(int)*DIV_MAX_CHANS);
|
||||||
|
@ -3811,7 +3813,9 @@ bool FurnaceGUI::loop() {
|
||||||
if (!e->isRunning()) {
|
if (!e->isRunning()) {
|
||||||
activeNotes.clear();
|
activeNotes.clear();
|
||||||
memset(chanOscVol,0,DIV_MAX_CHANS*sizeof(float));
|
memset(chanOscVol,0,DIV_MAX_CHANS*sizeof(float));
|
||||||
memset(chanOscPitch,0,DIV_MAX_CHANS*sizeof(float));
|
for (int i=0; i<DIV_MAX_CHANS; i++) {
|
||||||
|
chanOscChan[i].pitch=0.0f;
|
||||||
|
}
|
||||||
memset(chanOscBright,0,DIV_MAX_CHANS*sizeof(float));
|
memset(chanOscBright,0,DIV_MAX_CHANS*sizeof(float));
|
||||||
|
|
||||||
e->synchronized([this]() {
|
e->synchronized([this]() {
|
||||||
|
@ -7417,7 +7421,9 @@ FurnaceGUI::FurnaceGUI():
|
||||||
memset(chanOscLP0,0,sizeof(float)*DIV_MAX_CHANS);
|
memset(chanOscLP0,0,sizeof(float)*DIV_MAX_CHANS);
|
||||||
memset(chanOscLP1,0,sizeof(float)*DIV_MAX_CHANS);
|
memset(chanOscLP1,0,sizeof(float)*DIV_MAX_CHANS);
|
||||||
memset(chanOscVol,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<DIV_MAX_CHANS; i++) {
|
||||||
|
chanOscChan[i].pitch=0.0f;
|
||||||
|
}
|
||||||
memset(chanOscBright,0,sizeof(float)*DIV_MAX_CHANS);
|
memset(chanOscBright,0,sizeof(float)*DIV_MAX_CHANS);
|
||||||
memset(lastCorrPos,0,sizeof(short)*DIV_MAX_CHANS);
|
memset(lastCorrPos,0,sizeof(short)*DIV_MAX_CHANS);
|
||||||
|
|
||||||
|
|
|
@ -2061,7 +2061,6 @@ class FurnaceGUI {
|
||||||
float chanOscLP0[DIV_MAX_CHANS];
|
float chanOscLP0[DIV_MAX_CHANS];
|
||||||
float chanOscLP1[DIV_MAX_CHANS];
|
float chanOscLP1[DIV_MAX_CHANS];
|
||||||
float chanOscVol[DIV_MAX_CHANS];
|
float chanOscVol[DIV_MAX_CHANS];
|
||||||
float chanOscPitch[DIV_MAX_CHANS];
|
|
||||||
float chanOscBright[DIV_MAX_CHANS];
|
float chanOscBright[DIV_MAX_CHANS];
|
||||||
unsigned short lastNeedlePos[DIV_MAX_CHANS];
|
unsigned short lastNeedlePos[DIV_MAX_CHANS];
|
||||||
unsigned short lastCorrPos[DIV_MAX_CHANS];
|
unsigned short lastCorrPos[DIV_MAX_CHANS];
|
||||||
|
@ -2074,8 +2073,9 @@ class FurnaceGUI {
|
||||||
double inBufPosFrac;
|
double inBufPosFrac;
|
||||||
double waveLen;
|
double waveLen;
|
||||||
int waveLenBottom, waveLenTop, relatedCh;
|
int waveLenBottom, waveLenTop, relatedCh;
|
||||||
|
float pitch, windowSize;
|
||||||
unsigned short needle;
|
unsigned short needle;
|
||||||
bool ready, loudEnough;
|
bool ready, loudEnough, waveCorr;
|
||||||
fftw_plan plan;
|
fftw_plan plan;
|
||||||
fftw_plan planI;
|
fftw_plan planI;
|
||||||
ChanOscStatus():
|
ChanOscStatus():
|
||||||
|
@ -2089,9 +2089,12 @@ class FurnaceGUI {
|
||||||
waveLenBottom(0),
|
waveLenBottom(0),
|
||||||
waveLenTop(0),
|
waveLenTop(0),
|
||||||
relatedCh(0),
|
relatedCh(0),
|
||||||
|
pitch(0.0f),
|
||||||
|
windowSize(1.0f),
|
||||||
needle(0),
|
needle(0),
|
||||||
ready(false),
|
ready(false),
|
||||||
loudEnough(false),
|
loudEnough(false),
|
||||||
|
waveCorr(false),
|
||||||
plan(NULL),
|
plan(NULL),
|
||||||
planI(NULL) {}
|
planI(NULL) {}
|
||||||
} chanOscChan[DIV_MAX_CHANS];
|
} chanOscChan[DIV_MAX_CHANS];
|
||||||
|
|
Loading…
Reference in a new issue