From 1c3dcae05e9aa98e0ec6cded73578d4ddba62418 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Sat, 30 Apr 2022 18:33:12 -0500 Subject: [PATCH] per-channel oscilloscope, part 3 K00/C64/NES fixed FDS, Game Boy and Sound Unit --- src/engine/platform/bubsyswsg.cpp | 10 +++++++++- src/engine/platform/bubsyswsg.h | 1 + src/engine/platform/c64.cpp | 6 +++--- src/engine/platform/fds.cpp | 12 ++++++++++++ src/engine/platform/fds.h | 3 +++ src/engine/platform/gb.cpp | 17 +++++++++++++++-- src/engine/platform/gb.h | 2 ++ src/engine/platform/nes.cpp | 10 +++++----- src/engine/platform/sound/su.h | 6 ++++++ src/engine/platform/su.cpp | 14 ++++++++++++++ src/engine/platform/su.h | 2 ++ 11 files changed, 72 insertions(+), 11 deletions(-) diff --git a/src/engine/platform/bubsyswsg.cpp b/src/engine/platform/bubsyswsg.cpp index 2c09cf23d..b12a92ed4 100644 --- a/src/engine/platform/bubsyswsg.cpp +++ b/src/engine/platform/bubsyswsg.cpp @@ -63,10 +63,14 @@ void DivPlatformBubSysWSG::acquire(short* bufL, short* bufR, size_t start, size_ } else { chanOut=chan[i].waveROM[k005289->addr(i)]*(regPool[2+i]&0xf); out+=chanOut; - oscBuf[i]->data[oscBuf[i]->needle++]=chanOut; + if (writeOscBuf==0) { + oscBuf[i]->data[oscBuf[i]->needle++]=chanOut<<7; + } } } + if (++writeOscBuf>=64) writeOscBuf=0; + out<<=6; // scale output to 16 bit if (out<-32768) out=-32768; @@ -330,6 +334,9 @@ void DivPlatformBubSysWSG::notifyInsDeletion(void* ins) { void DivPlatformBubSysWSG::setFlags(unsigned int flags) { chipClock=COLOR_NTSC; rate=chipClock; + for (int i=0; i<2; i++) { + oscBuf[i]->rate=rate/64; + } } void DivPlatformBubSysWSG::poke(unsigned int addr, unsigned short val) { @@ -344,6 +351,7 @@ int DivPlatformBubSysWSG::init(DivEngine* p, int channels, int sugRate, unsigned parent=p; dumpWrites=false; skipRegisterWrites=false; + writeOscBuf=0; for (int i=0; i<2; i++) { isMuted[i]=false; oscBuf[i]=new DivDispatchOscBuffer; diff --git a/src/engine/platform/bubsyswsg.h b/src/engine/platform/bubsyswsg.h index 8eb6726fa..cb30d85c0 100644 --- a/src/engine/platform/bubsyswsg.h +++ b/src/engine/platform/bubsyswsg.h @@ -58,6 +58,7 @@ class DivPlatformBubSysWSG: public DivDispatch { Channel chan[2]; DivDispatchOscBuffer* oscBuf[2]; bool isMuted[2]; + unsigned char writeOscBuf; k005289_core* k005289; unsigned short regPool[4]; diff --git a/src/engine/platform/c64.cpp b/src/engine/platform/c64.cpp index 63f1b4709..c0efdd6f2 100644 --- a/src/engine/platform/c64.cpp +++ b/src/engine/platform/c64.cpp @@ -114,9 +114,9 @@ void DivPlatformC64::acquire(short* bufL, short* bufR, size_t start, size_t len) bufL[i]=sid.output(); if (++writeOscBuf>=8) { writeOscBuf=0; - oscBuf[0]->data[oscBuf[0]->needle++]=sid.last_chan_out[0]; - oscBuf[1]->data[oscBuf[1]->needle++]=sid.last_chan_out[1]; - oscBuf[2]->data[oscBuf[2]->needle++]=sid.last_chan_out[2]; + oscBuf[0]->data[oscBuf[0]->needle++]=sid.last_chan_out[0]>>5; + oscBuf[1]->data[oscBuf[1]->needle++]=sid.last_chan_out[1]>>5; + oscBuf[2]->data[oscBuf[2]->needle++]=sid.last_chan_out[2]>>5; } } } diff --git a/src/engine/platform/fds.cpp b/src/engine/platform/fds.cpp index f1e2bfdec..4c8e92b38 100644 --- a/src/engine/platform/fds.cpp +++ b/src/engine/platform/fds.cpp @@ -85,6 +85,10 @@ void DivPlatformFDS::acquire(short* bufL, short* bufR, size_t start, size_t len) if (sample>32767) sample=32767; if (sample<-32768) sample=-32768; bufL[i]=sample; + if (++writeOscBuf>=32) { + writeOscBuf=0; + oscBuf->data[oscBuf->needle++]=sample<<1; + } } } @@ -396,6 +400,10 @@ void* DivPlatformFDS::getChanState(int ch) { return &chan[ch]; } +DivDispatchOscBuffer* DivPlatformFDS::getOscBuffer(int ch) { + return oscBuf; +} + unsigned char* DivPlatformFDS::getRegisterPool() { return regPool; } @@ -436,6 +444,7 @@ void DivPlatformFDS::setFlags(unsigned int flags) { rate=COLOR_NTSC/2.0; } chipClock=rate; + oscBuf->rate=rate/32; } void DivPlatformFDS::notifyInsDeletion(void* ins) { @@ -457,7 +466,9 @@ int DivPlatformFDS::init(DivEngine* p, int channels, int sugRate, unsigned int f apuType=flags; dumpWrites=false; skipRegisterWrites=false; + writeOscBuf=0; fds=new struct _fds; + oscBuf=new DivDispatchOscBuffer; for (int i=0; i<1; i++) { isMuted[i]=false; } @@ -468,6 +479,7 @@ int DivPlatformFDS::init(DivEngine* p, int channels, int sugRate, unsigned int f } void DivPlatformFDS::quit() { + delete oscBuf; delete fds; } diff --git a/src/engine/platform/fds.h b/src/engine/platform/fds.h index ed0c77d72..c7c53aea2 100644 --- a/src/engine/platform/fds.h +++ b/src/engine/platform/fds.h @@ -64,9 +64,11 @@ class DivPlatformFDS: public DivDispatch { } }; Channel chan[1]; + DivDispatchOscBuffer* oscBuf; bool isMuted[1]; DivWaveSynth ws; unsigned char apuType; + unsigned char writeOscBuf; struct _fds* fds; unsigned char regPool[128]; @@ -78,6 +80,7 @@ class DivPlatformFDS: public DivDispatch { void acquire(short* bufL, short* bufR, size_t start, size_t len); int dispatch(DivCommand c); void* getChanState(int chan); + DivDispatchOscBuffer* getOscBuffer(int chan); unsigned char* getRegisterPool(); int getRegisterPoolSize(); void reset(); diff --git a/src/engine/platform/gb.cpp b/src/engine/platform/gb.cpp index e55e703ef..1fc2b278e 100644 --- a/src/engine/platform/gb.cpp +++ b/src/engine/platform/gb.cpp @@ -87,6 +87,10 @@ void DivPlatformGB::acquire(short* bufL, short* bufR, size_t start, size_t len) GB_advance_cycles(gb,16); bufL[i]=gb->apu_output.final_sample.left; bufR[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; + } } } @@ -429,6 +433,10 @@ void* DivPlatformGB::getChanState(int ch) { return &chan[ch]; } +DivDispatchOscBuffer* DivPlatformGB::getOscBuffer(int ch) { + return oscBuf[ch]; +} + unsigned char* DivPlatformGB::getRegisterPool() { return regPool; } @@ -495,20 +503,25 @@ void DivPlatformGB::poke(std::vector& wlist) { } int DivPlatformGB::init(DivEngine* p, int channels, int sugRate, unsigned int flags) { + chipClock=4194304; + rate=chipClock/16; for (int i=0; i<4; i++) { isMuted[i]=false; + oscBuf[i]=new DivDispatchOscBuffer; + oscBuf[i]->rate=rate; } parent=p; dumpWrites=false; skipRegisterWrites=false; - chipClock=4194304; - rate=chipClock/16; gb=new GB_gameboy_t; reset(); return 4; } void DivPlatformGB::quit() { + for (int i=0; i<4; i++) { + delete oscBuf[i]; + } delete gb; } diff --git a/src/engine/platform/gb.h b/src/engine/platform/gb.h index 2cdbc7858..cce1ffb6c 100644 --- a/src/engine/platform/gb.h +++ b/src/engine/platform/gb.h @@ -57,6 +57,7 @@ class DivPlatformGB: public DivDispatch { wave(-1) {} }; Channel chan[4]; + DivDispatchOscBuffer* oscBuf[4]; bool isMuted[4]; unsigned char lastPan; DivWaveSynth ws; @@ -71,6 +72,7 @@ class DivPlatformGB: public DivDispatch { void acquire(short* bufL, short* bufR, size_t start, size_t len); int dispatch(DivCommand c); void* getChanState(int chan); + DivDispatchOscBuffer* getOscBuffer(int chan); unsigned char* getRegisterPool(); int getRegisterPoolSize(); void reset(); diff --git a/src/engine/platform/nes.cpp b/src/engine/platform/nes.cpp index ca528d82a..7f35dc5bd 100644 --- a/src/engine/platform/nes.cpp +++ b/src/engine/platform/nes.cpp @@ -117,11 +117,11 @@ void DivPlatformNES::acquire(short* bufL, short* bufR, size_t start, size_t len) bufL[i]=sample; if (++writeOscBuf>=32) { writeOscBuf=0; - oscBuf[0]->data[oscBuf[0]->needle++]=nes->S1.output<<7; - oscBuf[1]->data[oscBuf[1]->needle++]=nes->S2.output<<7; - oscBuf[2]->data[oscBuf[2]->needle++]=nes->TR.output<<7; - oscBuf[3]->data[oscBuf[3]->needle++]=nes->NS.output<<7; - oscBuf[4]->data[oscBuf[4]->needle++]=nes->DMC.output<<7; + oscBuf[0]->data[oscBuf[0]->needle++]=nes->S1.output<<11; + oscBuf[1]->data[oscBuf[1]->needle++]=nes->S2.output<<11; + oscBuf[2]->data[oscBuf[2]->needle++]=nes->TR.output<<11; + oscBuf[3]->data[oscBuf[3]->needle++]=nes->NS.output<<11; + oscBuf[4]->data[oscBuf[4]->needle++]=nes->DMC.output<<8; } } } diff --git a/src/engine/platform/sound/su.h b/src/engine/platform/sound/su.h index 972d5343e..3152e8568 100644 --- a/src/engine/platform/sound/su.h +++ b/src/engine/platform/sound/su.h @@ -88,6 +88,12 @@ class SoundUnit { bool muted[8]; void Write(unsigned char addr, unsigned char data); void NextSample(short* l, short* r); + inline int GetSample(int ch) { + int ret=(nsL[ch]+nsR[ch])>>1; + if (ret<-32768) ret=-32768; + if (ret>32767) ret=32767; + return ret; + } void Init(); void Reset(); SoundUnit(); diff --git a/src/engine/platform/su.cpp b/src/engine/platform/su.cpp index 3a6003cb8..a75b7c0b8 100644 --- a/src/engine/platform/su.cpp +++ b/src/engine/platform/su.cpp @@ -99,6 +99,9 @@ void DivPlatformSoundUnit::acquire(short* bufL, short* bufR, size_t start, size_ writes.pop(); } su->NextSample(&bufL[h],&bufR[h]); + for (int i=0; i<8; i++) { + oscBuf[i]->data[oscBuf[i]->needle++]=su->GetSample(i); + } } } @@ -313,6 +316,10 @@ void* DivPlatformSoundUnit::getChanState(int ch) { return &chan[ch]; } +DivDispatchOscBuffer* DivPlatformSoundUnit::getOscBuffer(int ch) { + return oscBuf[ch]; +} + unsigned char* DivPlatformSoundUnit::getRegisterPool() { return (unsigned char*)su->chan; } @@ -365,6 +372,9 @@ void DivPlatformSoundUnit::setFlags(unsigned int flags) { chipClock=1236000; } rate=chipClock/4; + for (int i=0; i<8; i++) { + oscBuf[i]->rate=rate; + } } void DivPlatformSoundUnit::poke(unsigned int addr, unsigned short val) { @@ -381,6 +391,7 @@ int DivPlatformSoundUnit::init(DivEngine* p, int channels, int sugRate, unsigned skipRegisterWrites=false; for (int i=0; i<8; i++) { isMuted[i]=false; + oscBuf[i]=new DivDispatchOscBuffer; } setFlags(flags); su=new SoundUnit(); @@ -390,6 +401,9 @@ int DivPlatformSoundUnit::init(DivEngine* p, int channels, int sugRate, unsigned } void DivPlatformSoundUnit::quit() { + for (int i=0; i<8; i++) { + delete oscBuf[i]; + } delete su; } diff --git a/src/engine/platform/su.h b/src/engine/platform/su.h index 7315f49a3..7ff3e8709 100644 --- a/src/engine/platform/su.h +++ b/src/engine/platform/su.h @@ -71,6 +71,7 @@ class DivPlatformSoundUnit: public DivDispatch { wave(0) {} }; Channel chan[8]; + DivDispatchOscBuffer* oscBuf[8]; bool isMuted[8]; struct QueuedWrite { unsigned char addr; @@ -94,6 +95,7 @@ class DivPlatformSoundUnit: public DivDispatch { void acquire(short* bufL, short* bufR, size_t start, size_t len); int dispatch(DivCommand c); void* getChanState(int chan); + DivDispatchOscBuffer* getOscBuffer(int chan); unsigned char* getRegisterPool(); int getRegisterPoolSize(); void reset();