ESFM: optimize osc buf
This commit is contained in:
parent
cf4807b5d0
commit
b3b50bdb66
|
@ -427,18 +427,20 @@ struct DivSamplePos {
|
||||||
constexpr size_t OSCBUF_PREC=(sizeof(size_t)>=8)?16:16;
|
constexpr size_t OSCBUF_PREC=(sizeof(size_t)>=8)?16:16;
|
||||||
constexpr size_t OSCBUF_MASK=(UINTMAX_C(1)<<OSCBUF_PREC)-1;
|
constexpr size_t OSCBUF_MASK=(UINTMAX_C(1)<<OSCBUF_PREC)-1;
|
||||||
|
|
||||||
|
#define putSampleIKnowWhatIAmDoing(_ob,_pos,_val) \
|
||||||
|
_ob->data[_pos]=_val;
|
||||||
|
|
||||||
// the actual output of all DivDispatchOscBuffer instanced runs at 65536Hz.
|
// the actual output of all DivDispatchOscBuffer instanced runs at 65536Hz.
|
||||||
struct DivDispatchOscBuffer {
|
struct DivDispatchOscBuffer {
|
||||||
size_t rate;
|
size_t rate;
|
||||||
size_t rateMul;
|
size_t rateMul;
|
||||||
unsigned int needle;
|
unsigned int needle;
|
||||||
unsigned short readNeedle;
|
unsigned short readNeedle;
|
||||||
unsigned short followNeedle;
|
//unsigned short lastSample;
|
||||||
unsigned short lastSample;
|
|
||||||
bool follow;
|
bool follow;
|
||||||
short data[65536];
|
short data[65536];
|
||||||
|
|
||||||
inline void putSample(size_t pos, short val) {
|
inline void putSample(const size_t pos, const short val) {
|
||||||
unsigned short realPos=((needle+pos*rateMul)>>OSCBUF_PREC);
|
unsigned short realPos=((needle+pos*rateMul)>>OSCBUF_PREC);
|
||||||
if (val==-1) {
|
if (val==-1) {
|
||||||
data[realPos]=0xfffe;
|
data[realPos]=0xfffe;
|
||||||
|
@ -447,6 +449,16 @@ struct DivDispatchOscBuffer {
|
||||||
//lastSample=val;
|
//lastSample=val;
|
||||||
data[realPos]=val;
|
data[realPos]=val;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
inline void putSampleIKnowWhatIAmDoing(const unsigned short pos, const short val) {
|
||||||
|
//unsigned short realPos=((needle+pos*rateMul)>>OSCBUF_PREC);
|
||||||
|
if (val==-1) {
|
||||||
|
data[pos]=0xfffe;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//lastSample=val;
|
||||||
|
data[pos]=val;
|
||||||
|
}*/
|
||||||
inline void begin(unsigned short len) {
|
inline void begin(unsigned short len) {
|
||||||
size_t calc=(len*rateMul);
|
size_t calc=(len*rateMul);
|
||||||
unsigned short start=needle>>16;
|
unsigned short start=needle>>16;
|
||||||
|
@ -473,8 +485,7 @@ struct DivDispatchOscBuffer {
|
||||||
memset(data,-1,65536*sizeof(short));
|
memset(data,-1,65536*sizeof(short));
|
||||||
needle=0;
|
needle=0;
|
||||||
readNeedle=0;
|
readNeedle=0;
|
||||||
followNeedle=0;
|
//lastSample=0;
|
||||||
lastSample=0;
|
|
||||||
}
|
}
|
||||||
void setRate(unsigned int r) {
|
void setRate(unsigned int r) {
|
||||||
double rateMulD=65536.0/(double)r;
|
double rateMulD=65536.0/(double)r;
|
||||||
|
@ -487,8 +498,7 @@ struct DivDispatchOscBuffer {
|
||||||
rateMul(UINTMAX_C(1)<<OSCBUF_PREC),
|
rateMul(UINTMAX_C(1)<<OSCBUF_PREC),
|
||||||
needle(0),
|
needle(0),
|
||||||
readNeedle(0),
|
readNeedle(0),
|
||||||
followNeedle(0),
|
//lastSample(0),
|
||||||
lastSample(0),
|
|
||||||
follow(true) {
|
follow(true) {
|
||||||
memset(data,-1,65536*sizeof(short));
|
memset(data,-1,65536*sizeof(short));
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,6 +66,46 @@ void DivPlatformESFM::acquire(short** buf, size_t len) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DivPlatformESFM::acquireDirect(blip_buffer_t** bb, size_t off, size_t len) {
|
||||||
|
thread_local short o[2];
|
||||||
|
unsigned int sharedNeedlePos=oscBuf[0]->needle;
|
||||||
|
for (int i=0; i<18; i++) {
|
||||||
|
oscBuf[i]->begin(len);
|
||||||
|
}
|
||||||
|
size_t pos=off;
|
||||||
|
for (size_t h=0; h<len; h++) {
|
||||||
|
if (!writes.empty()) {
|
||||||
|
QueuedWrite& w=writes.front();
|
||||||
|
ESFM_write_reg_buffered_fast(&chip,w.addr,w.val);
|
||||||
|
if (w.addr<ESFM_REG_POOL_SIZE) {
|
||||||
|
regPool[w.addr]=w.val;
|
||||||
|
}
|
||||||
|
writes.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
ESFM_generate(&chip,o);
|
||||||
|
const unsigned int shiftedNeedlePos=sharedNeedlePos>>OSCBUF_PREC;
|
||||||
|
for (int c=0; c<18; c++) {
|
||||||
|
putSampleIKnowWhatIAmDoing(oscBuf[c],shiftedNeedlePos,ESFM_get_channel_output_native(&chip,c));
|
||||||
|
}
|
||||||
|
sharedNeedlePos+=oscBuf[0]->rateMul;
|
||||||
|
|
||||||
|
if (o[0]!=oldOut[0]) {
|
||||||
|
blip_add_delta(bb[0],pos,oldOut[0]-o[0]);
|
||||||
|
oldOut[0]=o[0];
|
||||||
|
}
|
||||||
|
if (o[1]!=oldOut[1]) {
|
||||||
|
blip_add_delta(bb[1],pos,oldOut[1]-o[1]);
|
||||||
|
oldOut[1]=o[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
pos++;
|
||||||
|
}
|
||||||
|
for (int i=0; i<18; i++) {
|
||||||
|
oscBuf[i]->end(len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void DivPlatformESFM::tick(bool sysTick) {
|
void DivPlatformESFM::tick(bool sysTick) {
|
||||||
for (int i=0; i<18; i++) {
|
for (int i=0; i<18; i++) {
|
||||||
chan[i].std.next();
|
chan[i].std.next();
|
||||||
|
@ -1024,6 +1064,9 @@ void DivPlatformESFM::reset() {
|
||||||
chan[i].vol=0x3f;
|
chan[i].vol=0x3f;
|
||||||
chan[i].outVol=0x3f;
|
chan[i].outVol=0x3f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
oldOut[0]=0;
|
||||||
|
oldOut[1]=0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int DivPlatformESFM::getOutputCount() {
|
int DivPlatformESFM::getOutputCount() {
|
||||||
|
@ -1038,6 +1081,10 @@ bool DivPlatformESFM::keyOffAffectsPorta(int ch) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool DivPlatformESFM::hasAcquireDirect() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool DivPlatformESFM::getLegacyAlwaysSetVolume() {
|
bool DivPlatformESFM::getLegacyAlwaysSetVolume() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -120,6 +120,7 @@ class DivPlatformESFM: public DivDispatch {
|
||||||
};
|
};
|
||||||
FixedQueue<QueuedWrite,2048> writes;
|
FixedQueue<QueuedWrite,2048> writes;
|
||||||
esfm_chip chip;
|
esfm_chip chip;
|
||||||
|
short oldOut[2];
|
||||||
bool isFast;
|
bool isFast;
|
||||||
|
|
||||||
unsigned char regPool[ESFM_REG_POOL_SIZE];
|
unsigned char regPool[ESFM_REG_POOL_SIZE];
|
||||||
|
@ -180,6 +181,7 @@ class DivPlatformESFM: public DivDispatch {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void acquire(short** buf, size_t len);
|
void acquire(short** buf, size_t len);
|
||||||
|
void acquireDirect(blip_buffer_t** bb, size_t off, size_t len);
|
||||||
int dispatch(DivCommand c);
|
int dispatch(DivCommand c);
|
||||||
void* getChanState(int chan);
|
void* getChanState(int chan);
|
||||||
DivMacroInt* getChanMacroInt(int ch);
|
DivMacroInt* getChanMacroInt(int ch);
|
||||||
|
@ -194,6 +196,7 @@ class DivPlatformESFM: public DivDispatch {
|
||||||
void muteChannel(int ch, bool mute);
|
void muteChannel(int ch, bool mute);
|
||||||
bool keyOffAffectsArp(int ch);
|
bool keyOffAffectsArp(int ch);
|
||||||
bool keyOffAffectsPorta(int ch);
|
bool keyOffAffectsPorta(int ch);
|
||||||
|
bool hasAcquireDirect();
|
||||||
bool getLegacyAlwaysSetVolume();
|
bool getLegacyAlwaysSetVolume();
|
||||||
void toggleRegisterDump(bool enable);
|
void toggleRegisterDump(bool enable);
|
||||||
void notifyInsChange(int ins);
|
void notifyInsChange(int ins);
|
||||||
|
|
|
@ -276,10 +276,9 @@ void FurnaceGUI::drawDebug() {
|
||||||
ImGui::Checkbox(fmt::sprintf("##%d_OSCFollow_%d",i,c).c_str(),&oscBuf->follow);
|
ImGui::Checkbox(fmt::sprintf("##%d_OSCFollow_%d",i,c).c_str(),&oscBuf->follow);
|
||||||
// address
|
// address
|
||||||
ImGui::TableNextColumn();
|
ImGui::TableNextColumn();
|
||||||
int needle=oscBuf->follow?oscBuf->needle:oscBuf->followNeedle;
|
int needle=oscBuf->needle;
|
||||||
ImGui::BeginDisabled(oscBuf->follow);
|
ImGui::BeginDisabled(oscBuf->follow);
|
||||||
if (ImGui::InputInt(fmt::sprintf("##%d_OSCFollowNeedle_%d",i,c).c_str(),&needle,1,100)) {
|
if (ImGui::InputInt(fmt::sprintf("##%d_OSCFollowNeedle_%d",i,c).c_str(),&needle,1,100)) {
|
||||||
oscBuf->followNeedle=MIN(MAX(needle,0),65535);
|
|
||||||
}
|
}
|
||||||
ImGui::EndDisabled();
|
ImGui::EndDisabled();
|
||||||
// data
|
// data
|
||||||
|
|
Loading…
Reference in a new issue