new chan osc work in progress

This commit is contained in:
tildearrow 2025-03-01 05:05:50 -05:00
parent 0eea0ec139
commit dd7e1def3d
11 changed files with 171 additions and 74 deletions

View file

@ -424,40 +424,79 @@ struct DivSamplePos {
freq(0) {}
};
constexpr uintmax_t OSCBUF_PREC=(sizeof(uintmax_t)>=8)?32:16;
constexpr uintmax_t OSCBUF_MASK=(1UL<<OSCBUF_PREC)-1;
// the actual output of all DivDispatchOscBuffer instanced runs at 65536Hz.
struct DivDispatchOscBuffer {
bool follow;
unsigned int rate;
size_t rateMul;
uintmax_t rate;
uintmax_t rateMul;
unsigned int needleSub;
unsigned short needle;
unsigned short readNeedle;
unsigned short followNeedle;
unsigned short lastSample;
bool follow;
short data[65536];
// TODO: all of this
inline void putSample(unsigned short pos, short val) {
unsigned short realPos=needle+pos;
if (val==0xffff) {
data[needle+pos]=0xfffe;
inline void putSample(uintmax_t pos, short val) {
unsigned short realPos=needle+((needleSub+pos*rateMul)>>OSCBUF_PREC);
if (val==-1) {
data[realPos]=0xfffe;
return;
}
data[needle+pos]=val;
lastSample=val;
data[realPos]=val;
}
inline void begin(unsigned short len) {
uintmax_t calc=(needleSub+len*rateMul)>>OSCBUF_PREC;
unsigned short start=needle;
unsigned short end=needle+calc;
if (end<start) {
logE("ELS %d %d %d",end,start,calc);
memset(&data[start],-1,(0x10000-start)*sizeof(short));
memset(data,-1,end*sizeof(short));
data[needle]=lastSample;
return;
}
memset(&data[start],-1,calc*sizeof(short));
data[needle]=lastSample;
}
inline void end(unsigned short len) {
needle+=len;
uintmax_t calc=len*rateMul;
if (((calc&OSCBUF_MASK)+needleSub)>=(OSCBUF_MASK+1UL)) {
needle++;
}
needleSub=(needleSub+calc)&OSCBUF_MASK;
needle+=calc>>OSCBUF_PREC;
data[needle]=lastSample;
}
void reset() {
memset(data,-1,65536*sizeof(short));
needle=0;
readNeedle=0;
followNeedle=0;
needleSub=0;
lastSample=0;
}
void setRate(unsigned int r) {
double rateMulD=65536.0/(double)r;
rateMulD*=(double)(1UL<<OSCBUF_PREC);
rate=r;
rateMul=(uintmax_t)rateMulD;
}
DivDispatchOscBuffer():
follow(true),
rate(65536),
rateMul(1UL<<OSCBUF_PREC),
needleSub(0),
needle(0),
readNeedle(0),
followNeedle(0) {
memset(data,0,65536*sizeof(short));
followNeedle(0),
lastSample(0),
follow(true) {
memset(data,-1,65536*sizeof(short));
}
};

View file

@ -2064,9 +2064,7 @@ void DivEngine::stop() {
for (int i=0; i<chans; i++) {
DivDispatchOscBuffer* buf=disCont[dispatchOfChan[i]].dispatch->getOscBuffer(dispatchChanOfChan[i]);
if (buf!=NULL) {
memset(buf->data,0,65536*sizeof(short));
buf->needle=0;
buf->readNeedle=0;
buf->reset();
}
}
BUSY_END;

View file

@ -134,10 +134,6 @@ bool DivDispatch::hasAcquireDirect() {
return false;
}
bool DivDispatch::isOscBufPositional() {
return false;
}
bool DivDispatch::getWantPreNote() {
return false;
}

View file

@ -82,6 +82,10 @@ const char** DivPlatformAmiga::getRegisterSheet() {
void DivPlatformAmiga::acquire(short** buf, size_t len) {
thread_local int outL, outR, output;
for (int i=0; i<4; i++) {
oscBuf[i]->begin(len);
}
for (size_t h=0; h<len; h++) {
if (--delay<0) delay=0;
if (!writes.empty() && delay<=0) {
@ -182,9 +186,10 @@ void DivPlatformAmiga::acquire(short** buf, size_t len) {
outL+=(output*sep2)>>7;
outR+=(output*sep1)>>7;
}
oscBuf[i]->data[oscBuf[i]->needle++]=(amiga.nextOut[i]*MIN(64,amiga.audVol[i]&127))<<1;
oscBuf[i]->putSample(h,(amiga.nextOut[i]*MIN(64,amiga.audVol[i]&127))<<1);
} else {
oscBuf[i]->data[oscBuf[i]->needle++]=0;
// TODO: we can remove this!
oscBuf[i]->putSample(h,0);
}
}
@ -195,6 +200,10 @@ void DivPlatformAmiga::acquire(short** buf, size_t len) {
buf[0][h]=filter[0][1];
buf[1][h]=filter[1][1];
}
for (int i=0; i<4; i++) {
oscBuf[i]->end(len);
}
}
void DivPlatformAmiga::irq(int ch) {
@ -826,7 +835,7 @@ void DivPlatformAmiga::setFlags(const DivConfig& flags) {
rate=chipClock/AMIGA_DIVIDER;
for (int i=0; i<4; i++) {
oscBuf[i]->rate=rate;
oscBuf[i]->setRate(rate);
}
int sep=flags.getInt("stereoSep",0)&127;
sep1=sep+127;

View file

@ -60,6 +60,10 @@ void DivPlatformGA20::acquire(short** buf, size_t len) {
}
}
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);
@ -80,9 +84,13 @@ void DivPlatformGA20::acquire(short** buf, size_t len) {
ga20.sound_stream_update(buffer,1);
buf[0][h]=(signed int)(ga20Buf[0][h]+ga20Buf[1][h]+ga20Buf[2][h]+ga20Buf[3][h])>>2;
for (int i=0; i<4; i++) {
oscBuf[i]->data[oscBuf[i]->needle++]=ga20Buf[i][h]>>1;
oscBuf[i]->putSample(h,ga20Buf[i][h]>>1);
}
}
for (int i=0; i<4; i++) {
oscBuf[i]->end(len);
}
}
u8 DivPlatformGA20::read_byte(u32 address) {
@ -403,7 +411,7 @@ void DivPlatformGA20::setFlags(const DivConfig& flags) {
CHECK_CUSTOM_CLOCK;
rate=chipClock/4;
for (int i=0; i<4; i++) {
oscBuf[i]->rate=rate;
oscBuf[i]->setRate(rate);
}
}

View file

@ -196,6 +196,7 @@ void DivPlatformPCSpeaker::acquire_unfilt(blip_buffer_t** bb, size_t off, size_t
int out=0;
int freq1=freq+1;
int timeToNextToggle=0;
oscBuf->begin(len);
if (on) {
// just in case
if (pos>freq1) {
@ -210,11 +211,11 @@ void DivPlatformPCSpeaker::acquire_unfilt(blip_buffer_t** bb, size_t off, size_t
}
out=(posToggle && !isMuted[0])?32767:0;
blip_add_delta(bb[0],off,out-oldOut);
oscBuf->data[oscBuf->needle++]=oscBufPos;
oscBuf->data[oscBuf->needle++]=out;
oldOut=out;
if (freq>=1) {
size_t boff=off;
size_t oscOff=0;
size_t i=len;
while (true) {
if ((int)i<timeToNextToggle) {
@ -223,8 +224,8 @@ void DivPlatformPCSpeaker::acquire_unfilt(blip_buffer_t** bb, size_t off, size_t
}
i-=timeToNextToggle;
boff+=timeToNextToggle;
oscOff+=timeToNextToggle;
pos-=timeToNextToggle;
oscBufPos+=timeToNextToggle;
if (pos<=0) {
pos=freq1;
}
@ -237,19 +238,21 @@ void DivPlatformPCSpeaker::acquire_unfilt(blip_buffer_t** bb, size_t off, size_t
}
out=(posToggle && !isMuted[0])?32767:0;
blip_add_delta(bb[0],boff,out-oldOut);
oscBuf->data[oscBuf->needle++]=oscBufPos;
oscBuf->data[oscBuf->needle++]=out;
oscBuf->putSample(oscOff,out);
oldOut=out;
}
}
} else {
out=0;
blip_add_delta(bb[0],off,out-oldOut);
oscBuf->putSample(0,out);
oldOut=out;
}
oscBuf->end(len);
}
void DivPlatformPCSpeaker::acquire_cone(short** buf, size_t len) {
oscBuf->begin(len);
for (size_t i=0; i<len; i++) {
if (on) {
pos-=PCSPKR_DIVIDER;
@ -268,15 +271,17 @@ void DivPlatformPCSpeaker::acquire_cone(short** buf, size_t len) {
if (out>1.0) out=1.0;
if (out<-1.0) out=-1.0;
buf[0][i]=out*32767;
oscBuf->data[oscBuf->needle++]=out*32767;
oscBuf->putSample(i,out*32767);
} else {
buf[0][i]=0;
oscBuf->data[oscBuf->needle++]=0;
oscBuf->putSample(i,0);
}
}
oscBuf->end(len);
}
void DivPlatformPCSpeaker::acquire_piezo(short** buf, size_t len) {
oscBuf->begin(len);
for (size_t i=0; i<len; i++) {
if (on) {
pos-=PCSPKR_DIVIDER;
@ -295,12 +300,13 @@ void DivPlatformPCSpeaker::acquire_piezo(short** buf, size_t len) {
if (out>1.0) out=1.0;
if (out<-1.0) out=-1.0;
buf[0][i]=out*32767;
oscBuf->data[oscBuf->needle++]=out*32767;
oscBuf->putSample(i,out*32767);
} else {
buf[0][i]=0;
oscBuf->data[oscBuf->needle++]=0;
oscBuf->putSample(i,0);
}
}
oscBuf->end(len);
}
void DivPlatformPCSpeaker::beepFreq(int freq, int delay) {
@ -670,7 +676,7 @@ void DivPlatformPCSpeaker::setFlags(const DivConfig& flags) {
} else {
rate=chipClock/PCSPKR_DIVIDER;
}
oscBuf->rate=rate;
oscBuf->setRate(rate);
switch (speakerType) {
case 1:
@ -714,7 +720,6 @@ int DivPlatformPCSpeaker::init(DivEngine* p, int channels, int sugRate, const Di
for (int i=0; i<1; i++) {
isMuted[i]=false;
}
oscBufPos=0;
oscBuf=new DivDispatchOscBuffer;
setFlags(flags);

View file

@ -71,6 +71,9 @@ const char** DivPlatformSNES::getRegisterSheet() {
void DivPlatformSNES::acquire(short** buf, size_t len) {
short out[2];
short chOut[16];
for (int i=0; i<8; i++) {
oscBuf[i]->begin(len);
}
for (size_t h=0; h<len; h++) {
if (--delay<=0) {
delay=0;
@ -94,9 +97,12 @@ void DivPlatformSNES::acquire(short** buf, size_t len) {
next=(next*254)/MAX(1,globalVolL+globalVolR);
if (next<-32768) next=-32768;
if (next>32767) next=32767;
oscBuf[i]->data[oscBuf[i]->needle++]=next>>1;
oscBuf[i]->putSample(h,next>>1);
}
}
for (int i=0; i<8; i++) {
oscBuf[i]->end(len);
}
}
void DivPlatformSNES::tick(bool sysTick) {
@ -1058,7 +1064,7 @@ int DivPlatformSNES::init(DivEngine* p, int channels, int sugRate, const DivConf
rate=chipClock/32;
for (int i=0; i<8; i++) {
oscBuf[i]=new DivDispatchOscBuffer;
oscBuf[i]->rate=rate;
oscBuf[i]->setRate(rate);
isMuted[i]=false;
}
setFlags(flags);

View file

@ -1986,9 +1986,7 @@ bool DivEngine::nextTick(bool noAccum, bool inhibitLowLat) {
for (int i=0; i<chans; i++) {
DivDispatchOscBuffer* buf=disCont[dispatchOfChan[i]].dispatch->getOscBuffer(dispatchChanOfChan[i]);
if (buf!=NULL) {
memset(buf->data,0,65536*sizeof(short));
buf->needle=0;
buf->readNeedle=0;
buf->reset();
}
}
return ret;