acquireDirect proof of concept

extremely low CPU usage in PC Speaker

WARNING! no per-chan osc yet!
This commit is contained in:
tildearrow 2025-02-25 19:58:25 -05:00
parent 4502fa6912
commit d935d3c6d1
2 changed files with 41 additions and 21 deletions

View file

@ -192,26 +192,39 @@ const char** DivPlatformPCSpeaker::getRegisterSheet() {
return regCheatSheetPCSpeaker; return regCheatSheetPCSpeaker;
} }
void DivPlatformPCSpeaker::acquire_unfilt(short** buf, size_t len) { void DivPlatformPCSpeaker::acquire_unfilt(blip_buffer_t** bb, size_t off, size_t len) {
int out=0; int out=0;
for (size_t i=0; i<len; i++) {
if (on) { if (on) {
pos-=PCSPKR_DIVIDER; // just in case
out=(posToggle && !isMuted[0])?32767:0;
blip_add_delta(bb[0],off,out-oldOut);
oldOut=out;
if (freq>=1) {
if (pos>freq) pos=freq; if (pos>freq) pos=freq;
while (pos<0) { size_t boff=off;
if (freq<1) { size_t i=len;
pos=1; while (true) {
if ((int)i<pos) {
pos-=i;
break;
}
i-=pos;
boff+=pos;
posToggle=!posToggle;
out=(posToggle && !isMuted[0])?32767:0;
blip_add_delta(bb[0],boff,out-oldOut);
oldOut=out;
if (freq&1) {
pos=(freq>>1)+(posToggle?1:0);
} else { } else {
pos+=freq; pos=freq>>1;
}
} }
} }
out=(pos>(freq>>1) && !isMuted[0])?32767:0;
buf[0][i]=out;
oscBuf->data[oscBuf->needle++]=out;
} else { } else {
buf[0][i]=0; out=0;
oscBuf->data[oscBuf->needle++]=0; blip_add_delta(bb[0],off,out-oldOut);
} oldOut=out;
} }
} }
@ -325,9 +338,6 @@ void DivPlatformPCSpeaker::acquire_real(blip_buffer_t** bb, size_t off, size_t l
void DivPlatformPCSpeaker::acquire(short** buf, size_t len) { void DivPlatformPCSpeaker::acquire(short** buf, size_t len) {
switch (speakerType) { switch (speakerType) {
case 0:
acquire_unfilt(buf,len);
break;
case 1: case 1:
acquire_cone(buf,len); acquire_cone(buf,len);
break; break;
@ -339,6 +349,9 @@ void DivPlatformPCSpeaker::acquire(short** buf, size_t len) {
void DivPlatformPCSpeaker::acquireDirect(blip_buffer_t** bb, size_t off, size_t len) { void DivPlatformPCSpeaker::acquireDirect(blip_buffer_t** bb, size_t off, size_t len) {
switch (speakerType) { switch (speakerType) {
case 0:
acquire_unfilt(bb,off,len);
break;
case 3: case 3:
acquire_real(bb,off,len); acquire_real(bb,off,len);
break; break;
@ -383,6 +396,7 @@ void DivPlatformPCSpeaker::tick(bool sysTick) {
} }
if (freq!=chan[i].freq && resetPhase) { if (freq!=chan[i].freq && resetPhase) {
pos=0; pos=0;
posToggle=false;
} }
freq=chan[i].freq; freq=chan[i].freq;
if (chan[i].keyOn) chan[i].keyOn=false; if (chan[i].keyOn) chan[i].keyOn=false;
@ -544,9 +558,11 @@ void DivPlatformPCSpeaker::reset() {
freq=0; freq=0;
lastFreq=0; lastFreq=0;
pos=0; pos=0;
posToggle=true;
flip=false; flip=false;
low=0; low=0;
band=0; band=0;
oldOut=0;
//if (speakerType==3) { //if (speakerType==3) {
#ifdef __linux__ #ifdef __linux__
@ -623,9 +639,13 @@ void DivPlatformPCSpeaker::setFlags(const DivConfig& flags) {
break; break;
} }
CHECK_CUSTOM_CLOCK; CHECK_CUSTOM_CLOCK;
rate=chipClock/PCSPKR_DIVIDER;
speakerType=flags.getInt("speakerType",0)&3; speakerType=flags.getInt("speakerType",0)&3;
resetPhase=flags.getBool("resetPhase",false); resetPhase=flags.getBool("resetPhase",false);
if (speakerType==0 || speakerType==3) {
rate=chipClock;
} else {
rate=chipClock/PCSPKR_DIVIDER;
}
oscBuf->rate=rate; oscBuf->rate=rate;
switch (speakerType) { switch (speakerType) {

View file

@ -51,8 +51,8 @@ class DivPlatformPCSpeaker: public DivDispatch {
FixedQueue<RealQueueVal,2048> realQueue; FixedQueue<RealQueueVal,2048> realQueue;
std::mutex realQueueLock; std::mutex realQueueLock;
bool isMuted[1]; bool isMuted[1];
bool on, flip, lastOn, realOutEnabled, resetPhase; bool on, flip, lastOn, realOutEnabled, resetPhase, posToggle;
int pos, speakerType, beepFD, realOutMethod; int pos, oldOut, speakerType, beepFD, realOutMethod;
float low, band; float low, band;
float low2, high2, band2; float low2, high2, band2;
float low3, band3; float low3, band3;
@ -67,7 +67,7 @@ class DivPlatformPCSpeaker: public DivDispatch {
void beepFreq(int freq, int delay=0); void beepFreq(int freq, int delay=0);
void acquire_unfilt(short** buf, size_t len); void acquire_unfilt(blip_buffer_t** bb, size_t off, size_t len);
void acquire_cone(short** buf, size_t len); void acquire_cone(short** buf, size_t len);
void acquire_piezo(short** buf, size_t len); void acquire_piezo(short** buf, size_t len);
void acquire_real(blip_buffer_t** bb, size_t off, size_t len); void acquire_real(blip_buffer_t** bb, size_t off, size_t len);