gearmulator

Emulation of classic VA synths of the late 90s/2000s that are based on Motorola 56300 family DSPs
Log | Files | Refs | Submodules | README | LICENSE

commit 8d08fe9161bbb7b7225f399284c07c9ddd2f4339
parent 75efdb9f7166a00b355bf93f6ee18a8db7099c42
Author: dsp56300 <dsp56300@users.noreply.github.com>
Date:   Sun, 28 Jul 2024 22:03:22 +0200

implement get/set button functions

Diffstat:
Msource/nord/n2x/n2xLib/n2xfrontpanel.cpp | 70++++++++++++++++++++++++++++------------------------------------------
Msource/nord/n2x/n2xLib/n2xfrontpanel.h | 17++++++++++++++++-
Msource/nord/n2x/n2xLib/n2xhardware.cpp | 10++++++++++
Msource/nord/n2x/n2xLib/n2xhardware.h | 3+++
Msource/nord/n2x/n2xLib/n2xmc.h | 3+++
Msource/nord/n2x/n2xLib/n2xtypes.h | 7+++----
Msource/nord/n2x/n2xTestConsole/n2xTestConsole.cpp | 21+++++++++++++++++++++
7 files changed, 84 insertions(+), 47 deletions(-)

diff --git a/source/nord/n2x/n2xLib/n2xfrontpanel.cpp b/source/nord/n2x/n2xLib/n2xfrontpanel.cpp @@ -61,8 +61,9 @@ namespace n2x } } - FrontPanelCS6::FrontPanelCS6(FrontPanel& _fp) : FrontPanelCS(_fp) + FrontPanelCS6::FrontPanelCS6(FrontPanel& _fp) : FrontPanelCS(_fp), m_buttonStates({}) { + m_buttonStates.fill(0xff); } void FrontPanelCS6::write8(const mc68k::PeriphAddress _addr, const uint8_t _val) @@ -111,58 +112,43 @@ namespace n2x FrontPanelCS::write8(_addr, _val); } - static uint32_t g_counter = 0; - constexpr uint32_t g_len = 4096; - constexpr uint32_t g_threshold = 512; - static bool wasPressed = false; - static bool wasReleased = false; - uint8_t FrontPanelCS6::read8(mc68k::PeriphAddress _addr) { - ++g_counter; - g_counter &= (g_len - 1); - auto press = g_counter >= (g_len - g_threshold); - - if(press) - wasPressed = true; - else if(!press && wasPressed) - wasReleased = true; - if(wasReleased) - press = false; - const auto a = static_cast<uint32_t>(_addr); switch (a) { - case g_frontPanelAddressCS6: - return 0xff; - case g_frontPanelAddressCS6 + 2: - if(press) - { - constexpr auto bt = static_cast<uint8_t>(ButtonType::OscSync) & 0xff; - return 0xff ^ bt; - } - return 0xff; - case g_frontPanelAddressCS6 + 4: - return 0xff; - case g_frontPanelAddressCS6 + 6: - { - if(press) - { - constexpr auto bt = static_cast<uint8_t>(ButtonType::ModwheelDest) & 0xff; - return 0xff ^ bt; - } - return 0xff; - } + case g_frontPanelAddressCS6: return m_buttonStates[0]; + case g_frontPanelAddressCS6 + 2: return m_buttonStates[1]; + case g_frontPanelAddressCS6 + 4: return m_buttonStates[2]; + case g_frontPanelAddressCS6 + 6: return m_buttonStates[3]; } return FrontPanelCS::read8(_addr); } - static uint32_t g_count = 0; + void FrontPanelCS6::setButtonState(ButtonType _button, const bool _pressed) + { + const auto id = static_cast<uint32_t>(_button); + const auto index = id>>9; + const auto mask = id & 0xff; + if(_pressed) + m_buttonStates[index] |= mask; + else + m_buttonStates[index] &= ~mask; + } + + bool FrontPanelCS6::getButtonState(ButtonType _button) const + { + const auto id = static_cast<uint32_t>(_button); + const auto index = id>>9; + const auto mask = id & 0xff; + return m_buttonStates[index] & mask ? false : true; + } - void FrontPanelCS6::printLCD() + void FrontPanelCS6::printLCD() const { - ++g_count; - if(g_count & 0xff) + static uint32_t count = 0; + ++count; + if(count & 0xff) return; /* -- -- -- diff --git a/source/nord/n2x/n2xLib/n2xfrontpanel.h b/source/nord/n2x/n2xLib/n2xfrontpanel.h @@ -35,8 +35,11 @@ namespace n2x auto getKnobType() const { return m_selectedKnob; } + void setButtonState(ButtonType _button, bool _pressed); + bool getButtonState(ButtonType _button) const; + private: - void printLCD(); + void printLCD() const; uint8_t m_ledLatch8 = 0; uint8_t m_ledLatch10 = 0; @@ -44,6 +47,8 @@ namespace n2x std::array<uint8_t,3> m_lcds{0,0,0}; std::array<uint8_t,3> m_lcdsPrev{0,0,0}; KnobType m_selectedKnob = KnobType::PitchBend; + + std::array<uint8_t, 4> m_buttonStates; }; class FrontPanel @@ -59,6 +64,16 @@ namespace n2x return m_cs4.isInRange(_pa) || m_cs6.isInRange(_pa); } + bool getButtonState(ButtonType _type) const + { + return m_cs6.getButtonState(_type); + } + + void setButtonState(ButtonType _type, bool _pressed) + { + m_cs6.setButtonState(_type, _pressed); + } + private: FrontPanelCS4 m_cs4; FrontPanelCS6 m_cs6; diff --git a/source/nord/n2x/n2xLib/n2xhardware.cpp b/source/nord/n2x/n2xLib/n2xhardware.cpp @@ -224,4 +224,14 @@ namespace n2x m_dspHalted = false; m_dspB.getHaltDSP().resumeDSP(); } + + bool Hardware::getButtonState(const ButtonType _type) const + { + return m_uc.getFrontPanel().getButtonState(_type); + } + + void Hardware::setButtonState(const ButtonType _type, const bool _pressed) + { + m_uc.getFrontPanel().setButtonState(_type, _pressed); + } } diff --git a/source/nord/n2x/n2xLib/n2xhardware.h b/source/nord/n2x/n2xLib/n2xhardware.h @@ -29,6 +29,9 @@ namespace n2x void haltDSPs(); void resumeDSPs(); + bool getButtonState(ButtonType _type) const; + void setButtonState(ButtonType _type, bool _pressed); + private: void ensureBufferSize(uint32_t _frames); void onEsaiCallbackA(); diff --git a/source/nord/n2x/n2xLib/n2xmc.h b/source/nord/n2x/n2xLib/n2xmc.h @@ -26,6 +26,9 @@ namespace n2x auto getPrevPC() const { return m_prevPC; } + auto& getFrontPanel() { return m_panel; } + const auto& getFrontPanel() const { return m_panel; } + private: uint32_t read32(uint32_t _addr) override; uint16_t readImm16(uint32_t _addr) override; diff --git a/source/nord/n2x/n2xLib/n2xtypes.h b/source/nord/n2x/n2xLib/n2xtypes.h @@ -40,7 +40,6 @@ namespace n2x static constexpr uint32_t g_keyboardSize = 0x800; static constexpr uint32_t g_samplerate = 98200; - static constexpr uint32_t g_ucFreqHz = 25165824; // Fext=32768Hz, SYNCR=$d700, W=1, X=1, Y=17 enum class ButtonType { @@ -88,9 +87,9 @@ namespace n2x enum class KnobType { Invalid = 0, - Osc1Fm = 0x38, Porta, Lfo2Rate, Lfo1Rate, MasterVol, ModEnvAmt, ModEnvD, ModEnvA, - AmpEnvD = 0x58, FilterFreq, FilterEnvA, AmpEnvA, OscMix, Osc2Fine, Lfo1Amount, OscPW, - AmpGain = 0x68, FilterEnvR, AmpEnvR, FilterEnvAmt, FilterEnvS, AmpEnvS, FilterReso, FilterEnvD, + Osc1Fm = 0x38, Porta, Lfo2Rate, Lfo1Rate, MasterVol, ModEnvAmt, ModEnvD, ModEnvA, + AmpEnvD = 0x58, FilterFreq, FilterEnvA, AmpEnvA, OscMix, Osc2Fine, Lfo1Amount, OscPW, + AmpGain = 0x68, FilterEnvR, AmpEnvR, FilterEnvAmt, FilterEnvS, AmpEnvS, FilterReso, FilterEnvD, PitchBend = 0x70, ModWheel, ExpPedal, Lfo2Amount, Osc2Semi, }; } diff --git a/source/nord/n2x/n2xTestConsole/n2xTestConsole.cpp b/source/nord/n2x/n2xTestConsole/n2xTestConsole.cpp @@ -51,10 +51,31 @@ int main() synthLib::AsyncWriter writer("n2xEmu_out.wav", n2x::g_samplerate, false); + uint32_t totalSamples = 0; + while(true) { hw->processAudio(blockSize, blockSize); + totalSamples += blockSize; + + auto seconds = [&](uint32_t _seconds) + { + return _seconds * (n2x::g_samplerate / blockSize) * blockSize; + }; + + if(totalSamples == seconds(4)) + { + hw->setButtonState(n2x::ButtonType::Shift, true); + hw->setButtonState(n2x::ButtonType::OscSync, true); + } + + else if(totalSamples == seconds(5)) + { + hw->setButtonState(n2x::ButtonType::Shift, false); + hw->setButtonState(n2x::ButtonType::OscSync, false); + } + auto& outs = hw->getAudioOutputs(); for(size_t i=0; i<blockSize; ++i)