From 6efcfc2e8ab812b926f425796dbc57aa6d0a3565 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Mon, 6 Dec 2021 05:21:42 -0500 Subject: [PATCH 1/2] prepare for possible major optimization by just forwarding an output buffer to the dispatch and begin/length, the number of calls may be reduced which improves performance. --- src/engine/dispatch.h | 4 +- src/engine/engine.cpp | 4 ++ src/engine/engine.h | 3 ++ src/engine/platform/abstract.cpp | 4 +- src/engine/platform/c64.cpp | 10 ++-- src/engine/platform/c64.h | 2 +- src/engine/platform/dummy.cpp | 17 ++++--- src/engine/platform/dummy.h | 2 +- src/engine/platform/gb.cpp | 10 ++-- src/engine/platform/gb.h | 2 +- src/engine/platform/genesis.cpp | 87 ++++++++++++++++---------------- src/engine/platform/genesis.h | 2 +- src/engine/platform/nes.cpp | 46 +++++++++-------- src/engine/platform/nes.h | 2 +- src/engine/platform/pce.cpp | 64 +++++++++++------------ src/engine/platform/pce.h | 2 +- src/engine/platform/sms.cpp | 10 ++-- src/engine/platform/sms.h | 3 +- src/engine/playback.cpp | 36 ++++++++++--- 19 files changed, 178 insertions(+), 132 deletions(-) diff --git a/src/engine/dispatch.h b/src/engine/dispatch.h index 12831b5fb..127ffc18c 100644 --- a/src/engine/dispatch.h +++ b/src/engine/dispatch.h @@ -1,6 +1,8 @@ #ifndef _DISPATCH_H #define _DISPATCH_H +#include + #define ONE_SEMITONE 2200 enum DivDispatchCmds { @@ -83,7 +85,7 @@ class DivDispatch { * the engine shall resample to the output rate. */ int rate; - virtual void acquire(int& l, int& r); + virtual void acquire(short** buf, size_t start, size_t len); virtual int dispatch(DivCommand c); virtual void tick(); diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp index 360d5d5b6..6d663664e 100644 --- a/src/engine/engine.cpp +++ b/src/engine/engine.cpp @@ -738,6 +738,10 @@ bool DivEngine::init() { bbOut[0]=new short[got.bufsize]; bbOut[1]=new short[got.bufsize]; + bbIn[0]=new short[32768]; + bbIn[1]=new short[32768]; + bbInLen=32768; + for (int i=0; i<64; i++) { vibTable[i]=127*sin(((double)i/64.0)*(2*M_PI)); } diff --git a/src/engine/engine.h b/src/engine/engine.h index 47c17ff62..79f0d948d 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -67,7 +67,9 @@ class DivEngine { short vibTable[64]; blip_buffer_t* bb[2]; + size_t bbInLen; int temp[2], prevSample[2]; + short* bbIn[2]; short* bbOut[2]; int dispatchCmd(DivCommand c); @@ -117,6 +119,7 @@ class DivEngine { cmdsPerSecond(0), view(DIV_STATUS_PATTERN), audioEngine(DIV_AUDIO_SDL), + bbInLen(0), temp{0,0}, prevSample{0,0} {} }; diff --git a/src/engine/platform/abstract.cpp b/src/engine/platform/abstract.cpp index 344e1c230..52a100756 100644 --- a/src/engine/platform/abstract.cpp +++ b/src/engine/platform/abstract.cpp @@ -1,8 +1,6 @@ #include "../dispatch.h" -void DivDispatch::acquire(int& l, int& r) { - l=0; - r=0; +void DivDispatch::acquire(short** buf, size_t start, size_t len) { } void DivDispatch::tick() { diff --git a/src/engine/platform/c64.cpp b/src/engine/platform/c64.cpp index f5052f0cc..11fb8cb63 100644 --- a/src/engine/platform/c64.cpp +++ b/src/engine/platform/c64.cpp @@ -4,10 +4,12 @@ #define FREQ_BASE 277.0f -void DivPlatformC64::acquire(int& l, int& r) { - sid.clock(); - l=sid.output(); - r=l; +void DivPlatformC64::acquire(short** buf, size_t start, size_t len) { + for (size_t i=start; i #include -void DivPlatformDummy::acquire(int& l, int& r) { - l=0; - for (unsigned char i=0; i=0x8000)?chan[i].vol:-chan[i].vol)*chan[i].amp; - - chan[i].pos+=chan[i].freq; +void DivPlatformDummy::acquire(short** buf, size_t start, size_t len) { + for (size_t i=start; i=0x8000)?chan[j].vol:-chan[j].vol)*chan[j].amp; + chan[j].pos+=chan[j].freq; + } } + buf[1][i]=buf[0][i]; } - r=l; } void DivPlatformDummy::tick() { diff --git a/src/engine/platform/dummy.h b/src/engine/platform/dummy.h index 333389d90..f220e35a5 100644 --- a/src/engine/platform/dummy.h +++ b/src/engine/platform/dummy.h @@ -15,7 +15,7 @@ class DivPlatformDummy: public DivDispatch { Channel chan[17]; unsigned char chans; public: - void acquire(int& l, int& r); + void acquire(short** buf, size_t start, size_t len); int dispatch(DivCommand c); void tick(); int init(DivEngine* parent, int channels, int sugRate); diff --git a/src/engine/platform/gb.cpp b/src/engine/platform/gb.cpp index 36e234f52..90385cd24 100644 --- a/src/engine/platform/gb.cpp +++ b/src/engine/platform/gb.cpp @@ -7,10 +7,12 @@ #define FREQ_BASE 8015.85f -void DivPlatformGB::acquire(int& l, int& r) { - GB_advance_cycles(gb,16); - l=gb->apu_output.final_sample.left<<2; - r=gb->apu_output.final_sample.right<<2; +void DivPlatformGB::acquire(short** buf, size_t start, size_t len) { + for (int i=start; iapu_output.final_sample.left<<2; + buf[1][i]=gb->apu_output.final_sample.right<<2; + } } void DivPlatformGB::updateWave() { diff --git a/src/engine/platform/gb.h b/src/engine/platform/gb.h index 404017d44..19e4f519d 100644 --- a/src/engine/platform/gb.h +++ b/src/engine/platform/gb.h @@ -36,7 +36,7 @@ class DivPlatformGB: public DivDispatch { GB_gameboy_t* gb; void updateWave(); public: - void acquire(int& l, int& r); + void acquire(short** buf, size_t start, size_t len); int dispatch(DivCommand c); void tick(); int init(DivEngine* parent, int channels, int sugRate); diff --git a/src/engine/platform/genesis.cpp b/src/engine/platform/genesis.cpp index 7bbad5c20..6aa1b0862 100644 --- a/src/engine/platform/genesis.cpp +++ b/src/engine/platform/genesis.cpp @@ -12,59 +12,60 @@ static unsigned char konOffs[6]={ 0, 1, 2, 4, 5, 6 }; -void DivPlatformGenesis::acquire(int& l, int& r) { +void DivPlatformGenesis::acquire(short** buf, size_t start, size_t len) { static short o[2]; static int os[2]; - if (dacMode && dacSample!=-1) { - dacPeriod-=6; - if (dacPeriod<1) { - DivSample* s=parent->song.sample[dacSample]; - if (s->depth==8) { - writes.emplace(0x2a,(unsigned char)s->rendData[dacPos++]+0x80); - } else { - writes.emplace(0x2a,((unsigned short)s->rendData[dacPos++]+0x8000)>>8); + for (size_t h=start; hsong.sample[dacSample]; + if (s->depth==8) { + writes.emplace(0x2a,(unsigned char)s->rendData[dacPos++]+0x80); + } else { + writes.emplace(0x2a,((unsigned short)s->rendData[dacPos++]+0x8000)>>8); + } + if (dacPos>=s->rendLength) { + dacSample=-1; + } + dacPeriod+=dacRate; } - if (dacPos>=s->rendLength) { - dacSample=-1; - } - dacPeriod+=dacRate; } - } - - os[0]=0; os[1]=0; - for (int i=0; i<6; i++) { - if (!writes.empty() && --delay<0) { - delay=0; - QueuedWrite& w=writes.front(); - if (w.addrOrVal) { - OPN2_Write(&fm,0x1+((w.addr>>8)<<1),w.val); - //printf("write: %x = %.2x\n",w.addr,w.val); - lastBusy=0; - writes.pop(); - } else { - lastBusy++; - if (fm.write_busy==0) { - //printf("busycounter: %d\n",lastBusy); - OPN2_Write(&fm,0x0+((w.addr>>8)<<1),w.addr); - w.addrOrVal=true; + + os[0]=0; os[1]=0; + for (int i=0; i<6; i++) { + if (!writes.empty() && --delay<0) { + delay=0; + QueuedWrite& w=writes.front(); + if (w.addrOrVal) { + OPN2_Write(&fm,0x1+((w.addr>>8)<<1),w.val); + //printf("write: %x = %.2x\n",w.addr,w.val); + lastBusy=0; + writes.pop(); + } else { + lastBusy++; + if (fm.write_busy==0) { + //printf("busycounter: %d\n",lastBusy); + OPN2_Write(&fm,0x0+((w.addr>>8)<<1),w.addr); + w.addrOrVal=true; + } } } - } + + OPN2_Clock(&fm,o); os[0]+=o[0]; os[1]+=o[1]; + //OPN2_Write(&fm,0,0); + } - OPN2_Clock(&fm,o); os[0]+=o[0]; os[1]+=o[1]; - //OPN2_Write(&fm,0,0); - } + psgClocks+=223722; + while (psgClocks>=rate) { + psgOut=(psg.acquireOne()*3)>>3; + psgClocks-=rate; + } - psgClocks+=223722; - while (psgClocks>=rate) { - psg.acquire(psgOut,psgOut); - psgClocks-=rate; - psgOut=(psgOut>>2)+(psgOut>>3); + buf[0][h]=(os[0]<<5)+psgOut; + buf[1][h]=(os[1]<<5)+psgOut; } - - l=(os[0]<<5)+psgOut; - r=(os[1]<<5)+psgOut; } void DivPlatformGenesis::tick() { diff --git a/src/engine/platform/genesis.h b/src/engine/platform/genesis.h index 62dfcc58f..522c002fb 100644 --- a/src/engine/platform/genesis.h +++ b/src/engine/platform/genesis.h @@ -48,7 +48,7 @@ class DivPlatformGenesis: public DivDispatch { int toFreq(int freq); public: - void acquire(int& l, int& r); + void acquire(short** buf, size_t start, size_t len); int dispatch(DivCommand c); void tick(); int init(DivEngine* parent, int channels, int sugRate); diff --git a/src/engine/platform/nes.cpp b/src/engine/platform/nes.cpp index 504a6f98b..185d48ae0 100644 --- a/src/engine/platform/nes.cpp +++ b/src/engine/platform/nes.cpp @@ -5,30 +5,32 @@ #define FREQ_BASE 3424.0f -void DivPlatformNES::acquire(int& l, int& r) { - if (dacSample!=-1) { - dacPeriod+=dacRate; - if (dacPeriod>=rate) { - DivSample* s=parent->song.sample[dacSample]; - if (s->depth==8) { - apu_wr_reg(0x4011,((unsigned char)s->rendData[dacPos++]+0x80)>>1); - } else { - apu_wr_reg(0x4011,((unsigned short)s->rendData[dacPos++]+0x8000)>>9); +void DivPlatformNES::acquire(short** buf, size_t start, size_t len) { + for (size_t i=start; i=rate) { + DivSample* s=parent->song.sample[dacSample]; + if (s->depth==8) { + apu_wr_reg(0x4011,((unsigned char)s->rendData[dacPos++]+0x80)>>1); + } else { + apu_wr_reg(0x4011,((unsigned short)s->rendData[dacPos++]+0x8000)>>9); + } + if (dacPos>=s->rendLength) { + dacSample=-1; + } + dacPeriod-=rate; } - if (dacPos>=s->rendLength) { - dacSample=-1; - } - dacPeriod-=rate; } - } - - apu_tick(NULL); - apu.odd_cycle=!apu.odd_cycle; - if (apu.clocked) { - apu.clocked=false; - l=(pulse_output()+tnd_output())*30; - r=l; - //printf("output value: %d\n",l); + + apu_tick(NULL); + apu.odd_cycle=!apu.odd_cycle; + if (apu.clocked) { + apu.clocked=false; + buf[0][i]=(pulse_output()+tnd_output())*30; + buf[1][i]=buf[0][i]; + //printf("output value: %d\n",l); + } } } diff --git a/src/engine/platform/nes.h b/src/engine/platform/nes.h index eacfc21ea..2e1859ac4 100644 --- a/src/engine/platform/nes.h +++ b/src/engine/platform/nes.h @@ -36,7 +36,7 @@ class DivPlatformNES: public DivDispatch { void updateWave(); public: - void acquire(int& l, int& r); + void acquire(short** buf, size_t start, size_t len); int dispatch(DivCommand c); void tick(); int init(DivEngine* parent, int channels, int sugRate); diff --git a/src/engine/platform/pce.cpp b/src/engine/platform/pce.cpp index 57db7b5d0..ff6f7c602 100644 --- a/src/engine/platform/pce.cpp +++ b/src/engine/platform/pce.cpp @@ -13,41 +13,43 @@ #define FREQ_BASE 1712.0f*2 -void DivPlatformPCE::acquire(int& l, int& r) { - // PCM part - for (int i=0; i<6; i++) { - if (chan[i].pcm && chan[i].dacSample!=-1) { - if (--chan[i].dacPeriod<1) { - DivSample* s=parent->song.sample[chan[i].dacSample]; - chWrite(i,0x07,0); - if (s->depth==8) { - chWrite(i,0x04,0xdf); - chWrite(i,0x06,(((unsigned char)s->rendData[chan[i].dacPos++]+0x80)>>3)); - } else { - chWrite(i,0x04,0xdf); - chWrite(i,0x06,(((unsigned short)s->rendData[chan[i].dacPos++]+0x8000)>>11)); +void DivPlatformPCE::acquire(short** buf, size_t start, size_t len) { + for (size_t h=start; hsong.sample[chan[i].dacSample]; + chWrite(i,0x07,0); + if (s->depth==8) { + chWrite(i,0x04,0xdf); + chWrite(i,0x06,(((unsigned char)s->rendData[chan[i].dacPos++]+0x80)>>3)); + } else { + chWrite(i,0x04,0xdf); + chWrite(i,0x06,(((unsigned short)s->rendData[chan[i].dacPos++]+0x8000)>>11)); + } + if (chan[i].dacPos>=s->rendLength) { + chan[i].dacSample=-1; + } + chan[i].dacPeriod=chan[i].dacRate; } - if (chan[i].dacPos>=s->rendLength) { - chan[i].dacSample=-1; - } - chan[i].dacPeriod=chan[i].dacRate; } } - } - - // PCE part - while (!writes.empty()) { - QueuedWrite w=writes.front(); - pce->Write(cycles,w.addr,w.val); - writes.pop(); - } - tempL=0; tempR=0; - pce->Update(4); - pce->ResetTS(0); - //printf("tempL: %d tempR: %d\n",tempL,tempR); - l=tempL; - r=tempR; + // PCE part + while (!writes.empty()) { + QueuedWrite w=writes.front(); + pce->Write(cycles,w.addr,w.val); + writes.pop(); + } + tempL=0; tempR=0; + pce->Update(4); + pce->ResetTS(0); + + //printf("tempL: %d tempR: %d\n",tempL,tempR); + buf[0][h]=tempL; + buf[1][h]=tempR; + } } void DivPlatformPCE::updateWave(int ch) { diff --git a/src/engine/platform/pce.h b/src/engine/platform/pce.h index 689c04955..2775dc0bb 100644 --- a/src/engine/platform/pce.h +++ b/src/engine/platform/pce.h @@ -50,7 +50,7 @@ class DivPlatformPCE: public DivDispatch { PCE_PSG* pce; void updateWave(int ch); public: - void acquire(int& l, int& r); + void acquire(short** buf, size_t start, size_t len); int dispatch(DivCommand c); void tick(); int init(DivEngine* parent, int channels, int sugRate); diff --git a/src/engine/platform/sms.cpp b/src/engine/platform/sms.cpp index b88415229..99cc2a89f 100644 --- a/src/engine/platform/sms.cpp +++ b/src/engine/platform/sms.cpp @@ -2,11 +2,15 @@ #include "../engine.h" #include -void DivPlatformSMS::acquire(int& l, int& r) { +void DivPlatformSMS::acquire(short** buf, size_t start, size_t len) { + sn->sound_stream_update(buf[0]+start,len); + memcpy(buf[1]+start,buf[0]+start,sizeof(short)*len); +} + +int DivPlatformSMS::acquireOne() { short v; sn->sound_stream_update(&v,1); - l=v; - r=v; + return v; } void DivPlatformSMS::tick() { diff --git a/src/engine/platform/sms.h b/src/engine/platform/sms.h index c6e6f261e..a390ca909 100644 --- a/src/engine/platform/sms.h +++ b/src/engine/platform/sms.h @@ -30,7 +30,8 @@ class DivPlatformSMS: public DivDispatch { bool updateSNMode; sn76496_device* sn; public: - void acquire(int& l, int& r); + int acquireOne(); + void acquire(short** buf, size_t start, size_t len); int dispatch(DivCommand c); void tick(); int init(DivEngine* parent, int channels, int sugRate); diff --git a/src/engine/playback.cpp b/src/engine/playback.cpp index 33bf419b6..d98339b13 100644 --- a/src/engine/playback.cpp +++ b/src/engine/playback.cpp @@ -604,15 +604,39 @@ void DivEngine::nextTick() { void DivEngine::nextBuf(float** in, float** out, int inChans, int outChans, unsigned int size) { size_t runtotal=blip_clocks_needed(bb[0],size); - for (size_t i=0; iacquire(temp[0],temp[1]); + if (runtotal>bbInLen) { + delete bbIn[0]; + delete bbIn[1]; + bbIn[0]=new short[runtotal+256]; + bbIn[1]=new short[runtotal+256]; + bbInLen=runtotal+256; + } + + size_t runLeft=runtotal; + size_t runPos=0; + while (runLeft) { + if (runLeft>=cycles) { + runLeft-=cycles; + dispatch->acquire(bbIn,runPos,cycles); + runPos+=cycles; + nextTick(); + } else { + dispatch->acquire(bbIn,runPos,runLeft); + cycles-=runLeft; + break; + } + } + + for (size_t i=0; i Date: Mon, 6 Dec 2021 16:51:18 -0500 Subject: [PATCH 2/2] more optimization as of now non-stereo sound chips are only processed once --- src/engine/dispatch.h | 4 +++- src/engine/platform/abstract.cpp | 6 +++++- src/engine/platform/c64.cpp | 5 ++--- src/engine/platform/c64.h | 2 +- src/engine/platform/dummy.cpp | 7 +++---- src/engine/platform/dummy.h | 2 +- src/engine/platform/gb.cpp | 10 +++++++--- src/engine/platform/gb.h | 3 ++- src/engine/platform/genesis.cpp | 10 +++++++--- src/engine/platform/genesis.h | 3 ++- src/engine/platform/nes.cpp | 6 ++---- src/engine/platform/nes.h | 2 +- src/engine/platform/pce.cpp | 10 +++++++--- src/engine/platform/pce.h | 3 ++- src/engine/platform/sms.cpp | 5 ++--- src/engine/platform/sms.h | 2 +- src/engine/playback.cpp | 27 ++++++++++++++++++--------- 17 files changed, 66 insertions(+), 41 deletions(-) diff --git a/src/engine/dispatch.h b/src/engine/dispatch.h index 127ffc18c..abfe370a7 100644 --- a/src/engine/dispatch.h +++ b/src/engine/dispatch.h @@ -85,10 +85,12 @@ class DivDispatch { * the engine shall resample to the output rate. */ int rate; - virtual void acquire(short** buf, size_t start, size_t len); + virtual void acquire(short* bufL, short* bufR, size_t start, size_t len); virtual int dispatch(DivCommand c); virtual void tick(); + virtual bool isStereo(); + /** * initialize this DivDispatch. * @param parent the parent DivEngine. diff --git a/src/engine/platform/abstract.cpp b/src/engine/platform/abstract.cpp index 52a100756..4086edb00 100644 --- a/src/engine/platform/abstract.cpp +++ b/src/engine/platform/abstract.cpp @@ -1,6 +1,6 @@ #include "../dispatch.h" -void DivDispatch::acquire(short** buf, size_t start, size_t len) { +void DivDispatch::acquire(short* bufL, short* bufR, size_t start, size_t len) { } void DivDispatch::tick() { @@ -10,6 +10,10 @@ int DivDispatch::dispatch(DivCommand c) { return 1; } +bool DivDispatch::isStereo() { + return false; +} + int DivDispatch::init(DivEngine* p, int channels, int sugRate) { return 0; } diff --git a/src/engine/platform/c64.cpp b/src/engine/platform/c64.cpp index 11fb8cb63..b7c4e9dbc 100644 --- a/src/engine/platform/c64.cpp +++ b/src/engine/platform/c64.cpp @@ -4,11 +4,10 @@ #define FREQ_BASE 277.0f -void DivPlatformC64::acquire(short** buf, size_t start, size_t len) { +void DivPlatformC64::acquire(short* bufL, short* bufR, size_t start, size_t len) { for (size_t i=start; i #include -void DivPlatformDummy::acquire(short** buf, size_t start, size_t len) { +void DivPlatformDummy::acquire(short* bufL, short* bufR, size_t start, size_t len) { for (size_t i=start; i=0x8000)?chan[j].vol:-chan[j].vol)*chan[j].amp; + bufL[i]+=((chan[j].pos>=0x8000)?chan[j].vol:-chan[j].vol)*chan[j].amp; chan[j].pos+=chan[j].freq; } } - buf[1][i]=buf[0][i]; } } diff --git a/src/engine/platform/dummy.h b/src/engine/platform/dummy.h index f220e35a5..626a502d7 100644 --- a/src/engine/platform/dummy.h +++ b/src/engine/platform/dummy.h @@ -15,7 +15,7 @@ class DivPlatformDummy: public DivDispatch { Channel chan[17]; unsigned char chans; public: - void acquire(short** buf, size_t start, size_t len); + void acquire(short* bufL, short* bufR, size_t start, size_t len); int dispatch(DivCommand c); void tick(); int init(DivEngine* parent, int channels, int sugRate); diff --git a/src/engine/platform/gb.cpp b/src/engine/platform/gb.cpp index 90385cd24..331e31cbe 100644 --- a/src/engine/platform/gb.cpp +++ b/src/engine/platform/gb.cpp @@ -7,11 +7,11 @@ #define FREQ_BASE 8015.85f -void DivPlatformGB::acquire(short** buf, size_t start, size_t len) { +void DivPlatformGB::acquire(short* bufL, short* bufR, size_t start, size_t len) { for (int i=start; iapu_output.final_sample.left<<2; - buf[1][i]=gb->apu_output.final_sample.right<<2; + bufL[i]=gb->apu_output.final_sample.left<<2; + bufR[i]=gb->apu_output.final_sample.right<<2; } } @@ -270,6 +270,10 @@ int DivPlatformGB::dispatch(DivCommand c) { return 1; } +bool DivPlatformGB::isStereo() { + return true; +} + int DivPlatformGB::init(DivEngine* p, int channels, int sugRate) { parent=p; rate=262144; diff --git a/src/engine/platform/gb.h b/src/engine/platform/gb.h index 19e4f519d..aab8fe481 100644 --- a/src/engine/platform/gb.h +++ b/src/engine/platform/gb.h @@ -36,9 +36,10 @@ class DivPlatformGB: public DivDispatch { GB_gameboy_t* gb; void updateWave(); public: - void acquire(short** buf, size_t start, size_t len); + void acquire(short* bufL, short* bufR, size_t start, size_t len); int dispatch(DivCommand c); void tick(); + bool isStereo(); int init(DivEngine* parent, int channels, int sugRate); }; diff --git a/src/engine/platform/genesis.cpp b/src/engine/platform/genesis.cpp index 6aa1b0862..5321303c6 100644 --- a/src/engine/platform/genesis.cpp +++ b/src/engine/platform/genesis.cpp @@ -12,7 +12,7 @@ static unsigned char konOffs[6]={ 0, 1, 2, 4, 5, 6 }; -void DivPlatformGenesis::acquire(short** buf, size_t start, size_t len) { +void DivPlatformGenesis::acquire(short* bufL, short* bufR, size_t start, size_t len) { static short o[2]; static int os[2]; @@ -63,8 +63,8 @@ void DivPlatformGenesis::acquire(short** buf, size_t start, size_t len) { psgClocks-=rate; } - buf[0][h]=(os[0]<<5)+psgOut; - buf[1][h]=(os[1]<<5)+psgOut; + bufL[h]=(os[0]<<5)+psgOut; + bufR[h]=(os[1]<<5)+psgOut; } } @@ -340,6 +340,10 @@ int DivPlatformGenesis::dispatch(DivCommand c) { return 1; } +bool DivPlatformGenesis::isStereo() { + return true; +} + int DivPlatformGenesis::init(DivEngine* p, int channels, int sugRate) { parent=p; rate=213068; diff --git a/src/engine/platform/genesis.h b/src/engine/platform/genesis.h index 522c002fb..c4292d47a 100644 --- a/src/engine/platform/genesis.h +++ b/src/engine/platform/genesis.h @@ -48,9 +48,10 @@ class DivPlatformGenesis: public DivDispatch { int toFreq(int freq); public: - void acquire(short** buf, size_t start, size_t len); + void acquire(short* bufL, short* bufR, size_t start, size_t len); int dispatch(DivCommand c); void tick(); + bool isStereo(); int init(DivEngine* parent, int channels, int sugRate); }; #endif diff --git a/src/engine/platform/nes.cpp b/src/engine/platform/nes.cpp index 185d48ae0..1a256fe4e 100644 --- a/src/engine/platform/nes.cpp +++ b/src/engine/platform/nes.cpp @@ -5,7 +5,7 @@ #define FREQ_BASE 3424.0f -void DivPlatformNES::acquire(short** buf, size_t start, size_t len) { +void DivPlatformNES::acquire(short* bufL, short* bufR, size_t start, size_t len) { for (size_t i=start; iResetTS(0); //printf("tempL: %d tempR: %d\n",tempL,tempR); - buf[0][h]=tempL; - buf[1][h]=tempR; + bufL[h]=tempL; + bufR[h]=tempR; } } @@ -250,6 +250,10 @@ int DivPlatformPCE::dispatch(DivCommand c) { return 1; } +bool DivPlatformPCE::isStereo() { + return true; +} + int DivPlatformPCE::init(DivEngine* p, int channels, int sugRate) { parent=p; rate=1789773; diff --git a/src/engine/platform/pce.h b/src/engine/platform/pce.h index 2775dc0bb..8ed9d8a7a 100644 --- a/src/engine/platform/pce.h +++ b/src/engine/platform/pce.h @@ -50,9 +50,10 @@ class DivPlatformPCE: public DivDispatch { PCE_PSG* pce; void updateWave(int ch); public: - void acquire(short** buf, size_t start, size_t len); + void acquire(short* bufL, short* bufR, size_t start, size_t len); int dispatch(DivCommand c); void tick(); + bool isStereo(); int init(DivEngine* parent, int channels, int sugRate); }; diff --git a/src/engine/platform/sms.cpp b/src/engine/platform/sms.cpp index 99cc2a89f..6abbbc20c 100644 --- a/src/engine/platform/sms.cpp +++ b/src/engine/platform/sms.cpp @@ -2,9 +2,8 @@ #include "../engine.h" #include -void DivPlatformSMS::acquire(short** buf, size_t start, size_t len) { - sn->sound_stream_update(buf[0]+start,len); - memcpy(buf[1]+start,buf[0]+start,sizeof(short)*len); +void DivPlatformSMS::acquire(short* bufL, short* bufR, size_t start, size_t len) { + sn->sound_stream_update(bufL+start,len); } int DivPlatformSMS::acquireOne() { diff --git a/src/engine/platform/sms.h b/src/engine/platform/sms.h index a390ca909..33d4a9c40 100644 --- a/src/engine/platform/sms.h +++ b/src/engine/platform/sms.h @@ -31,7 +31,7 @@ class DivPlatformSMS: public DivDispatch { sn76496_device* sn; public: int acquireOne(); - void acquire(short** buf, size_t start, size_t len); + void acquire(short* bufL, short* bufR, size_t start, size_t len); int dispatch(DivCommand c); void tick(); int init(DivEngine* parent, int channels, int sugRate); diff --git a/src/engine/playback.cpp b/src/engine/playback.cpp index d98339b13..a60320cf7 100644 --- a/src/engine/playback.cpp +++ b/src/engine/playback.cpp @@ -618,11 +618,11 @@ void DivEngine::nextBuf(float** in, float** out, int inChans, int outChans, unsi while (runLeft) { if (runLeft>=cycles) { runLeft-=cycles; - dispatch->acquire(bbIn,runPos,cycles); + dispatch->acquire(bbIn[0],bbIn[1],runPos,cycles); runPos+=cycles; nextTick(); } else { - dispatch->acquire(bbIn,runPos,runLeft); + dispatch->acquire(bbIn[0],bbIn[1],runPos,runLeft); cycles-=runLeft; break; } @@ -634,20 +634,29 @@ void DivEngine::nextBuf(float** in, float** out, int inChans, int outChans, unsi prevSample[0]=temp[0]; } - for (size_t i=0; iisStereo()) for (size_t i=0; iisStereo()) { + blip_end_frame(bb[1],runtotal); + blip_read_samples(bb[1],bbOut[1],size,0); + } + + if (dispatch->isStereo()) { + for (size_t i=0; i