diff --git a/extern/vgsound_emu-modified/vgsound_emu/src/vrcvi/vrcvi.cpp b/extern/vgsound_emu-modified/vgsound_emu/src/vrcvi/vrcvi.cpp index 77ac0c31e..19527d3f5 100644 --- a/extern/vgsound_emu-modified/vgsound_emu/src/vrcvi/vrcvi.cpp +++ b/extern/vgsound_emu-modified/vgsound_emu/src/vrcvi/vrcvi.cpp @@ -8,15 +8,27 @@ #include "vrcvi.hpp" -void vrcvi_core::tick() +int vrcvi_core::predict() { + const int p0=m_pulse[0].predict(); + const int p1=m_pulse[1].predict(); + const int s=m_sawtooth.predict(); + + int ret=p0; + if (p1 m_control.m_duty) ? true : false); } -bool vrcvi_core::sawtooth_t::tick() +bool vrcvi_core::sawtooth_t::tick(int cycles) { if (!m_divider.m_enable) { return false; } - if (vrcvi_core::alu_t::tick()) + if (vrcvi_core::alu_t::tick(cycles)) { if ((m_cycle++)&1) { // Even step only @@ -109,23 +132,24 @@ bool vrcvi_core::sawtooth_t::tick() return (m_accum != 0); } -s8 vrcvi_core::pulse_t::get_output() +s8 vrcvi_core::pulse_t::get_output(int cycles) { // add 4 bit pulse output - m_out = tick() ? m_control.m_volume : 0; + m_out = tick(cycles) ? m_control.m_volume : 0; return m_out; } -s8 vrcvi_core::sawtooth_t::get_output() +s8 vrcvi_core::sawtooth_t::get_output(int cycles) { // add 5 bit sawtooth output - m_out = tick() ? ((m_accum>>3)&31) : 0; + m_out = tick(cycles) ? ((m_accum>>3)&31) : 0; return m_out; } void vrcvi_core::alu_t::reset() { m_divider.reset(); + m_divider.m_divider = 1023; m_counter = 0; m_cycle = 0; m_out = 0; @@ -135,6 +159,7 @@ void vrcvi_core::pulse_t::reset() { vrcvi_core::alu_t::reset(); m_control.reset(); + m_divider.m_divider = 1023; } void vrcvi_core::sawtooth_t::reset() @@ -142,6 +167,7 @@ void vrcvi_core::sawtooth_t::reset() vrcvi_core::alu_t::reset(); m_rate = 0; m_accum = 0; + m_divider.m_divider = 1023; } bool vrcvi_core::timer_t::tick() diff --git a/extern/vgsound_emu-modified/vgsound_emu/src/vrcvi/vrcvi.hpp b/extern/vgsound_emu-modified/vgsound_emu/src/vrcvi/vrcvi.hpp index 71dacd5a0..be4d2e82d 100644 --- a/extern/vgsound_emu-modified/vgsound_emu/src/vrcvi/vrcvi.hpp +++ b/extern/vgsound_emu-modified/vgsound_emu/src/vrcvi/vrcvi.hpp @@ -47,7 +47,7 @@ class vrcvi_core : public vgsound_emu_core void reset() { - m_divider = 0; + m_divider = 1023; m_enable = 0; } @@ -75,9 +75,10 @@ class vrcvi_core : public vgsound_emu_core } virtual void reset(); - virtual bool tick(); + virtual bool tick(int cycles); + virtual int predict(); - virtual s8 get_output() + virtual s8 get_output(int cycles) { m_out = 0; return 0; @@ -155,8 +156,8 @@ class vrcvi_core : public vgsound_emu_core } virtual void reset() override; - virtual bool tick() override; - virtual s8 get_output() override; + virtual bool tick(int cycles) override; + virtual s8 get_output(int cycles) override; // getters pulse_control_t &control() { return m_control; } @@ -177,8 +178,8 @@ class vrcvi_core : public vgsound_emu_core } virtual void reset() override; - virtual bool tick() override; - virtual s8 get_output() override; + virtual bool tick(int cycles) override; + virtual s8 get_output(int cycles) override; // accessors inline void clear_accum() { m_accum = 0; } @@ -385,7 +386,8 @@ class vrcvi_core : public vgsound_emu_core // internal state void reset(); - void tick(); + int predict(); + void tick(int cycles=1); // 6 bit output inline s8 out() { return m_out; } diff --git a/src/engine/platform/vrc6.cpp b/src/engine/platform/vrc6.cpp index a6fe57734..3bf54dfa0 100644 --- a/src/engine/platform/vrc6.cpp +++ b/src/engine/platform/vrc6.cpp @@ -46,16 +46,28 @@ const char** DivPlatformVRC6::getRegisterSheet() { return regCheatSheetVRC6; } -void DivPlatformVRC6::acquire(short** buf, size_t len) { +void DivPlatformVRC6::acquireDirect(blip_buffer_t** bb, size_t len) { for (int i=0; i<3; i++) { oscBuf[i]->begin(len); } for (size_t h=0; hrate) { DivSample* s=parent->getSample(chan[i].dacSample); if (s->samples<=0 || chan[i].dacPos>=s->samples) { @@ -81,11 +93,13 @@ void DivPlatformVRC6::acquire(short** buf, size_t len) { } // VRC6 part - vrc6.tick(); + vrc6.tick(advance); + h+=advance-1; int sample=vrc6.out()<<9; // scale to 16 bit - if (sample>32767) sample=32767; - if (sample<-32768) sample=-32768; - buf[0][h]=sample; + if (sample!=prevSample) { + blip_add_delta(bb[0],h,sample-prevSample); + prevSample=sample; + } // Oscilloscope buffer part if (++writeOscBuf>=32) { @@ -96,7 +110,7 @@ void DivPlatformVRC6::acquire(short** buf, size_t len) { oscBuf[2]->putSample(h,vrc6.sawtooth_out()<<10); } - // Command part + // Command part (what the heck why at the END?!) while (!writes.empty()) { QueuedWrite w=writes.front(); switch (w.addr&0xf000) { @@ -523,6 +537,7 @@ void DivPlatformVRC6::reset() { } sampleBank=0; + prevSample=0; vrc6.reset(); // Initialize control register @@ -537,6 +552,10 @@ bool DivPlatformVRC6::keyOffAffectsArp(int ch) { return true; } +bool DivPlatformVRC6::hasAcquireDirect() { + return true; +} + void DivPlatformVRC6::setFlags(const DivConfig& flags) { int clockSel=flags.getInt("clockSel",0); if (clockSel==2) { // Dendy diff --git a/src/engine/platform/vrc6.h b/src/engine/platform/vrc6.h index 9f6c4de80..e093ee612 100644 --- a/src/engine/platform/vrc6.h +++ b/src/engine/platform/vrc6.h @@ -57,13 +57,14 @@ class DivPlatformVRC6: public DivDispatch, public vrcvi_intf { unsigned char sampleBank; unsigned char writeOscBuf; vrcvi_core vrc6; + int prevSample; unsigned char regPool[13]; friend void putDispatchChip(void*,int); friend void putDispatchChan(void*,int,int); public: - void acquire(short** buf, size_t len); + void acquireDirect(blip_buffer_t** bb, size_t len); int dispatch(DivCommand c); void* getChanState(int chan); DivMacroInt* getChanMacroInt(int ch); @@ -76,6 +77,7 @@ class DivPlatformVRC6: public DivDispatch, public vrcvi_intf { void tick(bool sysTick=true); void muteChannel(int ch, bool mute); bool keyOffAffectsArp(int ch); + bool hasAcquireDirect(); void setFlags(const DivConfig& flags); void notifyInsDeletion(void* ins); void poke(unsigned int addr, unsigned short val);