n2xhardware.h (2620B)
1 #pragma once 2 3 #include "n2xdsp.h" 4 #include "n2xmc.h" 5 #include "n2xrom.h" 6 7 #include "synthLib/audioTypes.h" 8 #include "synthLib/midiTypes.h" 9 10 namespace n2x 11 { 12 class Hardware 13 { 14 public: 15 using AudioOutputs = std::array<std::vector<dsp56k::TWord>, 4>; 16 Hardware(const std::vector<uint8_t>& _romData = {}, const std::string& _romName = {}); 17 ~Hardware(); 18 19 bool isValid() const; 20 21 void processUC(); 22 23 Microcontroller& getUC() {return m_uc; } 24 25 const auto& getAudioOutputs() const { return m_audioOutputs; } 26 27 void processAudio(uint32_t _frames, uint32_t _latency); 28 29 auto& getDSPA() { return m_dspA; } 30 auto& getDSPB() { return m_dspB; } 31 32 auto& getMidi() { return m_uc.getMidi(); } 33 34 void haltDSPs(); 35 void resumeDSPs(); 36 bool requestingHaltDSPs() const { return m_dspHalted; } 37 38 bool getButtonState(ButtonType _type) const; 39 void setButtonState(ButtonType _type, bool _pressed); 40 41 uint8_t getKnobPosition(KnobType _knob) const; 42 void setKnobPosition(KnobType _knob, uint8_t _value); 43 44 void processAudio(const synthLib::TAudioOutputs& _outputs, uint32_t _frames, uint32_t _latency); 45 bool sendMidi(const synthLib::SMidiEvent& _ev); 46 void notifyBootFinished(); 47 48 const std::string& getRomFilename() const { return m_rom.getFilename(); } 49 50 private: 51 void ensureBufferSize(uint32_t _frames); 52 void onEsaiCallbackA(); 53 void processMidiInput(); 54 void onEsaiCallbackB(); 55 void syncUCtoDSP(); 56 void ucThreadFunc(); 57 void advanceSamples(uint32_t _samples, uint32_t _latency); 58 59 Rom m_rom; 60 Microcontroller m_uc; 61 DSP m_dspA; 62 DSP m_dspB; 63 64 std::vector<dsp56k::TWord> m_dummyInput; 65 std::vector<dsp56k::TWord> m_dummyOutput; 66 std::vector<dsp56k::TWord> m_dspAtoBBuffer; 67 68 AudioOutputs m_audioOutputs; 69 70 // timing 71 const double m_samplerateInv; 72 uint32_t m_esaiFrameIndex = 0; 73 uint32_t m_lastEsaiFrameIndex = 0; 74 int64_t m_remainingUcCycles = 0; 75 double m_remainingUcCyclesD = 0; 76 std::mutex m_esaiFrameAddedMutex; 77 dsp56k::ConditionVariable m_esaiFrameAddedCv; 78 std::mutex m_requestedFramesAvailableMutex; 79 dsp56k::ConditionVariable m_requestedFramesAvailableCv; 80 size_t m_requestedFrames = 0; 81 bool m_dspHalted = false; 82 dsp56k::SpscSemaphore m_semDspAtoB; 83 84 dsp56k::RingBuffer<dsp56k::Audio::RxFrame, 4, true> m_dspAtoBbuf; 85 86 std::unique_ptr<std::thread> m_ucThread; 87 bool m_destroy = false; 88 89 // Midi 90 dsp56k::RingBuffer<synthLib::SMidiEvent, 16384, true> m_midiIn; 91 uint32_t m_midiOffsetCounter = 0; 92 93 // DSP slowdown 94 uint32_t m_esaiLatency = 0; 95 int32_t m_dspNotifyCorrection = 0; 96 dsp56k::SpscSemaphoreWithCount m_haltDSPSem; 97 98 bool m_bootFinished = false; 99 }; 100 }