GA20: acquireDirect optimizations, part 1

buggy, slow and glitchy
output is good but chan osc is now broken

from 1.5 to 0.4 seconds
This commit is contained in:
tildearrow 2025-03-02 20:29:28 -05:00
parent 2c75555fae
commit 8f54445625
5 changed files with 52 additions and 77 deletions

View file

@ -52,39 +52,23 @@ inline void DivPlatformGA20::chWrite(unsigned char ch, unsigned int addr, unsign
}
void DivPlatformGA20::acquire(short** buf, size_t len) {
if (ga20BufLen<len) {
ga20BufLen=len;
for (int i=0; i<4; i++) {
delete[] ga20Buf[i];
ga20Buf[i]=new short[ga20BufLen];
}
}
thread_local short ga20Buf[4];
for (int i=0; i<4; i++) {
oscBuf[i]->begin(len);
}
for (size_t h=0; h<len; h++) {
if ((--delay)<=0) {
delay=MAX(0,delay);
if (!writes.empty()) {
QueuedWrite& w=writes.front();
ga20.write(w.addr,w.val);
regPool[w.addr]=w.val;
writes.pop();
delay=1;
}
if (!writes.empty()) {
QueuedWrite& w=writes.front();
ga20.write(w.addr,w.val);
regPool[w.addr]=w.val;
writes.pop();
}
short *buffer[4]={
&ga20Buf[0][h],
&ga20Buf[1][h],
&ga20Buf[2][h],
&ga20Buf[3][h]
};
ga20.sound_stream_update(buffer,1);
buf[0][h]=(signed int)(ga20Buf[0][h]+ga20Buf[1][h]+ga20Buf[2][h]+ga20Buf[3][h])>>2;
ga20.sound_stream_update(ga20Buf,1);
buf[0][h]=(signed int)(ga20Buf[0]+ga20Buf[1]+ga20Buf[2]+ga20Buf[3])>>2;
for (int i=0; i<4; i++) {
oscBuf[i]->putSample(h,ga20Buf[i][h]>>1);
oscBuf[i]->putSample(h,ga20Buf[i]>>1);
}
}
@ -94,43 +78,42 @@ void DivPlatformGA20::acquire(short** buf, size_t len) {
}
void DivPlatformGA20::acquireDirect(blip_buffer_t** bb, size_t off, size_t len) {
if (ga20BufLen<len) {
ga20BufLen=len;
for (int i=0; i<4; i++) {
delete[] ga20Buf[i];
ga20Buf[i]=new short[ga20BufLen];
}
}
thread_local short ga20Buf[4];
for (int i=0; i<4; i++) {
oscBuf[i]->begin(len);
}
for (size_t h=off; h<off+len; h++) {
if ((--delay)<=0) {
delay=MAX(0,delay);
if (!writes.empty()) {
QueuedWrite& w=writes.front();
ga20.write(w.addr,w.val);
regPool[w.addr]=w.val;
writes.pop();
delay=1;
size_t advance=0;
if (!writes.empty()) {
QueuedWrite& w=writes.front();
ga20.write(w.addr,w.val);
regPool[w.addr]=w.val;
writes.pop();
} else {
// heuristic
advance=off+len-h-1;
for (int i=0; i<4; i++) {
if (!ga20.m_channel[i].play) continue;
if (ga20.m_channel[i].hot) {
advance=0;
break;
}
const size_t newAdvance=ga20.m_channel[i].counter-ga20.m_channel[i].rate-1;
if (newAdvance<advance) advance=newAdvance;
}
}
short *buffer[4]={
&ga20Buf[0][h],
&ga20Buf[1][h],
&ga20Buf[2][h],
&ga20Buf[3][h]
};
ga20.sound_stream_update(buffer,1);
const int out=(signed int)(ga20Buf[0][h]+ga20Buf[1][h]+ga20Buf[2][h]+ga20Buf[3][h])>>2;
ga20.sound_stream_update(ga20Buf,advance+1);
h+=advance;
const int out=(signed int)(ga20Buf[0]+ga20Buf[1]+ga20Buf[2]+ga20Buf[3])>>2;
if (out!=oldOut) {
blip_add_delta(bb[0],h,out-oldOut);
oldOut=out;
}
for (int i=0; i<4; i++) {
oscBuf[i]->putSample(h,ga20Buf[i][h]>>1);
oscBuf[i]->putSample(h,ga20Buf[i]>>1);
}
}
@ -420,7 +403,6 @@ void DivPlatformGA20::reset() {
writes.clear();
memset(regPool,0,32);
ga20.device_reset();
delay=0;
oldOut=0;
for (int i=0; i<4; i++) {
chan[i]=DivPlatformGA20::Channel();
@ -561,7 +543,6 @@ int DivPlatformGA20::init(DivEngine* p, int channels, int sugRate, const DivConf
}
sampleMem=new unsigned char[getSampleMemCapacity()];
sampleMemLen=0;
delay=0;
setFlags(flags);
ga20BufLen=65536;
for (int i=0; i<4; i++) ga20Buf[i]=new short[ga20BufLen];