new chan osc work in progress
This commit is contained in:
parent
0eea0ec139
commit
dd7e1def3d
|
@ -424,40 +424,79 @@ struct DivSamplePos {
|
||||||
freq(0) {}
|
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.
|
// the actual output of all DivDispatchOscBuffer instanced runs at 65536Hz.
|
||||||
struct DivDispatchOscBuffer {
|
struct DivDispatchOscBuffer {
|
||||||
bool follow;
|
uintmax_t rate;
|
||||||
unsigned int rate;
|
uintmax_t rateMul;
|
||||||
size_t rateMul;
|
unsigned int needleSub;
|
||||||
unsigned short needle;
|
unsigned short needle;
|
||||||
unsigned short readNeedle;
|
unsigned short readNeedle;
|
||||||
unsigned short followNeedle;
|
unsigned short followNeedle;
|
||||||
|
unsigned short lastSample;
|
||||||
|
bool follow;
|
||||||
short data[65536];
|
short data[65536];
|
||||||
|
|
||||||
// TODO: all of this
|
// TODO: all of this
|
||||||
inline void putSample(unsigned short pos, short val) {
|
inline void putSample(uintmax_t pos, short val) {
|
||||||
unsigned short realPos=needle+pos;
|
unsigned short realPos=needle+((needleSub+pos*rateMul)>>OSCBUF_PREC);
|
||||||
if (val==0xffff) {
|
if (val==-1) {
|
||||||
data[needle+pos]=0xfffe;
|
data[realPos]=0xfffe;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
data[needle+pos]=val;
|
lastSample=val;
|
||||||
|
data[realPos]=val;
|
||||||
}
|
}
|
||||||
inline void begin(unsigned short len) {
|
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) {
|
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) {
|
void setRate(unsigned int r) {
|
||||||
|
double rateMulD=65536.0/(double)r;
|
||||||
|
rateMulD*=(double)(1UL<<OSCBUF_PREC);
|
||||||
|
rate=r;
|
||||||
|
rateMul=(uintmax_t)rateMulD;
|
||||||
}
|
}
|
||||||
DivDispatchOscBuffer():
|
DivDispatchOscBuffer():
|
||||||
follow(true),
|
|
||||||
rate(65536),
|
rate(65536),
|
||||||
|
rateMul(1UL<<OSCBUF_PREC),
|
||||||
|
needleSub(0),
|
||||||
needle(0),
|
needle(0),
|
||||||
readNeedle(0),
|
readNeedle(0),
|
||||||
followNeedle(0) {
|
followNeedle(0),
|
||||||
memset(data,0,65536*sizeof(short));
|
lastSample(0),
|
||||||
|
follow(true) {
|
||||||
|
memset(data,-1,65536*sizeof(short));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -2064,9 +2064,7 @@ void DivEngine::stop() {
|
||||||
for (int i=0; i<chans; i++) {
|
for (int i=0; i<chans; i++) {
|
||||||
DivDispatchOscBuffer* buf=disCont[dispatchOfChan[i]].dispatch->getOscBuffer(dispatchChanOfChan[i]);
|
DivDispatchOscBuffer* buf=disCont[dispatchOfChan[i]].dispatch->getOscBuffer(dispatchChanOfChan[i]);
|
||||||
if (buf!=NULL) {
|
if (buf!=NULL) {
|
||||||
memset(buf->data,0,65536*sizeof(short));
|
buf->reset();
|
||||||
buf->needle=0;
|
|
||||||
buf->readNeedle=0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BUSY_END;
|
BUSY_END;
|
||||||
|
|
|
@ -134,10 +134,6 @@ bool DivDispatch::hasAcquireDirect() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DivDispatch::isOscBufPositional() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DivDispatch::getWantPreNote() {
|
bool DivDispatch::getWantPreNote() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,6 +82,10 @@ const char** DivPlatformAmiga::getRegisterSheet() {
|
||||||
void DivPlatformAmiga::acquire(short** buf, size_t len) {
|
void DivPlatformAmiga::acquire(short** buf, size_t len) {
|
||||||
thread_local int outL, outR, output;
|
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++) {
|
for (size_t h=0; h<len; h++) {
|
||||||
if (--delay<0) delay=0;
|
if (--delay<0) delay=0;
|
||||||
if (!writes.empty() && delay<=0) {
|
if (!writes.empty() && delay<=0) {
|
||||||
|
@ -182,9 +186,10 @@ void DivPlatformAmiga::acquire(short** buf, size_t len) {
|
||||||
outL+=(output*sep2)>>7;
|
outL+=(output*sep2)>>7;
|
||||||
outR+=(output*sep1)>>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 {
|
} 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[0][h]=filter[0][1];
|
||||||
buf[1][h]=filter[1][1];
|
buf[1][h]=filter[1][1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (int i=0; i<4; i++) {
|
||||||
|
oscBuf[i]->end(len);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DivPlatformAmiga::irq(int ch) {
|
void DivPlatformAmiga::irq(int ch) {
|
||||||
|
@ -826,7 +835,7 @@ void DivPlatformAmiga::setFlags(const DivConfig& flags) {
|
||||||
|
|
||||||
rate=chipClock/AMIGA_DIVIDER;
|
rate=chipClock/AMIGA_DIVIDER;
|
||||||
for (int i=0; i<4; i++) {
|
for (int i=0; i<4; i++) {
|
||||||
oscBuf[i]->rate=rate;
|
oscBuf[i]->setRate(rate);
|
||||||
}
|
}
|
||||||
int sep=flags.getInt("stereoSep",0)&127;
|
int sep=flags.getInt("stereoSep",0)&127;
|
||||||
sep1=sep+127;
|
sep1=sep+127;
|
||||||
|
|
|
@ -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++) {
|
for (size_t h=0; h<len; h++) {
|
||||||
if ((--delay)<=0) {
|
if ((--delay)<=0) {
|
||||||
delay=MAX(0,delay);
|
delay=MAX(0,delay);
|
||||||
|
@ -80,9 +84,13 @@ void DivPlatformGA20::acquire(short** buf, size_t len) {
|
||||||
ga20.sound_stream_update(buffer,1);
|
ga20.sound_stream_update(buffer,1);
|
||||||
buf[0][h]=(signed int)(ga20Buf[0][h]+ga20Buf[1][h]+ga20Buf[2][h]+ga20Buf[3][h])>>2;
|
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++) {
|
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) {
|
u8 DivPlatformGA20::read_byte(u32 address) {
|
||||||
|
@ -403,7 +411,7 @@ void DivPlatformGA20::setFlags(const DivConfig& flags) {
|
||||||
CHECK_CUSTOM_CLOCK;
|
CHECK_CUSTOM_CLOCK;
|
||||||
rate=chipClock/4;
|
rate=chipClock/4;
|
||||||
for (int i=0; i<4; i++) {
|
for (int i=0; i<4; i++) {
|
||||||
oscBuf[i]->rate=rate;
|
oscBuf[i]->setRate(rate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -196,6 +196,7 @@ void DivPlatformPCSpeaker::acquire_unfilt(blip_buffer_t** bb, size_t off, size_t
|
||||||
int out=0;
|
int out=0;
|
||||||
int freq1=freq+1;
|
int freq1=freq+1;
|
||||||
int timeToNextToggle=0;
|
int timeToNextToggle=0;
|
||||||
|
oscBuf->begin(len);
|
||||||
if (on) {
|
if (on) {
|
||||||
// just in case
|
// just in case
|
||||||
if (pos>freq1) {
|
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;
|
out=(posToggle && !isMuted[0])?32767:0;
|
||||||
blip_add_delta(bb[0],off,out-oldOut);
|
blip_add_delta(bb[0],off,out-oldOut);
|
||||||
oscBuf->data[oscBuf->needle++]=oscBufPos;
|
|
||||||
oscBuf->data[oscBuf->needle++]=out;
|
oscBuf->data[oscBuf->needle++]=out;
|
||||||
oldOut=out;
|
oldOut=out;
|
||||||
if (freq>=1) {
|
if (freq>=1) {
|
||||||
size_t boff=off;
|
size_t boff=off;
|
||||||
|
size_t oscOff=0;
|
||||||
size_t i=len;
|
size_t i=len;
|
||||||
while (true) {
|
while (true) {
|
||||||
if ((int)i<timeToNextToggle) {
|
if ((int)i<timeToNextToggle) {
|
||||||
|
@ -223,8 +224,8 @@ void DivPlatformPCSpeaker::acquire_unfilt(blip_buffer_t** bb, size_t off, size_t
|
||||||
}
|
}
|
||||||
i-=timeToNextToggle;
|
i-=timeToNextToggle;
|
||||||
boff+=timeToNextToggle;
|
boff+=timeToNextToggle;
|
||||||
|
oscOff+=timeToNextToggle;
|
||||||
pos-=timeToNextToggle;
|
pos-=timeToNextToggle;
|
||||||
oscBufPos+=timeToNextToggle;
|
|
||||||
if (pos<=0) {
|
if (pos<=0) {
|
||||||
pos=freq1;
|
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;
|
out=(posToggle && !isMuted[0])?32767:0;
|
||||||
blip_add_delta(bb[0],boff,out-oldOut);
|
blip_add_delta(bb[0],boff,out-oldOut);
|
||||||
oscBuf->data[oscBuf->needle++]=oscBufPos;
|
oscBuf->putSample(oscOff,out);
|
||||||
oscBuf->data[oscBuf->needle++]=out;
|
|
||||||
oldOut=out;
|
oldOut=out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
out=0;
|
out=0;
|
||||||
blip_add_delta(bb[0],off,out-oldOut);
|
blip_add_delta(bb[0],off,out-oldOut);
|
||||||
|
oscBuf->putSample(0,out);
|
||||||
oldOut=out;
|
oldOut=out;
|
||||||
}
|
}
|
||||||
|
oscBuf->end(len);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DivPlatformPCSpeaker::acquire_cone(short** buf, size_t len) {
|
void DivPlatformPCSpeaker::acquire_cone(short** buf, size_t len) {
|
||||||
|
oscBuf->begin(len);
|
||||||
for (size_t i=0; i<len; i++) {
|
for (size_t i=0; i<len; i++) {
|
||||||
if (on) {
|
if (on) {
|
||||||
pos-=PCSPKR_DIVIDER;
|
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;
|
||||||
if (out<-1.0) out=-1.0;
|
if (out<-1.0) out=-1.0;
|
||||||
buf[0][i]=out*32767;
|
buf[0][i]=out*32767;
|
||||||
oscBuf->data[oscBuf->needle++]=out*32767;
|
oscBuf->putSample(i,out*32767);
|
||||||
} else {
|
} else {
|
||||||
buf[0][i]=0;
|
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) {
|
void DivPlatformPCSpeaker::acquire_piezo(short** buf, size_t len) {
|
||||||
|
oscBuf->begin(len);
|
||||||
for (size_t i=0; i<len; i++) {
|
for (size_t i=0; i<len; i++) {
|
||||||
if (on) {
|
if (on) {
|
||||||
pos-=PCSPKR_DIVIDER;
|
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;
|
||||||
if (out<-1.0) out=-1.0;
|
if (out<-1.0) out=-1.0;
|
||||||
buf[0][i]=out*32767;
|
buf[0][i]=out*32767;
|
||||||
oscBuf->data[oscBuf->needle++]=out*32767;
|
oscBuf->putSample(i,out*32767);
|
||||||
} else {
|
} else {
|
||||||
buf[0][i]=0;
|
buf[0][i]=0;
|
||||||
oscBuf->data[oscBuf->needle++]=0;
|
oscBuf->putSample(i,0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
oscBuf->end(len);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DivPlatformPCSpeaker::beepFreq(int freq, int delay) {
|
void DivPlatformPCSpeaker::beepFreq(int freq, int delay) {
|
||||||
|
@ -670,7 +676,7 @@ void DivPlatformPCSpeaker::setFlags(const DivConfig& flags) {
|
||||||
} else {
|
} else {
|
||||||
rate=chipClock/PCSPKR_DIVIDER;
|
rate=chipClock/PCSPKR_DIVIDER;
|
||||||
}
|
}
|
||||||
oscBuf->rate=rate;
|
oscBuf->setRate(rate);
|
||||||
|
|
||||||
switch (speakerType) {
|
switch (speakerType) {
|
||||||
case 1:
|
case 1:
|
||||||
|
@ -714,7 +720,6 @@ int DivPlatformPCSpeaker::init(DivEngine* p, int channels, int sugRate, const Di
|
||||||
for (int i=0; i<1; i++) {
|
for (int i=0; i<1; i++) {
|
||||||
isMuted[i]=false;
|
isMuted[i]=false;
|
||||||
}
|
}
|
||||||
oscBufPos=0;
|
|
||||||
oscBuf=new DivDispatchOscBuffer;
|
oscBuf=new DivDispatchOscBuffer;
|
||||||
setFlags(flags);
|
setFlags(flags);
|
||||||
|
|
||||||
|
|
|
@ -71,6 +71,9 @@ const char** DivPlatformSNES::getRegisterSheet() {
|
||||||
void DivPlatformSNES::acquire(short** buf, size_t len) {
|
void DivPlatformSNES::acquire(short** buf, size_t len) {
|
||||||
short out[2];
|
short out[2];
|
||||||
short chOut[16];
|
short chOut[16];
|
||||||
|
for (int i=0; i<8; i++) {
|
||||||
|
oscBuf[i]->begin(len);
|
||||||
|
}
|
||||||
for (size_t h=0; h<len; h++) {
|
for (size_t h=0; h<len; h++) {
|
||||||
if (--delay<=0) {
|
if (--delay<=0) {
|
||||||
delay=0;
|
delay=0;
|
||||||
|
@ -94,9 +97,12 @@ void DivPlatformSNES::acquire(short** buf, size_t len) {
|
||||||
next=(next*254)/MAX(1,globalVolL+globalVolR);
|
next=(next*254)/MAX(1,globalVolL+globalVolR);
|
||||||
if (next<-32768) next=-32768;
|
if (next<-32768) next=-32768;
|
||||||
if (next>32767) next=32767;
|
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) {
|
void DivPlatformSNES::tick(bool sysTick) {
|
||||||
|
@ -1058,7 +1064,7 @@ int DivPlatformSNES::init(DivEngine* p, int channels, int sugRate, const DivConf
|
||||||
rate=chipClock/32;
|
rate=chipClock/32;
|
||||||
for (int i=0; i<8; i++) {
|
for (int i=0; i<8; i++) {
|
||||||
oscBuf[i]=new DivDispatchOscBuffer;
|
oscBuf[i]=new DivDispatchOscBuffer;
|
||||||
oscBuf[i]->rate=rate;
|
oscBuf[i]->setRate(rate);
|
||||||
isMuted[i]=false;
|
isMuted[i]=false;
|
||||||
}
|
}
|
||||||
setFlags(flags);
|
setFlags(flags);
|
||||||
|
|
|
@ -1986,9 +1986,7 @@ bool DivEngine::nextTick(bool noAccum, bool inhibitLowLat) {
|
||||||
for (int i=0; i<chans; i++) {
|
for (int i=0; i<chans; i++) {
|
||||||
DivDispatchOscBuffer* buf=disCont[dispatchOfChan[i]].dispatch->getOscBuffer(dispatchChanOfChan[i]);
|
DivDispatchOscBuffer* buf=disCont[dispatchOfChan[i]].dispatch->getOscBuffer(dispatchChanOfChan[i]);
|
||||||
if (buf!=NULL) {
|
if (buf!=NULL) {
|
||||||
memset(buf->data,0,65536*sizeof(short));
|
buf->reset();
|
||||||
buf->needle=0;
|
|
||||||
buf->readNeedle=0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -102,14 +102,14 @@ void FurnaceGUI::calcChanOsc() {
|
||||||
}
|
}
|
||||||
if (buf!=NULL && e->curSubSong->chanShowChanOsc[i]) {
|
if (buf!=NULL && e->curSubSong->chanShowChanOsc[i]) {
|
||||||
// 30ms should be enough
|
// 30ms should be enough
|
||||||
int displaySize=(float)(buf->rate)*0.03f;
|
int displaySize=65536.0f*0.03f;
|
||||||
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;
|
||||||
needlePos-=displaySize;
|
for (unsigned short i=needlePos-displaySize; i!=needlePos; i++) {
|
||||||
for (unsigned short i=0; i<512; i++) {
|
short y=buf->data[i];
|
||||||
short y=buf->data[(unsigned short)(needlePos+(i*displaySize/512))];
|
if (y==-1) continue;
|
||||||
if (minLevel>y) minLevel=y;
|
if (minLevel>y) minLevel=y;
|
||||||
if (maxLevel<y) maxLevel=y;
|
if (maxLevel<y) maxLevel=y;
|
||||||
}
|
}
|
||||||
|
@ -460,17 +460,36 @@ void FurnaceGUI::drawChanOsc() {
|
||||||
// I have a feeling this could be simplified to two FFTs or even one...
|
// I have a feeling this could be simplified to two FFTs or even one...
|
||||||
// if you know how, please tell me
|
// if you know how, please tell me
|
||||||
|
|
||||||
|
// TODO: utterly broken!
|
||||||
|
|
||||||
// initialization
|
// initialization
|
||||||
double phase=0.0;
|
double phase=0.0;
|
||||||
int displaySize=(float)(buf->rate)*(fft->windowSize/1000.0f);
|
int displaySize=65536.0f*(fft->windowSize/1000.0f);
|
||||||
|
int displaySize2=65536.0f*(fft->windowSize/500.0f);
|
||||||
fft->loudEnough=false;
|
fft->loudEnough=false;
|
||||||
fft->needle=buf->needle;
|
fft->needle=buf->needle;
|
||||||
|
|
||||||
// first FFT
|
// first FFT
|
||||||
for (int j=0; j<FURNACE_FFT_SIZE; j++) {
|
int k=0;
|
||||||
fft->inBuf[j]=(double)buf->data[(unsigned short)(fft->needle-displaySize*2+((j*displaySize*2)/(FURNACE_FFT_SIZE)))]/32768.0;
|
short lastSample=0;
|
||||||
if (fft->inBuf[j]>0.001 || fft->inBuf[j]<-0.001) fft->loudEnough=true;
|
memset(fft->inBuf,0,FURNACE_FFT_SIZE*sizeof(double));
|
||||||
fft->inBuf[j]*=0.55-0.45*cos(M_PI*(double)j/(double)(FURNACE_FFT_SIZE>>1));
|
if (displaySize2<FURNACE_FFT_SIZE) {
|
||||||
|
for (int j=0; j<FURNACE_FFT_SIZE; j++) {
|
||||||
|
const short newData=buf->data[(unsigned short)(fft->needle-displaySize2+((j*displaySize2)/(FURNACE_FFT_SIZE)))];
|
||||||
|
if (newData!=-1) lastSample=newData;
|
||||||
|
fft->inBuf[j]=(double)lastSample/32768.0;
|
||||||
|
if (fft->inBuf[j]>0.001 || fft->inBuf[j]<-0.001) fft->loudEnough=true;
|
||||||
|
fft->inBuf[j]*=0.55-0.45*cos(M_PI*(double)j/(double)(FURNACE_FFT_SIZE>>1));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (unsigned short j=fft->needle-displaySize2; j!=fft->needle; j++, k++) {
|
||||||
|
const int kIn=(k*FURNACE_FFT_SIZE)/displaySize2;
|
||||||
|
if (kIn>=FURNACE_FFT_SIZE) break;
|
||||||
|
if (buf->data[j]!=-1) lastSample=buf->data[j];
|
||||||
|
fft->inBuf[kIn]=(double)lastSample/32768.0;
|
||||||
|
if (fft->inBuf[kIn]>0.001 || fft->inBuf[kIn]<-0.001) fft->loudEnough=true;
|
||||||
|
fft->inBuf[kIn]*=0.55-0.45*cos(M_PI*(double)kIn/(double)(FURNACE_FFT_SIZE>>1));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// only proceed if not quiet
|
// only proceed if not quiet
|
||||||
|
@ -615,7 +634,8 @@ void FurnaceGUI::drawChanOsc() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
int displaySize=(float)(buf->rate)*(chanOscWindowSize/1000.0f);
|
int displaySize=65536.0f*(chanOscWindowSize/1000.0f);
|
||||||
|
int displaySize2=65536.0f*(chanOscWindowSize/500.0f);
|
||||||
|
|
||||||
float minLevel=1.0f;
|
float minLevel=1.0f;
|
||||||
float maxLevel=-1.0f;
|
float maxLevel=-1.0f;
|
||||||
|
@ -654,7 +674,7 @@ void FurnaceGUI::drawChanOsc() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (fft->loudEnough) {
|
if (fft->loudEnough) {
|
||||||
String cPhase=fmt::sprintf("\n%.1f (b: %d t: %d)",fft->waveLen,fft->waveLenBottom,fft->waveLenTop);
|
String cPhase=fmt::sprintf("\n%.1f (b: %d t: %d)\nSIZES: %d, %d, %d",fft->waveLen,fft->waveLenBottom,fft->waveLenTop,displaySize,displaySize2,FURNACE_FFT_SIZE);
|
||||||
dl->AddText(inRect.Min,0xffffffff,cPhase.c_str());
|
dl->AddText(inRect.Min,0xffffffff,cPhase.c_str());
|
||||||
|
|
||||||
dl->AddLine(
|
dl->AddLine(
|
||||||
|
@ -673,31 +693,48 @@ void FurnaceGUI::drawChanOsc() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (unsigned short j=0; j<precision; j++) {
|
String dStr=fmt::sprintf("DS: %d P: %d",displaySize,precision);
|
||||||
float y=(float)buf->data[(unsigned short)(fft->needle+(j*displaySize/precision))]/32768.0f;
|
dl->AddText(inRect.Min,0xffffffff,dStr.c_str());
|
||||||
if (minLevel>y) minLevel=y;
|
if (displaySize<precision) {
|
||||||
if (maxLevel<y) maxLevel=y;
|
float y=0;
|
||||||
|
for (unsigned short j=0; j<precision; j++) {
|
||||||
|
const short y_s=buf->data[(unsigned short)(fft->needle+(j*displaySize/precision))];
|
||||||
|
if (y_s!=-1) {
|
||||||
|
y=(float)y_s/32768.0f;
|
||||||
|
if (minLevel>y) minLevel=y;
|
||||||
|
if (maxLevel<y) maxLevel=y;
|
||||||
|
}
|
||||||
|
float yOut=y-dcOff;
|
||||||
|
if (yOut<-0.5f) yOut=-0.5f;
|
||||||
|
if (yOut>0.5f) yOut=0.5f;
|
||||||
|
yOut*=chanOscAmplify*2.0f;
|
||||||
|
fft->oscTex[j]=yOut;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
float y=0;
|
||||||
|
int k=0;
|
||||||
|
for (unsigned short j=fft->needle; j!=fft->needle+displaySize; j++, k++) {
|
||||||
|
const short y_s=buf->data[j];
|
||||||
|
const int kTex=(k*precision)/displaySize;
|
||||||
|
if (kTex>=precision) break;
|
||||||
|
if (y_s!=-1) {
|
||||||
|
y=(float)y_s/32768.0f;
|
||||||
|
if (minLevel>y) minLevel=y;
|
||||||
|
if (maxLevel<y) maxLevel=y;
|
||||||
|
}
|
||||||
|
float yOut=y-dcOff;
|
||||||
|
if (yOut<-0.5f) yOut=-0.5f;
|
||||||
|
if (yOut>0.5f) yOut=0.5f;
|
||||||
|
yOut*=chanOscAmplify*2.0f;
|
||||||
|
fft->oscTex[kTex]=yOut;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
dcOff=(minLevel+maxLevel)*0.5f;
|
dcOff=(minLevel+maxLevel)*0.5f;
|
||||||
|
|
||||||
if (rend->supportsDrawOsc() && settings.shaderOsc) {
|
if (!(rend->supportsDrawOsc() && settings.shaderOsc)) {
|
||||||
for (unsigned short j=0; j<precision; j++) {
|
|
||||||
float y=(float)buf->data[(unsigned short)(fft->needle+(j*displaySize/precision))]/32768.0f;
|
|
||||||
y-=dcOff;
|
|
||||||
if (y<-0.5f) y=-0.5f;
|
|
||||||
if (y>0.5f) y=0.5f;
|
|
||||||
y*=chanOscAmplify*2.0f;
|
|
||||||
fft->oscTex[j]=y;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for (unsigned short j=0; j<precision; j++) {
|
for (unsigned short j=0; j<precision; j++) {
|
||||||
float x=(float)j/(float)precision;
|
float x=(float)j/(float)precision;
|
||||||
float y=(float)buf->data[(unsigned short)(fft->needle+(j*displaySize/precision))]/32768.0f;
|
waveform[j]=ImLerp(inRect.Min,inRect.Max,ImVec2(x,0.5f-fft->oscTex[j]*0.5f));
|
||||||
y-=dcOff;
|
|
||||||
if (y<-0.5f) y=-0.5f;
|
|
||||||
if (y>0.5f) y=0.5f;
|
|
||||||
y*=chanOscAmplify;
|
|
||||||
waveform[j]=ImLerp(inRect.Min,inRect.Max,ImVec2(x,0.5f-y));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -252,7 +252,7 @@ void FurnaceGUI::drawDebug() {
|
||||||
ImGui::TableNextColumn();
|
ImGui::TableNextColumn();
|
||||||
ImGui::Text("Follow");
|
ImGui::Text("Follow");
|
||||||
ImGui::TableNextColumn();
|
ImGui::TableNextColumn();
|
||||||
ImGui::Text("Address");
|
ImGui::Text("Needle");
|
||||||
ImGui::TableNextColumn();
|
ImGui::TableNextColumn();
|
||||||
ImGui::Text("Data");
|
ImGui::Text("Data");
|
||||||
|
|
||||||
|
|
|
@ -4181,8 +4181,9 @@ bool FurnaceGUI::loop() {
|
||||||
for (int i=0; i<e->getTotalChannelCount(); i++) {
|
for (int i=0; i<e->getTotalChannelCount(); i++) {
|
||||||
DivDispatchOscBuffer* buf=e->getOscBuffer(i);
|
DivDispatchOscBuffer* buf=e->getOscBuffer(i);
|
||||||
if (buf!=NULL) {
|
if (buf!=NULL) {
|
||||||
buf->needle=0;
|
//buf->needle=0;
|
||||||
buf->readNeedle=0;
|
//buf->readNeedle=0;
|
||||||
|
// TODO: should we reset here?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue