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

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 }