Merge branch 'master' of https://github.com/tildearrow/furnace into k053260

This commit is contained in:
cam900 2023-06-17 10:41:56 +09:00
commit 7402575d11
398 changed files with 23113 additions and 12190 deletions

View file

@ -168,7 +168,7 @@ 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]))<<2;
oscBuf[i]->data[oscBuf[i]->needle++]=(amiga.nextOut[i]*MIN(64,amiga.audVol[i]))<<1;
} else {
oscBuf[i]->data[oscBuf[i]->needle++]=0;
}

View file

@ -76,7 +76,7 @@ void DivPlatformArcade::acquire_nuked(short** buf, size_t len) {
}
for (int i=0; i<8; i++) {
oscBuf[i]->data[oscBuf[i]->needle++]=fm.ch_out[i];
oscBuf[i]->data[oscBuf[i]->needle++]=fm.ch_out[i]>>1;
}
if (o[0]<-32768) o[0]=-32768;
@ -111,7 +111,7 @@ void DivPlatformArcade::acquire_ymfm(short** buf, size_t len) {
fm_ymfm->generate(&out_ymfm);
for (int i=0; i<8; i++) {
oscBuf[i]->data[oscBuf[i]->needle++]=(fme->debug_channel(i)->debug_output(0)+fme->debug_channel(i)->debug_output(1));
oscBuf[i]->data[oscBuf[i]->needle++]=(fme->debug_channel(i)->debug_output(0)+fme->debug_channel(i)->debug_output(1))>>1;
}
os[0]=out_ymfm.data[0];

View file

@ -120,7 +120,7 @@ void DivPlatformAY8910::runDAC() {
bool end=false;
bool changed=false;
int prevOut=chan[i].dac.out;
while (chan[i].dac.period>rate && !end) {
while (chan[i].dac.period>dacRate && !end) {
DivSample* s=parent->getSample(chan[i].dac.sample);
if (s->samples<=0) {
chan[i].dac.sample=-1;
@ -143,7 +143,7 @@ void DivPlatformAY8910::runDAC() {
end=true;
break;
}
chan[i].dac.period-=rate;
chan[i].dac.period-=dacRate;
}
if (changed && !end) {
if (!isMuted[i]) {
@ -187,9 +187,9 @@ void DivPlatformAY8910::acquire(short** buf, size_t len) {
buf[0][i]=ayBuf[0][0];
buf[1][i]=buf[0][i];
oscBuf[0]->data[oscBuf[0]->needle++]=sunsoftVolTable[31-(ay->lastIndx&31)]>>3;
oscBuf[1]->data[oscBuf[1]->needle++]=sunsoftVolTable[31-((ay->lastIndx>>5)&31)]>>3;
oscBuf[2]->data[oscBuf[2]->needle++]=sunsoftVolTable[31-((ay->lastIndx>>10)&31)]>>3;
oscBuf[0]->data[oscBuf[0]->needle++]=sunsoftVolTable[31-(ay->lastIndx&31)]<<2;
oscBuf[1]->data[oscBuf[1]->needle++]=sunsoftVolTable[31-((ay->lastIndx>>5)&31)]<<2;
oscBuf[2]->data[oscBuf[2]->needle++]=sunsoftVolTable[31-((ay->lastIndx>>10)&31)]<<2;
}
} else {
for (size_t i=0; i<len; i++) {
@ -205,9 +205,9 @@ void DivPlatformAY8910::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]->data[oscBuf[0]->needle++]=ayBuf[0][0]<<1;
oscBuf[1]->data[oscBuf[1]->needle++]=ayBuf[1][0]<<1;
oscBuf[2]->data[oscBuf[2]->needle++]=ayBuf[2][0]<<1;
}
}
}
@ -797,6 +797,7 @@ void DivPlatformAY8910::setFlags(const DivConfig& flags) {
chipClock=extClock;
rate=chipClock/extDiv;
clockSel=false;
dacRate=chipClock/dacRateDiv;
} else {
clockSel=flags.getBool("halfClock",false);
switch (flags.getInt("clockSel",0)) {
@ -851,6 +852,7 @@ void DivPlatformAY8910::setFlags(const DivConfig& flags) {
}
CHECK_CUSTOM_CLOCK;
rate=chipClock/8;
dacRate=rate;
}
for (int i=0; i<3; i++) {
oscBuf[i]->rate=rate;

View file

@ -104,7 +104,9 @@ class DivPlatformAY8910: public DivDispatch {
bool extMode;
unsigned int extClock;
int dacRate;
unsigned char extDiv;
unsigned char dacRateDiv;
bool stereo, sunsoft, intellivision, clockSel;
bool ioPortA, ioPortB;
@ -119,7 +121,6 @@ class DivPlatformAY8910: public DivDispatch {
short* ayBuf[3];
size_t ayBufLen;
void runDAC();
void checkWrites();
void updateOutSel(bool immediate=false);
@ -127,6 +128,7 @@ class DivPlatformAY8910: public DivDispatch {
friend void putDispatchChan(void*,int,int);
public:
void runDAC();
void setExtClockDiv(unsigned int eclk=COLOR_NTSC, unsigned char ediv=8);
void acquire(short** buf, size_t len);
int dispatch(DivCommand c);
@ -151,10 +153,11 @@ class DivPlatformAY8910: public DivDispatch {
const char** getRegisterSheet();
int init(DivEngine* parent, int channels, int sugRate, const DivConfig& flags);
void quit();
DivPlatformAY8910(bool useExtMode=false, unsigned int eclk=COLOR_NTSC, unsigned char ediv=8):
DivPlatformAY8910(bool useExtMode=false, unsigned int eclk=COLOR_NTSC, unsigned char ediv=8, unsigned char ddiv=24):
DivDispatch(),
extMode(useExtMode),
extClock(eclk),
extDiv(ediv) {}
extDiv(ediv),
dacRateDiv(ddiv) {}
};
#endif

View file

@ -186,9 +186,9 @@ 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]->data[oscBuf[0]->needle++]=ayBuf[0][0]<<1;
oscBuf[1]->data[oscBuf[1]->needle++]=ayBuf[1][0]<<1;
oscBuf[2]->data[oscBuf[2]->needle++]=ayBuf[2][0]<<1;
}
}

View file

@ -55,7 +55,7 @@ void DivPlatformBubSysWSG::acquire(short** buf, size_t len) {
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]->data[oscBuf[i]->needle++]=chanOut<<6;
}
}
}

View file

@ -80,18 +80,18 @@ void DivPlatformC64::acquire(short** buf, size_t len) {
sid_fp.clock(4,&buf[0][i]);
if (++writeOscBuf>=4) {
writeOscBuf=0;
oscBuf[0]->data[oscBuf[0]->needle++]=(sid_fp.lastChanOut[0]-dcOff)>>5;
oscBuf[1]->data[oscBuf[1]->needle++]=(sid_fp.lastChanOut[1]-dcOff)>>5;
oscBuf[2]->data[oscBuf[2]->needle++]=(sid_fp.lastChanOut[2]-dcOff)>>5;
oscBuf[0]->data[oscBuf[0]->needle++]=(sid_fp.lastChanOut[0]-dcOff)>>6;
oscBuf[1]->data[oscBuf[1]->needle++]=(sid_fp.lastChanOut[1]-dcOff)>>6;
oscBuf[2]->data[oscBuf[2]->needle++]=(sid_fp.lastChanOut[2]-dcOff)>>6;
}
} else {
sid.clock();
buf[0][i]=sid.output();
if (++writeOscBuf>=16) {
writeOscBuf=0;
oscBuf[0]->data[oscBuf[0]->needle++]=(sid.last_chan_out[0]-dcOff)>>5;
oscBuf[1]->data[oscBuf[1]->needle++]=(sid.last_chan_out[1]-dcOff)>>5;
oscBuf[2]->data[oscBuf[2]->needle++]=(sid.last_chan_out[2]-dcOff)>>5;
oscBuf[0]->data[oscBuf[0]->needle++]=(sid.last_chan_out[0]-dcOff)>>6;
oscBuf[1]->data[oscBuf[1]->needle++]=(sid.last_chan_out[1]-dcOff)>>6;
oscBuf[2]->data[oscBuf[2]->needle++]=(sid.last_chan_out[2]-dcOff)>>6;
}
}
}
@ -105,6 +105,7 @@ void DivPlatformC64::updateFilter() {
}
void DivPlatformC64::tick(bool sysTick) {
bool willUpdateFilter=false;
for (int i=0; i<3; i++) {
chan[i].std.next();
if (chan[i].std.vol.had) {
@ -117,10 +118,10 @@ void DivPlatformC64::tick(bool sysTick) {
if (filtCut>2047) filtCut=2047;
if (filtCut<0) filtCut=0;
}
updateFilter();
willUpdateFilter=true;
} else {
vol=MIN(15,chan[i].std.vol.val);
updateFilter();
willUpdateFilter=true;
}
}
if (NEW_ARP_STRAT) {
@ -156,11 +157,11 @@ void DivPlatformC64::tick(bool sysTick) {
}
if (chan[i].std.ex1.had) {
filtControl=chan[i].std.ex1.val&15;
updateFilter();
willUpdateFilter=true;
}
if (chan[i].std.ex2.had) {
filtRes=chan[i].std.ex2.val&15;
updateFilter();
willUpdateFilter=true;
}
if (chan[i].std.ex3.had) {
chan[i].sync=chan[i].std.ex3.val&1;
@ -207,6 +208,7 @@ void DivPlatformC64::tick(bool sysTick) {
chan[i].freqChanged=false;
}
}
if (willUpdateFilter) updateFilter();
}
int DivPlatformC64::dispatch(DivCommand c) {

View file

@ -32,7 +32,7 @@ void DivPlatformDummy::acquire(short** buf, size_t len) {
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;
oscBuf[j]->data[oscBuf[j]->needle++]=chanOut>>1;
out+=chanOut;
} else {
oscBuf[j]->data[oscBuf[j]->needle++]=0;

View file

@ -168,7 +168,7 @@ 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]->data[oscBuf[i]->needle++]=(es5506.voice_lout(i)+es5506.voice_rout(i))>>6;
}
}
}

View file

@ -64,7 +64,7 @@ void DivPlatformFDS::acquire_puNES(short* buf, size_t len) {
buf[i]=sample;
if (++writeOscBuf>=32) {
writeOscBuf=0;
oscBuf->data[oscBuf->needle++]=sample<<1;
oscBuf->data[oscBuf->needle++]=sample;
}
}
}
@ -80,7 +80,7 @@ void DivPlatformFDS::acquire_NSFPlay(short* buf, size_t len) {
buf[i]=sample;
if (++writeOscBuf>=32) {
writeOscBuf=0;
oscBuf->data[oscBuf->needle++]=sample<<1;
oscBuf->data[oscBuf->needle++]=sample;
}
}
}

View file

@ -75,7 +75,7 @@ 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];
oscBuf[i]->data[oscBuf[i]->needle++]=ga20Buf[i][h]>>1;
}
}
}

View file

@ -74,7 +74,7 @@ void DivPlatformGB::acquire(short** buf, size_t len) {
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;
oscBuf[i]->data[oscBuf[i]->needle++]=(gb->apu_output.current_sample[i].left+gb->apu_output.current_sample[i].right)<<5;
}
}
}
@ -82,8 +82,12 @@ void DivPlatformGB::acquire(short** buf, size_t len) {
void DivPlatformGB::updateWave() {
rWrite(0x1a,0);
for (int i=0; i<16; i++) {
int nibble1=15-ws.output[((i<<1)+antiClickWavePos-1)&31];
int nibble2=15-ws.output[((1+(i<<1))+antiClickWavePos-1)&31];
int nibble1=ws.output[((i<<1)+antiClickWavePos)&31];
int nibble2=ws.output[((1+(i<<1))+antiClickWavePos)&31];
if (invertWave) {
nibble1^=15;
nibble2^=15;
}
rWrite(0x30+i,(nibble1<<4)|nibble2);
}
antiClickWavePos&=31;
@ -658,6 +662,7 @@ void DivPlatformGB::setFlags(const DivConfig& flags) {
model=GB_MODEL_AGB;
break;
}
invertWave=flags.getBool("invertWave",true);
enoughAlready=flags.getBool("enoughAlready",false);
}

View file

@ -57,6 +57,7 @@ class DivPlatformGB: public DivDispatch {
DivDispatchOscBuffer* oscBuf[4];
bool isMuted[4];
bool antiClickEnabled;
bool invertWave;
bool enoughAlready;
unsigned char lastPan;
DivWaveSynth ws;

View file

@ -184,16 +184,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<<7;
oscBuf[6]->data[oscBuf[6]->needle++]=chan[6].dacOutput<<7;
oscBuf[5]->data[oscBuf[5]->needle++]=chan[5].dacOutput<<6;
oscBuf[6]->data[oscBuf[6]->needle++]=chan[6].dacOutput<<6;
} else {
oscBuf[i]->data[oscBuf[i]->needle++]=fm.dacdata<<7;
oscBuf[i]->data[oscBuf[i]->needle++]=fm.dacdata<<6;
oscBuf[6]->data[oscBuf[6]->needle++]=0;
}
} else {
oscBuf[i]->data[oscBuf[i]->needle++]=fm.ch_out[i]<<(chipType==2?0:7);
oscBuf[i]->data[oscBuf[i]->needle++]=CLAMP(fm.ch_out[i]<<(chipType==2?1:6),-32768,32767);
oscBuf[6]->data[oscBuf[6]->needle++]=0;
}
} else {
oscBuf[i]->data[oscBuf[i]->needle++]=fm.ch_out[i]<<(chipType==2?0:7);
oscBuf[i]->data[oscBuf[i]->needle++]=CLAMP(fm.ch_out[i]<<(chipType==2?1:6),-32768,32767);
}
}
@ -241,19 +243,21 @@ void DivPlatformGenesis::acquire_ymfm(short** buf, size_t len) {
//OPN2_Write(&fm,0,0);
for (int i=0; i<6; i++) {
int chOut=(fme->debug_channel(i)->debug_output(0)+fme->debug_channel(i)->debug_output(1))<<6;
int chOut=(fme->debug_channel(i)->debug_output(0)+fme->debug_channel(i)->debug_output(1))<<5;
if (chOut<-32768) chOut=-32768;
if (chOut>32767) chOut=32767;
if (i==5) {
if (fm_ymfm->debug_dac_enable()) {
if (softPCM) {
oscBuf[5]->data[oscBuf[5]->needle++]=chan[5].dacOutput<<7;
oscBuf[6]->data[oscBuf[6]->needle++]=chan[6].dacOutput<<7;
oscBuf[5]->data[oscBuf[5]->needle++]=chan[5].dacOutput<<6;
oscBuf[6]->data[oscBuf[6]->needle++]=chan[6].dacOutput<<6;
} else {
oscBuf[i]->data[oscBuf[i]->needle++]=fm_ymfm->debug_dac_data()<<7;
oscBuf[i]->data[oscBuf[i]->needle++]=fm_ymfm->debug_dac_data()<<6;
oscBuf[6]->data[oscBuf[6]->needle++]=0;
}
} else {
oscBuf[i]->data[oscBuf[i]->needle++]=chOut;
oscBuf[6]->data[oscBuf[6]->needle++]=0;
}
} else {
oscBuf[i]->data[oscBuf[i]->needle++]=chOut;

View file

@ -79,14 +79,14 @@ void DivPlatformK007232::acquire(short** buf, size_t len) {
buf[0][h]=(lout[0]+lout[1])<<4;
buf[1][h]=(rout[0]+rout[1])<<4;
for (int i=0; i<2; i++) {
oscBuf[i]->data[oscBuf[i]->needle++]=(lout[i]+rout[i])<<4;
oscBuf[i]->data[oscBuf[i]->needle++]=(lout[i]+rout[i])<<3;
}
} else {
const unsigned char vol=regPool[0xc];
const signed int out[2]={(k007232.output(0)*(vol&0xf)),(k007232.output(1)*((vol>>4)&0xf))};
buf[0][h]=(out[0]+out[1])<<4;
for (int i=0; i<2; i++) {
oscBuf[i]->data[oscBuf[i]->needle++]=out[i]<<5;
oscBuf[i]->data[oscBuf[i]->needle++]=out[i]<<4;
}
}
}

View file

@ -81,7 +81,7 @@ void DivPlatformK053260::acquire(short** buf, size_t len) {
buf[1][i]=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]->data[oscBuf[i]->needle++]=(k053260.voice_out(i,0)+k053260.voice_out(i,1))>>2;
}
}
}

View file

@ -85,9 +85,9 @@ 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*10)<<7);
oscBuf[1]->data[oscBuf[1]->needle++]=isMuted[1]?0:((mmc5->S4.output*10)<<7);
oscBuf[2]->data[oscBuf[2]->needle++]=isMuted[2]?0:((mmc5->pcm.output*2)<<6);
oscBuf[0]->data[oscBuf[0]->needle++]=isMuted[0]?0:((mmc5->S3.output*10)<<6);
oscBuf[1]->data[oscBuf[1]->needle++]=isMuted[1]?0:((mmc5->S4.output*10)<<6);
oscBuf[2]->data[oscBuf[2]->needle++]=isMuted[2]?0:((mmc5->pcm.output*2)<<5);
}
}
}

View file

@ -60,7 +60,7 @@ void DivPlatformMSM5232::acquire(short** buf, size_t len) {
((regPool[12+(i>>4)]&2)?((msm->vo8[i]*partVolume[2+(i&4)])>>8):0)+
((regPool[12+(i>>4)]&4)?((msm->vo4[i]*partVolume[1+(i&4)])>>8):0)+
((regPool[12+(i>>4)]&8)?((msm->vo2[i]*partVolume[i&4])>>8):0)
)<<3;
)<<2;
oscBuf[i]->data[oscBuf[i]->needle++]=CLAMP(o,-32768,32767);
}

View file

@ -84,7 +84,7 @@ void DivPlatformMSM6258::acquire(short** buf, size_t len) {
} else {
buf[0][h]=(msmPan&2)?msmOut:0;
buf[1][h]=(msmPan&1)?msmOut:0;
oscBuf[0]->data[oscBuf[0]->needle++]=msmPan?msmOut:0;
oscBuf[0]->data[oscBuf[0]->needle++]=msmPan?(msmOut>>1):0;
}
}
}

View file

@ -79,9 +79,8 @@ void DivPlatformMSM6295::acquire(short** buf, size_t len) {
if (++updateOsc>=22) {
updateOsc=0;
// TODO: per-channel osc
for (int i=0; i<4; i++) {
oscBuf[i]->data[oscBuf[i]->needle++]=msm.voice_out(i)<<6;
oscBuf[i]->data[oscBuf[i]->needle++]=msm.voice_out(i)<<5;
}
}
}

View file

@ -118,7 +118,7 @@ void DivPlatformN163::acquire(short** buf, size_t len) {
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;
oscBuf[i]->data[oscBuf[i]->needle++]=n163.voice_out(i)<<6;
}
// command queue

View file

@ -177,7 +177,7 @@ void DivPlatformNamcoWSG::acquire(short** buf, size_t len) {
};
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;
oscBuf[i]->data[oscBuf[i]->needle++]=(namco->m_channel_list[i].last_out*chans)>>1;
}
}
}

View file

@ -115,11 +115,11 @@ 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]->data[oscBuf[0]->needle++]=isMuted[0]?0:(nes->S1.output<<10);
oscBuf[1]->data[oscBuf[1]->needle++]=isMuted[1]?0:(nes->S2.output<<10);
oscBuf[2]->data[oscBuf[2]->needle++]=isMuted[2]?0:(nes->TR.output<<10);
oscBuf[3]->data[oscBuf[3]->needle++]=isMuted[3]?0:(nes->NS.output<<10);
oscBuf[4]->data[oscBuf[4]->needle++]=isMuted[4]?0:(nes->DMC.output<<7);
}
}
}
@ -142,11 +142,11 @@ void DivPlatformNES::acquire_NSFPlay(short** buf, size_t len) {
buf[0][i]=sample;
if (++writeOscBuf>=32) {
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]->data[oscBuf[0]->needle++]=nes1_NP->out[0]<<10;
oscBuf[1]->data[oscBuf[1]->needle++]=nes1_NP->out[1]<<10;
oscBuf[2]->data[oscBuf[2]->needle++]=nes2_NP->out[0]<<10;
oscBuf[3]->data[oscBuf[3]->needle++]=nes2_NP->out[1]<<10;
oscBuf[4]->data[oscBuf[4]->needle++]=nes2_NP->out[2]<<7;
}
}
}
@ -211,7 +211,7 @@ void DivPlatformNES::tick(bool sysTick) {
chan[i].outVol=VOL_SCALE_LINEAR_BROKEN(chan[i].vol&15,MIN(15,chan[i].std.vol.val),15);
if (chan[i].outVol<0) chan[i].outVol=0;
if (i==2) { // triangle
rWrite(0x4000+i*4,(chan[i].outVol==0)?0:255);
rWrite(0x4000+i*4,(chan[i].outVol==0)?0:linearCount);
chan[i].freqChanged=true;
} else {
rWrite(0x4000+i*4,(chan[i].envMode<<4)|chan[i].outVol|((chan[i].duty&3)<<6));
@ -262,7 +262,7 @@ void DivPlatformNES::tick(bool sysTick) {
//rWrite(16+i*5,chan[i].sweep);
}
}
if (i<2) if (chan[i].std.phaseReset.had) {
if (i<3) if (chan[i].std.phaseReset.had) {
if (chan[i].std.phaseReset.val==1) {
chan[i].freqChanged=true;
chan[i].prevFreq=-1;
@ -337,14 +337,22 @@ void DivPlatformNES::tick(bool sysTick) {
goingToLoop=parent->getSample(dacSample)->isLoopable();
// write DPCM
rWrite(0x4015,15);
rWrite(0x4010,calcDPCMRate(dacRate)|(goingToLoop?0x40:0));
if (nextDPCMFreq>=0) {
rWrite(0x4010,nextDPCMFreq|(goingToLoop?0x40:0));
nextDPCMFreq=-1;
} else {
rWrite(0x4010,calcDPCMRate(dacRate)|(goingToLoop?0x40:0));
}
rWrite(0x4012,(dpcmAddr>>6)&0xff);
rWrite(0x4013,dpcmLen&0xff);
rWrite(0x4015,31);
dpcmBank=dpcmAddr>>14;
}
} else {
if (dpcmMode) {
if (nextDPCMFreq>=0) {
rWrite(0x4010,nextDPCMFreq|(goingToLoop?0x40:0));
nextDPCMFreq=-1;
} else {
rWrite(0x4010,calcDPCMRate(dacRate)|(goingToLoop?0x40:0));
}
}
@ -353,6 +361,8 @@ void DivPlatformNES::tick(bool sysTick) {
if (chan[4].keyOn) chan[4].keyOn=false;
chan[4].freqChanged=false;
}
nextDPCMFreq=-1;
}
int DivPlatformNES::dispatch(DivCommand c) {
@ -401,12 +411,17 @@ int DivPlatformNES::dispatch(DivCommand c) {
chan[c.chan].furnaceDac=false;
if (dpcmMode && !skipRegisterWrites) {
unsigned int dpcmAddr=sampleOffDPCM[dacSample];
unsigned int dpcmLen=(parent->getSample(dacSample)->lengthDPCM+15)>>4;
unsigned int dpcmLen=parent->getSample(dacSample)->lengthDPCM>>4;
if (dpcmLen>255) dpcmLen=255;
goingToLoop=parent->getSample(dacSample)->isLoopable();
// write DPCM
rWrite(0x4015,15);
rWrite(0x4010,calcDPCMRate(dacRate)|(goingToLoop?0x40:0));
if (nextDPCMFreq>=0) {
rWrite(0x4010,nextDPCMFreq|(goingToLoop?0x40:0));
nextDPCMFreq=-1;
} else {
rWrite(0x4010,calcDPCMRate(dacRate)|(goingToLoop?0x40:0));
}
rWrite(0x4012,(dpcmAddr>>6)&0xff);
rWrite(0x4013,dpcmLen&0xff);
rWrite(0x4015,31);
@ -434,7 +449,7 @@ int DivPlatformNES::dispatch(DivCommand c) {
chan[c.chan].outVol=chan[c.chan].vol;
}
if (c.chan==2) {
rWrite(0x4000+c.chan*4,0xff);
rWrite(0x4000+c.chan*4,linearCount);
} else if (!parent->song.brokenOutVol2) {
rWrite(0x4000+c.chan*4,(chan[c.chan].envMode<<4)|chan[c.chan].vol|((chan[c.chan].duty&3)<<6));
}
@ -466,7 +481,7 @@ int DivPlatformNES::dispatch(DivCommand c) {
}
if (chan[c.chan].active) {
if (c.chan==2) {
rWrite(0x4000+c.chan*4,0xff);
rWrite(0x4000+c.chan*4,linearCount);
} else {
rWrite(0x4000+c.chan*4,(chan[c.chan].envMode<<4)|chan[c.chan].vol|((chan[c.chan].duty&3)<<6));
}
@ -542,6 +557,16 @@ int DivPlatformNES::dispatch(DivCommand c) {
countMode=c.value;
rWrite(0x4017,countMode?0x80:0);
break;
case DIV_CMD_NES_LINEAR_LENGTH:
if (c.chan==2) {
linearCount=c.value;
if (chan[c.chan].active) {
rWrite(0x4000+c.chan*4,(chan[c.chan].outVol==0)?0:linearCount);
chan[c.chan].freqChanged=true;
chan[c.chan].prevFreq=-1;
}
}
break;
case DIV_CMD_NES_DMC:
rWrite(0x4011,c.value&0x7f);
break;
@ -555,6 +580,14 @@ int DivPlatformNES::dispatch(DivCommand c) {
rWrite(0x4013,0);
rWrite(0x4015,31);
break;
case DIV_CMD_SAMPLE_FREQ: {
bool goingToLoop=parent->getSample(dacSample)->isLoopable();
if (dpcmMode) {
nextDPCMFreq=c.value&15;
rWrite(0x4010,(c.value&15)|(goingToLoop?0x40:0));
}
break;
}
case DIV_CMD_SAMPLE_BANK:
sampleBank=c.value;
if (sampleBank>(parent->song.sample.size()/12)) {
@ -655,9 +688,11 @@ void DivPlatformNES::reset() {
dacSample=-1;
sampleBank=0;
dpcmBank=0;
dpcmMode=false;
dpcmMode=dpcmModeDefault;
goingToLoop=false;
countMode=false;
nextDPCMFreq=-1;
linearCount=255;
if (useNP) {
nes1_NP->Reset();
@ -709,6 +744,8 @@ void DivPlatformNES::setFlags(const DivConfig& flags) {
for (int i=0; i<5; i++) {
oscBuf[i]->rate=rate/32;
}
dpcmModeDefault=flags.getBool("dpcmMode",true);
}
void DivPlatformNES::notifyInsDeletion(void* ins) {

View file

@ -52,7 +52,10 @@ class DivPlatformNES: public DivDispatch {
unsigned char sampleBank;
unsigned char writeOscBuf;
unsigned char apuType;
unsigned char linearCount;
signed char nextDPCMFreq;
bool dpcmMode;
bool dpcmModeDefault;
bool dacAntiClickOn;
bool useNP;
bool goingToLoop;

View file

@ -211,7 +211,7 @@ 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];
oscBuf[adpcmChan]->data[oscBuf[adpcmChan]->needle++]=aOut.data[0]>>1;
} else {
oscBuf[adpcmChan]->data[oscBuf[adpcmChan]->needle++]=0;
}
@ -234,14 +234,13 @@ void DivPlatformOPL::acquire_nuked(short** buf, size_t len) {
if (fm.channel[i].out[3]!=NULL) {
oscBuf[i]->data[oscBuf[i]->needle]+=*fm.channel[ch].out[3];
}
oscBuf[i]->data[oscBuf[i]->needle]<<=1;
oscBuf[i]->needle++;
}
// special
oscBuf[melodicChans+1]->data[oscBuf[melodicChans+1]->needle++]=fm.slot[16].out*6;
oscBuf[melodicChans+2]->data[oscBuf[melodicChans+2]->needle++]=fm.slot[14].out*6;
oscBuf[melodicChans+3]->data[oscBuf[melodicChans+3]->needle++]=fm.slot[17].out*6;
oscBuf[melodicChans+4]->data[oscBuf[melodicChans+4]->needle++]=fm.slot[13].out*6;
oscBuf[melodicChans+1]->data[oscBuf[melodicChans+1]->needle++]=fm.slot[16].out*3;
oscBuf[melodicChans+2]->data[oscBuf[melodicChans+2]->needle++]=fm.slot[14].out*3;
oscBuf[melodicChans+3]->data[oscBuf[melodicChans+3]->needle++]=fm.slot[17].out*3;
oscBuf[melodicChans+4]->data[oscBuf[melodicChans+4]->needle++]=fm.slot[13].out*3;
} else {
for (int i=0; i<chans; i++) {
unsigned char ch=outChanMap[i];
@ -259,7 +258,6 @@ void DivPlatformOPL::acquire_nuked(short** buf, size_t len) {
if (fm.channel[i].out[3]!=NULL) {
oscBuf[i]->data[oscBuf[i]->needle]+=*fm.channel[ch].out[3];
}
oscBuf[i]->data[oscBuf[i]->needle]<<=1;
oscBuf[i]->needle++;
}
}

View file

@ -68,7 +68,7 @@ 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]->data[oscBuf[nextOut]->needle++]=(o[0]+o[1])<<5;
} else {
if (vrc7 || (fm.rm_enable&0x20)) oscBuf[nextOut]->data[oscBuf[nextOut]->needle++]=0;
}
@ -76,7 +76,7 @@ void DivPlatformOPLL::acquire_nuked(short** buf, size_t len) {
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]->data[oscBuf[ch]->needle++]=(fm.output_ch[i])<<5;
} else {
oscBuf[ch]->data[oscBuf[ch]->needle++]=0;
}
@ -101,8 +101,17 @@ void DivPlatformOPLL::tick(bool sysTick) {
if (chan[i].std.vol.had) {
chan[i].outVol=VOL_SCALE_LOG_BROKEN(chan[i].vol,MIN(15,chan[i].std.vol.val),15);
if (i<9) {
rWrite(0x30+i,((15-VOL_SCALE_LOG_BROKEN(chan[i].outVol,15-chan[i].state.op[1].tl,15))&15)|(chan[i].state.opllPreset<<4));
if (i>=6 && properDrums) {
drumVol[i-6]=15-chan[i].outVol;
rWrite(0x36,drumVol[0]);
rWrite(0x37,drumVol[1]|(drumVol[4]<<4));
rWrite(0x38,drumVol[3]|(drumVol[2]<<4));
break;
} else if (i<6 || !drums) {
if (i<9) {
rWrite(0x30+i,((15-VOL_SCALE_LOG_BROKEN(chan[i].outVol,15-chan[i].state.op[1].tl,15))&15)|(chan[i].state.opllPreset<<4));
}
}
}
@ -409,10 +418,6 @@ int DivPlatformOPLL::dispatch(DivCommand c) {
case 8: case 9:
chan[c.chan].fixedFreq=(chan[c.chan].state.tomTopFreq&511)<<(chan[c.chan].state.tomTopFreq>>9);
break;
default:
chan[c.chan].fixedFreq=0;
chan[c.chan].baseFreq=NOTE_FREQUENCY(c.value);
break;
}
} else {
chan[c.chan].baseFreq=NOTE_FREQUENCY(c.value);

View file

@ -101,7 +101,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])<<1,-32768,32767);
oscBuf[i]->data[oscBuf[i]->needle++]=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);

View file

@ -42,12 +42,65 @@ void DivPlatformPCMDAC::acquire(short** buf, size_t len) {
while (chan[0].audSub>=0x10000) {
chan[0].audSub-=0x10000;
chan[0].audPos+=((!chan[0].useWave) && chan[0].audDir)?-1:1;
if (chan[0].audPos>=(int)chan[0].audLen) {
chan[0].audPos%=chan[0].audLen;
chan[0].audDir=false;
}
chan[0].audDat[0]=chan[0].audDat[1];
chan[0].audDat[1]=chan[0].audDat[2];
chan[0].audDat[2]=chan[0].audDat[3];
chan[0].audDat[3]=chan[0].audDat[4];
chan[0].audDat[4]=chan[0].audDat[5];
chan[0].audDat[5]=chan[0].audDat[6];
chan[0].audDat[6]=chan[0].audDat[7];
chan[0].audDat[7]=(chan[0].ws.output[chan[0].audPos]-0x80)<<8;
}
if (chan[0].audPos>=(int)chan[0].audLen) {
chan[0].audPos%=chan[0].audLen;
chan[0].audDir=false;
const short s0=chan[0].audDat[0];
const short s1=chan[0].audDat[1];
const short s2=chan[0].audDat[2];
const short s3=chan[0].audDat[3];
const short s4=chan[0].audDat[4];
const short s5=chan[0].audDat[5];
const short s6=chan[0].audDat[6];
const short s7=chan[0].audDat[7];
switch (interp) {
case 1: // linear
output=s6+((s7-s6)*(chan[0].audSub&0xffff)>>16);
break;
case 2: { // cubic
float* cubicTable=DivFilterTables::getCubicTable();
float* t=&cubicTable[((chan[0].audSub&0xffff)>>6)<<2];
float result=(float)s4*t[0]+(float)s5*t[1]+(float)s6*t[2]+(float)s7*t[3];
if (result<-32768) result=-32768;
if (result>32767) result=32767;
output=result;
break;
}
case 3: { // sinc
float* sincTable=DivFilterTables::getSincTable8();
float* t1=&sincTable[(8191-((chan[0].audSub&0xffff)>>3))<<2];
float* t2=&sincTable[((chan[0].audSub&0xffff)>>3)<<2];
float result=(
s0*t2[3]+
s1*t2[2]+
s2*t2[1]+
s3*t2[0]+
s4*t1[0]+
s5*t1[1]+
s6*t1[2]+
s7*t1[3]
);
if (result<-32768) result=-32768;
if (result>32767) result=32767;
output=result;
break;
}
default: // none
output=s7;
break;
}
output=(chan[0].ws.output[chan[0].audPos]-0x80)<<8;
} else {
DivSample* s=parent->getSample(chan[0].sample);
if (s->samples>0) {
@ -176,7 +229,7 @@ void DivPlatformPCMDAC::acquire(short** buf, size_t len) {
} else {
output=output*chan[0].vol*chan[0].envVol/16384;
}
oscBuf->data[oscBuf->needle++]=output;
oscBuf->data[oscBuf->needle++]=output>>1;
if (outStereo) {
buf[0][h]=((output*chan[0].panL)>>(depthScale+8))<<depthScale;
buf[1][h]=((output*chan[0].panR)>>(depthScale+8))<<depthScale;

View file

@ -366,8 +366,10 @@ void DivPlatformPCSpeaker::tick(bool sysTick) {
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,chan[i].fixedArp?chan[i].baseNoteOverride:chan[i].arpOff,chan[i].fixedArp,true,0,chan[i].pitch2,chipClock,CHIP_DIVIDER)-1;
if (chan[i].freq<0) chan[i].freq=0;
if (chan[i].freq>65535) chan[i].freq=65535;
if (chan[i].keyOn) {
on=true;
if (!chan[i].std.vol.had) {
if (chan[i].keyOn) {
on=true;
}
}
if (chan[i].keyOff) {
on=false;

View file

@ -85,10 +85,10 @@ void DivPlatformPOKEY::acquireMZ(short* buf, size_t len) {
if (++oscBufDelay>=14) {
oscBufDelay=0;
oscBuf[0]->data[oscBuf[0]->needle++]=pokey.outvol_0<<11;
oscBuf[1]->data[oscBuf[1]->needle++]=pokey.outvol_1<<11;
oscBuf[2]->data[oscBuf[2]->needle++]=pokey.outvol_2<<11;
oscBuf[3]->data[oscBuf[3]->needle++]=pokey.outvol_3<<11;
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;
}
}
}
@ -156,7 +156,7 @@ void DivPlatformPOKEY::tick(bool sysTick) {
for (int i=0; i<4; i++) {
if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) {
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,chan[i].fixedArp?chan[i].baseNoteOverride:chan[i].arpOff,chan[i].fixedArp,true,0,chan[i].pitch2,chipClock,CHIP_DIVIDER);
chan[i].freq=parent->calcFreq(chan[i].baseFreq,parent->song.linearPitch?chan[i].pitch:0,chan[i].fixedArp?chan[i].baseNoteOverride:chan[i].arpOff,chan[i].fixedArp,true,0,parent->song.linearPitch?chan[i].pitch2:0,chipClock,CHIP_DIVIDER);
if ((i==0 && !(audctl&64)) || (i==2 && !(audctl&32)) || i==1 || i==3) {
chan[i].freq/=7;
@ -194,6 +194,11 @@ void DivPlatformPOKEY::tick(bool sysTick) {
chan[i].freq>>=2;
}
// non-linear pitch
if (parent->song.linearPitch==0) {
chan[i].freq-=chan[i].pitch;
}
if (--chan[i].freq<0) chan[i].freq=0;
// snap buzz periods

View file

@ -272,7 +272,7 @@ void DivPlatformQSound::acquire(short** buf, size_t len) {
buf[1][h]=chip.out[1];
for (int i=0; i<19; i++) {
int data=chip.voice_output[i]<<2;
int data=chip.voice_output[i]<<1;
if (data<-32768) data=-32768;
if (data>32767) data=32767;
oscBuf[i]->data[oscBuf[i]->needle++]=data;
@ -319,7 +319,7 @@ void DivPlatformQSound::tick(bool sysTick) {
if (length > 65536 - 16) {
length = 65536 - 16;
}
if (loopStart == -1 || loopStart >= length) {
if (!s->isLoopable()) {
if (i<16) {
qsound_end = offPCM[chan[i].sample] + length + 15;
} else {
@ -466,6 +466,7 @@ int DivPlatformQSound::dispatch(DivCommand c) {
}
chan[c.chan].active=true;
chan[c.chan].keyOn=true;
chan[c.chan].keyOff=false;
chan[c.chan].macroInit(ins);
if (!parent->song.brokenOutVol && !chan[c.chan].std.vol.will) {
chan[c.chan].outVol=chan[c.chan].vol;
@ -609,6 +610,7 @@ void DivPlatformQSound::forceIns() {
for (int i=0; i<19; i++) {
chan[i].insChanged=true;
chan[i].freqChanged=true;
chan[i].keyOff=true;
//chan[i].sample=-1;
}
}

View file

@ -74,7 +74,7 @@ void DivPlatformRF5C68::acquire(short** buf, size_t len) {
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];
oscBuf[i]->data[oscBuf[i]->needle++]=(bufC[i*2][j]+bufC[i*2+1][j])>>1;
}
}
pos+=blockLen;

View file

@ -87,7 +87,7 @@ void DivPlatformSCC::acquire(short** buf, size_t len) {
buf[0][h]=out;
for (int i=0; i<5; i++) {
oscBuf[i]->data[oscBuf[i]->needle++]=scc->voice_out(i)<<7;
oscBuf[i]->data[oscBuf[i]->needle++]=scc->voice_out(i)<<6;
}
}
}

View file

@ -49,7 +49,7 @@ 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];
oscBuf[i]->data[oscBuf[i]->needle++]=(pcm.lastOut[i][0]+pcm.lastOut[i][1])>>1;
}
}
}
@ -121,7 +121,7 @@ void DivPlatformSegaPCM::tick(bool sysTick) {
DivSample* s=parent->getSample(chan[i].pcm.sample);
off=(double)s->centerRate/8363.0;
}
chan[i].pcm.freq=MIN(255,(15625+(off*parent->song.tuning*pow(2.0,double(chan[i].freq+512)/(128.0*12.0)))*255)/31250)+(oldSlides?chan[i].pitch2:0);
chan[i].pcm.freq=MIN(255,((rate*0.5)+(off*parent->song.tuning*pow(2.0,double(chan[i].freq+512)/(128.0*12.0)))*255)/rate)+(oldSlides?chan[i].pitch2:0);
rWrite(7+(i<<3),chan[i].pcm.freq);
}
chan[i].freqChanged=false;
@ -138,7 +138,7 @@ void DivPlatformSegaPCM::tick(bool sysTick) {
rWrite(0x84+(i<<3),(sampleOffSegaPCM[chan[i].pcm.sample])&0xff);
rWrite(0x85+(i<<3),(sampleOffSegaPCM[chan[i].pcm.sample]>>8)&0xff);
rWrite(6+(i<<3),sampleEndSegaPCM[chan[i].pcm.sample]);
if (loopStart<0 || loopStart>=actualLength) {
if (!s->isLoopable()) {
rWrite(0x86+(i<<3),2+((sampleOffSegaPCM[chan[i].pcm.sample]>>16)<<3));
} else {
int loopPos=(sampleOffSegaPCM[chan[i].pcm.sample]&0xffff)+loopStart;
@ -156,7 +156,7 @@ void DivPlatformSegaPCM::tick(bool sysTick) {
rWrite(0x84+(i<<3),(sampleOffSegaPCM[chan[i].pcm.sample])&0xff);
rWrite(0x85+(i<<3),(sampleOffSegaPCM[chan[i].pcm.sample]>>8)&0xff);
rWrite(6+(i<<3),sampleEndSegaPCM[chan[i].pcm.sample]);
if (loopStart<0 || loopStart>=actualLength) {
if (!s->isLoopable()) {
rWrite(0x86+(i<<3),2+((sampleOffSegaPCM[chan[i].pcm.sample]>>16)<<3));
} else {
int loopPos=(sampleOffSegaPCM[chan[i].pcm.sample]&0xffff)+loopStart;
@ -220,7 +220,7 @@ int DivPlatformSegaPCM::dispatch(DivCommand c) {
rWrite(0x86+(c.chan<<3),3);
break;
}
chan[c.chan].pcm.freq=MIN(255,(parent->getSample(chan[c.chan].pcm.sample)->rate*255)/31250);
chan[c.chan].pcm.freq=MIN(255,(parent->getSample(chan[c.chan].pcm.sample)->rate*255)/rate);
chan[c.chan].furnacePCM=false;
chan[c.chan].active=true;
chan[c.chan].keyOn=true;

View file

@ -58,9 +58,9 @@ void DivPlatformSM8521::acquire(short** buf, size_t len) {
sm8521_sound_tick(&sm8521,8);
buf[0][h]=sm8521.out<<6;
for (int i=0; i<2; i++) {
oscBuf[i]->data[oscBuf[i]->needle++]=sm8521.sg[i].base.out<<6;
oscBuf[i]->data[oscBuf[i]->needle++]=sm8521.sg[i].base.out<<5;
}
oscBuf[2]->data[oscBuf[2]->needle++]=sm8521.noise.base.out<<6;
oscBuf[2]->data[oscBuf[2]->needle++]=sm8521.noise.base.out<<5;
}
}

View file

@ -91,7 +91,7 @@ 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;
oscBuf[i]->data[oscBuf[i]->needle++]=next>>1;
}
}
}
@ -202,6 +202,7 @@ void DivPlatformSNES::tick(bool sysTick) {
}
}
for (int i=0; i<8; i++) {
// TODO: if wavetable length is higher than 32, we lose precision!
if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) {
DivSample* s=parent->getSample(chan[i].sample);
double off=(s->centerRate>=1)?((double)s->centerRate/8363.0):1.0;
@ -221,7 +222,7 @@ void DivPlatformSNES::tick(bool sysTick) {
if (chan[i].audPos>0) {
start=start+MIN(chan[i].audPos,s->lengthBRR-1)/16*9;
}
if (s->loopStart>=0) {
if (s->isLoopable()) {
loop=((s->depth!=DIV_SAMPLE_DEPTH_BRR)?9:0)+start+((s->loopStart/16)*9);
}
} else {
@ -300,6 +301,11 @@ void DivPlatformSNES::tick(bool sysTick) {
rWrite(0x4d,echoBits);
writeEcho=false;
}
if (writeDryVol) {
rWrite(0x0c,dryVolL);
rWrite(0x1c,dryVolR);
writeDryVol=false;
}
for (int i=0; i<8; i++) {
if (chan[i].shallWriteEnv) {
writeEnv(i);
@ -563,6 +569,14 @@ int DivPlatformSNES::dispatch(DivCommand c) {
rWrite(0x3c,echoVolR);
}
break;
case DIV_CMD_SNES_GLOBAL_VOL_LEFT:
dryVolL=c.value;
writeDryVol=true;
break;
case DIV_CMD_SNES_GLOBAL_VOL_RIGHT:
dryVolR=c.value;
writeDryVol=true;
break;
case DIV_CMD_GET_VOLMAX:
return 127;
break;
@ -673,6 +687,7 @@ void DivPlatformSNES::forceIns() {
writeNoise=true;
writePitchMod=true;
writeEcho=true;
writeDryVol=true;
initEcho();
}
@ -761,6 +776,10 @@ void DivPlatformSNES::reset() {
writeNoise=false;
writePitchMod=false;
writeEcho=true;
writeDryVol=false;
dryVolL=127;
dryVolR=127;
echoDelay=initEchoDelay;
echoFeedback=initEchoFeedback;

View file

@ -59,6 +59,7 @@ class DivPlatformSNES: public DivDispatch {
unsigned char noiseFreq;
signed char delay;
signed char echoVolL, echoVolR, echoFeedback;
signed char dryVolL, dryVolR;
signed char echoFIR[8];
unsigned char echoDelay;
size_t sampleTableBase;
@ -66,6 +67,7 @@ class DivPlatformSNES: public DivDispatch {
bool writeNoise;
bool writePitchMod;
bool writeEcho;
bool writeDryVol;
bool echoOn;
bool initEchoOn;

View file

@ -509,7 +509,7 @@ public:
}
if (oscb!=NULL) {
oscb[i]->data[oscb[i]->needle++]=oscbWrite;
oscb[i]->data[oscb[i]->needle++]=oscbWrite>>1;
}
}

View file

@ -39,7 +39,7 @@ static constexpr int MuteInit = 2;
static constexpr int MuteSerialInput = 8;
//just some magick value to match the audio level of mzpokeysnd
static constexpr int16_t MAGICK_VOLUME_BOOSTER = 160;
static constexpr int16_t MAGICK_OSC_VOLUME_BOOSTER = 4;
static constexpr int16_t MAGICK_OSC_VOLUME_BOOSTER = 2;
struct PokeyBase
{

View file

@ -87,7 +87,7 @@ 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]->data[oscBuf[i]->needle++]=(ws->sample_cache[i][0]+ws->sample_cache[i][1])<<5;
}
}
}

View file

@ -51,8 +51,8 @@ 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]->data[oscBuf[0]->needle++]=tia.myChannelOut[0]>>1;
oscBuf[1]->data[oscBuf[1]->needle++]=tia.myChannelOut[1]>>1;
}
}
}

View file

@ -78,7 +78,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++]=(fme->debug_channel(i)->debug_output(0)+fme->debug_channel(i)->debug_output(1));
oscBuf[i]->data[oscBuf[i]->needle++]=(fme->debug_channel(i)->debug_output(0)+fme->debug_channel(i)->debug_output(1))>>1;
}
os[0]=out_ymfm.data[0];

View file

@ -107,7 +107,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]->data[oscBuf[i]->needle++]=(vb->last_output[i][0]+vb->last_output[i][1])*4;
tempL+=vb->last_output[i][0];
tempR+=vb->last_output[i][1];
}

View file

@ -35,7 +35,7 @@ extern "C" {
#define rWritePCMCtrl(d) {regPool[64]=(d); pcm_write_ctrl(pcm,d);}
#define rWritePCMRate(d) {regPool[65]=(d); pcm_write_rate(pcm,d);}
#define rWritePCMData(d) {regPool[66]=(d); pcm_write_fifo(pcm,d);}
#define rWritePCMVol(d) rWritePCMCtrl((regPool[64]&(~0x3f))|((d)&0x3f))
#define rWritePCMVol(d) rWritePCMCtrl((regPool[64]&(~0x8f))|((d)&15))
const char* regCheatSheetVERA[]={
"CHxFreq", "00+x*4",
@ -107,9 +107,9 @@ void DivPlatformVERA::acquire(short** buf, size_t len) {
pos++;
for (int i=0; i<16; i++) {
oscBuf[i]->data[oscBuf[i]->needle++]=psg->channels[i].lastOut<<4;
oscBuf[i]->data[oscBuf[i]->needle++]=psg->channels[i].lastOut<<3;
}
int pcmOut=whyCallItBuf[2][i]+whyCallItBuf[3][i];
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;

View file

@ -69,7 +69,7 @@ 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]->data[oscBuf[i]->needle++]=vic->ch[i].out?(vic->volume<<10):0;
}
}
}

View file

@ -87,9 +87,9 @@ void DivPlatformVRC6::acquire(short** buf, size_t len) {
if (++writeOscBuf>=32) {
writeOscBuf=0;
for (int i=0; i<2; i++) {
oscBuf[i]->data[oscBuf[i]->needle++]=vrc6.pulse_out(i)<<10;
oscBuf[i]->data[oscBuf[i]->needle++]=vrc6.pulse_out(i)<<9;
}
oscBuf[2]->data[oscBuf[2]->needle++]=vrc6.sawtooth_out()<<10;
oscBuf[2]->data[oscBuf[2]->needle++]=vrc6.sawtooth_out()<<9;
}
// Command part

View file

@ -222,7 +222,7 @@ void DivPlatformX1_010::acquire(short** buf, size_t len) {
if (stereo) buf[1][h]=tempR;
for (int i=0; i<16; i++) {
int vo=(x1_010.voice_out(i,0)+x1_010.voice_out(i,1))<<3;
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);
}
}

View file

@ -169,6 +169,15 @@ void DivPlatformYM2203::acquire_combo(short** buf, size_t len) {
static short ignored[2];
for (size_t h=0; h<len; h++) {
// AY -> OPN
ay->runDAC();
ay->flushWrites();
for (DivRegWrite& i: ay->getRegisterWrites()) {
if (i.addr>15) continue;
immWrite(i.addr&15,i.val);
}
ay->getRegisterWrites().clear();
os=0;
// Nuked part
for (unsigned int i=0; i<nukedMult; i++) {
@ -222,11 +231,11 @@ 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++]=fm_nuked.ch_out[i];
oscBuf[i]->data[oscBuf[i]->needle++]=fm_nuked.ch_out[i]>>1;
}
for (int i=3; i<6; i++) {
oscBuf[i]->data[oscBuf[i]->needle++]=fmout.data[i-2];
oscBuf[i]->data[oscBuf[i]->needle++]=fmout.data[i-2]>>1;
}
}
}
@ -242,6 +251,15 @@ void DivPlatformYM2203::acquire_ymfm(short** buf, size_t len) {
}
for (size_t h=0; h<len; h++) {
// AY -> OPN
ay->runDAC();
ay->flushWrites();
for (DivRegWrite& i: ay->getRegisterWrites()) {
if (i.addr>15) continue;
immWrite(i.addr&15,i.val);
}
ay->getRegisterWrites().clear();
os=0;
if (!writes.empty()) {
if (--delay<1) {
@ -264,11 +282,11 @@ void DivPlatformYM2203::acquire_ymfm(short** buf, size_t len) {
for (int i=0; i<3; i++) {
oscBuf[i]->data[oscBuf[i]->needle++]=(fmChan[i]->debug_output(0)+fmChan[i]->debug_output(1));
oscBuf[i]->data[oscBuf[i]->needle++]=(fmChan[i]->debug_output(0)+fmChan[i]->debug_output(1))>>1;
}
for (int i=3; i<6; i++) {
oscBuf[i]->data[oscBuf[i]->needle++]=fmout.data[i-2];
oscBuf[i]->data[oscBuf[i]->needle++]=fmout.data[i-2]>>1;
}
}
}
@ -567,7 +585,7 @@ int DivPlatformYM2203::dispatch(DivCommand c) {
chan[c.chan].keyOff=true;
chan[c.chan].keyOn=false;
chan[c.chan].active=false;
chan[c.chan].macroInit(NULL);
if (parent->song.brokenFMOff) chan[c.chan].macroInit(NULL);
break;
case DIV_CMD_NOTE_OFF_ENV:
chan[c.chan].keyOff=true;

View file

@ -321,6 +321,15 @@ void DivPlatformYM2608::acquire_combo(short** buf, size_t len) {
}
for (size_t h=0; h<len; h++) {
// AY -> OPN
ay->runDAC();
ay->flushWrites();
for (DivRegWrite& i: ay->getRegisterWrites()) {
if (i.addr>15) continue;
immWrite(i.addr&15,i.val);
}
ay->getRegisterWrites().clear();
os[0]=0; os[1]=0;
// Nuked part
for (int i=0; i<nukedMult; i++) {
@ -393,19 +402,19 @@ void DivPlatformYM2608::acquire_combo(short** buf, size_t len) {
for (int i=0; i<psgChanOffs; i++) {
oscBuf[i]->data[oscBuf[i]->needle++]=fm_nuked.ch_out[i];
oscBuf[i]->data[oscBuf[i]->needle++]=fm_nuked.ch_out[i]>>1;
}
ssge->get_last_out(ssgOut);
for (int i=psgChanOffs; i<adpcmAChanOffs; i++) {
oscBuf[i]->data[oscBuf[i]->needle++]=ssgOut.data[i-psgChanOffs];
oscBuf[i]->data[oscBuf[i]->needle++]=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);
oscBuf[i]->data[oscBuf[i]->needle++]=(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);
oscBuf[adpcmBChanOffs]->data[oscBuf[adpcmBChanOffs]->needle++]=(abe->get_last_out(0)+abe->get_last_out(1))>>1;
}
}
@ -427,6 +436,15 @@ void DivPlatformYM2608::acquire_ymfm(short** buf, size_t len) {
}
for (size_t h=0; h<len; h++) {
// AY -> OPN
ay->runDAC();
ay->flushWrites();
for (DivRegWrite& i: ay->getRegisterWrites()) {
if (i.addr>15) continue;
immWrite(i.addr&15,i.val);
}
ay->getRegisterWrites().clear();
os[0]=0; os[1]=0;
if (!writes.empty()) {
if (--delay<1) {
@ -453,19 +471,19 @@ void DivPlatformYM2608::acquire_ymfm(short** buf, size_t len) {
buf[1][h]=os[1];
for (int i=0; i<6; i++) {
oscBuf[i]->data[oscBuf[i]->needle++]=(fmChan[i]->debug_output(0)+fmChan[i]->debug_output(1));
oscBuf[i]->data[oscBuf[i]->needle++]=(fmChan[i]->debug_output(0)+fmChan[i]->debug_output(1))>>1;
}
ssge->get_last_out(ssgOut);
for (int i=6; i<9; i++) {
oscBuf[i]->data[oscBuf[i]->needle++]=ssgOut.data[i-6];
oscBuf[i]->data[oscBuf[i]->needle++]=ssgOut.data[i-6]>>1;
}
for (int i=9; i<15; i++) {
oscBuf[i]->data[oscBuf[i]->needle++]=adpcmAChan[i-9]->get_last_out(0)+adpcmAChan[i-9]->get_last_out(1);
oscBuf[i]->data[oscBuf[i]->needle++]=(adpcmAChan[i-9]->get_last_out(0)+adpcmAChan[i-9]->get_last_out(1))>>1;
}
oscBuf[15]->data[oscBuf[15]->needle++]=abe->get_last_out(0)+abe->get_last_out(1);
oscBuf[15]->data[oscBuf[15]->needle++]=(abe->get_last_out(0)+abe->get_last_out(1))>>1;
}
}
@ -1007,7 +1025,7 @@ int DivPlatformYM2608::dispatch(DivCommand c) {
chan[c.chan].keyOff=true;
chan[c.chan].keyOn=false;
chan[c.chan].active=false;
chan[c.chan].macroInit(NULL);
if (parent->song.brokenFMOff) chan[c.chan].macroInit(NULL);
break;
case DIV_CMD_NOTE_OFF_ENV:
chan[c.chan].keyOff=true;
@ -1675,7 +1693,7 @@ int DivPlatformYM2608::init(DivEngine* p, int channels, int sugRate, const DivCo
fm=new ymfm::ym2608(iface);
fm->set_fidelity(ymfm::OPN_FIDELITY_MIN);
// YM2149, 2MHz
ay=new DivPlatformAY8910(true,chipClock,ayDiv);
ay=new DivPlatformAY8910(true,chipClock,ayDiv,48);
ay->init(p,3,sugRate,ayFlags);
ay->toggleRegisterDump(true);
setFlags(flags);

View file

@ -256,6 +256,15 @@ void DivPlatformYM2610::acquire_combo(short** buf, size_t len) {
}
for (size_t h=0; h<len; h++) {
// AY -> OPN
ay->runDAC();
ay->flushWrites();
for (DivRegWrite& i: ay->getRegisterWrites()) {
if (i.addr>15) continue;
immWrite(i.addr&15,i.val);
}
ay->getRegisterWrites().clear();
os[0]=0; os[1]=0;
// Nuked part
for (int i=0; i<24; i++) {
@ -324,19 +333,19 @@ void DivPlatformYM2610::acquire_combo(short** buf, size_t len) {
for (int i=0; i<psgChanOffs; i++) {
oscBuf[i]->data[oscBuf[i]->needle++]=fm_nuked.ch_out[bchOffs[i]];
oscBuf[i]->data[oscBuf[i]->needle++]=fm_nuked.ch_out[bchOffs[i]]>>1;
}
ssge->get_last_out(ssgOut);
for (int i=psgChanOffs; i<adpcmAChanOffs; i++) {
oscBuf[i]->data[oscBuf[i]->needle++]=ssgOut.data[i-psgChanOffs];
oscBuf[i]->data[oscBuf[i]->needle++]=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);
oscBuf[i]->data[oscBuf[i]->needle++]=(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);
oscBuf[adpcmBChanOffs]->data[oscBuf[adpcmBChanOffs]->needle++]=(abe->get_last_out(0)+abe->get_last_out(1))>>1;
}
}
@ -360,6 +369,15 @@ void DivPlatformYM2610::acquire_ymfm(short** buf, size_t len) {
}
for (size_t h=0; h<len; h++) {
// AY -> OPN
ay->runDAC();
ay->flushWrites();
for (DivRegWrite& i: ay->getRegisterWrites()) {
if (i.addr>15) continue;
immWrite(i.addr&15,i.val);
}
ay->getRegisterWrites().clear();
os[0]=0; os[1]=0;
if (!writes.empty()) {
if (--delay<1 && !(fm->read(0)&0x80)) {
@ -386,19 +404,19 @@ void DivPlatformYM2610::acquire_ymfm(short** buf, size_t len) {
buf[1][h]=os[1];
for (int i=0; i<psgChanOffs; i++) {
oscBuf[i]->data[oscBuf[i]->needle++]=(fmChan[i]->debug_output(0)+fmChan[i]->debug_output(1));
oscBuf[i]->data[oscBuf[i]->needle++]=(fmChan[i]->debug_output(0)+fmChan[i]->debug_output(1))>>1;
}
ssge->get_last_out(ssgOut);
for (int i=psgChanOffs; i<adpcmAChanOffs; i++) {
oscBuf[i]->data[oscBuf[i]->needle++]=ssgOut.data[i-psgChanOffs];
oscBuf[i]->data[oscBuf[i]->needle++]=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);
oscBuf[i]->data[oscBuf[i]->needle++]=(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);
oscBuf[adpcmBChanOffs]->data[oscBuf[adpcmBChanOffs]->needle++]=(abe->get_last_out(0)+abe->get_last_out(1))>>1;
}
}
@ -979,7 +997,7 @@ int DivPlatformYM2610::dispatch(DivCommand c) {
chan[c.chan].keyOff=true;
chan[c.chan].keyOn=false;
chan[c.chan].active=false;
chan[c.chan].macroInit(NULL);
if (parent->song.brokenFMOff) chan[c.chan].macroInit(NULL);
break;
case DIV_CMD_NOTE_OFF_ENV:
chan[c.chan].keyOff=true;

View file

@ -320,7 +320,16 @@ void DivPlatformYM2610B::acquire_combo(short** buf, size_t len) {
}
for (size_t h=0; h<len; h++) {
// AY -> OPN
ay->runDAC();
ay->flushWrites();
for (DivRegWrite& i: ay->getRegisterWrites()) {
if (i.addr>15) continue;
immWrite(i.addr&15,i.val);
}
ay->getRegisterWrites().clear();
os[0]=0; os[1]=0;
// Nuked part
for (int i=0; i<24; i++) {
if (!writes.empty()) {
@ -392,19 +401,19 @@ void DivPlatformYM2610B::acquire_combo(short** buf, size_t len) {
for (int i=0; i<psgChanOffs; i++) {
oscBuf[i]->data[oscBuf[i]->needle++]=fm_nuked.ch_out[i];
oscBuf[i]->data[oscBuf[i]->needle++]=fm_nuked.ch_out[i]>>1;
}
ssge->get_last_out(ssgOut);
for (int i=psgChanOffs; i<adpcmAChanOffs; i++) {
oscBuf[i]->data[oscBuf[i]->needle++]=ssgOut.data[i-psgChanOffs];
oscBuf[i]->data[oscBuf[i]->needle++]=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);
oscBuf[i]->data[oscBuf[i]->needle++]=(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);
oscBuf[adpcmBChanOffs]->data[oscBuf[adpcmBChanOffs]->needle++]=(abe->get_last_out(0)+abe->get_last_out(1))>>1;
}
}
@ -426,6 +435,15 @@ void DivPlatformYM2610B::acquire_ymfm(short** buf, size_t len) {
}
for (size_t h=0; h<len; h++) {
// AY -> OPN
ay->runDAC();
ay->flushWrites();
for (DivRegWrite& i: ay->getRegisterWrites()) {
if (i.addr>15) continue;
immWrite(i.addr&15,i.val);
}
ay->getRegisterWrites().clear();
os[0]=0; os[1]=0;
if (!writes.empty()) {
if (--delay<1 && !(fm->read(0)&0x80)) {
@ -453,19 +471,19 @@ void DivPlatformYM2610B::acquire_ymfm(short** buf, size_t len) {
for (int i=0; i<psgChanOffs; i++) {
oscBuf[i]->data[oscBuf[i]->needle++]=(fmChan[i]->debug_output(0)+fmChan[i]->debug_output(1));
oscBuf[i]->data[oscBuf[i]->needle++]=(fmChan[i]->debug_output(0)+fmChan[i]->debug_output(1))>>1;
}
ssge->get_last_out(ssgOut);
for (int i=psgChanOffs; i<adpcmAChanOffs; i++) {
oscBuf[i]->data[oscBuf[i]->needle++]=ssgOut.data[i-psgChanOffs];
oscBuf[i]->data[oscBuf[i]->needle++]=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);
oscBuf[i]->data[oscBuf[i]->needle++]=(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);
oscBuf[adpcmBChanOffs]->data[oscBuf[adpcmBChanOffs]->needle++]=(abe->get_last_out(0)+abe->get_last_out(1))>>1;
}
}
@ -1046,7 +1064,7 @@ int DivPlatformYM2610B::dispatch(DivCommand c) {
chan[c.chan].keyOff=true;
chan[c.chan].keyOn=false;
chan[c.chan].active=false;
chan[c.chan].macroInit(NULL);
if (parent->song.brokenFMOff) chan[c.chan].macroInit(NULL);
break;
case DIV_CMD_NOTE_OFF_ENV:
chan[c.chan].keyOff=true;

View file

@ -250,7 +250,7 @@ class DivPlatformYM2610Base: public DivPlatformOPN {
fm->set_fidelity(ymfm::OPN_FIDELITY_MED);
setFlags(flags);
// YM2149, 2MHz
ay=new DivPlatformAY8910(true,chipClock,32);
ay=new DivPlatformAY8910(true,chipClock,32,144);
ay->init(p,3,sugRate,ayFlags);
ay->toggleRegisterDump(true);
return 0;

View file

@ -76,7 +76,7 @@ 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])/2);
oscBuf[j]->data[oscBuf[j]->needle++]=(short)(((int)why[j*2][i]+why[j*2+1][i])/4);
}
buf[0][pos]=(short)(dataL/8);
buf[1][pos]=(short)(dataR/8);