Merge branch 'newChanOsc' - read for info

copy-paste from Discord

the new DivDispatch::acquireDirect() function allows optimizing emulation cores by only rendering what is needed (such as state changes in PC Speaker).
it gives DivDispatch direct access to blip_buf structures in order to allow that.

however, this requires changes to the chan osc buffer API since we're not gonna fill entire bufs anymore with acquireDirect

the accommodations consist of:
- new functions to fill a chan osc buffer
- the sample `-1` means "no changes" (don't worry, the new funcs will handle this for you), and
- all chan osc bufs now run at 65536Hz (as opposed to a rate defined by the dispatch). this also avoids buffer overruns and maybe glitches when audio buf size is too large.

if you've been working on a DivDispatch (in other words, a new chip or system), make sure to adapt your code to the new API. here are some guidelines:
1. in your acquire() function, call begin(len) of all DivDispatchOscBuffers before you run emu code and fill the out buffer.
2. replace `oscBuf[]->data[oscBuf[]->needle++]=val` with `oscBuf[]->putSample(h,val)`. `h` is the position of the buffer iterator (e.g. in the `for (size_t h=0; h<len; h++)` function). yes, this API is positional...
3. after emulation code runs and you fill the out buf (including all osc bufs), call end(len). this will advance the needle and all.

here's some sample code.

```
int DivPlatformDango::acquire(short** buf, size_t len) {
  for (size_t h=0; h<len; h++) {
    buf[0][h]=dango.tick();
    for (int i=0; i<16; i++) {
      oscBuf[i]->data[oscBuf[i]->needle++]=dango.getChOut(i);
    }
  }
}
```

```
int DivPlatformDango::acquire(short** buf, size_t len) {
  for (int i=0; i<16; i++) {
    oscBuf[i]->begin(len);
  }
  for (size_t h=0; h<len; h++) {
    buf[0][h]=dango.tick();
    for (int i=0; i<16; i++) {
      oscBuf[i]->putSample(h,dango.getChOut(i));
    }
  }
  for (int i=0; i<16; i++) {
    oscBuf[i]->end(len);
  }
}
```

thanks and sorry for any trouble this may cause
i kept running into the character limit
This commit is contained in:
tildearrow 2025-03-02 18:52:01 -05:00
commit cf86b9ab9a
89 changed files with 1347 additions and 492 deletions

View file

@ -307,7 +307,7 @@ BYTE CSAADevice::_ReadData(void)
}
#endif
void CSAADevice::_TickAndOutputStereo(unsigned int& left_mixed, unsigned int& right_mixed, DivDispatchOscBuffer** oscBuf)
void CSAADevice::_TickAndOutputStereo(unsigned int& left_mixed, unsigned int& right_mixed, DivDispatchOscBuffer** oscBuf, unsigned int where)
{
unsigned int temp_left, temp_right;
unsigned int accum_left = 0, accum_right = 0;
@ -316,27 +316,27 @@ void CSAADevice::_TickAndOutputStereo(unsigned int& left_mixed, unsigned int& ri
m_Noise0.Tick();
m_Noise1.Tick();
m_Amp0.TickAndOutputStereo(temp_left, temp_right);
oscBuf[0]->data[oscBuf[0]->needle++]=(temp_left+temp_right)<<5;
oscBuf[0]->putSample(where,(temp_left+temp_right)<<5);
accum_left += temp_left;
accum_right += temp_right;
m_Amp1.TickAndOutputStereo(temp_left, temp_right);
oscBuf[1]->data[oscBuf[1]->needle++]=(temp_left+temp_right)<<5;
oscBuf[1]->putSample(where,(temp_left+temp_right)<<5);
accum_left += temp_left;
accum_right += temp_right;
m_Amp2.TickAndOutputStereo(temp_left, temp_right);
oscBuf[2]->data[oscBuf[2]->needle++]=(temp_left+temp_right)<<5;
oscBuf[2]->putSample(where,(temp_left+temp_right)<<5);
accum_left += temp_left;
accum_right += temp_right;
m_Amp3.TickAndOutputStereo(temp_left, temp_right);
oscBuf[3]->data[oscBuf[3]->needle++]=(temp_left+temp_right)<<5;
oscBuf[3]->putSample(where,(temp_left+temp_right)<<5);
accum_left += temp_left;
accum_right += temp_right;
m_Amp4.TickAndOutputStereo(temp_left, temp_right);
oscBuf[4]->data[oscBuf[4]->needle++]=(temp_left+temp_right)<<5;
oscBuf[4]->putSample(where,(temp_left+temp_right)<<5);
accum_left += temp_left;
accum_right += temp_right;
m_Amp5.TickAndOutputStereo(temp_left, temp_right);
oscBuf[5]->data[oscBuf[5]->needle++]=(temp_left+temp_right)<<5;
oscBuf[5]->putSample(where,(temp_left+temp_right)<<5);
accum_left += temp_left;
accum_right += temp_right;
}

View file

@ -53,7 +53,7 @@ public:
void _SetClockRate(unsigned int nClockRate);
void _SetSampleRate(unsigned int nSampleRate);
void _SetOversample(unsigned int nOversample);
void _TickAndOutputStereo(unsigned int& left_mixed, unsigned int& right_mixed, DivDispatchOscBuffer** oscBuf);
void _TickAndOutputStereo(unsigned int& left_mixed, unsigned int& right_mixed, DivDispatchOscBuffer** oscBuf, unsigned int where);
void _TickAndOutputSeparate(unsigned int& left_mixed, unsigned int& right_mixed,
unsigned int& left0, unsigned int& right0,
unsigned int& left1, unsigned int& right1,

View file

@ -373,9 +373,10 @@ void CSAASoundInternal::GenerateMany(BYTE* pBuffer, unsigned int nSamples, DivDi
else
{
#endif
unsigned int where=0;
while (nSamples--)
{
m_chip._TickAndOutputStereo(left_mixed, right_mixed, oscBuf);
m_chip._TickAndOutputStereo(left_mixed, right_mixed, oscBuf, where++);
scale_for_output(left_mixed, right_mixed, oversample, m_bHighpass, nBoost, filterout_z1_left_mixed, filterout_z1_right_mixed, pBuffer);
}

View file

@ -424,21 +424,80 @@ 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;
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];
inline void putSample(uintmax_t pos, short val) {
unsigned short realPos=needle+((needleSub+pos*rateMul)>>OSCBUF_PREC);
if (val==-1) {
data[realPos]=0xfffe;
return;
}
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;
//logD("C %d %d %d",len,calc,rate);
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) {
uintmax_t calc=len*rateMul;
if (((calc&OSCBUF_MASK)+needleSub)>OSCBUF_MASK) {
calc+=1UL<<OSCBUF_PREC;
}
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

@ -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

@ -54,6 +54,10 @@ const char** DivPlatformArcade::getRegisterSheet() {
void DivPlatformArcade::acquire_nuked(short** buf, size_t len) {
thread_local int o[2];
for (int i=0; i<8; i++) {
oscBuf[i]->begin(len);
}
for (size_t h=0; h<len; h++) {
if (delay>0) delay--;
for (int i=0; i<8; i++) {
@ -81,7 +85,7 @@ void DivPlatformArcade::acquire_nuked(short** buf, size_t len) {
for (int i=0; i<8; i++) {
int chOut=(int16_t)fm.ch_out[i];
oscBuf[i]->data[oscBuf[i]->needle++]=CLAMP(chOut<<1,-32768,32767);
oscBuf[i]->putSample(h,CLAMP(chOut<<1,-32768,32767));
}
if (o[0]<-32768) o[0]=-32768;
@ -93,6 +97,10 @@ void DivPlatformArcade::acquire_nuked(short** buf, size_t len) {
buf[0][h]=o[0];
buf[1][h]=o[1];
}
for (int i=0; i<8; i++) {
oscBuf[i]->end(len);
}
}
void DivPlatformArcade::acquire_ymfm(short** buf, size_t len) {
@ -100,6 +108,10 @@ void DivPlatformArcade::acquire_ymfm(short** buf, size_t len) {
ymfm::ym2151::fm_engine* fme=fm_ymfm->debug_engine();
for (int i=0; i<8; i++) {
oscBuf[i]->begin(len);
}
for (size_t h=0; h<len; h++) {
os[0]=0; os[1]=0;
if (!writes.empty()) {
@ -121,7 +133,7 @@ void DivPlatformArcade::acquire_ymfm(short** buf, size_t len) {
for (int i=0; i<8; i++) {
int chOut=fme->debug_channel(i)->debug_output(0)+fme->debug_channel(i)->debug_output(1);
oscBuf[i]->data[oscBuf[i]->needle++]=CLAMP(chOut,-32768,32767);
oscBuf[i]->putSample(h,CLAMP(chOut,-32768,32767));
}
os[0]=out_ymfm.data[0];
@ -135,6 +147,10 @@ void DivPlatformArcade::acquire_ymfm(short** buf, size_t len) {
buf[0][h]=os[0];
buf[1][h]=os[1];
}
for (int i=0; i<8; i++) {
oscBuf[i]->end(len);
}
}
void DivPlatformArcade::acquire(short** buf, size_t len) {
@ -964,7 +980,7 @@ void DivPlatformArcade::setFlags(const DivConfig& flags) {
rate=chipClock/64;
for (int i=0; i<8; i++) {
oscBuf[i]->rate=rate;
oscBuf[i]->setRate(rate);
}
}

View file

@ -257,6 +257,10 @@ void DivPlatformAY8910::acquire_mame(short** buf, size_t len) {
}
}
for (int i=0; i<3; i++) {
oscBuf[i]->begin(len);
}
if (sunsoft) {
for (size_t i=0; i<len; i++) {
runDAC();
@ -267,9 +271,9 @@ void DivPlatformAY8910::acquire_mame(short** buf, size_t len) {
buf[0][i]=ayBuf[0][0];
buf[1][i]=buf[0][i];
oscBuf[0]->data[oscBuf[0]->needle++]=CLAMP(sunsoftVolTable[31-(ay->lastIndx&31)]<<3,-32768,32767);
oscBuf[1]->data[oscBuf[1]->needle++]=CLAMP(sunsoftVolTable[31-((ay->lastIndx>>5)&31)]<<3,-32768,32767);
oscBuf[2]->data[oscBuf[2]->needle++]=CLAMP(sunsoftVolTable[31-((ay->lastIndx>>10)&31)]<<3,-32768,32767);
oscBuf[0]->putSample(i,CLAMP(sunsoftVolTable[31-(ay->lastIndx&31)]<<3,-32768,32767));
oscBuf[1]->putSample(i,CLAMP(sunsoftVolTable[31-((ay->lastIndx>>5)&31)]<<3,-32768,32767));
oscBuf[2]->putSample(i,CLAMP(sunsoftVolTable[31-((ay->lastIndx>>10)&31)]<<3,-32768,32767));
}
} else {
for (size_t i=0; i<len; i++) {
@ -286,14 +290,21 @@ void DivPlatformAY8910::acquire_mame(short** buf, size_t len) {
buf[1][i]=buf[0][i];
}
oscBuf[0]->data[oscBuf[0]->needle++]=ayBuf[0][0]<<2;
oscBuf[1]->data[oscBuf[1]->needle++]=ayBuf[1][0]<<2;
oscBuf[2]->data[oscBuf[2]->needle++]=ayBuf[2][0]<<2;
oscBuf[0]->putSample(i,ayBuf[0][0]<<2);
oscBuf[1]->putSample(i,ayBuf[1][0]<<2);
oscBuf[2]->putSample(i,ayBuf[2][0]<<2);
}
}
for (int i=0; i<3; i++) {
oscBuf[i]->end(len);
}
}
void DivPlatformAY8910::acquire_atomic(short** buf, size_t len) {
for (int i=0; i<3; i++) {
oscBuf[i]->begin(len);
}
for (size_t i=0; i<len; i++) {
runDAC();
runTFX();
@ -316,9 +327,12 @@ void DivPlatformAY8910::acquire_atomic(short** buf, size_t len) {
buf[1][i]=buf[0][i];
}
oscBuf[0]->data[oscBuf[0]->needle++]=ay_atomic.o_analog[0];
oscBuf[1]->data[oscBuf[1]->needle++]=ay_atomic.o_analog[1];
oscBuf[2]->data[oscBuf[2]->needle++]=ay_atomic.o_analog[2];
oscBuf[0]->putSample(i,ay_atomic.o_analog[0]);
oscBuf[1]->putSample(i,ay_atomic.o_analog[1]);
oscBuf[2]->putSample(i,ay_atomic.o_analog[2]);
}
for (int i=0; i<3; i++) {
oscBuf[i]->end(len);
}
}
@ -1154,7 +1168,7 @@ void DivPlatformAY8910::setFlags(const DivConfig& flags) {
}
for (int i=0; i<3; i++) {
oscBuf[i]->rate=rate;
oscBuf[i]->setRate(rate);
}
stereo=flags.getBool("stereo",false);

View file

@ -173,6 +173,10 @@ void DivPlatformAY8930::acquire(short** buf, size_t len) {
}
}
for (int i=0; i<3; i++) {
oscBuf[i]->begin(len);
}
for (size_t i=0; i<len; i++) {
runDAC();
checkWrites();
@ -186,9 +190,13 @@ void DivPlatformAY8930::acquire(short** buf, size_t len) {
buf[1][i]=buf[0][i];
}
oscBuf[0]->data[oscBuf[0]->needle++]=ayBuf[0][0]<<2;
oscBuf[1]->data[oscBuf[1]->needle++]=ayBuf[1][0]<<2;
oscBuf[2]->data[oscBuf[2]->needle++]=ayBuf[2][0]<<2;
oscBuf[0]->putSample(i,ayBuf[0][0]<<2);
oscBuf[1]->putSample(i,ayBuf[1][0]<<2);
oscBuf[2]->putSample(i,ayBuf[2][0]<<2);
}
for (int i=0; i<3; i++) {
oscBuf[i]->end(len);
}
}
@ -923,7 +931,7 @@ void DivPlatformAY8930::setFlags(const DivConfig& flags) {
CHECK_CUSTOM_CLOCK;
rate=chipClock/4;
for (int i=0; i<3; i++) {
oscBuf[i]->rate=rate;
oscBuf[i]->setRate(rate);
}
stereo=flags.getBool("stereo",false);

View file

@ -48,6 +48,9 @@ void DivPlatformBifurcator::acquire(short** buf, size_t len) {
chan[i].chVolL=regPool[i*8+6];
chan[i].chVolR=regPool[i*8+7];
}
for (int i=0; i<4; i++) {
oscBuf[i]->begin(len);
}
for (size_t h=0; h<len; h++) {
int l=0;
int r=0;
@ -62,13 +65,16 @@ void DivPlatformBifurcator::acquire(short** buf, size_t len) {
int out=chan[i].curx-32768;
int outL=out*chan[i].chVolL/256;
int outR=out*chan[i].chVolR/256;
oscBuf[i]->data[oscBuf[i]->needle++]=(short)((outL+outR)/2);
oscBuf[i]->putSample(h,(short)((outL+outR)/2));
l+=outL/4;
r+=outR/4;
}
buf[0][h]=(short)l;
buf[1][h]=(short)r;
}
for (int i=0; i<4; i++) {
oscBuf[i]->end(len);
}
for (int i=0; i<4; i++) {
regPool[i*8]=chan[i].curx&0xff;
regPool[i*8+1]=chan[i].curx>>8;
@ -347,7 +353,7 @@ void DivPlatformBifurcator::setFlags(const DivConfig& flags) {
CHECK_CUSTOM_CLOCK;
rate=chipClock/16;
for (int i=0; i<4; i++) {
oscBuf[i]->rate=rate;
oscBuf[i]->setRate(rate);
}
}

View file

@ -41,6 +41,9 @@ const char** DivPlatformBubSysWSG::getRegisterSheet() {
void DivPlatformBubSysWSG::acquire(short** buf, size_t len) {
int chanOut=0;
for (int i=0; i<2; i++) {
oscBuf[i]->begin(len);
}
for (size_t h=0; h<len; h++) {
signed int out=0;
// K005289 part
@ -49,13 +52,13 @@ void DivPlatformBubSysWSG::acquire(short** buf, size_t len) {
// Wavetable part
for (int i=0; i<2; i++) {
if (isMuted[i]) {
oscBuf[i]->data[oscBuf[i]->needle++]=0;
oscBuf[i]->putSample(h,0);
continue;
} else {
chanOut=chan[i].waveROM[k005289.addr(i)]*(regPool[2+i]&0xf);
out+=chanOut;
if (writeOscBuf==0) {
oscBuf[i]->data[oscBuf[i]->needle++]=chanOut<<7;
oscBuf[i]->putSample(h,chanOut<<7);
}
}
}
@ -70,6 +73,9 @@ void DivPlatformBubSysWSG::acquire(short** buf, size_t len) {
//printf("out: %d\n",out);
buf[0][h]=out;
}
for (int i=0; i<2; i++) {
oscBuf[i]->end(len);
}
}
void DivPlatformBubSysWSG::updateWave(int ch) {
@ -334,7 +340,7 @@ void DivPlatformBubSysWSG::setFlags(const DivConfig& flags) {
CHECK_CUSTOM_CLOCK;
rate=chipClock/coreQuality;
for (int i=0; i<2; i++) {
oscBuf[i]->rate=rate/8;
oscBuf[i]->setRate(rate);
}
}

View file

@ -68,6 +68,9 @@ const char** DivPlatformC140::getRegisterSheet() {
}
void DivPlatformC140::acquire_219(short** buf, size_t len) {
for (int i=0; i<totalChans; i++) {
oscBuf[i]->begin(len);
}
for (size_t h=0; h<len; h++) {
while (!writes.empty()) {
QueuedWrite w=writes.front();
@ -92,15 +95,21 @@ void DivPlatformC140::acquire_219(short** buf, size_t len) {
for (int i=0; i<totalChans; i++) {
if (c219.voice[i].inv_lout) {
oscBuf[i]->data[oscBuf[i]->needle++]=(c219.voice[i].lout-c219.voice[i].rout)>>10;
oscBuf[i]->putSample(h,(c219.voice[i].lout-c219.voice[i].rout)>>10);
} else {
oscBuf[i]->data[oscBuf[i]->needle++]=(c219.voice[i].lout+c219.voice[i].rout)>>10;
oscBuf[i]->putSample(h,(c219.voice[i].lout+c219.voice[i].rout)>>10);
}
}
}
for (int i=0; i<totalChans; i++) {
oscBuf[i]->end(len);
}
}
void DivPlatformC140::acquire_140(short** buf, size_t len) {
for (int i=0; i<totalChans; i++) {
oscBuf[i]->begin(len);
}
for (size_t h=0; h<len; h++) {
while (!writes.empty()) {
QueuedWrite w=writes.front();
@ -124,9 +133,12 @@ void DivPlatformC140::acquire_140(short** buf, size_t len) {
buf[1][h]=c140.rout;
for (int i=0; i<totalChans; i++) {
oscBuf[i]->data[oscBuf[i]->needle++]=(c140.voice[i].lout+c140.voice[i].rout)>>10;
oscBuf[i]->putSample(h,(c140.voice[i].lout+c140.voice[i].rout)>>10);
}
}
for (int i=0; i<totalChans; i++) {
oscBuf[i]->end(len);
}
}
void DivPlatformC140::acquire(short** buf, size_t len) {
@ -752,7 +764,7 @@ void DivPlatformC140::setFlags(const DivConfig& flags) {
c140_bank_type(&c140,bankType);
}
for (int i=0; i<totalChans; i++) {
oscBuf[i]->rate=rate;
oscBuf[i]->setRate(rate);
}
}

View file

@ -139,6 +139,9 @@ void DivPlatformC64::processDAC(int sRate) {
void DivPlatformC64::acquire(short** buf, size_t len) {
int dcOff=(sidCore)?0:sid->get_dc(0);
for (int i=0; i<4; i++) {
oscBuf[i]->begin(len);
}
for (size_t i=0; i<len; i++) {
// run PCM
pcmCycle+=lineRate;
@ -165,32 +168,35 @@ void DivPlatformC64::acquire(short** buf, size_t len) {
buf[0][i]=32767*CLAMP(o,-1.0,1.0);
if (++writeOscBuf>=4) {
writeOscBuf=0;
oscBuf[0]->data[oscBuf[0]->needle++]=sid_d->lastOut[0];
oscBuf[1]->data[oscBuf[1]->needle++]=sid_d->lastOut[1];
oscBuf[2]->data[oscBuf[2]->needle++]=sid_d->lastOut[2];
oscBuf[3]->data[oscBuf[3]->needle++]=chan[3].pcmOut<<11;
oscBuf[0]->putSample(i,sid_d->lastOut[0]);
oscBuf[1]->putSample(i,sid_d->lastOut[1]);
oscBuf[2]->putSample(i,sid_d->lastOut[2]);
oscBuf[3]->putSample(i,chan[3].pcmOut<<11);
}
} else if (sidCore==1) {
sid_fp->clock(4,&buf[0][i]);
if (++writeOscBuf>=4) {
writeOscBuf=0;
oscBuf[0]->data[oscBuf[0]->needle++]=runFakeFilter(0,(sid_fp->lastChanOut[0]-dcOff)>>5);
oscBuf[1]->data[oscBuf[1]->needle++]=runFakeFilter(1,(sid_fp->lastChanOut[1]-dcOff)>>5);
oscBuf[2]->data[oscBuf[2]->needle++]=runFakeFilter(2,(sid_fp->lastChanOut[2]-dcOff)>>5);
oscBuf[3]->data[oscBuf[3]->needle++]=chan[3].pcmOut<<11;
oscBuf[0]->putSample(i,runFakeFilter(0,(sid_fp->lastChanOut[0]-dcOff)>>5));
oscBuf[1]->putSample(i,runFakeFilter(1,(sid_fp->lastChanOut[1]-dcOff)>>5));
oscBuf[2]->putSample(i,runFakeFilter(2,(sid_fp->lastChanOut[2]-dcOff)>>5));
oscBuf[3]->putSample(i,chan[3].pcmOut<<11);
}
} else {
sid->clock();
buf[0][i]=sid->output();
if (++writeOscBuf>=16) {
writeOscBuf=0;
oscBuf[0]->data[oscBuf[0]->needle++]=runFakeFilter(0,(sid->last_chan_out[0]-dcOff)>>5);
oscBuf[1]->data[oscBuf[1]->needle++]=runFakeFilter(1,(sid->last_chan_out[1]-dcOff)>>5);
oscBuf[2]->data[oscBuf[2]->needle++]=runFakeFilter(2,(sid->last_chan_out[2]-dcOff)>>5);
oscBuf[3]->data[oscBuf[3]->needle++]=chan[3].pcmOut<<11;
oscBuf[0]->putSample(i,runFakeFilter(0,(sid->last_chan_out[0]-dcOff)>>5));
oscBuf[1]->putSample(i,runFakeFilter(1,(sid->last_chan_out[1]-dcOff)>>5));
oscBuf[2]->putSample(i,runFakeFilter(2,(sid->last_chan_out[2]-dcOff)>>5));
oscBuf[3]->putSample(i,chan[3].pcmOut<<11);
}
}
}
for (int i=0; i<4; i++) {
oscBuf[i]->end(len);
}
}
void DivPlatformC64::updateFilter() {
@ -912,13 +918,13 @@ void DivPlatformC64::setFlags(const DivConfig& flags) {
}
CHECK_CUSTOM_CLOCK;
rate=chipClock;
for (int i=0; i<4; i++) {
oscBuf[i]->rate=rate/16;
}
if (sidCore>0) {
rate/=(sidCore==2)?coreQuality:4;
if (sidCore==1) sid_fp->setSamplingParameters(chipClock,reSIDfp::DECIMATE,rate,0);
}
for (int i=0; i<4; i++) {
oscBuf[i]->setRate(rate);
}
keyPriority=flags.getBool("keyPriority",true);
no1EUpdate=flags.getBool("no1EUpdate",false);
multiplyRel=flags.getBool("multiplyRel",false);
@ -930,15 +936,16 @@ void DivPlatformC64::setFlags(const DivConfig& flags) {
// init fake filter table
// taken from dSID
double cutRatio=-2.0*3.14*(sidIs6581?(((double)oscBuf[0]->rate/44100.0)*(20000.0/256.0)):(12500.0/256.0))/(double)oscBuf[0]->rate;
double oscBufRate=(double)rate/16.0;
double cutRatio=-2.0*3.14*(sidIs6581?((oscBufRate/44100.0)*(20000.0/256.0)):(12500.0/256.0))/oscBufRate;
for (int i=0; i<2048; i++) {
double c=(double)i/8.0+0.2;
if (sidIs6581) {
if (c<24) {
c=2.0*sin(771.78/(double)oscBuf[0]->rate);
c=2.0*sin(771.78/oscBufRate);
} else {
c=(44100.0/(double)oscBuf[0]->rate)-1.263*(44100.0/(double)oscBuf[0]->rate)*exp(c*cutRatio);
c=(44100.0/oscBufRate)-1.263*(44100.0/oscBufRate)*exp(c*cutRatio);
}
} else {
c=1-exp(c*cutRatio);

View file

@ -64,6 +64,10 @@ const char** DivPlatformDave::getRegisterSheet() {
}
void DivPlatformDave::acquire(short** buf, size_t len) {
for (int i=0; i<6; i++) {
oscBuf[i]->begin(len);
}
for (size_t h=0; h<len; h++) {
for (int i=4; i<6; i++) {
if (chan[i].dacSample!=-1) {
@ -107,38 +111,42 @@ void DivPlatformDave::acquire(short** buf, size_t len) {
unsigned short nextR=next>>16;
if ((regPool[7]&0x18)==0x18) {
oscBuf[0]->data[oscBuf[0]->needle++]=0;
oscBuf[1]->data[oscBuf[1]->needle++]=0;
oscBuf[2]->data[oscBuf[2]->needle++]=0;
oscBuf[3]->data[oscBuf[3]->needle++]=0;
oscBuf[4]->data[oscBuf[4]->needle++]=dave->chn0_left<<9;
oscBuf[5]->data[oscBuf[5]->needle++]=dave->chn0_right<<9;
oscBuf[0]->putSample(h,0);
oscBuf[1]->putSample(h,0);
oscBuf[2]->putSample(h,0);
oscBuf[3]->putSample(h,0);
oscBuf[4]->putSample(h,dave->chn0_left<<9);
oscBuf[5]->putSample(h,dave->chn0_right<<9);
} else if (regPool[7]&0x08) {
oscBuf[0]->data[oscBuf[0]->needle++]=dave->chn0_state?(dave->chn0_right<<8):0;
oscBuf[1]->data[oscBuf[1]->needle++]=dave->chn1_state?(dave->chn1_right<<8):0;
oscBuf[2]->data[oscBuf[2]->needle++]=dave->chn2_state?(dave->chn2_right<<8):0;
oscBuf[3]->data[oscBuf[3]->needle++]=dave->chn3_state?(dave->chn3_right<<8):0;
oscBuf[4]->data[oscBuf[4]->needle++]=dave->chn0_left<<9;
oscBuf[5]->data[oscBuf[5]->needle++]=0;
oscBuf[0]->putSample(h,dave->chn0_state?(dave->chn0_right<<8):0);
oscBuf[1]->putSample(h,dave->chn1_state?(dave->chn1_right<<8):0);
oscBuf[2]->putSample(h,dave->chn2_state?(dave->chn2_right<<8):0);
oscBuf[3]->putSample(h,dave->chn3_state?(dave->chn3_right<<8):0);
oscBuf[4]->putSample(h,dave->chn0_left<<9);
oscBuf[5]->putSample(h,0);
} else if (regPool[7]&0x10) {
oscBuf[0]->data[oscBuf[0]->needle++]=dave->chn0_state?(dave->chn0_left<<8):0;
oscBuf[1]->data[oscBuf[1]->needle++]=dave->chn1_state?(dave->chn1_left<<8):0;
oscBuf[2]->data[oscBuf[2]->needle++]=dave->chn2_state?(dave->chn2_left<<8):0;
oscBuf[3]->data[oscBuf[3]->needle++]=dave->chn3_state?(dave->chn3_left<<8):0;
oscBuf[4]->data[oscBuf[4]->needle++]=0;
oscBuf[5]->data[oscBuf[5]->needle++]=dave->chn0_right<<9;
oscBuf[0]->putSample(h,dave->chn0_state?(dave->chn0_left<<8):0);
oscBuf[1]->putSample(h,dave->chn1_state?(dave->chn1_left<<8):0);
oscBuf[2]->putSample(h,dave->chn2_state?(dave->chn2_left<<8):0);
oscBuf[3]->putSample(h,dave->chn3_state?(dave->chn3_left<<8):0);
oscBuf[4]->putSample(h,0);
oscBuf[5]->putSample(h,dave->chn0_right<<9);
} else {
oscBuf[0]->data[oscBuf[0]->needle++]=dave->chn0_state?((dave->chn0_left+dave->chn0_right)<<8):0;
oscBuf[1]->data[oscBuf[1]->needle++]=dave->chn1_state?((dave->chn1_left+dave->chn1_right)<<8):0;
oscBuf[2]->data[oscBuf[2]->needle++]=dave->chn2_state?((dave->chn2_left+dave->chn2_right)<<8):0;
oscBuf[3]->data[oscBuf[3]->needle++]=dave->chn3_state?((dave->chn3_left+dave->chn3_right)<<8):0;
oscBuf[4]->data[oscBuf[4]->needle++]=0;
oscBuf[5]->data[oscBuf[5]->needle++]=0;
oscBuf[0]->putSample(h,dave->chn0_state?((dave->chn0_left+dave->chn0_right)<<8):0);
oscBuf[1]->putSample(h,dave->chn1_state?((dave->chn1_left+dave->chn1_right)<<8):0);
oscBuf[2]->putSample(h,dave->chn2_state?((dave->chn2_left+dave->chn2_right)<<8):0);
oscBuf[3]->putSample(h,dave->chn3_state?((dave->chn3_left+dave->chn3_right)<<8):0);
oscBuf[4]->putSample(h,0);
oscBuf[5]->putSample(h,0);
}
buf[0][h]=(short)nextL;
buf[1][h]=(short)nextR;
}
for (int i=0; i<6; i++) {
oscBuf[i]->end(len);
}
}
void DivPlatformDave::tick(bool sysTick) {
@ -596,7 +604,7 @@ void DivPlatformDave::setFlags(const DivConfig& flags) {
CHECK_CUSTOM_CLOCK;
rate=chipClock/16;
for (int i=0; i<6; i++) {
oscBuf[i]->rate=rate;
oscBuf[i]->setRate(rate);
}
}

View file

@ -26,26 +26,32 @@
void DivPlatformDummy::acquire(short** buf, size_t len) {
int chanOut;
for (int i=0; i<chans; i++) {
oscBuf[i]->begin(len);
}
for (size_t i=0; i<len; i++) {
int out=0;
for (unsigned char j=0; j<chans; j++) {
if (chan[j].active) {
if (!isMuted[j]) {
chanOut=(((signed short)chan[j].pos)*chan[j].amp*chan[j].vol)>>12;
oscBuf[j]->data[oscBuf[j]->needle++]=chanOut<<1;
oscBuf[j]->putSample(i,chanOut<<1);
out+=chanOut;
} else {
oscBuf[j]->data[oscBuf[j]->needle++]=0;
oscBuf[j]->putSample(i,0);
}
chan[j].pos+=chan[j].freq;
} else {
oscBuf[j]->data[oscBuf[j]->needle++]=0;
oscBuf[j]->putSample(i,0);
}
}
if (out<-32768) out=-32768;
if (out>32767) out=32767;
buf[0][i]=out;
}
for (int i=0; i<chans; i++) {
oscBuf[i]->end(len);
}
}
void DivPlatformDummy::muteChannel(int ch, bool mute) {
@ -150,7 +156,7 @@ int DivPlatformDummy::init(DivEngine* p, int channels, int sugRate, const DivCon
isMuted[i]=false;
if (i<channels) {
oscBuf[i]=new DivDispatchOscBuffer;
oscBuf[i]->rate=65536;
oscBuf[i]->setRate(65536);
}
}
rate=65536;

View file

@ -111,6 +111,9 @@ const char** DivPlatformES5506::getRegisterSheet() {
}
void DivPlatformES5506::acquire(short** buf, size_t len) {
for (int i=0; i<chanMax; i++) {
oscBuf[i]->begin(len);
}
for (size_t h=0; h<len; h++) {
// convert 32 bit access to 8 bit host interface
while (!hostIntf32.empty()) {
@ -166,9 +169,12 @@ void DivPlatformES5506::acquire(short** buf, size_t len) {
buf[(o<<1)|1][h]=es5506.rout(o);
}
for (int i=chanMax; i>=0; i--) {
oscBuf[i]->data[oscBuf[i]->needle++]=(es5506.voice_lout(i)+es5506.voice_rout(i))>>5;
oscBuf[i]->putSample(h,(es5506.voice_lout(i)+es5506.voice_rout(i))>>5);
}
}
for (int i=0; i<chanMax; i++) {
oscBuf[i]->end(len);
}
}
void DivPlatformES5506::e_pin(bool state) {
@ -1259,7 +1265,7 @@ void DivPlatformES5506::setFlags(const DivConfig& flags) {
rate=chipClock/(16*(initChanMax+1)); // 2 E clock tick (16 CLKIN tick) per voice / 4
for (int i=0; i<32; i++) {
oscBuf[i]->rate=rate;
oscBuf[i]->setRate(rate);
}
}

View file

@ -40,6 +40,9 @@
void DivPlatformESFM::acquire(short** buf, size_t len) {
thread_local short o[2];
for (int i=0; i<18; i++) {
oscBuf[i]->begin(len);
}
for (size_t h=0; h<len; h++) {
if (!writes.empty()) {
QueuedWrite& w=writes.front();
@ -52,12 +55,15 @@ void DivPlatformESFM::acquire(short** buf, size_t len) {
ESFM_generate(&chip,o);
for (int c=0; c<18; c++) {
oscBuf[c]->data[oscBuf[c]->needle++]=ESFM_get_channel_output_native(&chip,c);
oscBuf[c]->putSample(h,ESFM_get_channel_output_native(&chip,c));
}
buf[0][h]=o[0];
buf[1][h]=o[1];
}
for (int i=0; i<18; i++) {
oscBuf[i]->end(len);
}
}
void DivPlatformESFM::tick(bool sysTick) {
@ -1068,6 +1074,9 @@ void DivPlatformESFM::poke(std::vector<DivRegWrite>& wlist) {
void DivPlatformESFM::setFlags(const DivConfig& flags) {
chipClock=COLOR_NTSC*4.0;
rate=chipClock/288.0;
for (int i=0; i<18; i++) {
oscBuf[i]->setRate(rate);
}
}
void DivPlatformESFM::setFast(bool fast) {

View file

@ -56,6 +56,7 @@ const char** DivPlatformFDS::getRegisterSheet() {
}
void DivPlatformFDS::acquire_puNES(short* buf, size_t len) {
oscBuf->begin(len);
for (size_t i=0; i<len; i++) {
extcl_apu_tick_FDS(fds);
int sample=isMuted[0]?0:fds->snd.main.output;
@ -64,13 +65,15 @@ void DivPlatformFDS::acquire_puNES(short* buf, size_t len) {
buf[i]=sample;
if (++writeOscBuf>=32) {
writeOscBuf=0;
oscBuf->data[oscBuf->needle++]=sample*3;
oscBuf->putSample(i,sample*3);
}
}
oscBuf->end(len);
}
void DivPlatformFDS::acquire_NSFPlay(short* buf, size_t len) {
int out[2];
oscBuf->begin(len);
for (size_t i=0; i<len; i++) {
fds_NP->Tick(1);
fds_NP->Render(out);
@ -80,9 +83,10 @@ void DivPlatformFDS::acquire_NSFPlay(short* buf, size_t len) {
buf[i]=sample;
if (++writeOscBuf>=32) {
writeOscBuf=0;
oscBuf->data[oscBuf->needle++]=sample*3;
oscBuf->putSample(i,sample*3);
}
}
oscBuf->end(len);
}
void DivPlatformFDS::doWrite(unsigned short addr, unsigned char data) {
@ -486,7 +490,7 @@ void DivPlatformFDS::setFlags(const DivConfig& flags) {
}
CHECK_CUSTOM_CLOCK;
rate=chipClock;
oscBuf->rate=rate/32;
oscBuf->setRate(rate);
if (useNP) {
fds_NP->SetClock(rate);
fds_NP->SetRate(rate);

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

@ -63,6 +63,9 @@ const char** DivPlatformGB::getRegisterSheet() {
}
void DivPlatformGB::acquire(short** buf, size_t len) {
for (int i=0; i<4; i++) {
oscBuf[i]->begin(len);
}
for (size_t i=0; i<len; i++) {
if (!writes.empty()) {
QueuedWrite& w=writes.front();
@ -74,10 +77,13 @@ void DivPlatformGB::acquire(short** buf, size_t len) {
buf[0][i]=gb->apu_output.final_sample.left;
buf[1][i]=gb->apu_output.final_sample.right;
for (int i=0; i<4; i++) {
oscBuf[i]->data[oscBuf[i]->needle++]=(gb->apu_output.current_sample[i].left+gb->apu_output.current_sample[i].right)<<6;
for (int j=0; j<4; j++) {
oscBuf[j]->putSample(i,(gb->apu_output.current_sample[j].left+gb->apu_output.current_sample[j].right)<<6);
}
}
for (int i=0; i<4; i++) {
oscBuf[i]->end(len);
}
}
void DivPlatformGB::updateWave() {
@ -724,7 +730,7 @@ void DivPlatformGB::setFlags(const DivConfig& flags) {
CHECK_CUSTOM_CLOCK;
rate=chipClock/coreQuality;
for (int i=0; i<4; i++) {
oscBuf[i]->rate=rate;
oscBuf[i]->setRate(rate);
}
}

View file

@ -29,6 +29,9 @@ void DivPlatformGBADMA::acquire(short** buf, size_t len) {
// HLE for now
int outL[2]={0,0};
int outR[2]={0,0};
for (int i=0; i<2; i++) {
oscBuf[i]->begin(len);
}
for (size_t h=0; h<len; h++) {
// internal mixing is always 10-bit
for (int i=0; i<2; i++) {
@ -87,7 +90,7 @@ void DivPlatformGBADMA::acquire(short** buf, size_t len) {
outL[i]=(chan[i].pan&2)?out:0;
outR[i]=(chan[i].pan&1)?out:0;
}
oscBuf[i]->data[oscBuf[i]->needle++]=(short)((outL[i]+outR[i])<<5);
oscBuf[i]->putSample(h,(short)((outL[i]+outR[i])<<5));
}
int l=outL[0]+outL[1];
int r=outR[0]+outR[1];
@ -100,6 +103,9 @@ void DivPlatformGBADMA::acquire(short** buf, size_t len) {
buf[0][h]=(short)l;
buf[1][h]=(short)r;
}
for (int i=0; i<2; i++) {
oscBuf[i]->end(len);
}
}
void DivPlatformGBADMA::tick(bool sysTick) {
@ -493,7 +499,7 @@ void DivPlatformGBADMA::setFlags(const DivConfig& flags) {
CHECK_CUSTOM_CLOCK;
rate=chipClock>>outDepth;
for (int i=0; i<2; i++) {
oscBuf[i]->rate=rate;
oscBuf[i]->setRate(rate);
}
}

View file

@ -61,6 +61,9 @@ void DivPlatformGBAMinMod::acquire(short** buf, size_t len) {
chState[i].volL=(short)chReg[14];
chState[i].volR=(short)chReg[15];
}
for (int i=0; i<chanMax; i++) {
oscBuf[i]->begin(len);
}
for (size_t h=0; h<len; h++) {
while (sampTimer>=sampCycles) {
// the driver generates 4 samples at a time and can be start-offset
@ -133,10 +136,10 @@ void DivPlatformGBAMinMod::acquire(short** buf, size_t len) {
buf[0][h]=sampL;
buf[1][h]=sampR;
for (int i=0; i<chanMax; i++) {
oscBuf[i]->data[oscBuf[i]->needle++]=oscOut[i][sampPos];
oscBuf[i]->putSample(h,oscOut[i][sampPos]);
}
for (int i=chanMax; i<16; i++) {
oscBuf[i]->data[oscBuf[i]->needle++]=0;
oscBuf[i]->putSample(h,0);
}
while (updTimer>=updCycles) {
// flip buffer
@ -197,6 +200,9 @@ void DivPlatformGBAMinMod::acquire(short** buf, size_t len) {
updTimer+=1<<dacDepth;
sampTimer+=1<<dacDepth;
}
for (int i=0; i<chanMax; i++) {
oscBuf[i]->end(len);
}
// write back changed cached channel registers
for (int i=0; i<chanMax; i++) {
unsigned short* chReg=&regPool[i*16];
@ -728,7 +734,7 @@ void DivPlatformGBAMinMod::setFlags(const DivConfig& flags) {
chanMax=flags.getInt("channels",16);
rate=16777216>>dacDepth;
for (int i=0; i<16; i++) {
oscBuf[i]->rate=rate;
oscBuf[i]->setRate(rate);
}
sampCycles=16777216/flags.getInt("sampRate",21845);
chipClock=16777216/sampCycles;

View file

@ -139,6 +139,10 @@ void DivPlatformGenesis::acquire_nuked(short** buf, size_t len) {
thread_local short o[2];
thread_local int os[2];
for (int i=0; i<7; i++) {
oscBuf[i]->begin(len);
}
for (size_t h=0; h<len; h++) {
processDAC(rate);
@ -193,18 +197,18 @@ void DivPlatformGenesis::acquire_nuked(short** buf, size_t len) {
if (i==5) {
if (fm.dacen) {
if (softPCM) {
oscBuf[5]->data[oscBuf[5]->needle++]=chan[5].dacOutput<<6;
oscBuf[6]->data[oscBuf[6]->needle++]=chan[6].dacOutput<<6;
oscBuf[5]->putSample(h,chan[5].dacOutput<<6);
oscBuf[6]->putSample(h,chan[6].dacOutput<<6);
} else {
oscBuf[i]->data[oscBuf[i]->needle++]=((fm.dacdata^0x100)-0x100)<<6;
oscBuf[6]->data[oscBuf[6]->needle++]=0;
oscBuf[i]->putSample(h,((fm.dacdata^0x100)-0x100)<<6);
oscBuf[6]->putSample(h,0);
}
} else {
oscBuf[i]->data[oscBuf[i]->needle++]=CLAMP(fm.ch_out[i]<<(chipType==2?1:6),-32768,32767);
oscBuf[6]->data[oscBuf[6]->needle++]=0;
oscBuf[i]->putSample(h,CLAMP(fm.ch_out[i]<<(chipType==2?1:6),-32768,32767));
oscBuf[6]->putSample(h,0);
}
} else {
oscBuf[i]->data[oscBuf[i]->needle++]=CLAMP(fm.ch_out[i]<<(chipType==2?1:6),-32768,32767);
oscBuf[i]->putSample(h,CLAMP(fm.ch_out[i]<<(chipType==2?1:6),-32768,32767));
}
}
@ -219,6 +223,10 @@ void DivPlatformGenesis::acquire_nuked(short** buf, size_t len) {
buf[0][h]=os[0];
buf[1][h]=os[1];
}
for (int i=0; i<7; i++) {
oscBuf[i]->end(len);
}
}
void DivPlatformGenesis::acquire_ymfm(short** buf, size_t len) {
@ -226,6 +234,10 @@ void DivPlatformGenesis::acquire_ymfm(short** buf, size_t len) {
ymfm::ym2612::fm_engine* fme=fm_ymfm->debug_engine();
for (int i=0; i<7; i++) {
oscBuf[i]->begin(len);
}
for (size_t h=0; h<len; h++) {
processDAC(rate);
@ -278,18 +290,18 @@ void DivPlatformGenesis::acquire_ymfm(short** buf, size_t len) {
if (i==5) {
if (fm_ymfm->debug_dac_enable()) {
if (softPCM) {
oscBuf[5]->data[oscBuf[5]->needle++]=chan[5].dacOutput<<6;
oscBuf[6]->data[oscBuf[6]->needle++]=chan[6].dacOutput<<6;
oscBuf[5]->putSample(h,chan[5].dacOutput<<6);
oscBuf[6]->putSample(h,chan[6].dacOutput<<6);
} else {
oscBuf[i]->data[oscBuf[i]->needle++]=((fm_ymfm->debug_dac_data()^0x100)-0x100)<<6;
oscBuf[6]->data[oscBuf[6]->needle++]=0;
oscBuf[i]->putSample(h,((fm_ymfm->debug_dac_data()^0x100)-0x100)<<6);
oscBuf[6]->putSample(h,0);
}
} else {
oscBuf[i]->data[oscBuf[i]->needle++]=chOut;
oscBuf[6]->data[oscBuf[6]->needle++]=0;
oscBuf[i]->putSample(h,chOut);
oscBuf[6]->putSample(h,0);
}
} else {
oscBuf[i]->data[oscBuf[i]->needle++]=chOut;
oscBuf[i]->putSample(h,chOut);
}
}
@ -302,6 +314,10 @@ void DivPlatformGenesis::acquire_ymfm(short** buf, size_t len) {
buf[0][h]=os[0];
buf[1][h]=os[1];
}
for (int i=0; i<7; i++) {
oscBuf[i]->end(len);
}
}
const unsigned char chanMap276[6]={
@ -309,7 +325,7 @@ const unsigned char chanMap276[6]={
};
// thanks LTVA
void DivPlatformGenesis::acquire276OscSub() {
inline void DivPlatformGenesis::acquire276OscSub(int h) {
if (fm_276.fsm_cnt2[1]==0 && llePrevCycle!=0) {
lleCycle=0;
}
@ -326,22 +342,22 @@ void DivPlatformGenesis::acquire276OscSub() {
for (int i=0; i<6; i++) {
if ((softPCM && ((chanMap276[i]!=5) || !chan[5].dacMode)) || (!softPCM)) {
oscBuf[chanMap276[i]]->data[oscBuf[chanMap276[i]]->needle++]=lleOscData[i];
oscBuf[chanMap276[i]]->putSample(h,lleOscData[i]);
}
lleOscData[i]=0;
}
if (softPCM && chan[5].dacMode) {
oscBuf[5]->data[oscBuf[5]->needle++]=chan[5].dacOutput<<6;
oscBuf[6]->data[oscBuf[6]->needle++]=chan[6].dacOutput<<6;
oscBuf[5]->putSample(h,chan[5].dacOutput<<6);
oscBuf[6]->putSample(h,chan[6].dacOutput<<6);
} else {
oscBuf[6]->data[oscBuf[6]->needle++]=0;
oscBuf[6]->putSample(h,0);
}
}
} else {
for (int i=0; i<6; i++) {
if (lleCycle==((7+i)*12)) {
oscBuf[i]->data[oscBuf[i]->needle]=(fm_276.osc_out>>1)*8;
oscBuf[i]->putSample(h,(fm_276.osc_out>>1)*4);
}
}
@ -351,18 +367,15 @@ void DivPlatformGenesis::acquire276OscSub() {
lleCycle=0;
for (int i=0; i<6; i++) {
oscBuf[i]->data[oscBuf[i]->needle]>>=1;
// we cannot do this anymore
//oscBuf[i]->putSample(h,>>=1);
}
if (softPCM && chan[5].dacMode) {
oscBuf[5]->data[oscBuf[5]->needle]=chan[5].dacOutput<<6;
oscBuf[6]->data[oscBuf[6]->needle]=chan[6].dacOutput<<6;
oscBuf[5]->putSample(h,chan[5].dacOutput<<6);
oscBuf[6]->putSample(h,chan[6].dacOutput<<6);
} else {
oscBuf[6]->data[oscBuf[6]->needle]=0;
}
for (int i=0; i<7; i++) {
oscBuf[i]->needle++;
oscBuf[6]->putSample(h,0);
}
}
}
@ -370,6 +383,10 @@ void DivPlatformGenesis::acquire276OscSub() {
// thanks LTVA
void DivPlatformGenesis::acquire_nuked276(short** buf, size_t len) {
for (int i=0; i<7; i++) {
oscBuf[i]->begin(len);
}
for (size_t h=0; h<len; h++) {
processDAC(rate);
@ -402,14 +419,14 @@ void DivPlatformGenesis::acquire_nuked276(short** buf, size_t len) {
sum_l+=fm_276.out_l;
sum_r+=fm_276.out_r;
acquire276OscSub();
acquire276OscSub(h);
fm_276.input.wr=0;
FMOPN2_Clock(&fm_276,1);
sum_l+=fm_276.out_l;
sum_r+=fm_276.out_r;
acquire276OscSub();
acquire276OscSub(h);
if (chipType==2) {
if (!o_bco && fm_276.o_bco) {
@ -432,13 +449,13 @@ void DivPlatformGenesis::acquire_nuked276(short** buf, size_t len) {
sum_l+=fm_276.out_l;
sum_r+=fm_276.out_r;
acquire276OscSub();
acquire276OscSub(h);
FMOPN2_Clock(&fm_276,1);
sum_l+=fm_276.out_l;
sum_r+=fm_276.out_r;
acquire276OscSub();
acquire276OscSub(h);
if (chipType==2) {
if (!o_bco && fm_276.o_bco) {
@ -465,13 +482,13 @@ void DivPlatformGenesis::acquire_nuked276(short** buf, size_t len) {
sum_r+=fm_276.out_r;
fm_276.input.wr=0;
acquire276OscSub();
acquire276OscSub(h);
FMOPN2_Clock(&fm_276,1);
sum_l+=fm_276.out_l;
sum_r+=fm_276.out_r;
acquire276OscSub();
acquire276OscSub(h);
if (chipType==2) {
if (!o_bco && fm_276.o_bco) {
@ -494,13 +511,13 @@ void DivPlatformGenesis::acquire_nuked276(short** buf, size_t len) {
sum_l+=fm_276.out_l;
sum_r+=fm_276.out_r;
acquire276OscSub();
acquire276OscSub(h);
FMOPN2_Clock(&fm_276,1);
sum_l+=fm_276.out_l;
sum_r+=fm_276.out_r;
acquire276OscSub();
acquire276OscSub(h);
if (chipType==2) {
if (!o_bco && fm_276.o_bco) {
@ -549,13 +566,13 @@ void DivPlatformGenesis::acquire_nuked276(short** buf, size_t len) {
sum_l+=fm_276.out_l;
sum_r+=fm_276.out_r;
acquire276OscSub();
acquire276OscSub(h);
FMOPN2_Clock(&fm_276,1);
sum_l+=fm_276.out_l;
sum_r+=fm_276.out_r;
acquire276OscSub();
acquire276OscSub(h);
if (chipType==2) {
if (!o_bco && fm_276.o_bco) {
@ -582,6 +599,10 @@ void DivPlatformGenesis::acquire_nuked276(short** buf, size_t len) {
buf[1][h]=(sum_r*3)>>2;
}
}
for (int i=0; i<7; i++) {
oscBuf[i]->end(len);
}
}
void DivPlatformGenesis::acquire(short** buf, size_t len) {
@ -1840,7 +1861,7 @@ void DivPlatformGenesis::setFlags(const DivConfig& flags) {
rate=chipClock/36;
}
for (int i=0; i<10; i++) {
oscBuf[i]->rate=rate;
oscBuf[i]->setRate(rate);
}
}

View file

@ -94,7 +94,7 @@ class DivPlatformGenesis: public DivPlatformOPN {
inline void processDAC(int iRate);
inline void commitState(int ch, DivInstrument* ins);
void acquire276OscSub();
inline void acquire276OscSub(int h);
void acquire_nuked(short** buf, size_t len);
void acquire_nuked276(short** buf, size_t len);
void acquire_ymfm(short** buf, size_t len);

View file

@ -55,6 +55,10 @@ inline void DivPlatformK007232::chWrite(unsigned char ch, unsigned int addr, uns
}
void DivPlatformK007232::acquire(short** buf, size_t len) {
for (int i=0; i<2; i++) {
oscBuf[i]->begin(len);
}
for (size_t h=0; h<len; h++) {
if ((--delay)<=0) {
delay=MAX(0,delay);
@ -81,7 +85,7 @@ void DivPlatformK007232::acquire(short** buf, size_t len) {
if (++oscDivider>=8) {
oscDivider=0;
for (int i=0; i<2; i++) {
oscBuf[i]->data[oscBuf[i]->needle++]=(lout[i]+rout[i])<<3;
oscBuf[i]->putSample(h,(lout[i]+rout[i])<<3);
}
}
} else {
@ -91,11 +95,15 @@ void DivPlatformK007232::acquire(short** buf, size_t len) {
if (++oscDivider>=8) {
oscDivider=0;
for (int i=0; i<2; i++) {
oscBuf[i]->data[oscBuf[i]->needle++]=out[i]<<4;
oscBuf[i]->putSample(h,out[i]<<4);
}
}
}
}
for (int i=0; i<2; i++) {
oscBuf[i]->end(len);
}
}
u8 DivPlatformK007232::read_sample(u8 ne, u32 address) {
@ -490,7 +498,7 @@ void DivPlatformK007232::setFlags(const DivConfig& flags) {
stereo=flags.getBool("stereo",false);
for (int i=0; i<2; i++) {
chan[i].volumeChanged=true;
oscBuf[i]->rate=rate/8;
oscBuf[i]->setRate(rate);
}
}

View file

@ -69,7 +69,11 @@ u8 DivPlatformK053260::read_sample(u32 address) {
}
void DivPlatformK053260::acquire(short** buf, size_t len) {
for (size_t i=0; i<len; i++) {
for (int i=0; i<4; i++) {
oscBuf[i]->begin(len);
}
for (size_t h=0; h<len; h++) {
k053260.tick(TICK_DIVIDER);
int lout=(k053260.output(0)); // scale to 16 bit
int rout=(k053260.output(1)); // scale to 16 bit
@ -77,13 +81,17 @@ void DivPlatformK053260::acquire(short** buf, size_t len) {
if (lout<-32768) lout=-32768;
if (rout>32767) rout=32767;
if (rout<-32768) rout=-32768;
buf[0][i]=lout;
buf[1][i]=rout;
buf[0][h]=lout;
buf[1][h]=rout;
for (int i=0; i<4; i++) {
oscBuf[i]->data[oscBuf[i]->needle++]=(k053260.voice_out(i,0)+k053260.voice_out(i,1))>>1;
oscBuf[i]->putSample(h,(k053260.voice_out(i,0)+k053260.voice_out(i,1))>>1);
}
}
for (int i=0; i<4; i++) {
oscBuf[i]->end(len);
}
}
void DivPlatformK053260::tick(bool sysTick) {
@ -427,7 +435,7 @@ void DivPlatformK053260::setFlags(const DivConfig& flags) {
CHECK_CUSTOM_CLOCK;
rate=chipClock/TICK_DIVIDER;
for (int i=0; i<4; i++) {
oscBuf[i]->rate=rate;
oscBuf[i]->setRate(rate);
}
}

View file

@ -154,6 +154,12 @@ void DivPlatformLynx::processDAC(int sRate) {
}
void DivPlatformLynx::acquire(short** buf, size_t len) {
thread_local int chanBuf[4];
for (int i=0; i<4; i++) {
oscBuf[i]->begin(len);
}
for (size_t h=0; h<len; h++) {
processDAC(rate);
@ -163,7 +169,15 @@ void DivPlatformLynx::acquire(short** buf, size_t len) {
writes.pop_front();
}
mikey->sampleAudio(buf[0]+h,buf[1]+h,1,oscBuf);
mikey->sampleAudio(buf[0]+h,buf[1]+h,1,chanBuf);
for (int i=0; i<4; i++) {
oscBuf[i]->putSample(h,chanBuf[i]);
}
}
for (int i=0; i<4; i++) {
oscBuf[i]->end(len);
}
}
@ -555,7 +569,7 @@ void DivPlatformLynx::setFlags(const DivConfig& flags) {
CHECK_CUSTOM_CLOCK;
rate=chipClock/128;
for (int i=0; i<4; i++) {
oscBuf[i]->rate=rate;
oscBuf[i]->setRate(rate);
}
}

View file

@ -44,6 +44,10 @@ const char** DivPlatformMMC5::getRegisterSheet() {
}
void DivPlatformMMC5::acquire(short** buf, size_t len) {
for (int i=0; i<3; i++) {
oscBuf[i]->begin(len);
}
for (size_t i=0; i<len; i++) {
if (dacSample!=-1) {
dacPeriod+=dacRate;
@ -85,11 +89,15 @@ void DivPlatformMMC5::acquire(short** buf, size_t len) {
if (++writeOscBuf>=32) {
writeOscBuf=0;
oscBuf[0]->data[oscBuf[0]->needle++]=isMuted[0]?0:((mmc5->S3.output)<<11);
oscBuf[1]->data[oscBuf[1]->needle++]=isMuted[1]?0:((mmc5->S4.output)<<11);
oscBuf[2]->data[oscBuf[2]->needle++]=isMuted[2]?0:((mmc5->pcm.output)<<7);
oscBuf[0]->putSample(i,isMuted[0]?0:((mmc5->S3.output)<<11));
oscBuf[1]->putSample(i,isMuted[1]?0:((mmc5->S4.output)<<11));
oscBuf[2]->putSample(i,isMuted[2]?0:((mmc5->pcm.output)<<7));
}
}
for (int i=0; i<3; i++) {
oscBuf[i]->end(len);
}
}
void DivPlatformMMC5::tick(bool sysTick) {
@ -427,7 +435,7 @@ void DivPlatformMMC5::setFlags(const DivConfig& flags) {
CHECK_CUSTOM_CLOCK;
rate=chipClock;
for (int i=0; i<3; i++) {
oscBuf[i]->rate=rate/32;
oscBuf[i]->setRate(rate);
}
}

View file

@ -46,6 +46,10 @@ const char** DivPlatformMSM5232::getRegisterSheet() {
}
void DivPlatformMSM5232::acquire(short** buf, size_t len) {
for (int i=0; i<8; i++) {
oscBuf[i]->begin(len);
}
for (size_t h=0; h<len; h++) {
while (!writes.empty()) {
QueuedWrite w=writes.front();
@ -56,7 +60,7 @@ void DivPlatformMSM5232::acquire(short** buf, size_t len) {
for (int i=0; i<8; i++) {
if (isMuted[i]) {
oscBuf[i]->data[oscBuf[i]->needle++]=0;
oscBuf[i]->putSample(h,0);
} else {
int o=(
((regPool[12+(i>>2)]&1)?((msm->vo16[i]*partVolume[3+(i&4)])>>8):0)+
@ -64,7 +68,7 @@ void DivPlatformMSM5232::acquire(short** buf, size_t len) {
((regPool[12+(i>>2)]&4)?((msm->vo4[i]*partVolume[1+(i&4)])>>8):0)+
((regPool[12+(i>>2)]&8)?((msm->vo2[i]*partVolume[i&4])>>8):0)
)<<2;
oscBuf[i]->data[oscBuf[i]->needle++]=CLAMP(o,-32768,32767);
oscBuf[i]->putSample(h,CLAMP(o,-32768,32767));
}
}
@ -84,6 +88,10 @@ void DivPlatformMSM5232::acquire(short** buf, size_t len) {
buf[0][h]+=(temp[i]*partVolume[i])>>8;
}
}
for (int i=0; i<8; i++) {
oscBuf[i]->end(len);
}
}
const int attackMap[8]={
@ -400,7 +408,7 @@ void DivPlatformMSM5232::setFlags(const DivConfig& flags) {
msm->set_clock(chipClock+detune*1024);
rate=msm->get_rate();
for (int i=0; i<8; i++) {
oscBuf[i]->rate=rate;
oscBuf[i]->setRate(rate);
}
initPartVolume[0]=flags.getInt("partVolume0",255);
initPartVolume[1]=flags.getInt("partVolume1",255);

View file

@ -41,6 +41,8 @@ int DivPlatformMSM6258::calcVGMRate() {
}
void DivPlatformMSM6258::acquire(short** buf, size_t len) {
oscBuf[0]->begin(len);
for (size_t h=0; h<len; h++) {
if (--msmClockCount<0) {
if (--msmDividerCount<=0) {
@ -86,13 +88,15 @@ void DivPlatformMSM6258::acquire(short** buf, size_t len) {
if (isMuted[0]) {
buf[0][h]=0;
buf[1][h]=0;
oscBuf[0]->data[oscBuf[0]->needle++]=0;
oscBuf[0]->putSample(h,0);
} else {
buf[0][h]=(msmPan&2)?0:msmOut;
buf[1][h]=(msmPan&1)?0:msmOut;
oscBuf[0]->data[oscBuf[0]->needle++]=msmPan?(msmOut>>1):0;
oscBuf[0]->putSample(h,(msmPan!=3)?(msmOut>>1):0);
}
}
oscBuf[0]->end(len);
}
void DivPlatformMSM6258::tick(bool sysTick) {
@ -407,7 +411,7 @@ void DivPlatformMSM6258::setFlags(const DivConfig& flags) {
CHECK_CUSTOM_CLOCK;
rate=chipClock/256;
for (int i=0; i<1; i++) {
oscBuf[i]->rate=rate;
oscBuf[i]->setRate(rate);
}
variableRate=flags.getBool("variableRate",false);
}

View file

@ -63,6 +63,10 @@ u8 DivPlatformMSM6295::read_byte(u32 address) {
}
void DivPlatformMSM6295::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) {
if (!writes.empty()) {
@ -106,10 +110,14 @@ void DivPlatformMSM6295::acquire(short** buf, size_t len) {
if (++updateOsc>=22) {
updateOsc=0;
for (int i=0; i<4; i++) {
oscBuf[i]->data[oscBuf[i]->needle++]=msm.voice_out(i)<<5;
oscBuf[i]->putSample(h,msm.voice_out(i)<<5);
}
}
}
for (int i=0; i<4; i++) {
oscBuf[i]->end(len);
}
}
void DivPlatformMSM6295::tick(bool sysTick) {
@ -560,7 +568,7 @@ void DivPlatformMSM6295::setFlags(const DivConfig& flags) {
CHECK_CUSTOM_CLOCK;
rate=chipClock/3;
for (int i=0; i<4; i++) {
oscBuf[i]->rate=rate/22;
oscBuf[i]->setRate(rate);;
}
if (rateSel!=rateSelInit) {
rWrite(12,!rateSelInit);

View file

@ -109,6 +109,10 @@ const char** DivPlatformN163::getRegisterSheet() {
}
void DivPlatformN163::acquire(short** buf, size_t len) {
for (int i=0; i<8; i++) {
oscBuf[i]->begin(len);
}
for (size_t i=0; i<len; i++) {
n163.tick();
int out=(n163.out()<<6)*2; // scale to 16 bit
@ -116,8 +120,8 @@ void DivPlatformN163::acquire(short** buf, size_t len) {
if (out<-32768) out=-32768;
buf[0][i]=out;
if (n163.voice_cycle()==0x78) for (int i=0; i<8; i++) {
oscBuf[i]->data[oscBuf[i]->needle++]=n163.voice_out(i)<<7;
if (n163.voice_cycle()==0x78) for (int j=0; j<8; j++) {
oscBuf[j]->putSample(i,n163.voice_out(j)<<7);
}
// command queue
@ -128,6 +132,10 @@ void DivPlatformN163::acquire(short** buf, size_t len) {
writes.pop();
}
}
for (int i=0; i<8; i++) {
oscBuf[i]->end(len);
}
}
void DivPlatformN163::updateWave(int ch, int wave, int pos, int len) {
@ -595,7 +603,7 @@ void DivPlatformN163::setFlags(const DivConfig& flags) {
n163.set_multiplex(multiplex);
rWrite(0x7f,initChanMax<<4);
for (int i=0; i<8; i++) {
oscBuf[i]->rate=rate/(initChanMax+1);
oscBuf[i]->setRate(rate);//=rate/(initChanMax+1);
}
lenCompensate=flags.getBool("lenCompensate",false);

View file

@ -171,15 +171,24 @@ void DivPlatformNamcoWSG::acquire(short** buf, size_t len) {
regPool[w.addr&0x3f]=w.val;
writes.pop();
}
for (int i=0; i<chans; i++) {
oscBuf[i]->begin(len);
}
for (size_t h=0; h<len; h++) {
short* bufC[2]={
buf[0]+h, buf[1]+h
};
namco->sound_stream_update(bufC,1);
for (int i=0; i<chans; i++) {
oscBuf[i]->data[oscBuf[i]->needle++]=(namco->m_channel_list[i].last_out*chans)>>1;
oscBuf[i]->putSample(h,(namco->m_channel_list[i].last_out*chans)>>1);
}
}
for (int i=0; i<chans; i++) {
oscBuf[i]->end(len);
}
}
void DivPlatformNamcoWSG::updateWave(int ch) {
@ -579,7 +588,7 @@ void DivPlatformNamcoWSG::setFlags(const DivConfig& flags) {
rate=chipClock/32;
namco->device_clock_changed(96000);
for (int i=0; i<chans; i++) {
oscBuf[i]->rate=rate;
oscBuf[i]->setRate(rate);
}
newNoise=flags.getBool("newNoise",true);
romMode=flags.getBool("romMode",false);

View file

@ -69,7 +69,11 @@ const char** DivPlatformNDS::getRegisterSheet() {
}
void DivPlatformNDS::acquire(short** buf, size_t len) {
for (size_t i=0; i<len; i++) {
for (int i=0; i<16; i++) {
oscBuf[i]->begin(len);
}
for (size_t h=0; h<len; h++) {
nds.tick(coreQuality);
int lout=((nds.loutput()-0x200)<<5); // scale to 16 bit
int rout=((nds.routput()-0x200)<<5); // scale to 16 bit
@ -77,13 +81,17 @@ void DivPlatformNDS::acquire(short** buf, size_t len) {
if (lout<-32768) lout=-32768;
if (rout>32767) rout=32767;
if (rout<-32768) rout=-32768;
buf[0][i]=lout;
buf[1][i]=rout;
buf[0][h]=lout;
buf[1][h]=rout;
for (int i=0; i<16; i++) {
oscBuf[i]->data[oscBuf[i]->needle++]=(nds.chan_lout(i)+nds.chan_rout(i))>>1;
oscBuf[i]->putSample(h,(nds.chan_lout(i)+nds.chan_rout(i))>>1);
}
}
for (int i=0; i<16; i++) {
oscBuf[i]->end(len);
}
}
u8 DivPlatformNDS::read_byte(u32 addr) {
@ -564,7 +572,7 @@ void DivPlatformNDS::setFlags(const DivConfig& flags) {
chipClock=33513982;
rate=chipClock/2/coreQuality;
for (int i=0; i<16; i++) {
oscBuf[i]->rate=rate;
oscBuf[i]->setRate(rate);
}
memCompo.capacity=(isDSi?16777216:4194304);
}

View file

@ -106,6 +106,10 @@ void DivPlatformNES::doWrite(unsigned short addr, unsigned char data) {
}
void DivPlatformNES::acquire_puNES(short** buf, size_t len) {
for (int i=0; i<5; i++) {
oscBuf[i]->begin(len);
}
for (size_t i=0; i<len; i++) {
doPCM;
@ -127,18 +131,27 @@ void DivPlatformNES::acquire_puNES(short** buf, size_t len) {
buf[0][i]=sample;
if (++writeOscBuf>=32) {
writeOscBuf=0;
oscBuf[0]->data[oscBuf[0]->needle++]=isMuted[0]?0:(nes->S1.output<<11);
oscBuf[1]->data[oscBuf[1]->needle++]=isMuted[1]?0:(nes->S2.output<<11);
oscBuf[2]->data[oscBuf[2]->needle++]=isMuted[2]?0:(nes->TR.output<<11);
oscBuf[3]->data[oscBuf[3]->needle++]=isMuted[3]?0:(nes->NS.output<<11);
oscBuf[4]->data[oscBuf[4]->needle++]=isMuted[4]?0:(nes->DMC.output<<8);
oscBuf[0]->putSample(i,isMuted[0]?0:(nes->S1.output<<11));
oscBuf[1]->putSample(i,isMuted[1]?0:(nes->S2.output<<11));
oscBuf[2]->putSample(i,isMuted[2]?0:(nes->TR.output<<11));
oscBuf[3]->putSample(i,isMuted[3]?0:(nes->NS.output<<11));
oscBuf[4]->putSample(i,isMuted[4]?0:(nes->DMC.output<<8));
}
}
for (int i=0; i<5; i++) {
oscBuf[i]->end(len);
}
}
void DivPlatformNES::acquire_NSFPlay(short** buf, size_t len) {
int out1[2];
int out2[2];
for (int i=0; i<5; i++) {
oscBuf[i]->begin(len);
}
for (size_t i=0; i<len; i++) {
doPCM;
@ -161,18 +174,27 @@ void DivPlatformNES::acquire_NSFPlay(short** buf, size_t len) {
buf[0][i]=sample;
if (++writeOscBuf>=4) {
writeOscBuf=0;
oscBuf[0]->data[oscBuf[0]->needle++]=nes1_NP->out[0]<<11;
oscBuf[1]->data[oscBuf[1]->needle++]=nes1_NP->out[1]<<11;
oscBuf[2]->data[oscBuf[2]->needle++]=nes2_NP->out[0]<<11;
oscBuf[3]->data[oscBuf[3]->needle++]=nes2_NP->out[1]<<11;
oscBuf[4]->data[oscBuf[4]->needle++]=nes2_NP->out[2]<<8;
oscBuf[0]->putSample(i,nes1_NP->out[0]<<11);
oscBuf[1]->putSample(i,nes1_NP->out[1]<<11);
oscBuf[2]->putSample(i,nes2_NP->out[0]<<11);
oscBuf[3]->putSample(i,nes2_NP->out[1]<<11);
oscBuf[4]->putSample(i,nes2_NP->out[2]<<8);
}
}
for (int i=0; i<5; i++) {
oscBuf[i]->end(len);
}
}
void DivPlatformNES::acquire_NSFPlayE(short** buf, size_t len) {
int out1[2];
int out2[2];
for (int i=0; i<5; i++) {
oscBuf[i]->begin(len);
}
for (size_t i=0; i<len; i++) {
doPCM;
@ -195,13 +217,17 @@ void DivPlatformNES::acquire_NSFPlayE(short** buf, size_t len) {
buf[0][i]=sample;
if (++writeOscBuf>=4) {
writeOscBuf=0;
oscBuf[0]->data[oscBuf[0]->needle++]=e1_NP->out[0]<<11;
oscBuf[1]->data[oscBuf[1]->needle++]=e1_NP->out[1]<<11;
oscBuf[2]->data[oscBuf[2]->needle++]=e2_NP->out[0]<<11;
oscBuf[3]->data[oscBuf[3]->needle++]=e2_NP->out[1]<<11;
oscBuf[4]->data[oscBuf[4]->needle++]=e2_NP->out[2]<<8;
oscBuf[0]->putSample(i,e1_NP->out[0]<<11);
oscBuf[1]->putSample(i,e1_NP->out[1]<<11);
oscBuf[2]->putSample(i,e2_NP->out[0]<<11);
oscBuf[3]->putSample(i,e2_NP->out[1]<<11);
oscBuf[4]->putSample(i,e2_NP->out[2]<<8);
}
}
for (int i=0; i<5; i++) {
oscBuf[i]->end(len);
}
}
void DivPlatformNES::acquire(short** buf, size_t len) {
@ -929,7 +955,7 @@ void DivPlatformNES::setFlags(const DivConfig& flags) {
rate/=8;
}
for (int i=0; i<5; i++) {
oscBuf[i]->rate=rate/(useNP?4:32);
oscBuf[i]->setRate(rate);
}
dpcmModeDefault=flags.getBool("dpcmMode",true);

View file

@ -188,6 +188,10 @@ void DivPlatformOPL::acquire_nuked(short** buf, size_t len) {
thread_local ymfm::ymfm_output<2> aOut;
thread_local short pcmBuf[24];
for (int i=0; i<totalChans; i++) {
oscBuf[i]->begin(len);
}
for (size_t h=0; h<len; h++) {
os[0]=0; os[1]=0; os[2]=0; os[3]=0; os[4]=0; os[5]=0;
if (!writes.empty() && --delay<0) {
@ -254,9 +258,9 @@ void DivPlatformOPL::acquire_nuked(short** buf, size_t len) {
if (!isMuted[adpcmChan]) {
os[0]-=aOut.data[0]>>3;
os[1]-=aOut.data[0]>>3;
oscBuf[adpcmChan]->data[oscBuf[adpcmChan]->needle++]=aOut.data[0]>>1;
oscBuf[adpcmChan]->putSample(h,aOut.data[0]>>1);
} else {
oscBuf[adpcmChan]->data[oscBuf[adpcmChan]->needle++]=0;
oscBuf[adpcmChan]->putSample(h,0);
}
}
@ -277,13 +281,13 @@ void DivPlatformOPL::acquire_nuked(short** buf, size_t len) {
if (fm.channel[i].out[3]!=NULL) {
chOut+=*fm.channel[ch].out[3];
}
oscBuf[i]->data[oscBuf[i]->needle++]=CLAMP(chOut<<(i==melodicChans?1:2),-32768,32767);
oscBuf[i]->putSample(h,CLAMP(chOut<<(i==melodicChans?1:2),-32768,32767));
}
// special
oscBuf[melodicChans+1]->data[oscBuf[melodicChans+1]->needle++]=fm.slot[16].out*4;
oscBuf[melodicChans+2]->data[oscBuf[melodicChans+2]->needle++]=fm.slot[14].out*4;
oscBuf[melodicChans+3]->data[oscBuf[melodicChans+3]->needle++]=fm.slot[17].out*4;
oscBuf[melodicChans+4]->data[oscBuf[melodicChans+4]->needle++]=fm.slot[13].out*4;
oscBuf[melodicChans+1]->putSample(h,fm.slot[16].out*4);
oscBuf[melodicChans+2]->putSample(h,fm.slot[14].out*4);
oscBuf[melodicChans+3]->putSample(h,fm.slot[17].out*4);
oscBuf[melodicChans+4]->putSample(h,fm.slot[13].out*4);
} else {
for (int i=0; i<chans; i++) {
unsigned char ch=outChanMap[i];
@ -301,13 +305,13 @@ void DivPlatformOPL::acquire_nuked(short** buf, size_t len) {
if (fm.channel[i].out[3]!=NULL) {
chOut+=*fm.channel[ch].out[3];
}
oscBuf[i]->data[oscBuf[i]->needle++]=CLAMP(chOut<<2,-32768,32767);
oscBuf[i]->putSample(h,CLAMP(chOut<<2,-32768,32767));
}
}
if (chipType==4) {
for (int i=pcmChanOffs; i<pcmChanOffs+24; i++) {
oscBuf[i]->data[oscBuf[i]->needle++]=CLAMP(pcmBuf[i-pcmChanOffs],-32768,32767);
oscBuf[i]->putSample(h,CLAMP(pcmBuf[i-pcmChanOffs],-32768,32767));
}
}
@ -344,6 +348,10 @@ void DivPlatformOPL::acquire_nuked(short** buf, size_t len) {
buf[5][h]=os[5];
}
}
for (int i=0; i<totalChans; i++) {
oscBuf[i]->end(len);
}
}
void DivPlatformOPL::acquire_ymfm1(short** buf, size_t len) {
@ -356,6 +364,10 @@ void DivPlatformOPL::acquire_ymfm1(short** buf, size_t len) {
fmChan[i]=fme->debug_channel(i);
}
for (int i=0; i<totalChans; i++) {
oscBuf[i]->begin(len);
}
for (size_t h=0; h<len; h++) {
if (!writes.empty() && --delay<0) {
QueuedWrite& w=writes.front();
@ -377,18 +389,22 @@ void DivPlatformOPL::acquire_ymfm1(short** buf, size_t len) {
if (properDrums) {
for (int i=0; i<7; i++) {
oscBuf[i]->data[oscBuf[i]->needle++]=CLAMP(fmChan[i]->debug_output(0)<<2,-32768,32767);
oscBuf[i]->putSample(h,CLAMP(fmChan[i]->debug_output(0)<<2,-32768,32767));
}
oscBuf[7]->data[oscBuf[7]->needle++]=CLAMP(fmChan[7]->debug_special1()<<2,-32768,32767);
oscBuf[8]->data[oscBuf[8]->needle++]=CLAMP(fmChan[8]->debug_special1()<<2,-32768,32767);
oscBuf[9]->data[oscBuf[9]->needle++]=CLAMP(fmChan[8]->debug_special2()<<2,-32768,32767);
oscBuf[10]->data[oscBuf[10]->needle++]=CLAMP(fmChan[7]->debug_special2()<<2,-32768,32767);
oscBuf[7]->putSample(h,CLAMP(fmChan[7]->debug_special1()<<2,-32768,32767));
oscBuf[8]->putSample(h,CLAMP(fmChan[8]->debug_special1()<<2,-32768,32767));
oscBuf[9]->putSample(h,CLAMP(fmChan[8]->debug_special2()<<2,-32768,32767));
oscBuf[10]->putSample(h,CLAMP(fmChan[7]->debug_special2()<<2,-32768,32767));
} else {
for (int i=0; i<9; i++) {
oscBuf[i]->data[oscBuf[i]->needle++]=CLAMP(fmChan[i]->debug_output(0)<<2,-32768,32767);
oscBuf[i]->putSample(h,CLAMP(fmChan[i]->debug_output(0)<<2,-32768,32767));
}
}
}
for (int i=0; i<totalChans; i++) {
oscBuf[i]->end(len);
}
}
void DivPlatformOPL::acquire_ymfm2(short** buf, size_t len) {
@ -401,6 +417,10 @@ void DivPlatformOPL::acquire_ymfm2(short** buf, size_t len) {
fmChan[i]=fme->debug_channel(i);
}
for (int i=0; i<totalChans; i++) {
oscBuf[i]->begin(len);
}
for (size_t h=0; h<len; h++) {
if (!writes.empty() && --delay<0) {
QueuedWrite& w=writes.front();
@ -422,18 +442,22 @@ void DivPlatformOPL::acquire_ymfm2(short** buf, size_t len) {
if (properDrums) {
for (int i=0; i<7; i++) {
oscBuf[i]->data[oscBuf[i]->needle++]=CLAMP(fmChan[i]->debug_output(0)<<2,-32768,32767);
oscBuf[i]->putSample(h,CLAMP(fmChan[i]->debug_output(0)<<2,-32768,32767));
}
oscBuf[7]->data[oscBuf[7]->needle++]=CLAMP(fmChan[7]->debug_special1()<<2,-32768,32767);
oscBuf[8]->data[oscBuf[8]->needle++]=CLAMP(fmChan[8]->debug_special1()<<2,-32768,32767);
oscBuf[9]->data[oscBuf[9]->needle++]=CLAMP(fmChan[8]->debug_special2()<<2,-32768,32767);
oscBuf[10]->data[oscBuf[10]->needle++]=CLAMP(fmChan[7]->debug_special2()<<2,-32768,32767);
oscBuf[7]->putSample(h,CLAMP(fmChan[7]->debug_special1()<<2,-32768,32767));
oscBuf[8]->putSample(h,CLAMP(fmChan[8]->debug_special1()<<2,-32768,32767));
oscBuf[9]->putSample(h,CLAMP(fmChan[8]->debug_special2()<<2,-32768,32767));
oscBuf[10]->putSample(h,CLAMP(fmChan[7]->debug_special2()<<2,-32768,32767));
} else {
for (int i=0; i<9; i++) {
oscBuf[i]->data[oscBuf[i]->needle++]=CLAMP(fmChan[i]->debug_output(0)<<2,-32768,32767);
oscBuf[i]->putSample(h,CLAMP(fmChan[i]->debug_output(0)<<2,-32768,32767));
}
}
}
for (int i=0; i<totalChans; i++) {
oscBuf[i]->end(len);
}
}
void DivPlatformOPL::acquire_ymfm8950(short** buf, size_t len) {
@ -447,6 +471,10 @@ void DivPlatformOPL::acquire_ymfm8950(short** buf, size_t len) {
fmChan[i]=fme->debug_channel(i);
}
for (int i=0; i<totalChans; i++) {
oscBuf[i]->begin(len);
}
for (size_t h=0; h<len; h++) {
if (!writes.empty() && --delay<0) {
QueuedWrite& w=writes.front();
@ -468,20 +496,24 @@ void DivPlatformOPL::acquire_ymfm8950(short** buf, size_t len) {
if (properDrums) {
for (int i=0; i<7; i++) {
oscBuf[i]->data[oscBuf[i]->needle++]=CLAMP(fmChan[i]->debug_output(0)<<2,-32768,32767);
oscBuf[i]->putSample(h,CLAMP(fmChan[i]->debug_output(0)<<2,-32768,32767));
}
oscBuf[7]->data[oscBuf[7]->needle++]=CLAMP(fmChan[7]->debug_special1()<<2,-32768,32767);
oscBuf[8]->data[oscBuf[8]->needle++]=CLAMP(fmChan[8]->debug_special1()<<2,-32768,32767);
oscBuf[9]->data[oscBuf[9]->needle++]=CLAMP(fmChan[8]->debug_special2()<<2,-32768,32767);
oscBuf[10]->data[oscBuf[10]->needle++]=CLAMP(fmChan[7]->debug_special2()<<2,-32768,32767);
oscBuf[11]->data[oscBuf[11]->needle++]=CLAMP(abe->get_last_out(0),-32768,32767);
oscBuf[7]->putSample(h,CLAMP(fmChan[7]->debug_special1()<<2,-32768,32767));
oscBuf[8]->putSample(h,CLAMP(fmChan[8]->debug_special1()<<2,-32768,32767));
oscBuf[9]->putSample(h,CLAMP(fmChan[8]->debug_special2()<<2,-32768,32767));
oscBuf[10]->putSample(h,CLAMP(fmChan[7]->debug_special2()<<2,-32768,32767));
oscBuf[11]->putSample(h,CLAMP(abe->get_last_out(0),-32768,32767));
} else {
for (int i=0; i<9; i++) {
oscBuf[i]->data[oscBuf[i]->needle++]=CLAMP(fmChan[i]->debug_output(0)<<2,-32768,32767);
oscBuf[i]->putSample(h,CLAMP(fmChan[i]->debug_output(0)<<2,-32768,32767));
}
oscBuf[9]->data[oscBuf[9]->needle++]=CLAMP(abe->get_last_out(0),-32768,32767);
oscBuf[9]->putSample(h,CLAMP(abe->get_last_out(0),-32768,32767));
}
}
for (int i=0; i<totalChans; i++) {
oscBuf[i]->end(len);
}
}
void DivPlatformOPL::acquire_ymfm3(short** buf, size_t len) {
@ -494,6 +526,10 @@ void DivPlatformOPL::acquire_ymfm3(short** buf, size_t len) {
fmChan[i]=fme->debug_channel(i);
}
for (int i=0; i<totalChans; i++) {
oscBuf[i]->begin(len);
}
for (size_t h=0; h<len; h++) {
if (!writes.empty() && --delay<0) {
QueuedWrite& w=writes.front();
@ -552,15 +588,15 @@ void DivPlatformOPL::acquire_ymfm3(short** buf, size_t len) {
chOut=fmChan[ch]->debug_output(3);
}
if (i==15) {
oscBuf[i]->data[oscBuf[i]->needle++]=CLAMP(chOut,-32768,32767);
oscBuf[i]->putSample(h,CLAMP(chOut,-32768,32767));
} else {
oscBuf[i]->data[oscBuf[i]->needle++]=CLAMP(chOut<<1,-32768,32767);
oscBuf[i]->putSample(h,CLAMP(chOut<<1,-32768,32767));
}
}
oscBuf[16]->data[oscBuf[16]->needle++]=CLAMP(fmChan[7]->debug_special2()<<1,-32768,32767);
oscBuf[17]->data[oscBuf[17]->needle++]=CLAMP(fmChan[8]->debug_special1()<<1,-32768,32767);
oscBuf[18]->data[oscBuf[18]->needle++]=CLAMP(fmChan[8]->debug_special2()<<1,-32768,32767);
oscBuf[19]->data[oscBuf[19]->needle++]=CLAMP(fmChan[7]->debug_special1()<<1,-32768,32767);
oscBuf[16]->putSample(h,CLAMP(fmChan[7]->debug_special2()<<1,-32768,32767));
oscBuf[17]->putSample(h,CLAMP(fmChan[8]->debug_special1()<<1,-32768,32767));
oscBuf[18]->putSample(h,CLAMP(fmChan[8]->debug_special2()<<1,-32768,32767));
oscBuf[19]->putSample(h,CLAMP(fmChan[7]->debug_special1()<<1,-32768,32767));
} else {
for (int i=0; i<18; i++) {
unsigned char ch=outChanMap[i];
@ -575,10 +611,14 @@ void DivPlatformOPL::acquire_ymfm3(short** buf, size_t len) {
if (chOut==0) {
chOut=fmChan[ch]->debug_output(3);
}
oscBuf[i]->data[oscBuf[i]->needle++]=CLAMP(chOut<<1,-32768,32767);
oscBuf[i]->putSample(h,CLAMP(chOut<<1,-32768,32767));
}
}
}
for (int i=0; i<totalChans; i++) {
oscBuf[i]->end(len);
}
}
void DivPlatformOPL::acquire_ymfm4(short** buf, size_t len) {
@ -597,6 +637,10 @@ void DivPlatformOPL::acquire_ymfm4(short** buf, size_t len) {
pcmChan[i]=pcme->debug_channel(i);
}
for (int i=0; i<totalChans; i++) {
oscBuf[i]->begin(len);
}
for (size_t h=0; h<len; h++) {
if (!writes.empty() && --delay<0) {
QueuedWrite& w=writes.front();
@ -644,15 +688,15 @@ void DivPlatformOPL::acquire_ymfm4(short** buf, size_t len) {
chOut=fmChan[ch]->debug_output(3);
}
if (i==15) {
oscBuf[i]->data[oscBuf[i]->needle++]=CLAMP(chOut,-32768,32767);
oscBuf[i]->putSample(h,CLAMP(chOut,-32768,32767));
} else {
oscBuf[i]->data[oscBuf[i]->needle++]=CLAMP(chOut<<1,-32768,32767);
oscBuf[i]->putSample(h,CLAMP(chOut<<1,-32768,32767));
}
}
oscBuf[16]->data[oscBuf[16]->needle++]=CLAMP(fmChan[7]->debug_special2()<<1,-32768,32767);
oscBuf[17]->data[oscBuf[17]->needle++]=CLAMP(fmChan[8]->debug_special1()<<1,-32768,32767);
oscBuf[18]->data[oscBuf[18]->needle++]=CLAMP(fmChan[8]->debug_special2()<<1,-32768,32767);
oscBuf[19]->data[oscBuf[19]->needle++]=CLAMP(fmChan[7]->debug_special1()<<1,-32768,32767);
oscBuf[16]->putSample(h,CLAMP(fmChan[7]->debug_special2()<<1,-32768,32767));
oscBuf[17]->putSample(h,CLAMP(fmChan[8]->debug_special1()<<1,-32768,32767));
oscBuf[18]->putSample(h,CLAMP(fmChan[8]->debug_special2()<<1,-32768,32767));
oscBuf[19]->putSample(h,CLAMP(fmChan[7]->debug_special1()<<1,-32768,32767));
} else {
for (int i=0; i<18; i++) {
unsigned char ch=outChanMap[i];
@ -667,7 +711,7 @@ void DivPlatformOPL::acquire_ymfm4(short** buf, size_t len) {
if (chOut==0) {
chOut=fmChan[ch]->debug_output(3);
}
oscBuf[i]->data[oscBuf[i]->needle++]=CLAMP(chOut<<1,-32768,32767);
oscBuf[i]->putSample(h,CLAMP(chOut<<1,-32768,32767));
}
}
for (int i=0; i<24; i++) {
@ -676,9 +720,13 @@ void DivPlatformOPL::acquire_ymfm4(short** buf, size_t len) {
chOut+=pcmChan[i]->debug_output(1);
chOut+=pcmChan[i]->debug_output(2);
chOut+=pcmChan[i]->debug_output(3);
oscBuf[oscOffs]->data[oscBuf[oscOffs]->needle++]=CLAMP(chOut<<1,-32768,32767);
oscBuf[oscOffs]->putSample(h,CLAMP(chOut<<1,-32768,32767));
}
}
for (int i=0; i<totalChans; i++) {
oscBuf[i]->end(len);
}
}
static const int cycleMap[18]={
@ -707,6 +755,10 @@ void DivPlatformOPL::acquire_nukedLLE2(short** buf, size_t len) {
int chOut[11];
thread_local ymfm::ymfm_output<2> aOut;
for (int i=0; i<totalChans; i++) {
oscBuf[i]->begin(len);
}
for (size_t h=0; h<len; h++) {
int curCycle=0;
unsigned char subCycle=0;
@ -825,7 +877,7 @@ void DivPlatformOPL::acquire_nukedLLE2(short** buf, size_t len) {
}
if (chOut[i]<-32768) chOut[i]=-32768;
if (chOut[i]>32767) chOut[i]=32767;
oscBuf[i]->data[oscBuf[i]->needle++]=chOut[i];
oscBuf[i]->putSample(h,chOut[i]);
}
if (chipType==8950) {
@ -835,9 +887,9 @@ void DivPlatformOPL::acquire_nukedLLE2(short** buf, size_t len) {
if (!isMuted[adpcmChan]) {
dacOut-=aOut.data[0]>>3;
oscBuf[adpcmChan]->data[oscBuf[adpcmChan]->needle++]=aOut.data[0]>>1;
oscBuf[adpcmChan]->putSample(h,aOut.data[0]>>1);
} else {
oscBuf[adpcmChan]->data[oscBuf[adpcmChan]->needle++]=0;
oscBuf[adpcmChan]->putSample(h,0);
}
}
@ -846,12 +898,20 @@ void DivPlatformOPL::acquire_nukedLLE2(short** buf, size_t len) {
buf[0][h]=dacOut;
}
for (int i=0; i<totalChans; i++) {
oscBuf[i]->end(len);
}
}
void DivPlatformOPL::acquire_nukedLLE3(short** buf, size_t len) {
int chOut[20];
int ch=0;
for (int i=0; i<totalChans; i++) {
oscBuf[i]->begin(len);
}
for (size_t h=0; h<len; h++) {
int curCycle=0;
unsigned char subCycle=0;
@ -956,7 +1016,7 @@ void DivPlatformOPL::acquire_nukedLLE3(short** buf, size_t len) {
}*/
if (chOut[i]<-32768) chOut[i]=-32768;
if (chOut[i]>32767) chOut[i]=32767;
oscBuf[i]->data[oscBuf[i]->needle++]=chOut[i];
oscBuf[i]->putSample(h,chOut[i]);
}
for (int i=0; i<MIN(4,totalOutputs); i++) {
@ -966,6 +1026,10 @@ void DivPlatformOPL::acquire_nukedLLE3(short** buf, size_t len) {
buf[i][h]=dacOut3[i];
}
}
for (int i=0; i<totalChans; i++) {
oscBuf[i]->end(len);
}
}
void DivPlatformOPL::acquire(short** buf, size_t len) {
@ -3146,7 +3210,7 @@ void DivPlatformOPL::setFlags(const DivConfig& flags) {
compatYPitch=flags.getBool("compatYPitch",false);
for (int i=0; i<44; i++) {
oscBuf[i]->rate=rate;
oscBuf[i]->setRate(rate);
}
}

View file

@ -47,6 +47,10 @@ void DivPlatformOPLL::acquire_nuked(short** buf, size_t len) {
thread_local int o[2];
thread_local int os;
for (int i=0; i<11; i++) {
oscBuf[i]->begin(len);
}
for (size_t h=0; h<len; h++) {
os=0;
for (int i=0; i<9; i++) {
@ -71,17 +75,17 @@ void DivPlatformOPLL::acquire_nuked(short** buf, size_t len) {
unsigned char nextOut=cycleMapOPLL[fm.cycles];
if ((nextOut>=6 && properDrums) || !isMuted[nextOut]) {
os+=(o[0]+o[1]);
if (vrc7 || (fm.rm_enable&0x20)) oscBuf[nextOut]->data[oscBuf[nextOut]->needle++]=(o[0]+o[1])<<6;
if (vrc7 || (fm.rm_enable&0x20)) oscBuf[nextOut]->putSample(h,(o[0]+o[1])<<6);
} else {
if (vrc7 || (fm.rm_enable&0x20)) oscBuf[nextOut]->data[oscBuf[nextOut]->needle++]=0;
if (vrc7 || (fm.rm_enable&0x20)) oscBuf[nextOut]->putSample(h,0);
}
}
if (!(vrc7 || (fm.rm_enable&0x20))) for (int i=0; i<9; i++) {
unsigned char ch=visMapOPLL[i];
if ((i>=6 && properDrums) || !isMuted[ch]) {
oscBuf[ch]->data[oscBuf[ch]->needle++]=(fm.output_ch[i])<<6;
oscBuf[ch]->putSample(h,(fm.output_ch[i])<<6);
} else {
oscBuf[ch]->data[oscBuf[ch]->needle++]=0;
oscBuf[ch]->putSample(h,0);
}
}
os*=50;
@ -89,6 +93,10 @@ void DivPlatformOPLL::acquire_nuked(short** buf, size_t len) {
if (os>32767) os=32767;
buf[0][h]=os;
}
for (int i=0; i<11; i++) {
oscBuf[i]->end(len);
}
}
void DivPlatformOPLL::acquire_ymfm(short** buf, size_t len) {
@ -101,6 +109,10 @@ static const unsigned char freakingDrumMap[5]={
void DivPlatformOPLL::acquire_emu(short** buf, size_t len) {
thread_local int os;
for (int i=0; i<11; i++) {
oscBuf[i]->begin(len);
}
for (size_t h=0; h<len; h++) {
if (!writes.empty()) {
QueuedWrite& w=writes.front();
@ -116,12 +128,16 @@ void DivPlatformOPLL::acquire_emu(short** buf, size_t len) {
for (int i=0; i<11; i++) {
if (i>=6 && properDrums) {
oscBuf[i]->data[oscBuf[i]->needle++]=(-fm_emu->ch_out[freakingDrumMap[i-6]])<<3;
oscBuf[i]->putSample(h,(-fm_emu->ch_out[freakingDrumMap[i-6]])<<3);
} else {
oscBuf[i]->data[oscBuf[i]->needle++]=(-fm_emu->ch_out[i])<<3;
oscBuf[i]->putSample(h,(-fm_emu->ch_out[i])<<3);
}
}
}
for (int i=0; i<11; i++) {
oscBuf[i]->end(len);
}
}
void DivPlatformOPLL::acquire(short** buf, size_t len) {
@ -1175,15 +1191,7 @@ void DivPlatformOPLL::setFlags(const DivConfig& flags) {
rate=chipClock/36;
}
for (int i=0; i<11; i++) {
if (selCore==1) {
oscBuf[i]->rate=rate;
} else {
if (i>=6 && properDrumsSys) {
oscBuf[i]->rate=rate;
} else {
oscBuf[i]->rate=rate/2;
}
}
oscBuf[i]->setRate(rate);
}
noTopHatFreq=flags.getBool("noTopHatFreq",false);
fixedAll=flags.getBool("fixedAll",true);

View file

@ -55,6 +55,10 @@ const char** DivPlatformPCE::getRegisterSheet() {
}
void DivPlatformPCE::acquire(short** buf, size_t len) {
for (int i=0; i<6; i++) {
oscBuf[i]->begin(len);
}
for (size_t h=0; h<len; h++) {
// PCM part
for (int i=0; i<6; i++) {
@ -100,7 +104,7 @@ void DivPlatformPCE::acquire(short** buf, size_t len) {
pce->ResetTS(0);
for (int i=0; i<6; i++) {
oscBuf[i]->data[oscBuf[i]->needle++]=CLAMP(pce->channel[i].blip_prev_samp[0]+pce->channel[i].blip_prev_samp[1],-32768,32767);
oscBuf[i]->putSample(h,CLAMP(pce->channel[i].blip_prev_samp[0]+pce->channel[i].blip_prev_samp[1],-32768,32767));
}
tempL[0]=(tempL[0]>>1)+(tempL[0]>>2);
@ -115,6 +119,10 @@ void DivPlatformPCE::acquire(short** buf, size_t len) {
buf[0][h]=tempL[0];
buf[1][h]=tempR[0];
}
for (int i=0; i<6; i++) {
oscBuf[i]->end(len);
}
}
void DivPlatformPCE::updateWave(int ch) {
@ -656,7 +664,7 @@ void DivPlatformPCE::setFlags(const DivConfig& flags) {
antiClickEnabled=!flags.getBool("noAntiClick",false);
rate=chipClock/(coreQuality>>1);
for (int i=0; i<6; i++) {
oscBuf[i]->rate=rate;
oscBuf[i]->setRate(rate);
}
if (pce!=NULL) {

View file

@ -29,11 +29,14 @@
void DivPlatformPCMDAC::acquire(short** buf, size_t len) {
const int depthScale=(15-outDepth);
int output=0;
oscBuf->begin(len);
for (size_t h=0; h<len; h++) {
if (!chan[0].active) {
buf[0][h]=0;
buf[1][h]=0;
oscBuf->data[oscBuf->needle++]=0;
oscBuf->putSample(h,0);
continue;
}
if (chan[0].useWave || (chan[0].sample>=0 && chan[0].sample<parent->song.sampleLen)) {
@ -229,7 +232,7 @@ void DivPlatformPCMDAC::acquire(short** buf, size_t len) {
} else {
output=((output*MIN(volMax,chan[0].vol)*MIN(chan[0].envVol,64))>>6)/volMax;
}
oscBuf->data[oscBuf->needle++]=((output>>depthScale)<<depthScale)>>1;
oscBuf->putSample(h,((output>>depthScale)<<depthScale)>>1);
if (outStereo) {
buf[0][h]=((output*chan[0].panL)>>(depthScale+8))<<depthScale;
buf[1][h]=((output*chan[0].panR)>>(depthScale+8))<<depthScale;
@ -239,6 +242,8 @@ void DivPlatformPCMDAC::acquire(short** buf, size_t len) {
buf[1][h]=output;
}
}
oscBuf->end(len);
}
void DivPlatformPCMDAC::tick(bool sysTick) {
@ -542,7 +547,7 @@ void DivPlatformPCMDAC::setFlags(const DivConfig& flags) {
outDepth=(flags.getInt("outDepth",15))&15;
outStereo=flags.getBool("stereo",true);
interp=flags.getInt("interpolation",0);
oscBuf->rate=rate;
oscBuf->setRate(rate);
volMax=flags.getInt("volMax",255);
if (volMax<1) volMax=1;
}

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,9 +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->putSample(0,out);
oldOut=out;
if (freq>=1) {
size_t boff=off;
size_t oscOff=0;
size_t i=len;
while (true) {
if ((int)i<timeToNextToggle) {
@ -221,6 +224,7 @@ void DivPlatformPCSpeaker::acquire_unfilt(blip_buffer_t** bb, size_t off, size_t
}
i-=timeToNextToggle;
boff+=timeToNextToggle;
oscOff+=timeToNextToggle;
pos-=timeToNextToggle;
if (pos<=0) {
pos=freq1;
@ -234,17 +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->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;
@ -263,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;
@ -290,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) {
@ -343,9 +354,7 @@ void DivPlatformPCSpeaker::acquire_real(blip_buffer_t** bb, size_t off, size_t l
}
}
out=(pos>(freq>>1) && !isMuted[0])?32767:0;
oscBuf->data[oscBuf->needle++]=out;
} else {
oscBuf->data[oscBuf->needle++]=0;
}
//buf[0][i]=0;
}
@ -641,6 +650,10 @@ bool DivPlatformPCSpeaker::hasAcquireDirect() {
return (speakerType==0 || speakerType==3);
}
bool DivPlatformPCSpeaker::isOscBufPositional() {
return (speakerType==0 || speakerType==3);
}
void DivPlatformPCSpeaker::setFlags(const DivConfig& flags) {
switch (flags.getInt("clockSel",0)) {
case 1: // PC-98
@ -661,7 +674,7 @@ void DivPlatformPCSpeaker::setFlags(const DivConfig& flags) {
} else {
rate=chipClock/PCSPKR_DIVIDER;
}
oscBuf->rate=rate;
oscBuf->setRate(rate);
switch (speakerType) {
case 1:

View file

@ -88,6 +88,7 @@ class DivPlatformPCSpeaker: public DivDispatch {
void muteChannel(int ch, bool mute);
bool keyOffAffectsArp(int ch);
bool hasAcquireDirect();
bool isOscBufPositional();
void setFlags(const DivConfig& flags);
void notifyInsDeletion(void* ins);
void notifyPlaybackStop();

View file

@ -57,6 +57,7 @@ void DivPlatformPET::rWrite(unsigned int addr, unsigned char val) {
void DivPlatformPET::acquire(short** buf, size_t len) {
bool hwSROutput=((regPool[11]>>2)&7)==4;
oscBuf->begin(len);
if (chan[0].enable) {
int reload=regPool[8]*2+4;
if (!hwSROutput) {
@ -71,7 +72,7 @@ void DivPlatformPET::acquire(short** buf, size_t len) {
chan[0].cnt-=SAMP_DIVIDER;
}
buf[0][h]=chan[0].out;
oscBuf->data[oscBuf->needle++]=chan[0].out;
oscBuf->putSample(h,chan[0].out);
}
// emulate driver writes to PCR
if (!hwSROutput) regPool[12]=chan[0].out?0xe0:0xc0;
@ -79,9 +80,10 @@ void DivPlatformPET::acquire(short** buf, size_t len) {
chan[0].out=0;
for (size_t h=0; h<len; h++) {
buf[0][h]=0;
oscBuf->data[oscBuf->needle++]=0;
oscBuf->putSample(h,0);
}
}
oscBuf->end(len);
}
void DivPlatformPET::writeOutVol() {
@ -311,7 +313,7 @@ int DivPlatformPET::init(DivEngine* p, int channels, int sugRate, const DivConfi
rate=chipClock/SAMP_DIVIDER; // = 250000kHz
isMuted=false;
oscBuf=new DivDispatchOscBuffer;
oscBuf->rate=rate;
oscBuf->setRate(rate);
reset();
return 1;
}

View file

@ -88,6 +88,7 @@ void DivPlatformPokeMini::rWrite(unsigned char addr, unsigned char val) {
void DivPlatformPokeMini::acquire(short** buf, size_t len) {
int out=0;
oscBuf->begin(len);
for (size_t i=0; i<len; i++) {
for (int j=0; j<PCSPKR_DIVIDER; j++) {
elapsedMain++;
@ -103,12 +104,13 @@ void DivPlatformPokeMini::acquire(short** buf, size_t len) {
if (on) {
out=(pos>=pivot && !isMuted[0])?volTable[vol&3]:0;
buf[0][i]=out;
oscBuf->data[oscBuf->needle++]=out;
oscBuf->putSample(i,out);
} else {
buf[0][i]=0;
oscBuf->data[oscBuf->needle++]=0;
oscBuf->putSample(i,0);
}
}
oscBuf->end(len);
}
void DivPlatformPokeMini::tick(bool sysTick) {
@ -323,7 +325,7 @@ void DivPlatformPokeMini::setFlags(const DivConfig& flags) {
CHECK_CUSTOM_CLOCK;
rate=chipClock/PCSPKR_DIVIDER;
oscBuf->rate=rate;
oscBuf->setRate(rate);
}
void DivPlatformPokeMini::notifyInsDeletion(void* ins) {

View file

@ -74,6 +74,10 @@ void DivPlatformPOKEY::acquire(short** buf, size_t len) {
}
void DivPlatformPOKEY::acquireMZ(short* buf, size_t len) {
for (int i=0; i<4; i++) {
oscBuf[i]->begin(len);
}
for (size_t h=0; h<len; h++) {
while (!writes.empty()) {
QueuedWrite w=writes.front();
@ -86,29 +90,47 @@ void DivPlatformPOKEY::acquireMZ(short* buf, size_t len) {
if (++oscBufDelay>=14) {
oscBufDelay=0;
oscBuf[0]->data[oscBuf[0]->needle++]=pokey.outvol_0<<10;
oscBuf[1]->data[oscBuf[1]->needle++]=pokey.outvol_1<<10;
oscBuf[2]->data[oscBuf[2]->needle++]=pokey.outvol_2<<10;
oscBuf[3]->data[oscBuf[3]->needle++]=pokey.outvol_3<<10;
oscBuf[0]->putSample(h,pokey.outvol_0<<10);
oscBuf[1]->putSample(h,pokey.outvol_1<<10);
oscBuf[2]->putSample(h,pokey.outvol_2<<10);
oscBuf[3]->putSample(h,pokey.outvol_3<<10);
}
}
for (int i=0; i<4; i++) {
oscBuf[i]->end(len);
}
}
void DivPlatformPOKEY::acquireASAP(short* buf, size_t len) {
thread_local short oscB[4];
while (!writes.empty()) {
QueuedWrite w=writes.front();
altASAP.write(w.addr, w.val);
writes.pop();
}
for (int i=0; i<4; i++) {
oscBuf[i]->begin(len);
}
for (size_t h=0; h<len; h++) {
if (++oscBufDelay>=2) {
oscBufDelay=0;
buf[h]=altASAP.sampleAudio(oscBuf);
buf[h]=altASAP.sampleAudio(oscB);
for (int i=0; i<4; i++) {
oscBuf[i]->putSample(h,oscB[i]);
}
} else {
buf[h]=altASAP.sampleAudio();
}
}
for (int i=0; i<4; i++) {
oscBuf[i]->end(len);
}
}
void DivPlatformPOKEY::tick(bool sysTick) {
@ -488,14 +510,14 @@ void DivPlatformPOKEY::setFlags(const DivConfig& flags) {
if (useAltASAP) {
rate=chipClock/7;
for (int i=0; i<4; i++) {
oscBuf[i]->rate=rate/2;
oscBuf[i]->setRate(rate);
}
altASAP.init(chipClock,rate);
altASAP.reset();
} else {
rate=chipClock;
for (int i=0; i<4; i++) {
oscBuf[i]->rate=rate/14;
oscBuf[i]->setRate(rate);
}
}
}

View file

@ -25,6 +25,7 @@
void DivPlatformPong::acquire(short** buf, size_t len) {
int out=0;
oscBuf->begin(len);
for (size_t i=0; i<len; i++) {
if (on) {
if (--pos<=0) {
@ -33,13 +34,14 @@ void DivPlatformPong::acquire(short** buf, size_t len) {
}
out=(flip && !isMuted[0])?32767:0;
buf[0][i]=out;
oscBuf->data[oscBuf->needle++]=out;
oscBuf->putSample(i,out);
} else {
buf[0][i]=0;
oscBuf->data[oscBuf->needle++]=0;
oscBuf->putSample(i,0);
flip=false;
}
}
oscBuf->end(len);
}
void DivPlatformPong::tick(bool sysTick) {
@ -237,7 +239,7 @@ void DivPlatformPong::setFlags(const DivConfig& flags) {
chipClock=1000000;
CHECK_CUSTOM_CLOCK;
rate=chipClock/64;
oscBuf->rate=rate;
oscBuf->setRate(rate);
}
void DivPlatformPong::notifyInsDeletion(void* ins) {

View file

@ -82,17 +82,25 @@ const char** DivPlatformPowerNoise::getRegisterSheet() {
void DivPlatformPowerNoise::acquire(short** buf, size_t len) {
short left, right;
for (int i=0; i<4; i++) {
oscBuf[i]->begin(len);
}
for (size_t h=0; h<len; h++) {
pwrnoise_step(&pn,coreQuality,&left,&right);
oscBuf[0]->data[oscBuf[0]->needle++]=mapAmp((pn.n1.out_latch&0xf)+(pn.n1.out_latch>>4));
oscBuf[1]->data[oscBuf[1]->needle++]=mapAmp((pn.n2.out_latch&0xf)+(pn.n2.out_latch>>4));
oscBuf[2]->data[oscBuf[2]->needle++]=mapAmp((pn.n3.out_latch&0xf)+(pn.n3.out_latch>>4));
oscBuf[3]->data[oscBuf[3]->needle++]=mapAmp((pn.s.out_latch&0xf)+(pn.s.out_latch>>4));
oscBuf[0]->putSample(h,mapAmp((pn.n1.out_latch&0xf)+(pn.n1.out_latch>>4)));
oscBuf[1]->putSample(h,mapAmp((pn.n2.out_latch&0xf)+(pn.n2.out_latch>>4)));
oscBuf[2]->putSample(h,mapAmp((pn.n3.out_latch&0xf)+(pn.n3.out_latch>>4)));
oscBuf[3]->putSample(h,mapAmp((pn.s.out_latch&0xf)+(pn.s.out_latch>>4)));
buf[0][h]=left;
buf[1][h]=right;
}
for (int i=0; i<4; i++) {
oscBuf[i]->end(len);
}
}
/* macros:
@ -506,7 +514,7 @@ void DivPlatformPowerNoise::setFlags(const DivConfig& flags) {
rate=chipClock/coreQuality;
for (int i=0; i<4; i++) {
oscBuf[i]->rate=rate;
oscBuf[i]->setRate(rate);
}
}

View file

@ -38,13 +38,21 @@ const char** DivPlatformPV1000::getRegisterSheet() {
}
void DivPlatformPV1000::acquire(short** buf, size_t len) {
for (int i=0; i<3; i++) {
oscBuf[i]->begin(len);
}
for (size_t h=0; h<len; h++) {
short samp=d65010g031_sound_tick(&d65010g031,1);
buf[0][h]=samp;
for (int i=0; i<3; i++) {
oscBuf[i]->data[oscBuf[i]->needle++]=MAX(d65010g031.out[i]<<2,0);
oscBuf[i]->putSample(h,MAX(d65010g031.out[i]<<2,0));
}
}
for (int i=0; i<3; i++) {
oscBuf[i]->end(len);
}
}
void DivPlatformPV1000::tick(bool sysTick) {
@ -263,7 +271,7 @@ void DivPlatformPV1000::setFlags(const DivConfig& flags) {
CHECK_CUSTOM_CLOCK;
rate=chipClock/1024;
for (int i=0; i<3; i++) {
oscBuf[i]->rate=rate;
oscBuf[i]->setRate(rate);
}
}

View file

@ -265,6 +265,10 @@ const char** DivPlatformQSound::getRegisterSheet() {
}
void DivPlatformQSound::acquire(short** buf, size_t len) {
for (int i=0; i<19; i++) {
oscBuf[i]->begin(len);
}
for (size_t h=0; h<len; h++) {
qsound_update(&chip);
buf[0][h]=chip.out[0];
@ -274,9 +278,13 @@ void DivPlatformQSound::acquire(short** buf, size_t len) {
int data=chip.voice_output[i]<<1;
if (data<-32768) data=-32768;
if (data>32767) data=32767;
oscBuf[i]->data[oscBuf[i]->needle++]=data;
oscBuf[i]->putSample(h,data);
}
}
for (int i=0; i<19; i++) {
oscBuf[i]->end(len);
}
}
void DivPlatformQSound::tick(bool sysTick) {
@ -861,7 +869,7 @@ int DivPlatformQSound::init(DivEngine* p, int channels, int sugRate, const DivCo
reset();
for (int i=0; i<19; i++) {
oscBuf[i]->rate=rate;
oscBuf[i]->setRate(rate);
}
return 19;
}

View file

@ -68,17 +68,26 @@ void DivPlatformRF5C68::acquire(short** buf, size_t len) {
memset(bufC[i],0,256*sizeof(short));
}
while (len > 0) {
size_t blockLen=MIN(len,256);
for (int i=0; i<8; i++) {
oscBuf[i]->begin(len);
}
size_t lenCopy=len;
while (lenCopy > 0) {
size_t blockLen=MIN(lenCopy,256);
short* bufPtrs[2]={&buf[0][pos],&buf[1][pos]};
rf5c68.sound_stream_update(bufPtrs,chBufPtrs,blockLen);
for (int i=0; i<8; i++) {
for (size_t j=0; j<blockLen; j++) {
oscBuf[i]->data[oscBuf[i]->needle++]=(bufC[i*2][j]+bufC[i*2+1][j])>>1;
oscBuf[i]->putSample(pos+j,(bufC[i*2][j]+bufC[i*2+1][j])>>1);
}
}
pos+=blockLen;
len-=blockLen;
lenCopy-=blockLen;
}
for (int i=0; i<8; i++) {
oscBuf[i]->end(len);
}
}
@ -375,7 +384,7 @@ void DivPlatformRF5C68::setFlags(const DivConfig& flags) {
chipType=flags.getInt("chipType",0);
rate=chipClock/384;
for (int i=0; i<8; i++) {
oscBuf[i]->rate=rate;
oscBuf[i]->setRate(rate);
}
rf5c68=(chipType==1)?rf5c164_device():rf5c68_device();
rf5c68.device_start(sampleMem);

View file

@ -71,7 +71,13 @@ void DivPlatformSAA1099::acquire_saaSound(short** buf, size_t len) {
regPool[w.addr&0x1f]=w.val;
writes.pop();
}
for (int i=0; i<6; i++) {
oscBuf[i]->begin(len);
}
saa_saaSound->GenerateMany((unsigned char*)saaBuf[0],len,oscBuf);
for (int i=0; i<6; i++) {
oscBuf[i]->end(len);
}
#ifdef TA_BIG_ENDIAN
for (size_t i=0; i<len; i++) {
buf[0][i]=(short)((((unsigned short)saaBuf[0][i<<1])<<8)|(((unsigned short)saaBuf[0][i<<1])>>8));

View file

@ -81,15 +81,23 @@ const char** DivPlatformSCC::getRegisterSheet() {
}
void DivPlatformSCC::acquire(short** buf, size_t len) {
for (int i=0; i<5; i++) {
oscBuf[i]->begin(len);
}
for (size_t h=0; h<len; h++) {
scc->tick(coreQuality);
short out=(short)scc->out()<<5;
buf[0][h]=out;
for (int i=0; i<5; i++) {
oscBuf[i]->data[oscBuf[i]->needle++]=scc->voice_out(i)<<7;
oscBuf[i]->putSample(h,scc->voice_out(i)<<7);
}
}
for (int i=0; i<5; i++) {
oscBuf[i]->end(len);
}
}
void DivPlatformSCC::updateWave(int ch) {
@ -385,7 +393,7 @@ void DivPlatformSCC::setFlags(const DivConfig& flags) {
CHECK_CUSTOM_CLOCK;
rate=chipClock/(coreQuality>>1);
for (int i=0; i<5; i++) {
oscBuf[i]->rate=rate;
oscBuf[i]->setRate(rate);
}
}

View file

@ -37,6 +37,10 @@ const char** DivPlatformSCVTone::getRegisterSheet() {
}
void DivPlatformSCVTone::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++) {
while (!writes.empty()) {
QueuedWrite w=writes.front();
@ -46,10 +50,14 @@ void DivPlatformSCVTone::acquire(short** buf, size_t len) {
}
scv.sound_stream_update(&buf[0][h],1);
oscBuf[0]->data[oscBuf[0]->needle++]=scv.chout[0]<<3;
oscBuf[1]->data[oscBuf[1]->needle++]=scv.chout[1]<<3;
oscBuf[2]->data[oscBuf[2]->needle++]=scv.chout[2]<<3;
oscBuf[3]->data[oscBuf[3]->needle++]=scv.chout[3]<<3;
oscBuf[0]->putSample(h,scv.chout[0]<<3);
oscBuf[1]->putSample(h,scv.chout[1]<<3);
oscBuf[2]->putSample(h,scv.chout[2]<<3);
oscBuf[3]->putSample(h,scv.chout[3]<<3);
}
for (int i=0; i<4; i++) {
oscBuf[i]->end(len);
}
}
@ -334,7 +342,7 @@ void DivPlatformSCVTone::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);
}
//upd1771c_sound_set_clock(&scv,(unsigned int)chipClock,8);
}

View file

@ -37,6 +37,8 @@ const char** DivPlatformSCVWave::getRegisterSheet() {
}
void DivPlatformSCVWave::acquire(short** buf, size_t len) {
oscBuf[0]->begin(len);
for (size_t h=0; h<len; h++) {
while (!writes.empty()) {
QueuedWrite w=writes.front();
@ -47,8 +49,10 @@ void DivPlatformSCVWave::acquire(short** buf, size_t len) {
scv.sound_stream_update(&buf[0][h],1);
if (isMuted[0]) buf[0][h]=0;
oscBuf[0]->data[oscBuf[0]->needle++]=buf[0][h];
oscBuf[0]->putSample(h,buf[0][h]);
}
oscBuf[0]->end(len);
}
void DivPlatformSCVWave::tick(bool sysTick) {
@ -324,9 +328,8 @@ void DivPlatformSCVWave::setFlags(const DivConfig& flags) {
CHECK_CUSTOM_CLOCK;
rate=chipClock/4;
for (int i=0; i<1; i++) {
oscBuf[i]->rate=rate;
oscBuf[i]->setRate(rate);
}
//upd1771c_sound_set_clock(&scv,(unsigned int)chipClock,8);
}
void DivPlatformSCVWave::poke(unsigned int addr, unsigned short val) {

View file

@ -29,6 +29,10 @@
void DivPlatformSegaPCM::acquire(short** buf, size_t len) {
thread_local int os[2];
for (int i=0; i<16; i++) {
oscBuf[i]->begin(len);
}
for (size_t h=0; h<len; h++) {
while (!writes.empty()) {
QueuedWrite w=writes.front();
@ -49,9 +53,13 @@ void DivPlatformSegaPCM::acquire(short** buf, size_t len) {
buf[1][h]=os[1];
for (int i=0; i<16; i++) {
oscBuf[i]->data[oscBuf[i]->needle++]=(pcm.lastOut[i][0]+pcm.lastOut[i][1])>>1;
oscBuf[i]->putSample(h,(pcm.lastOut[i][0]+pcm.lastOut[i][1])>>1);
}
}
for (int i=0; i<16; i++) {
oscBuf[i]->end(len);
}
}
void DivPlatformSegaPCM::tick(bool sysTick) {
@ -551,7 +559,7 @@ void DivPlatformSegaPCM::setFlags(const DivConfig& flags) {
CHECK_CUSTOM_CLOCK;
rate=chipClock/256;
for (int i=0; i<16; i++) {
oscBuf[i]->rate=rate;
oscBuf[i]->setRate(rate);
}
oldSlides=flags.getBool("oldSlides",false);

View file

@ -73,8 +73,11 @@ const char** DivPlatformSID2::getRegisterSheet() {
return regCheatSheetSID2;
}
void DivPlatformSID2::acquire(short** buf, size_t len)
{
void DivPlatformSID2::acquire(short** buf, size_t len) {
for (int i=0; i<3; i++) {
oscBuf[i]->begin(len);
}
for (size_t i=0; i<len; i++)
{
if (!writes.empty())
@ -96,10 +99,14 @@ void DivPlatformSID2::acquire(short** buf, size_t len)
int co=sid2->chan_out[j]>>2;
if (co<-32768) co=-32768;
if (co>32767) co=32767;
oscBuf[j]->data[oscBuf[j]->needle++]=co;
oscBuf[j]->putSample(i,co);
}
}
}
for (int i=0; i<3; i++) {
oscBuf[i]->end(len);
}
}
void DivPlatformSID2::updateFilter(int channel)
@ -710,7 +717,7 @@ void DivPlatformSID2::setFlags(const DivConfig& flags) {
CHECK_CUSTOM_CLOCK;
rate=chipClock;
for (int i=0; i<3; i++) {
oscBuf[i]->rate=rate/16;
oscBuf[i]->setRate(rate);
}
keyPriority=flags.getBool("keyPriority",true);

View file

@ -94,6 +94,10 @@ const char** DivPlatformSID3::getRegisterSheet() {
void DivPlatformSID3::acquire(short** buf, size_t len)
{
for (int i=0; i<SID3_NUM_CHANNELS; i++) {
oscBuf[i]->begin(len);
}
for (size_t i=0; i<len; i++)
{
if (chan[SID3_NUM_CHANNELS - 1].pcm && chan[SID3_NUM_CHANNELS - 1].dacSample!=-1)
@ -200,12 +204,16 @@ void DivPlatformSID3::acquire(short** buf, size_t len)
for(int j = 0; j < SID3_NUM_CHANNELS - 1; j++)
{
oscBuf[j]->data[oscBuf[j]->needle++] = sid3->muted[j] ? 0 : (sid3->channel_output[j] / 4);
oscBuf[j]->putSample(i,sid3->muted[j] ? 0 : (sid3->channel_output[j] / 4));
}
oscBuf[SID3_NUM_CHANNELS - 1]->data[oscBuf[SID3_NUM_CHANNELS - 1]->needle++] = sid3->muted[SID3_NUM_CHANNELS - 1] ? 0 : (sid3->wave_channel_output / 4);
oscBuf[SID3_NUM_CHANNELS - 1]->putSample(i,sid3->muted[SID3_NUM_CHANNELS - 1] ? 0 : (sid3->wave_channel_output / 4));
}
}
for (int i=0; i<SID3_NUM_CHANNELS; i++) {
oscBuf[i]->end(len);
}
}
void DivPlatformSID3::updateFlags(int channel, bool gate)
@ -1351,7 +1359,7 @@ void DivPlatformSID3::setFlags(const DivConfig& flags) {
rate=chipClock;
sid3_set_clock_rate(sid3, chipClock);
for (int i=0; i<SID3_NUM_CHANNELS; i++) {
oscBuf[i]->rate=rate/8;
oscBuf[i]->setRate(rate);
}
}

View file

@ -54,13 +54,22 @@ void DivPlatformSM8521::acquire(short** buf, size_t len) {
regPool[w.addr&0xff]=w.val;
writes.pop();
}
for (int i=0; i<3; i++) {
oscBuf[i]->begin(len);
}
for (size_t h=0; h<len; h++) {
sm8521_sound_tick(&sm8521,coreQuality);
buf[0][h]=sm8521.out<<6;
for (int i=0; i<2; i++) {
oscBuf[i]->data[oscBuf[i]->needle++]=sm8521.sg[i].base.out<<7;
oscBuf[i]->putSample(h,sm8521.sg[i].base.out<<7);
}
oscBuf[2]->data[oscBuf[2]->needle++]=sm8521.noise.base.out<<7;
oscBuf[2]->putSample(h,sm8521.noise.base.out<<7);
}
for (int i=0; i<3; i++) {
oscBuf[i]->end(len);
}
}
@ -369,7 +378,7 @@ void DivPlatformSM8521::setFlags(const DivConfig& flags) {
antiClickEnabled=!flags.getBool("noAntiClick",false);
rate=chipClock/4/coreQuality; // CKIN -> fCLK(/2) -> Function blocks (/2)
for (int i=0; i<3; i++) {
oscBuf[i]->rate=rate;
oscBuf[i]->setRate(rate);
}
}

View file

@ -63,6 +63,11 @@ void DivPlatformSMS::poolWrite(unsigned short a, unsigned char v) {
void DivPlatformSMS::acquire_nuked(short** buf, size_t len) {
int oL=0;
int oR=0;
for (int i=0; i<4; i++) {
oscBuf[i]->begin(len);
}
for (size_t h=0; h<len; h++) {
if (!writes.empty()) {
QueuedWrite w=writes.front();
@ -101,12 +106,16 @@ void DivPlatformSMS::acquire_nuked(short** buf, size_t len) {
if (stereo) buf[1][h]=oR;
for (int i=0; i<4; i++) {
if (isMuted[i]) {
oscBuf[i]->data[oscBuf[i]->needle++]=0;
oscBuf[i]->putSample(h,0);
} else {
oscBuf[i]->data[oscBuf[i]->needle++]=sn_nuked.vol_table[sn_nuked.volume_out[i]]*3;
oscBuf[i]->putSample(h,sn_nuked.vol_table[sn_nuked.volume_out[i]]*3);
}
}
}
for (int i=0; i<4; i++) {
oscBuf[i]->end(len);
}
}
void DivPlatformSMS::acquire_mame(short** buf, size_t len) {
@ -122,6 +131,11 @@ void DivPlatformSMS::acquire_mame(short** buf, size_t len) {
writes.pop();
}
for (int i=0; i<4; i++) {
oscBuf[i]->begin(len);
}
for (size_t h=0; h<len; h++) {
short* outs[2]={
&buf[0][h],
@ -130,12 +144,16 @@ void DivPlatformSMS::acquire_mame(short** buf, size_t len) {
sn->sound_stream_update(outs,1);
for (int i=0; i<4; i++) {
if (isMuted[i]) {
oscBuf[i]->data[oscBuf[i]->needle++]=0;
oscBuf[i]->putSample(h,0);
} else {
oscBuf[i]->data[oscBuf[i]->needle++]=sn->get_channel_output(i)*3;
oscBuf[i]->putSample(h,sn->get_channel_output(i)*3);
}
}
}
for (int i=0; i<4; i++) {
oscBuf[i]->end(len);
}
}
void DivPlatformSMS::acquire(short** buf, size_t len) {
@ -638,7 +656,7 @@ void DivPlatformSMS::setFlags(const DivConfig& flags) {
rate=chipClock/divider;
for (int i=0; i<4; i++) {
oscBuf[i]->rate=rate;
oscBuf[i]->setRate(rate);
}
}

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

@ -485,7 +485,7 @@ public:
return mAudioChannels[timer].fireAction( tick );
}
AudioSample sampleAudio( DivDispatchOscBuffer** oscb ) const
AudioSample sampleAudio( int* oscb ) const
{
int left{};
int right{};
@ -509,7 +509,7 @@ public:
}
if (oscb!=NULL) {
oscb[i]->data[oscb[i]->needle++]=oscbWrite;
oscb[i]=oscbWrite;
}
}
@ -570,7 +570,7 @@ void Mikey::enqueueSampling()
mQueue->push( ( mNextTick & ~15 ) | 4 );
}
void Mikey::sampleAudio( int16_t* bufL, int16_t* bufR, size_t size, DivDispatchOscBuffer** oscb )
void Mikey::sampleAudio( int16_t* bufL, int16_t* bufR, size_t size, int* oscb )
{
size_t i = 0;
while ( i < size )

View file

@ -21,7 +21,7 @@ public:
~Mikey();
void write( uint8_t address, uint8_t value );
void sampleAudio( int16_t* bufL, int16_t* bufR, size_t size, DivDispatchOscBuffer** oscb = NULL );
void sampleAudio( int16_t* bufL, int16_t* bufR, size_t size, int* oscb = NULL );
uint8_t const* getRegisterPool();

View file

@ -1,6 +1,6 @@
/**
* Furnace Tracker - multi-system chiptune tracker
* Copyright (C) 2021-2022 tildearrow and contributors
* Copyright (C) 2021-2025 tildearrow and contributors
*
* Original author: Piotr Fusik (http://asap.sourceforge.net)
* Rewritten based on Mikey emulation by Waldemar Pawlaszek
@ -490,7 +490,7 @@ public:
}
}
int16_t sampleAudio( DivDispatchOscBuffer** oscb )
int16_t sampleAudio( short* oscb )
{
for ( ;; )
{
@ -504,10 +504,10 @@ public:
if ( oscb != nullptr )
{
oscb[0]->data[oscb[0]->needle++]=ch0 * MAGICK_OSC_VOLUME_BOOSTER;
oscb[1]->data[oscb[1]->needle++]=ch1 * MAGICK_OSC_VOLUME_BOOSTER;
oscb[2]->data[oscb[2]->needle++]=ch2 * MAGICK_OSC_VOLUME_BOOSTER;
oscb[3]->data[oscb[3]->needle++]=ch3 * MAGICK_OSC_VOLUME_BOOSTER;
oscb[0]=ch0 * MAGICK_OSC_VOLUME_BOOSTER;
oscb[1]=ch1 * MAGICK_OSC_VOLUME_BOOSTER;
oscb[2]=ch2 * MAGICK_OSC_VOLUME_BOOSTER;
oscb[3]=ch3 * MAGICK_OSC_VOLUME_BOOSTER;
}
enqueueSampling();
@ -612,7 +612,7 @@ private:
};
//Initializing periods with safe defaults
Pokey::Pokey() : mPokeyClock{ (uint32_t)COLOR_NTSC / 2 }, mSampleRate{ mPokeyClock / 7 }, mPokey{}
Pokey::Pokey() : mPokeyClock{ (uint32_t)3579545.4545454545454545454545454545454644484879993035705375307 / 2 }, mSampleRate{ mPokeyClock / 7 }, mPokey{}
{
}
@ -638,7 +638,7 @@ void Pokey::write( uint8_t address, uint8_t value )
mPokey->write( address, value );
}
int16_t Pokey::sampleAudio( DivDispatchOscBuffer** oscb )
int16_t Pokey::sampleAudio( short* oscb )
{
assert( mPokey );
return mPokey->sampleAudio( oscb );

View file

@ -3,9 +3,6 @@
#include <cstdint>
#include <memory>
// can you forgive me
#include "../../../dispatch.h"
namespace AltASAP
{
@ -20,7 +17,7 @@ public:
~Pokey();
void write( uint8_t address, uint8_t value );
int16_t sampleAudio( DivDispatchOscBuffer** oscb = nullptr );
int16_t sampleAudio( short* oscb = nullptr );
uint8_t const* getRegisterPool();

View file

@ -41,6 +41,10 @@ double DivPlatformSoundUnit::NOTE_SU(int ch, int note) {
}
void DivPlatformSoundUnit::acquire(short** buf, size_t len) {
for (int i=0; i<8; i++) {
oscBuf[i]->begin(len);
}
for (size_t h=0; h<len; h++) {
while (!writes.empty()) {
QueuedWrite w=writes.front();
@ -49,9 +53,13 @@ void DivPlatformSoundUnit::acquire(short** buf, size_t len) {
}
su->NextSample(&buf[0][h],&buf[1][h]);
for (int i=0; i<8; i++) {
oscBuf[i]->data[oscBuf[i]->needle++]=su->GetSample(i);
oscBuf[i]->putSample(h,su->GetSample(i));
}
}
for (int i=0; i<8; i++) {
oscBuf[i]->end(len);
}
}
void DivPlatformSoundUnit::writeControl(int ch) {
@ -646,7 +654,7 @@ void DivPlatformSoundUnit::setFlags(const DivConfig& flags) {
CHECK_CUSTOM_CLOCK;
rate=chipClock/4;
for (int i=0; i<8; i++) {
oscBuf[i]->rate=rate;
oscBuf[i]->setRate(rate);
}
bool echoOn=flags.getBool("echo",false);
initIlCtrl=3|(echoOn?4:0);

View file

@ -58,10 +58,15 @@ const char** DivPlatformSupervision::getRegisterSheet() {
void DivPlatformSupervision::acquire(short** buf, size_t len) {
int mask_bits=0;
for (int i=0; i<4; i++)
for (int i=0; i<4; i++) {
mask_bits |= isMuted[i]?0:8>>i;
}
supervision_set_mute_mask(&svision,mask_bits);
for (int i=0; i<4; i++) {
oscBuf[i]->begin(len);
}
for (size_t h=0; h<len; h++) {
while (!writes.empty()) {
QueuedWrite w=writes.front();
@ -76,7 +81,7 @@ void DivPlatformSupervision::acquire(short** buf, size_t len) {
tempR[0]=(((int)s[1])-128)*256;
for (int i=0; i<4; i++) {
oscBuf[i]->data[oscBuf[i]->needle++]=CLAMP((((int)s[2+i])-128)*256,-32768,32767);
oscBuf[i]->putSample(h,CLAMP((((int)s[2+i])-128)*256,-32768,32767));
}
tempL[0]=(tempL[0]>>1)+(tempL[0]>>2);
@ -91,11 +96,14 @@ void DivPlatformSupervision::acquire(short** buf, size_t len) {
buf[0][h]=tempL[0];
buf[1][h]=tempR[0];
}
for (int i=0; i<4; i++) {
oscBuf[i]->end(len);
}
}
void DivPlatformSupervision::tick(bool sysTick) {
for (int i=0; i<4; i++) {
chan[i].std.next();
if (chan[i].std.vol.had) {
chan[i].outVol=VOL_SCALE_LINEAR(chan[i].vol&15,MIN(15,chan[i].std.vol.val),15);
@ -477,7 +485,7 @@ void DivPlatformSupervision::setFlags(const DivConfig& flags) {
CHECK_CUSTOM_CLOCK;
rate=chipClock/64;
for (int i=0; i<4; i++) {
oscBuf[i]->rate=rate;
oscBuf[i]->setRate(rate);
}
supervision_sound_set_clock(&svision,(unsigned int)chipClock);
supervision_sound_set_flags(&svision,(unsigned int)otherFlags);

View file

@ -54,6 +54,10 @@ const char** DivPlatformSwan::getRegisterSheet() {
}
void DivPlatformSwan::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++) {
// PCM part
if (pcm && dacSample!=-1) {
@ -89,9 +93,13 @@ void DivPlatformSwan::acquire(short** buf, size_t len) {
buf[0][h]=samp[0];
buf[1][h]=samp[1];
for (int i=0; i<4; i++) {
oscBuf[i]->data[oscBuf[i]->needle++]=(ws->sample_cache[i][0]+ws->sample_cache[i][1])<<6;
oscBuf[i]->putSample(h,(ws->sample_cache[i][0]+ws->sample_cache[i][1])<<6);
}
}
for (int i=0; i<4; i++) {
oscBuf[i]->end(len);
}
}
void DivPlatformSwan::updateWave(int ch) {
@ -607,7 +615,7 @@ void DivPlatformSwan::setFlags(const DivConfig& flags) {
CHECK_CUSTOM_CLOCK;
rate=chipClock/coreQuality;
for (int i=0; i<4; i++) {
oscBuf[i]->rate=rate;
oscBuf[i]->setRate(rate);
}
}

View file

@ -36,6 +36,10 @@ const char** DivPlatformT6W28::getRegisterSheet() {
}
void DivPlatformT6W28::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++) {
cycles=0;
while (!writes.empty() && cycles<16) {
@ -54,7 +58,7 @@ void DivPlatformT6W28::acquire(short** buf, size_t len) {
tempL=0;
tempR=0;
for (int i=0; i<4; i++) {
oscBuf[i]->data[oscBuf[i]->needle++]=(out[i][1].curValue+out[i][2].curValue)<<7;
oscBuf[i]->putSample(h,(out[i][1].curValue+out[i][2].curValue)<<7);
tempL+=out[i][1].curValue<<7;
tempR+=out[i][2].curValue<<7;
}
@ -67,6 +71,10 @@ void DivPlatformT6W28::acquire(short** buf, size_t len) {
buf[0][h]=tempL;
buf[1][h]=tempR;
}
for (int i=0; i<4; i++) {
oscBuf[i]->end(len);
}
}
void DivPlatformT6W28::writeOutVol(int ch) {
@ -364,7 +372,7 @@ void DivPlatformT6W28::setFlags(const DivConfig& flags) {
CHECK_CUSTOM_CLOCK;
rate=chipClock/16;
for (int i=0; i<4; i++) {
oscBuf[i]->rate=rate;
oscBuf[i]->setRate(rate);
}
easyNoise=!flags.getBool("noEasyNoise",false);

View file

@ -40,6 +40,10 @@ const char** DivPlatformTED::getRegisterSheet() {
}
void DivPlatformTED::acquire(short** buf, size_t len) {
for (int i=0; i<2; i++) {
oscBuf[i]->begin(len);
}
for (size_t h=0; h<len; h++) {
while (!writes.empty()) {
QueuedWrite w=writes.front();
@ -49,8 +53,12 @@ void DivPlatformTED::acquire(short** buf, size_t len) {
}
ted_sound_machine_calculate_samples(&ted,&buf[0][h],1,1);
oscBuf[0]->data[oscBuf[0]->needle++]=(ted.voice0_output_enabled && ted.voice0_sign)?(ted.volume<<1):0;
oscBuf[1]->data[oscBuf[1]->needle++]=(ted.voice1_output_enabled && ((ted.noise && (!(ted.noise_shift_register&1))) || (!ted.noise && ted.voice1_sign)))?(ted.volume<<1):0;
oscBuf[0]->putSample(h,(ted.voice0_output_enabled && ted.voice0_sign)?(ted.volume<<1):0);
oscBuf[1]->putSample(h,(ted.voice1_output_enabled && ((ted.noise && (!(ted.noise_shift_register&1))) || (!ted.noise && ted.voice1_sign)))?(ted.volume<<1):0);
}
for (int i=0; i<2; i++) {
oscBuf[i]->end(len);
}
}
@ -322,7 +330,7 @@ void DivPlatformTED::setFlags(const DivConfig& flags) {
CHECK_CUSTOM_CLOCK;
rate=chipClock/8;
for (int i=0; i<2; i++) {
oscBuf[i]->rate=rate;
oscBuf[i]->setRate(rate);
}
keyPriority=flags.getBool("keyPriority",true);
}

View file

@ -39,6 +39,10 @@ const char** DivPlatformTIA::getRegisterSheet() {
}
void DivPlatformTIA::acquire(short** buf, size_t len) {
for (int i=0; i<2; i++) {
oscBuf[i]->begin(len);
}
for (size_t h=0; h<len; h++) {
if (softwarePitch) {
int i=-1;
@ -75,10 +79,14 @@ void DivPlatformTIA::acquire(short** buf, size_t len) {
}
if (++chanOscCounter>=114) {
chanOscCounter=0;
oscBuf[0]->data[oscBuf[0]->needle++]=tia.myChannelOut[0];
oscBuf[1]->data[oscBuf[1]->needle++]=tia.myChannelOut[1];
oscBuf[0]->putSample(h,tia.myChannelOut[0]);
oscBuf[1]->putSample(h,tia.myChannelOut[1]);
}
}
for (int i=0; i<2; i++) {
oscBuf[i]->end(len);
}
}
unsigned char DivPlatformTIA::dealWithFreq(unsigned char shape, int base, int pitch) {
@ -471,7 +479,7 @@ void DivPlatformTIA::setFlags(const DivConfig& flags) {
softwarePitch=flags.getBool("softwarePitch",false);
oldPitch=flags.getBool("oldPitch",false);
for (int i=0; i<2; i++) {
oscBuf[i]->rate=rate/114;
oscBuf[i]->setRate(rate);
}
tia.reset(mixingType);
}

View file

@ -62,6 +62,10 @@ void DivPlatformTX81Z::acquire(short** buf, size_t len) {
ymfm::ym2414::fm_engine* fme=fm_ymfm->debug_engine();
for (int i=0; i<8; i++) {
oscBuf[i]->begin(len);
}
for (size_t h=0; h<len; h++) {
os[0]=0; os[1]=0;
if (!writes.empty()) {
@ -82,7 +86,7 @@ void DivPlatformTX81Z::acquire(short** buf, size_t len) {
fm_ymfm->generate(&out_ymfm);
for (int i=0; i<8; i++) {
oscBuf[i]->data[oscBuf[i]->needle++]=CLAMP(fme->debug_channel(i)->debug_output(0)+fme->debug_channel(i)->debug_output(1),-32768,32767);
oscBuf[i]->putSample(h,CLAMP(fme->debug_channel(i)->debug_output(0)+fme->debug_channel(i)->debug_output(1),-32768,32767));
}
os[0]=out_ymfm.data[0];
@ -96,6 +100,10 @@ void DivPlatformTX81Z::acquire(short** buf, size_t len) {
buf[0][h]=os[0];
buf[1][h]=os[1];
}
for (int i=0; i<8; i++) {
oscBuf[i]->end(len);
}
}
static unsigned char noteMap[12]={
@ -1114,7 +1122,7 @@ void DivPlatformTX81Z::setFlags(const DivConfig& flags) {
rate=chipClock/64;
for (int i=0; i<8; i++) {
oscBuf[i]->rate=rate;
oscBuf[i]->setRate(rate);
}
}

View file

@ -94,6 +94,10 @@ const char** DivPlatformVB::getRegisterSheet() {
}
void DivPlatformVB::acquire(short** buf, size_t len) {
for (int i=0; i<6; i++) {
oscBuf[i]->begin(len);
}
for (size_t h=0; h<len; h++) {
cycles=0;
if (!writes.empty()) {
@ -107,7 +111,7 @@ void DivPlatformVB::acquire(short** buf, size_t len) {
tempL=0;
tempR=0;
for (int i=0; i<6; i++) {
oscBuf[i]->data[oscBuf[i]->needle++]=(vb->last_output[i][0]+vb->last_output[i][1])*8;
oscBuf[i]->putSample(h,(vb->last_output[i][0]+vb->last_output[i][1])*8);
tempL+=vb->last_output[i][0];
tempR+=vb->last_output[i][1];
}
@ -120,6 +124,10 @@ void DivPlatformVB::acquire(short** buf, size_t len) {
buf[0][h]=tempL;
buf[1][h]=tempR;
}
for (int i=0; i<6; i++) {
oscBuf[i]->end(len);
}
}
void DivPlatformVB::updateWave(int ch) {
@ -586,7 +594,7 @@ void DivPlatformVB::setFlags(const DivConfig& flags) {
CHECK_CUSTOM_CLOCK;
rate=chipClock/coreQuality;
for (int i=0; i<6; i++) {
oscBuf[i]->rate=rate;
oscBuf[i]->setRate(rate);
}
romMode=flags.getBool("romMode",false);

View file

@ -58,12 +58,17 @@ const char** DivPlatformVERA::getRegisterSheet() {
// TODO: possible sample offset latency...
void DivPlatformVERA::acquire(short** buf, size_t len) {
for (int i=0; i<17; i++) {
oscBuf[i]->begin(len);
}
// both PSG part and PCM part output a full 16-bit range, putting bufL/R
// argument right into both could cause an overflow
short whyCallItBuf[4][128];
size_t pos=0;
size_t lenCopy=len;
DivSample* s=parent->getSample(chan[16].pcm.sample);
while (len>0) {
while (lenCopy>0) {
if (s->samples>0 && chan[16].pcm.pos<s->samples) {
while (pcm_is_fifo_almost_empty(pcm)) {
short tmp_l=0;
@ -109,24 +114,30 @@ void DivPlatformVERA::acquire(short** buf, size_t len) {
// just let the buffer run out
chan[16].pcm.sample=-1;
}
int curLen=MIN(len,128);
int curLen=MIN(lenCopy,128);
memset(whyCallItBuf,0,sizeof(whyCallItBuf));
pcm_render(pcm,whyCallItBuf[2],whyCallItBuf[3],curLen);
for (int i=0; i<curLen; i++) {
psg_render(psg,&whyCallItBuf[0][i],&whyCallItBuf[1][i],1);
buf[0][pos]=(short)(((int)whyCallItBuf[0][i]+whyCallItBuf[2][i])/2);
buf[1][pos]=(short)(((int)whyCallItBuf[1][i]+whyCallItBuf[3][i])/2);
pos++;
for (int i=0; i<16; i++) {
oscBuf[i]->data[oscBuf[i]->needle++]=psg->channels[i].lastOut;
for (int j=0; j<16; j++) {
oscBuf[j]->putSample(pos,psg->channels[j].lastOut);
}
int pcmOut=(whyCallItBuf[2][i]+whyCallItBuf[3][i])>>1;
if (pcmOut<-32768) pcmOut=-32768;
if (pcmOut>32767) pcmOut=32767;
oscBuf[16]->data[oscBuf[16]->needle++]=pcmOut;
oscBuf[16]->putSample(pos,pcmOut);
pos++;
}
len-=curLen;
lenCopy-=curLen;
}
for (int i=0; i<17; i++) {
oscBuf[i]->end(len);
}
}
@ -537,7 +548,7 @@ void DivPlatformVERA::setFlags(const DivConfig& flags) {
CHECK_CUSTOM_CLOCK;
rate=chipClock/512;
for (int i=0; i<17; i++) {
oscBuf[i]->rate=rate;
oscBuf[i]->setRate(rate);
}
}

View file

@ -46,6 +46,11 @@ void DivPlatformVIC20::acquire(short** buf, size_t len) {
0b0, 0b10, 0b100, 0b110, 0b1000, 0b1010, 0b1011, 0b1110,
0b10010, 0b10100, 0b10110, 0b11000, 0b11010, 0b100100, 0b101010, 0b101100
};
for (int i=0; i<4; i++) {
oscBuf[i]->begin(len);
}
for (size_t h=0; h<len; h++) {
if (hasWaveWrite) {
hasWaveWrite=false;
@ -69,9 +74,13 @@ void DivPlatformVIC20::acquire(short** buf, size_t len) {
vic_sound_machine_calculate_samples(vic,&samp,1,1,0,SAMP_DIVIDER);
buf[0][h]=samp;
for (int i=0; i<4; i++) {
oscBuf[i]->data[oscBuf[i]->needle++]=vic->ch[i].out?(vic->volume<<11):0;
oscBuf[i]->putSample(h,vic->ch[i].out?(vic->volume<<11):0);
}
}
for (int i=0; i<4; i++) {
oscBuf[i]->end(len);
}
}
void DivPlatformVIC20::calcAndWriteOutVol(int ch, int env) {
@ -345,7 +354,7 @@ void DivPlatformVIC20::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

@ -47,7 +47,11 @@ const char** DivPlatformVRC6::getRegisterSheet() {
}
void DivPlatformVRC6::acquire(short** buf, size_t len) {
for (size_t i=0; i<len; i++) {
for (int i=0; i<3; i++) {
oscBuf[i]->begin(len);
}
for (size_t h=0; h<len; h++) {
// PCM part
for (int i=0; i<2; i++) {
if (chan[i].pcm && chan[i].dacSample!=-1) {
@ -81,15 +85,15 @@ void DivPlatformVRC6::acquire(short** buf, size_t len) {
int sample=vrc6.out()<<9; // scale to 16 bit
if (sample>32767) sample=32767;
if (sample<-32768) sample=-32768;
buf[0][i]=sample;
buf[0][h]=sample;
// Oscilloscope buffer part
if (++writeOscBuf>=32) {
writeOscBuf=0;
for (int i=0; i<2; i++) {
oscBuf[i]->data[oscBuf[i]->needle++]=vrc6.pulse_out(i)<<11;
oscBuf[i]->putSample(h,vrc6.pulse_out(i)<<11);
}
oscBuf[2]->data[oscBuf[2]->needle++]=vrc6.sawtooth_out()<<10;
oscBuf[2]->putSample(h,vrc6.sawtooth_out()<<10);
}
// Command part
@ -128,6 +132,10 @@ void DivPlatformVRC6::acquire(short** buf, size_t len) {
writes.pop();
}
}
for (int i=0; i<3; i++) {
oscBuf[i]->end(len);
}
}
void DivPlatformVRC6::tick(bool sysTick) {
@ -541,7 +549,7 @@ void DivPlatformVRC6::setFlags(const DivConfig& flags) {
CHECK_CUSTOM_CLOCK;
rate=chipClock;
for (int i=0; i<3; i++) {
oscBuf[i]->rate=rate/32;
oscBuf[i]->setRate(rate);
}
}

View file

@ -206,6 +206,10 @@ const char** DivPlatformX1_010::getRegisterSheet() {
}
void DivPlatformX1_010::acquire(short** buf, size_t len) {
for (int i=0; i<16; i++) {
oscBuf[i]->begin(len);
}
for (size_t h=0; h<len; h++) {
x1_010.tick();
@ -223,9 +227,13 @@ void DivPlatformX1_010::acquire(short** buf, size_t len) {
for (int i=0; i<16; i++) {
int vo=(x1_010.voice_out(i,0)+x1_010.voice_out(i,1))<<2;
oscBuf[i]->data[oscBuf[i]->needle++]=CLAMP(vo,-32768,32767);
oscBuf[i]->putSample(h,CLAMP(vo,-32768,32767));
}
}
for (int i=0; i<16; i++) {
oscBuf[i]->end(len);
}
}
u8 DivPlatformX1_010::read_byte(u32 address) {
@ -965,7 +973,7 @@ void DivPlatformX1_010::setFlags(const DivConfig& flags) {
stereo=flags.getBool("stereo",false);
isBanked=flags.getBool("isBanked",false);
for (int i=0; i<16; i++) {
oscBuf[i]->rate=rate;
oscBuf[i]->setRate(rate);
}
}

View file

@ -169,6 +169,10 @@ void DivPlatformYM2203::acquire_combo(short** buf, size_t len) {
thread_local int os;
thread_local short ignored[2];
for (int i=0; i<7; i++) {
oscBuf[i]->begin(len);
}
for (size_t h=0; h<len; h++) {
// AY -> OPN
ay->runDAC();
@ -236,13 +240,17 @@ void DivPlatformYM2203::acquire_combo(short** buf, size_t len) {
buf[0][h]=os;
for (int i=0; i<3; i++) {
oscBuf[i]->data[oscBuf[i]->needle++]=CLAMP(fm_nuked.ch_out[i]<<1,-32768,32767);
oscBuf[i]->putSample(h,CLAMP(fm_nuked.ch_out[i]<<1,-32768,32767));
}
for (int i=(3+isCSM); i<(6+isCSM); i++) {
oscBuf[i]->data[oscBuf[i]->needle++]=fmout.data[i-(2+isCSM)]<<1;
oscBuf[i]->putSample(h,fmout.data[i-(2+isCSM)]<<1);
}
}
for (int i=0; i<7; i++) {
oscBuf[i]->end(len);
}
}
void DivPlatformYM2203::acquire_ymfm(short** buf, size_t len) {
@ -255,6 +263,10 @@ void DivPlatformYM2203::acquire_ymfm(short** buf, size_t len) {
fmChan[i]=fme->debug_channel(i);
}
for (int i=0; i<7; i++) {
oscBuf[i]->begin(len);
}
for (size_t h=0; h<len; h++) {
// AY -> OPN
ay->runDAC();
@ -294,13 +306,17 @@ void DivPlatformYM2203::acquire_ymfm(short** buf, size_t len) {
for (int i=0; i<3; i++) {
int out=(fmChan[i]->debug_output(0)+fmChan[i]->debug_output(1))<<1;
oscBuf[i]->data[oscBuf[i]->needle++]=CLAMP(out,-32768,32767);
oscBuf[i]->putSample(h,CLAMP(out,-32768,32767));
}
for (int i=(3+isCSM); i<(6+isCSM); i++) {
oscBuf[i]->data[oscBuf[i]->needle++]=fmout.data[i-(2+isCSM)]<<1;
oscBuf[i]->putSample(h,fmout.data[i-(2+isCSM)]<<1);
}
}
for (int i=0; i<7; i++) {
oscBuf[i]->end(len);
}
}
static const unsigned char subCycleMap[6]={
@ -310,6 +326,10 @@ static const unsigned char subCycleMap[6]={
void DivPlatformYM2203::acquire_lle(short** buf, size_t len) {
thread_local int fmOut[6];
for (int i=0; i<7; i++) {
oscBuf[i]->begin(len);
}
for (size_t h=0; h<len; h++) {
bool have0=false;
bool have1=false;
@ -444,11 +464,11 @@ void DivPlatformYM2203::acquire_lle(short** buf, size_t len) {
for (int i=0; i<3; i++) {
if (fmOut[i]<-32768) fmOut[i]=-32768;
if (fmOut[i]>32767) fmOut[i]=32767;
oscBuf[i]->data[oscBuf[i]->needle++]=fmOut[i];
oscBuf[i]->putSample(h,fmOut[i]);
}
// SSG
for (int i=0; i<3; i++) {
oscBuf[i+3]->data[oscBuf[i+3]->needle++]=fm_lle.o_analog_ch[i]*32767;
oscBuf[i+3]->putSample(h,fm_lle.o_analog_ch[i]*32767);
}
// DAC
@ -461,6 +481,10 @@ void DivPlatformYM2203::acquire_lle(short** buf, size_t len) {
buf[0][h]=outL;
}
for (int i=0; i<7; i++) {
oscBuf[i]->end(len);
}
}
void DivPlatformYM2203::fillStream(std::vector<DivDelayedWrite>& stream, int sRate, size_t len) {
@ -1386,7 +1410,7 @@ void DivPlatformYM2203::setFlags(const DivConfig& flags) {
rate=fm->sample_rate(chipClock);
}
for (int i=0; i<7; i++) {
oscBuf[i]->rate=rate;
oscBuf[i]->setRate(rate);
}
immWrite(0x2d,0xff);
immWrite(prescale,0xff);

View file

@ -320,6 +320,10 @@ void DivPlatformYM2608::acquire_combo(short** buf, size_t len) {
adpcmAChan[i]=aae->debug_channel(i);
}
for (int i=0; i<17; i++) {
oscBuf[i]->begin(len);
}
for (size_t h=0; h<len; h++) {
// AY -> OPN
ay->runDAC();
@ -406,19 +410,23 @@ void DivPlatformYM2608::acquire_combo(short** buf, size_t len) {
for (int i=0; i<(psgChanOffs-isCSM); i++) {
oscBuf[i]->data[oscBuf[i]->needle++]=CLAMP(fm_nuked.ch_out[i]<<1,-32768,32767);
oscBuf[i]->putSample(h,CLAMP(fm_nuked.ch_out[i]<<1,-32768,32767));
}
ssge->get_last_out(ssgOut);
for (int i=psgChanOffs; i<adpcmAChanOffs; i++) {
oscBuf[i]->data[oscBuf[i]->needle++]=ssgOut.data[i-psgChanOffs]<<1;
oscBuf[i]->putSample(h,ssgOut.data[i-psgChanOffs]<<1);
}
for (int i=adpcmAChanOffs; i<adpcmBChanOffs; i++) {
oscBuf[i]->data[oscBuf[i]->needle++]=(adpcmAChan[i-adpcmAChanOffs]->get_last_out(0)+adpcmAChan[i-adpcmAChanOffs]->get_last_out(1))>>1;
oscBuf[i]->putSample(h,(adpcmAChan[i-adpcmAChanOffs]->get_last_out(0)+adpcmAChan[i-adpcmAChanOffs]->get_last_out(1))>>1);
}
oscBuf[adpcmBChanOffs]->data[oscBuf[adpcmBChanOffs]->needle++]=(abe->get_last_out(0)+abe->get_last_out(1))>>1;
oscBuf[adpcmBChanOffs]->putSample(h,(abe->get_last_out(0)+abe->get_last_out(1))>>1);
}
for (int i=0; i<17; i++) {
oscBuf[i]->end(len);
}
}
@ -439,6 +447,10 @@ void DivPlatformYM2608::acquire_ymfm(short** buf, size_t len) {
adpcmAChan[i]=aae->debug_channel(i);
}
for (int i=0; i<17; i++) {
oscBuf[i]->begin(len);
}
for (size_t h=0; h<len; h++) {
// AY -> OPN
ay->runDAC();
@ -482,19 +494,23 @@ void DivPlatformYM2608::acquire_ymfm(short** buf, size_t len) {
for (int i=0; i<6; i++) {
int out=(fmChan[i]->debug_output(0)+fmChan[i]->debug_output(1))<<1;
oscBuf[i]->data[oscBuf[i]->needle++]=CLAMP(out,-32768,32767);
oscBuf[i]->putSample(h,CLAMP(out,-32768,32767));
}
ssge->get_last_out(ssgOut);
for (int i=(6+isCSM); i<(9+isCSM); i++) {
oscBuf[i]->data[oscBuf[i]->needle++]=ssgOut.data[i-6-isCSM]<<1;
oscBuf[i]->putSample(h,ssgOut.data[i-6-isCSM]<<1);
}
for (int i=(9+isCSM); i<(15+isCSM); i++) {
oscBuf[i]->data[oscBuf[i]->needle++]=(adpcmAChan[i-9-isCSM]->get_last_out(0)+adpcmAChan[i-9]->get_last_out(1))>>1;
oscBuf[i]->putSample(h,(adpcmAChan[i-9-isCSM]->get_last_out(0)+adpcmAChan[i-9]->get_last_out(1))>>1);
}
oscBuf[15+isCSM]->data[oscBuf[15+isCSM]->needle++]=(abe->get_last_out(0)+abe->get_last_out(1))>>1;
oscBuf[15+isCSM]->putSample(h,(abe->get_last_out(0)+abe->get_last_out(1))>>1);
}
for (int i=0; i<17; i++) {
oscBuf[i]->end(len);
}
}
@ -505,6 +521,10 @@ static const unsigned char subCycleMap[6]={
void DivPlatformYM2608::acquire_lle(short** buf, size_t len) {
thread_local int fmOut[6];
for (int i=0; i<17; i++) {
oscBuf[i]->begin(len);
}
for (size_t h=0; h<len; h++) {
bool have0=false;
bool have1=false;
@ -656,20 +676,20 @@ void DivPlatformYM2608::acquire_lle(short** buf, size_t len) {
for (int i=0; i<6; i++) {
if (fmOut[i]<-32768) fmOut[i]=-32768;
if (fmOut[i]>32767) fmOut[i]=32767;
oscBuf[i]->data[oscBuf[i]->needle++]=fmOut[i];
oscBuf[i]->putSample(h,fmOut[i]);
}
// SSG
for (int i=0; i<3; i++) {
oscBuf[i+6]->data[oscBuf[i+6]->needle++]=fm_lle.o_analog_ch[i]*32767;
oscBuf[i+6]->putSample(h,fm_lle.o_analog_ch[i]*32767);
}
// RSS
for (int i=0; i<6; i++) {
if (rssOut[i]<-32768) rssOut[i]=-32768;
if (rssOut[i]>32767) rssOut[i]=32767;
oscBuf[9+i]->data[oscBuf[9+i]->needle++]=rssOut[i];
oscBuf[9+i]->putSample(h,rssOut[i]);
}
// ADPCM
oscBuf[15]->data[oscBuf[15]->needle++]=fm_lle.ac_ad_output;
oscBuf[15]->putSample(h,fm_lle.ac_ad_output);
// DAC
int accm1=(short)dacOut[1];
@ -686,6 +706,10 @@ void DivPlatformYM2608::acquire_lle(short** buf, size_t len) {
buf[0][h]=outL;
buf[1][h]=outR;
}
for (int i=0; i<17; i++) {
oscBuf[i]->end(len);
}
}
void DivPlatformYM2608::fillStream(std::vector<DivDelayedWrite>& stream, int sRate, size_t len) {
@ -2018,7 +2042,7 @@ void DivPlatformYM2608::setFlags(const DivConfig& flags) {
rate=fm->sample_rate(chipClock);
}
for (int i=0; i<17; i++) {
oscBuf[i]->rate=rate;
oscBuf[i]->setRate(rate);
}
immWrite(0x2d,0xff);
immWrite(prescale,0xff);

View file

@ -256,6 +256,10 @@ void DivPlatformYM2610::acquire_combo(short** buf, size_t len) {
adpcmAChan[i]=aae->debug_channel(i);
}
for (int i=0; i<17; i++) {
oscBuf[i]->begin(len);
}
for (size_t h=0; h<len; h++) {
// AY -> OPN
ay->runDAC();
@ -338,19 +342,23 @@ void DivPlatformYM2610::acquire_combo(short** buf, size_t len) {
for (int i=0; i<(psgChanOffs-isCSM); i++) {
oscBuf[i]->data[oscBuf[i]->needle++]=CLAMP(fm_nuked.ch_out[bchOffs[i]]<<1,-32768,32767);
oscBuf[i]->putSample(h,CLAMP(fm_nuked.ch_out[bchOffs[i]]<<1,-32768,32767));
}
ssge->get_last_out(ssgOut);
for (int i=psgChanOffs; i<adpcmAChanOffs; i++) {
oscBuf[i]->data[oscBuf[i]->needle++]=ssgOut.data[i-psgChanOffs]<<1;
oscBuf[i]->putSample(h,ssgOut.data[i-psgChanOffs]<<1);
}
for (int i=adpcmAChanOffs; i<adpcmBChanOffs; i++) {
oscBuf[i]->data[oscBuf[i]->needle++]=(adpcmAChan[i-adpcmAChanOffs]->get_last_out(0)+adpcmAChan[i-adpcmAChanOffs]->get_last_out(1))>>1;
oscBuf[i]->putSample(h,(adpcmAChan[i-adpcmAChanOffs]->get_last_out(0)+adpcmAChan[i-adpcmAChanOffs]->get_last_out(1))>>1);
}
oscBuf[adpcmBChanOffs]->data[oscBuf[adpcmBChanOffs]->needle++]=(abe->get_last_out(0)+abe->get_last_out(1))>>1;
oscBuf[adpcmBChanOffs]->putSample(h,(abe->get_last_out(0)+abe->get_last_out(1))>>1);
}
for (int i=0; i<17; i++) {
oscBuf[i]->end(len);
}
}
@ -373,6 +381,10 @@ void DivPlatformYM2610::acquire_ymfm(short** buf, size_t len) {
adpcmAChan[i]=aae->debug_channel(i);
}
for (int i=0; i<17; i++) {
oscBuf[i]->begin(len);
}
for (size_t h=0; h<len; h++) {
// AY -> OPN
ay->runDAC();
@ -416,19 +428,23 @@ void DivPlatformYM2610::acquire_ymfm(short** buf, size_t len) {
for (int i=0; i<(psgChanOffs-isCSM); i++) {
int out=(fmChan[i]->debug_output(0)+fmChan[i]->debug_output(1))<<1;
oscBuf[i]->data[oscBuf[i]->needle++]=CLAMP(out,-32768,32767);
oscBuf[i]->putSample(h,CLAMP(out,-32768,32767));
}
ssge->get_last_out(ssgOut);
for (int i=psgChanOffs; i<adpcmAChanOffs; i++) {
oscBuf[i]->data[oscBuf[i]->needle++]=ssgOut.data[i-psgChanOffs]<<1;
oscBuf[i]->putSample(h,ssgOut.data[i-psgChanOffs]<<1);
}
for (int i=adpcmAChanOffs; i<adpcmBChanOffs; i++) {
oscBuf[i]->data[oscBuf[i]->needle++]=(adpcmAChan[i-adpcmAChanOffs]->get_last_out(0)+adpcmAChan[i-adpcmAChanOffs]->get_last_out(1))>>1;
oscBuf[i]->putSample(h,(adpcmAChan[i-adpcmAChanOffs]->get_last_out(0)+adpcmAChan[i-adpcmAChanOffs]->get_last_out(1))>>1);
}
oscBuf[adpcmBChanOffs]->data[oscBuf[adpcmBChanOffs]->needle++]=(abe->get_last_out(0)+abe->get_last_out(1))>>1;
oscBuf[adpcmBChanOffs]->putSample(h,(abe->get_last_out(0)+abe->get_last_out(1))>>1);
}
for (int i=0; i<17; i++) {
oscBuf[i]->end(len);
}
}
@ -439,6 +455,10 @@ static const unsigned char subCycleMap[6]={
void DivPlatformYM2610::acquire_lle(short** buf, size_t len) {
thread_local int fmOut[6];
for (int i=0; i<17; i++) {
oscBuf[i]->begin(len);
}
for (size_t h=0; h<len; h++) {
bool have0=false;
bool have1=false;
@ -588,20 +608,20 @@ void DivPlatformYM2610::acquire_lle(short** buf, size_t len) {
for (int i=0; i<4; i++) {
if (fmOut[i]<-32768) fmOut[i]=-32768;
if (fmOut[i]>32767) fmOut[i]=32767;
oscBuf[i]->data[oscBuf[i]->needle++]=fmOut[i];
oscBuf[i]->putSample(h,fmOut[i]);
}
// SSG
for (int i=0; i<3; i++) {
oscBuf[i+4]->data[oscBuf[i+4]->needle++]=fm_lle.o_analog_ch[i]*32767;
oscBuf[i+4]->putSample(h,fm_lle.o_analog_ch[i]*32767);
}
// RSS
for (int i=0; i<6; i++) {
if (rssOut[i]<-32768) rssOut[i]=-32768;
if (rssOut[i]>32767) rssOut[i]=32767;
oscBuf[7+i]->data[oscBuf[7+i]->needle++]=rssOut[i];
oscBuf[7+i]->putSample(h,rssOut[i]);
}
// ADPCM
oscBuf[13]->data[oscBuf[13]->needle++]=fm_lle.ac_ad_output;
oscBuf[13]->putSample(h,fm_lle.ac_ad_output);
// DAC
int accm1=(short)dacOut[1];
@ -618,6 +638,10 @@ void DivPlatformYM2610::acquire_lle(short** buf, size_t len) {
buf[0][h]=outL;
buf[1][h]=outR;
}
for (int i=0; i<17; i++) {
oscBuf[i]->end(len);
}
}
void DivPlatformYM2610::tick(bool sysTick) {

View file

@ -320,6 +320,10 @@ void DivPlatformYM2610B::acquire_combo(short** buf, size_t len) {
adpcmAChan[i]=aae->debug_channel(i);
}
for (int i=0; i<17; i++) {
oscBuf[i]->begin(len);
}
for (size_t h=0; h<len; h++) {
// AY -> OPN
ay->runDAC();
@ -406,19 +410,23 @@ void DivPlatformYM2610B::acquire_combo(short** buf, size_t len) {
for (int i=0; i<(psgChanOffs-isCSM); i++) {
oscBuf[i]->data[oscBuf[i]->needle++]=CLAMP(fm_nuked.ch_out[i]<<1,-32768,32767);
oscBuf[i]->putSample(h,CLAMP(fm_nuked.ch_out[i]<<1,-32768,32767));
}
ssge->get_last_out(ssgOut);
for (int i=psgChanOffs; i<adpcmAChanOffs; i++) {
oscBuf[i]->data[oscBuf[i]->needle++]=ssgOut.data[i-psgChanOffs]<<1;
oscBuf[i]->putSample(h,ssgOut.data[i-psgChanOffs]<<1);
}
for (int i=adpcmAChanOffs; i<adpcmBChanOffs; i++) {
oscBuf[i]->data[oscBuf[i]->needle++]=(adpcmAChan[i-adpcmAChanOffs]->get_last_out(0)+adpcmAChan[i-adpcmAChanOffs]->get_last_out(1))>>1;
oscBuf[i]->putSample(h,(adpcmAChan[i-adpcmAChanOffs]->get_last_out(0)+adpcmAChan[i-adpcmAChanOffs]->get_last_out(1))>>1);
}
oscBuf[adpcmBChanOffs]->data[oscBuf[adpcmBChanOffs]->needle++]=(abe->get_last_out(0)+abe->get_last_out(1))>>1;
oscBuf[adpcmBChanOffs]->putSample(h,(abe->get_last_out(0)+abe->get_last_out(1))>>1);
}
for (int i=0; i<17; i++) {
oscBuf[i]->end(len);
}
}
@ -439,6 +447,10 @@ void DivPlatformYM2610B::acquire_ymfm(short** buf, size_t len) {
adpcmAChan[i]=aae->debug_channel(i);
}
for (int i=0; i<17; i++) {
oscBuf[i]->begin(len);
}
for (size_t h=0; h<len; h++) {
// AY -> OPN
ay->runDAC();
@ -482,19 +494,23 @@ void DivPlatformYM2610B::acquire_ymfm(short** buf, size_t len) {
for (int i=0; i<(psgChanOffs-isCSM); i++) {
int out=(fmChan[i]->debug_output(0)+fmChan[i]->debug_output(1))<<1;
oscBuf[i]->data[oscBuf[i]->needle++]=CLAMP(out,-32768,32767);
oscBuf[i]->putSample(h,CLAMP(out,-32768,32767));
}
ssge->get_last_out(ssgOut);
for (int i=psgChanOffs; i<adpcmAChanOffs; i++) {
oscBuf[i]->data[oscBuf[i]->needle++]=ssgOut.data[i-psgChanOffs]<<1;
oscBuf[i]->putSample(h,ssgOut.data[i-psgChanOffs]<<1);
}
for (int i=adpcmAChanOffs; i<adpcmBChanOffs; i++) {
oscBuf[i]->data[oscBuf[i]->needle++]=(adpcmAChan[i-adpcmAChanOffs]->get_last_out(0)+adpcmAChan[i-adpcmAChanOffs]->get_last_out(1))>>1;
oscBuf[i]->putSample(h,(adpcmAChan[i-adpcmAChanOffs]->get_last_out(0)+adpcmAChan[i-adpcmAChanOffs]->get_last_out(1))>>1);
}
oscBuf[adpcmBChanOffs]->data[oscBuf[adpcmBChanOffs]->needle++]=(abe->get_last_out(0)+abe->get_last_out(1))>>1;
oscBuf[adpcmBChanOffs]->putSample(h,(abe->get_last_out(0)+abe->get_last_out(1))>>1);
}
for (int i=0; i<17; i++) {
oscBuf[i]->end(len);
}
}
@ -507,6 +523,10 @@ void DivPlatformYM2610B::acquire_lle(short** buf, size_t len) {
fm_lle.ym2610b=1;
for (int i=0; i<17; i++) {
oscBuf[i]->begin(len);
}
for (size_t h=0; h<len; h++) {
bool have0=false;
bool have1=false;
@ -656,20 +676,20 @@ void DivPlatformYM2610B::acquire_lle(short** buf, size_t len) {
for (int i=0; i<6; i++) {
if (fmOut[i]<-32768) fmOut[i]=-32768;
if (fmOut[i]>32767) fmOut[i]=32767;
oscBuf[i]->data[oscBuf[i]->needle++]=fmOut[i];
oscBuf[i]->putSample(h,fmOut[i]);
}
// SSG
for (int i=0; i<3; i++) {
oscBuf[i+6]->data[oscBuf[i+6]->needle++]=fm_lle.o_analog_ch[i]*32767;
oscBuf[i+6]->putSample(h,fm_lle.o_analog_ch[i]*32767);
}
// RSS
for (int i=0; i<6; i++) {
if (rssOut[i]<-32768) rssOut[i]=-32768;
if (rssOut[i]>32767) rssOut[i]=32767;
oscBuf[9+i]->data[oscBuf[9+i]->needle++]=rssOut[i];
oscBuf[9+i]->putSample(h,rssOut[i]);
}
// ADPCM
oscBuf[15]->data[oscBuf[15]->needle++]=fm_lle.ac_ad_output;
oscBuf[15]->putSample(h,fm_lle.ac_ad_output);
// DAC
int accm1=(short)dacOut[1];
@ -686,6 +706,10 @@ void DivPlatformYM2610B::acquire_lle(short** buf, size_t len) {
buf[0][h]=outL;
buf[1][h]=outR;
}
for (int i=0; i<17; i++) {
oscBuf[i]->end(len);
}
}
void DivPlatformYM2610B::tick(bool sysTick) {

View file

@ -323,7 +323,7 @@ class DivPlatformYM2610Base: public DivPlatformOPN {
rate=fm->sample_rate(chipClock);
}
for (int i=0; i<17; i++) {
oscBuf[i]->rate=rate;
oscBuf[i]->setRate(rate);
}
}

View file

@ -59,15 +59,22 @@ const char** DivPlatformYMZ280B::getRegisterSheet() {
return regCheatSheetYMZ280B;
}
// not this crap again... I hate while loops!
void DivPlatformYMZ280B::acquire(short** buf, size_t len) {
short why[16][256];
short *bufPtrs[16]={
why[0],why[1],why[2],why[3],why[4],why[5],why[6],why[7],
why[8],why[9],why[10],why[11],why[12],why[13],why[14],why[15]
};
for (int i=0; i<8; i++) {
oscBuf[i]->begin(len);
}
size_t lenCopy=len;
size_t pos=0;
while (len > 0) {
size_t blockLen = MIN(len, 256);
while (lenCopy > 0) {
size_t blockLen = MIN(lenCopy, 256);
ymz280b.sound_stream_update(bufPtrs, blockLen);
for (size_t i=0; i<blockLen; i++) {
int dataL=0;
@ -75,13 +82,17 @@ void DivPlatformYMZ280B::acquire(short** buf, size_t len) {
for (int j=0; j<8; j++) {
dataL+=why[j*2][i];
dataR+=why[j*2+1][i];
oscBuf[j]->data[oscBuf[j]->needle++]=(short)(((int)why[j*2][i]+why[j*2+1][i])/4);
oscBuf[j]->putSample(pos,(short)(((int)why[j*2][i]+why[j*2+1][i])/4));
}
buf[0][pos]=(short)(dataL/8);
buf[1][pos]=(short)(dataR/8);
pos++;
}
len-=blockLen;
lenCopy-=blockLen;
}
for (int i=0; i<8; i++) {
oscBuf[i]->end(len);
}
}
@ -531,7 +542,7 @@ void DivPlatformYMZ280B::setFlags(const DivConfig& flags) {
break;
}
for (int i=0; i<8; i++) {
oscBuf[i]->rate=rate;
oscBuf[i]->setRate(rate);
}
}

View file

@ -28,6 +28,10 @@ const char** DivPlatformZXBeeper::getRegisterSheet() {
}
void DivPlatformZXBeeper::acquire(short** buf, size_t len) {
for (int i=0; i<1; i++) {
oscBuf[i]->begin(len);
}
bool o=false;
for (size_t h=0; h<len; h++) {
// clock here
@ -47,7 +51,7 @@ void DivPlatformZXBeeper::acquire(short** buf, size_t len) {
}
o=sampleOut;
buf[0][h]=o?16384:0;
oscBuf[0]->data[oscBuf[0]->needle++]=o?16384:-16384;
oscBuf[0]->putSample(h,o?16384:-16384);
continue;
}
@ -65,7 +69,11 @@ void DivPlatformZXBeeper::acquire(short** buf, size_t len) {
if (++curChan>=6) curChan=0;
buf[0][h]=o?16384:0;
oscBuf[0]->data[oscBuf[0]->needle++]=o?16384:-16384;
oscBuf[0]->putSample(h,o?16384:-16384);
}
for (int i=0; i<1; i++) {
oscBuf[i]->end(len);
}
}
@ -304,7 +312,7 @@ void DivPlatformZXBeeper::setFlags(const DivConfig& flags) {
CHECK_CUSTOM_CLOCK;
rate=chipClock/4;
for (int i=0; i<6; i++) {
oscBuf[i]->rate=rate;
oscBuf[i]->setRate(rate);
}
}

View file

@ -30,6 +30,10 @@ const char** DivPlatformZXBeeperQuadTone::getRegisterSheet() {
}
void DivPlatformZXBeeperQuadTone::acquire(short** buf, size_t len) {
for (int i=0; i<5; i++) {
oscBuf[i]->begin(len);
}
for (size_t h=0; h<len; h++) {
bool sampleActive=false;
if (curSample>=0 && curSample<parent->song.sampleLen) {
@ -51,12 +55,12 @@ void DivPlatformZXBeeperQuadTone::acquire(short** buf, size_t len) {
if (sampleActive) {
buf[0][h]=chan[4].out?32767:0;
if (outputClock==0) {
oscBuf[0]->data[oscBuf[0]->needle++]=0;
oscBuf[1]->data[oscBuf[1]->needle++]=0;
oscBuf[2]->data[oscBuf[2]->needle++]=0;
oscBuf[3]->data[oscBuf[3]->needle++]=0;
oscBuf[0]->putSample(h,0);
oscBuf[1]->putSample(h,0);
oscBuf[2]->putSample(h,0);
oscBuf[3]->putSample(h,0);
}
oscBuf[4]->data[oscBuf[4]->needle++]=buf[0][h];
oscBuf[4]->putSample(h,buf[0][h]);
} else {
int ch=outputClock/2;
int b=ch*4;
@ -72,7 +76,7 @@ void DivPlatformZXBeeperQuadTone::acquire(short** buf, size_t len) {
} else {
oscOut=16383;
}
oscBuf[ch]->data[oscBuf[ch]->needle++]=oscOut;
oscBuf[ch]->putSample(h,oscOut);
}
if (!isMuted[ch]) o=chan[ch].out&0x10;
if (noHiss) {
@ -85,10 +89,14 @@ void DivPlatformZXBeeperQuadTone::acquire(short** buf, size_t len) {
buf[0][h]=o?32767:0;
}
chan[ch].out<<=1;
oscBuf[4]->data[oscBuf[4]->needle++]=0;
oscBuf[4]->putSample(h,0);
}
outputClock=(outputClock+1)&7;
}
for (int i=0; i<5; i++) {
oscBuf[i]->end(len);
}
}
void DivPlatformZXBeeperQuadTone::tick(bool sysTick) {
@ -385,10 +393,9 @@ void DivPlatformZXBeeperQuadTone::setFlags(const DivConfig& flags) {
CHECK_CUSTOM_CLOCK;
rate=chipClock/40;
noHiss=flags.getBool("noHiss",false);
for (int i=0; i<4; i++) {
oscBuf[i]->rate=rate/8;
for (int i=0; i<5; i++) {
oscBuf[i]->setRate(rate);
}
oscBuf[4]->rate=rate;
}
void DivPlatformZXBeeperQuadTone::poke(unsigned int addr, unsigned short val) {

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;

View file

@ -102,14 +102,14 @@ void FurnaceGUI::calcChanOsc() {
}
if (buf!=NULL && e->curSubSong->chanShowChanOsc[i]) {
// 30ms should be enough
int displaySize=(float)(buf->rate)*0.03f;
int displaySize=65536.0f*0.03f;
if (e->isRunning()) {
short minLevel=32767;
short maxLevel=-32768;
unsigned short needlePos=buf->needle;
needlePos-=displaySize;
for (unsigned short i=0; i<512; i++) {
short y=buf->data[(unsigned short)(needlePos+(i*displaySize/512))];
for (unsigned short i=needlePos-displaySize; i!=needlePos; i++) {
short y=buf->data[i];
if (y==-1) continue;
if (minLevel>y) minLevel=y;
if (maxLevel<y) maxLevel=y;
}
@ -462,15 +462,33 @@ void FurnaceGUI::drawChanOsc() {
// initialization
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->needle=buf->needle;
// first FFT
for (int j=0; j<FURNACE_FFT_SIZE; j++) {
fft->inBuf[j]=(double)buf->data[(unsigned short)(fft->needle-displaySize*2+((j*displaySize*2)/(FURNACE_FFT_SIZE)))]/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));
int k=0;
short lastSample=0;
memset(fft->inBuf,0,FURNACE_FFT_SIZE*sizeof(double));
if (displaySize2<FURNACE_FFT_SIZE) {
for (int j=-FURNACE_FFT_SIZE; 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;
if (j<0) continue;
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
@ -530,8 +548,11 @@ void FurnaceGUI::drawChanOsc() {
double dft[2];
dft[0]=0.0;
dft[1]=0.0;
for (int j=fft->needle-1-(displaySize>>1)-(int)fft->waveLen, k=0; k<fft->waveLen; j++, k++) {
double one=((double)buf->data[j&0xffff]/32768.0);
lastSample=0;
for (int j=fft->needle-1-displaySize-(int)fft->waveLen, k=-(displaySize>>1); k<fft->waveLen; j++, k++) {
if (buf->data[j&0xffff]!=-1) lastSample=buf->data[j&0xffff];
if (k<0) continue;
double one=((double)lastSample/32768.0);
double two=(double)k*(-2.0*M_PI)/fft->waveLen;
dft[0]+=one*cos(two);
dft[1]+=one*sin(two);
@ -540,6 +561,8 @@ void FurnaceGUI::drawChanOsc() {
// calculate and lock into phase
phase=(0.5+(atan2(dft[1],dft[0])/(2.0*M_PI)));
fft->debugPhase=phase;
if (fft->waveCorr) {
fft->needle-=(phase+(fft->phaseOff*2))*fft->waveLen;
}
@ -615,11 +638,11 @@ void FurnaceGUI::drawChanOsc() {
}
}
} 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 maxLevel=-1.0f;
float dcOff=0.0f;
if (debugFFT) {
// FFT debug code!
@ -654,7 +677,7 @@ void FurnaceGUI::drawChanOsc() {
}
}
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\nPHASE %f",fft->waveLen,fft->waveLenBottom,fft->waveLenTop,displaySize,displaySize2,FURNACE_FFT_SIZE,fft->debugPhase);
dl->AddText(inRect.Min,0xffffffff,cPhase.c_str());
dl->AddLine(
@ -667,37 +690,67 @@ void FurnaceGUI::drawChanOsc() {
ImLerp(inRect.Min,inRect.Max,ImVec2((double)fft->waveLenTop/(double)FURNACE_FFT_SIZE,1.0)),
0xff00ff00
);
dl->AddLine(
ImLerp(inRect.Min,inRect.Max,ImVec2(0.75-(fft->debugPhase*0.25),0.0)),
ImLerp(inRect.Min,inRect.Max,ImVec2(0.75-(fft->debugPhase*0.25),1.0)),
0xff00ffff
);
} else {
if (debugFFT) {
dl->AddText(inRect.Min,0xffffffff,"\nquiet");
}
}
} else {
for (unsigned short j=0; j<precision; j++) {
float y=(float)buf->data[(unsigned short)(fft->needle+(j*displaySize/precision))]/32768.0f;
if (minLevel>y) minLevel=y;
if (maxLevel<y) maxLevel=y;
}
dcOff=(minLevel+maxLevel)*0.5f;
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;
/*
String dStr=fmt::sprintf("DS: %d P: %d\nMAX: %d\nPHASE %f",displaySize,precision,(short)((fft->needle+displaySize)-fft->relatedBuf->needle),fft->debugPhase);
dl->AddText(inRect.Min,0xffffffff,dStr.c_str());
*/
if (displaySize<precision) {
float y=0;
for (int j=-2048; 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 (j<0) continue;
if (minLevel>y) minLevel=y;
if (maxLevel<y) maxLevel=y;
}
if (j<0) continue;
float yOut=y-fft->dcOff;
fft->dcOff+=(y-fft->dcOff)*0.001;
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=-2048;
for (unsigned short j=fft->needle-2048; 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 (k<0) continue;
if (minLevel>y) minLevel=y;
if (maxLevel<y) maxLevel=y;
}
if (kTex<0) continue;
float yOut=y-fft->dcOff;
fft->dcOff+=(y-fft->dcOff)*0.001;
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;
if (!(rend->supportsDrawOsc() && settings.shaderOsc)) {
for (unsigned short j=0; j<precision; j++) {
float x=(float)j/(float)precision;
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;
waveform[j]=ImLerp(inRect.Min,inRect.Max,ImVec2(x,0.5f-y));
waveform[j]=ImLerp(inRect.Min,inRect.Max,ImVec2(x,0.5f-fft->oscTex[j]*0.5f));
}
}
}

View file

@ -252,7 +252,7 @@ void FurnaceGUI::drawDebug() {
ImGui::TableNextColumn();
ImGui::Text("Follow");
ImGui::TableNextColumn();
ImGui::Text("Address");
ImGui::Text("Needle");
ImGui::TableNextColumn();
ImGui::Text("Data");

View file

@ -4181,8 +4181,9 @@ bool FurnaceGUI::loop() {
for (int i=0; i<e->getTotalChannelCount(); i++) {
DivDispatchOscBuffer* buf=e->getOscBuffer(i);
if (buf!=NULL) {
buf->needle=0;
buf->readNeedle=0;
//buf->needle=0;
//buf->readNeedle=0;
// TODO: should we reset here?
}
}
});
@ -8568,6 +8569,7 @@ FurnaceGUI::FurnaceGUI():
lastPatternWidth(0.0f),
longThreshold(0.48f),
buttonLongThreshold(0.20f),
lastAudioLoadsPos(0),
latchNote(-1),
latchIns(-2),
latchVol(-1),
@ -8936,6 +8938,8 @@ FurnaceGUI::FurnaceGUI():
memset(keyHit,0,sizeof(float)*DIV_MAX_CHANS);
memset(keyHit1,0,sizeof(float)*DIV_MAX_CHANS);
memset(lastAudioLoads,0,sizeof(float)*120);
memset(pianoKeyHit,0,sizeof(float)*180);
memset(pianoKeyPressed,0,sizeof(bool)*180);

View file

@ -2379,6 +2379,9 @@ class FurnaceGUI {
String nextDesc;
String nextDescName;
float lastAudioLoads[120];
int lastAudioLoadsPos;
OperationMask opMaskDelete, opMaskPullDelete, opMaskInsert, opMaskPaste, opMaskTransposeNote, opMaskTransposeValue;
OperationMask opMaskInterpolate, opMaskFade, opMaskInvertVal, opMaskScale;
OperationMask opMaskRandomize, opMaskFlip, opMaskCollapseExpand;
@ -2633,7 +2636,7 @@ class FurnaceGUI {
double inBufPosFrac;
double waveLen;
int waveLenBottom, waveLenTop, relatedCh;
float pitch, windowSize, phaseOff;
float pitch, windowSize, phaseOff, debugPhase, dcOff;
unsigned short needle;
bool ready, loudEnough, waveCorr;
fftw_plan plan;
@ -2654,6 +2657,8 @@ class FurnaceGUI {
pitch(0.0f),
windowSize(1.0f),
phaseOff(0.0f),
debugPhase(0.0f),
dcOff(0.0f),
needle(0),
ready(false),
loudEnough(false),

View file

@ -31,11 +31,21 @@ void FurnaceGUI::drawStats() {
if (ImGui::Begin("Statistics",&statsOpen,globalWinFlags,_("Statistics"))) {
size_t lastProcTime=e->processTime;
double maxGot=1000000000.0*(double)e->getAudioDescGot().bufsize/(double)e->getAudioDescGot().rate;
String procStr=fmt::sprintf("%.1f%%",100.0*((double)lastProcTime/(double)maxGot));
ImGui::AlignTextToFramePadding();
ImGui::Text(_("Audio load"));
ImGui::SameLine();
ImGui::ProgressBar((double)lastProcTime/maxGot,ImVec2(-FLT_MIN,0),procStr.c_str());
ImGui::ProgressBar((double)lastProcTime/maxGot,ImVec2(ImGui::GetContentRegionAvail().x-ImGui::CalcTextSize("100.0%").x,0),"");
ImGui::SameLine();
ImGui::Text("%.1f%%",100.0*((double)lastProcTime/(double)maxGot));
if (ImGui::GetContentRegionAvail().y>8.0f*dpiScale) {
// draw a chart
lastAudioLoads[lastAudioLoadsPos]=(double)lastProcTime/maxGot;
if (++lastAudioLoadsPos>=120) lastAudioLoadsPos=0;
ImGui::PushStyleColor(ImGuiCol_FrameBg,ImVec4(0,0,0,0));
ImGui::PlotLines("##ALChart",lastAudioLoads,120,lastAudioLoadsPos,NULL,0.0f,1.0f,ImGui::GetContentRegionAvail());
ImGui::PopStyleColor();
}
}
if (ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows)) curWindow=GUI_WINDOW_STATS;
ImGui::End();