diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/drumgizmo.cc | 2 | ||||
| -rw-r--r-- | src/events.h | 2 | ||||
| -rw-r--r-- | src/inputprocessor.cc | 5 | ||||
| -rw-r--r-- | src/inputprocessor.h | 4 | ||||
| -rw-r--r-- | src/latencyfilter.cc | 63 | ||||
| -rw-r--r-- | src/latencyfilter.h | 10 | ||||
| -rw-r--r-- | src/settings.h | 23 | 
7 files changed, 95 insertions, 14 deletions
| diff --git a/src/drumgizmo.cc b/src/drumgizmo.cc index 9874bbe..d30952e 100644 --- a/src/drumgizmo.cc +++ b/src/drumgizmo.cc @@ -47,7 +47,7 @@ DrumGizmo::DrumGizmo(Settings& settings,  	, oe(o)  	, ie(i)  	, audio_cache(settings) -	, input_processor(settings, kit, activeevents) +	, input_processor(settings, kit, activeevents, rand)  	, settings(settings)  	, settings_getter(settings)  { diff --git a/src/events.h b/src/events.h index 30a9e8b..f953031 100644 --- a/src/events.h +++ b/src/events.h @@ -54,7 +54,7 @@ public:  	virtual type_t getType() const = 0;  	channel_t channel; -	timepos_t offset; +	timepos_t offset; //< Global position (ie. not relative to buffer)  };  #define NO_RAMPDOWN -1 diff --git a/src/inputprocessor.cc b/src/inputprocessor.cc index 5d96e2d..1dbd79e 100644 --- a/src/inputprocessor.cc +++ b/src/inputprocessor.cc @@ -39,14 +39,15 @@  InputProcessor::InputProcessor(Settings& settings,                                 DrumKit& kit, -                               std::list<Event*>* activeevents) +                               std::list<Event*>* activeevents, +                               Random& random)  	: kit(kit)  	, activeevents(activeevents)  	, is_stopping(false)  {  	// Build filter list  	filters.emplace_back(std::make_unique<StaminaFilter>(settings)); -	filters.emplace_back(std::make_unique<LatencyFilter>(settings)); +	filters.emplace_back(std::make_unique<LatencyFilter>(settings, random));  }  bool InputProcessor::process(std::vector<event_t>& events, diff --git a/src/inputprocessor.h b/src/inputprocessor.h index fe72292..cf62ea2 100644 --- a/src/inputprocessor.h +++ b/src/inputprocessor.h @@ -37,13 +37,15 @@  #include "inputfilter.h"  struct Settings; +class Random;  class InputProcessor  {  public:  	InputProcessor(Settings& settings,  	               DrumKit& kit, -	               std::list<Event*>* activeevents); +	               std::list<Event*>* activeevents, +	               Random& random);  	bool process(std::vector<event_t>& events,  	             std::size_t pos, diff --git a/src/latencyfilter.cc b/src/latencyfilter.cc index d83eab6..2f4bfe5 100644 --- a/src/latencyfilter.cc +++ b/src/latencyfilter.cc @@ -26,19 +26,70 @@   */  #include "latencyfilter.h" -LatencyFilter::LatencyFilter(Settings& settings) -	//: settings(settings) +#include <cmath> +#include <hugin.hpp> + +#include "settings.h" +#include "random.h" + +LatencyFilter::LatencyFilter(Settings& settings, Random& random) +	: settings(settings) +	, random(random)  {  } -bool LatencyFilter::filter(event_t& events, size_t pos) +bool LatencyFilter::filter(event_t& event, std::size_t pos)  { +	auto enabled = settings.enable_latency_modifier.load(); +	auto latency = settings.latency_max.load(); +	auto samplerate = settings.samplerate.load(); +	auto latency_laid_back = settings.latency_laid_back.load(); +	auto latency_stddev = settings.latency_stddev.load(); +	auto latency_regain = settings.latency_regain.load(); + +	if(!enabled) +	{ +		return true; +	} + +	// Assert latency_regain is within range [0; 1]. +	assert(latency_regain >= 0.0f && latency_regain <= 1.0f); + +	float duration = (pos - latency_last_pos) / samplerate; +	latency_offset *= pow(latency_regain, duration); + +	latency_last_pos = pos; + +	float offset_min = latency * -1.0f; +	float offset_max = latency * 1.0f; + +	float mean = latency_laid_back; +	float stddev = latency_stddev; + +	float offset = random.normalDistribution(mean, stddev); + +	latency_offset += offset; + +	if(latency_offset > offset_max) latency_offset = offset_max; +	if(latency_offset < offset_min) latency_offset = offset_min; + +	DEBUG(offset, "latency: %d, offset: %f, drift: %f", +	      (int)latency, offset, latency_offset); + +	event.offset += latency; +	event.offset += latency_offset;//(int)std::round(offset); +  	return true;  }  std::size_t LatencyFilter::getLatency() const  { -	// TODO: If enabled in settings, return the maximum number of samples -	// with which the latency filter can move notes forward. -	return 0; +	bool enabled = settings.enable_latency_modifier.load(); +	std::size_t max_latency = settings.latency_max.load(); +	if(enabled) +	{ +		return max_latency; +	} + +	return 0u;  } diff --git a/src/latencyfilter.h b/src/latencyfilter.h index e34b050..a49dd47 100644 --- a/src/latencyfilter.h +++ b/src/latencyfilter.h @@ -29,17 +29,21 @@  #include "inputfilter.h"  struct Settings; +class Random;  class LatencyFilter  	: public InputFilter  {  public: -	LatencyFilter(Settings& settings); +	LatencyFilter(Settings& settings, Random& random); -	bool filter(event_t& events, size_t pos) override; +	bool filter(event_t& events, std::size_t pos) override;  	std::size_t getLatency() const override;  private: -	//Settings& settings; +	Settings& settings; +	Random& random; +	double latency_offset{0.0}; +	std::size_t latency_last_pos{0};  }; diff --git a/src/settings.h b/src/settings.h index 6bba237..cdce066 100644 --- a/src/settings.h +++ b/src/settings.h @@ -90,6 +90,29 @@ struct Settings  	Atomic<bool> enable_bleed_control{false};  	Atomic<float> master_bleed{1.0f}; + +	Atomic<bool> enable_latency_modifier{true}; + +	//! Maximum "early hits" introduces latency. In no. samples. +	Atomic<std::size_t> latency_max{5000u}; + +	//! 0 := on-beat +	//! positive := laid back +	//! negative := up-beat +	Atomic<int> latency_laid_back{0}; + +	//!   0 := Robot +	//! 100 := Good drummer +	//! 200 := Decent drummer +	//! 300 := Decent drummer on a bad day +	//! 400 := Bad drummer +	//! 500 := Bad and drunk drummer +	Atomic<float> latency_stddev{100.0f}; + +	//! Regain on-beat position. +	//! 0: instantaniously +	//! 1: never +	Atomic<float> latency_regain{0.9f};  };  //! Settings getter class. | 
