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

device.cpp (3150B)


      1 #include "device.h"
      2 
      3 #include "audioTypes.h"
      4 #include "dsp56kEmu/dsp.h"
      5 #include "dsp56kEmu/memory.h"
      6 
      7 #include <cmath>
      8 
      9 using namespace dsp56k;
     10 
     11 namespace synthLib
     12 {
     13 	Device::Device(const DeviceCreateParams& _params) : m_createParams(_params)  // NOLINT(modernize-pass-by-value) dll transition, do not mess with the input data
     14 	{
     15 	}
     16 	Device::~Device() = default;
     17 
     18 	ASMJIT_NOINLINE void Device::release(std::vector<SMidiEvent>& _events)
     19 	{
     20 		_events.clear();
     21 	}
     22 
     23 	void Device::dummyProcess(const uint32_t _numSamples)
     24 	{
     25 		std::vector<float> buf;
     26 		buf.resize(_numSamples);
     27 		const auto ptr = buf.data();
     28 
     29 		const TAudioInputs in = {ptr, ptr, nullptr, nullptr};//, nullptr, nullptr, nullptr, nullptr};
     30 		const TAudioOutputs out = {ptr, ptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr};
     31 
     32 		std::vector<SMidiEvent> midi;
     33 
     34 		process(in, out, _numSamples, midi, midi);
     35 	}
     36 
     37 	void Device::process(const TAudioInputs& _inputs, const TAudioOutputs& _outputs, const size_t _size, const std::vector<SMidiEvent>& _midiIn, std::vector<SMidiEvent>& _midiOut)
     38 	{
     39 		_midiOut.clear();
     40 
     41 		for (const auto& ev : _midiIn)
     42 		{
     43 			m_translatorOut.clear();
     44 
     45 			m_midiTranslator.process(m_translatorOut, ev);
     46 
     47 			for(auto & e : m_translatorOut)
     48 				sendMidi(e, _midiOut);
     49 		}
     50 
     51 		processAudio(_inputs, _outputs, _size);
     52 
     53 		readMidiOut(_midiOut);
     54 	}
     55 
     56 	void Device::setExtraLatencySamples(const uint32_t _size)
     57 	{
     58 		constexpr auto maxLatency = Audio::RingBufferSize >> 1;
     59 
     60 		m_extraLatency = std::min(_size, maxLatency);
     61 
     62 		LOG("Latency set to " << m_extraLatency << " samples at " << getSamplerate() << " Hz");
     63 
     64 		if(_size > maxLatency)
     65 		{
     66 			LOG("Warning, limited requested latency " << _size << " to maximum value " << maxLatency << ", audio will be out of sync!");
     67 		}
     68 	}
     69 
     70 	bool Device::isSamplerateSupported(const float& _samplerate) const
     71 	{
     72 		std::vector<float> srs;
     73 		getSupportedSamplerates(srs);
     74 		for (const auto& sr : srs)
     75 		{
     76 			if(std::fabs(sr - _samplerate) < 1.0f)
     77 				return true;
     78 		}
     79 		return false;
     80 	}
     81 
     82 	bool Device::setSamplerate(const float _samplerate)
     83 	{
     84 		return isSamplerateSupported(_samplerate);
     85 	}
     86 
     87 	float Device::getDeviceSamplerate(const float _preferredDeviceSamplerate, const float _hostSamplerate) const
     88 	{
     89 		if(_preferredDeviceSamplerate > 0.0f && isSamplerateSupported(_preferredDeviceSamplerate))
     90 			return _preferredDeviceSamplerate;
     91 		return getDeviceSamplerateForHostSamplerate(_hostSamplerate);
     92 	}
     93 
     94 	float Device::getDeviceSamplerateForHostSamplerate(const float _hostSamplerate) const
     95 	{
     96 		std::vector<float> preferred;
     97 		getPreferredSamplerates(preferred);
     98 
     99 		// if there is no choice we need to use the only one that is supported
    100 		if(preferred.size() == 1)
    101 			return preferred.front();
    102 
    103 		// find the lowest possible samplerate that is higher than the host samplerate
    104 		const std::set<float> samplerates(preferred.begin(), preferred.end());
    105 
    106 		for (const float sr : preferred)
    107 		{
    108 			if(sr >= _hostSamplerate)
    109 				return sr;
    110 		}
    111 
    112 		// if all supported device samplerates are lower than the host samplerate, use the maximum that the device supports
    113 		return *samplerates.rbegin();
    114 	}
    115 }