optimize putSample a bit

use 16-bit precision even on 64-bit....
this allows some code optimizations
This commit is contained in:
tildearrow 2025-03-03 00:51:47 -05:00
parent 2926fad77e
commit cf4807b5d0
2 changed files with 15 additions and 22 deletions

View file

@ -424,15 +424,14 @@ struct DivSamplePos {
freq(0) {} freq(0) {}
}; };
constexpr size_t OSCBUF_PREC=(sizeof(size_t)>=8)?32: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;
// 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 needleSub; unsigned int needle;
unsigned short needle;
unsigned short readNeedle; unsigned short readNeedle;
unsigned short followNeedle; unsigned short followNeedle;
unsigned short lastSample; unsigned short lastSample;
@ -440,18 +439,18 @@ struct DivDispatchOscBuffer {
short data[65536]; short data[65536];
inline void putSample(size_t pos, short val) { inline void putSample(size_t pos, short val) {
unsigned short realPos=needle+((needleSub+pos*rateMul)>>OSCBUF_PREC); unsigned short realPos=((needle+pos*rateMul)>>OSCBUF_PREC);
if (val==-1) { if (val==-1) {
data[realPos]=0xfffe; data[realPos]=0xfffe;
return; return;
} }
lastSample=val; //lastSample=val;
data[realPos]=val; data[realPos]=val;
} }
inline void begin(unsigned short len) { inline void begin(unsigned short len) {
size_t calc=(needleSub+len*rateMul)>>OSCBUF_PREC; size_t calc=(len*rateMul);
unsigned short start=needle; unsigned short start=needle>>16;
unsigned short end=needle+calc; unsigned short end=(needle+calc)>>16;
//logD("C %d %d %d",len,calc,rate); //logD("C %d %d %d",len,calc,rate);
@ -459,27 +458,22 @@ struct DivDispatchOscBuffer {
//logE("ELS %d %d %d",end,start,calc); //logE("ELS %d %d %d",end,start,calc);
memset(&data[start],-1,(0x10000-start)*sizeof(short)); memset(&data[start],-1,(0x10000-start)*sizeof(short));
memset(data,-1,end*sizeof(short)); memset(data,-1,end*sizeof(short));
data[needle]=lastSample; //data[needle>>16]=lastSample;
return; return;
} }
memset(&data[start],-1,calc*sizeof(short)); memset(&data[start],-1,(end-start)*sizeof(short));
data[needle]=lastSample; //data[needle>>16]=lastSample;
} }
inline void end(unsigned short len) { inline void end(unsigned short len) {
size_t calc=len*rateMul; size_t calc=len*rateMul;
if (((calc&OSCBUF_MASK)+needleSub)>OSCBUF_MASK) { needle+=calc;
calc+=UINTMAX_C(1)<<OSCBUF_PREC; //data[needle>>16]=lastSample;
}
needleSub=(needleSub+calc)&OSCBUF_MASK;
needle+=calc>>OSCBUF_PREC;
data[needle]=lastSample;
} }
void reset() { void reset() {
memset(data,-1,65536*sizeof(short)); memset(data,-1,65536*sizeof(short));
needle=0; needle=0;
readNeedle=0; readNeedle=0;
followNeedle=0; followNeedle=0;
needleSub=0;
lastSample=0; lastSample=0;
} }
void setRate(unsigned int r) { void setRate(unsigned int r) {
@ -491,7 +485,6 @@ struct DivDispatchOscBuffer {
DivDispatchOscBuffer(): DivDispatchOscBuffer():
rate(65536), rate(65536),
rateMul(UINTMAX_C(1)<<OSCBUF_PREC), rateMul(UINTMAX_C(1)<<OSCBUF_PREC),
needleSub(0),
needle(0), needle(0),
readNeedle(0), readNeedle(0),
followNeedle(0), followNeedle(0),

View file

@ -106,7 +106,7 @@ void FurnaceGUI::calcChanOsc() {
if (e->isRunning()) { if (e->isRunning()) {
short minLevel=32767; short minLevel=32767;
short maxLevel=-32768; short maxLevel=-32768;
unsigned short needlePos=buf->needle; unsigned short needlePos=buf->needle>>16;
for (unsigned short i=needlePos-displaySize; i!=needlePos; i++) { for (unsigned short i=needlePos-displaySize; i!=needlePos; i++) {
short y=buf->data[i]; short y=buf->data[i];
if (y==-1) continue; if (y==-1) continue;
@ -421,7 +421,7 @@ void FurnaceGUI::drawChanOsc() {
if (fft_->relatedBuf!=NULL) { if (fft_->relatedBuf!=NULL) {
// prepare // prepare
if (centerSettingReset) { if (centerSettingReset) {
fft_->relatedBuf->readNeedle=fft_->relatedBuf->needle; fft_->relatedBuf->readNeedle=fft_->relatedBuf->needle>>16;
} }
// check FFT status existence // check FFT status existence
@ -465,7 +465,7 @@ void FurnaceGUI::drawChanOsc() {
int displaySize=65536.0f*(fft->windowSize/1000.0f); int displaySize=65536.0f*(fft->windowSize/1000.0f);
int displaySize2=65536.0f*(fft->windowSize/500.0f); int displaySize2=65536.0f*(fft->windowSize/500.0f);
fft->loudEnough=false; fft->loudEnough=false;
fft->needle=buf->needle; fft->needle=buf->needle>>16;
// first FFT // first FFT
int k=0; int k=0;