diff options
| -rw-r--r-- | include/event.h | 23 | ||||
| -rw-r--r-- | plugin/Makefile.mingw32.in | 2 | ||||
| -rw-r--r-- | src/Makefile.am | 7 | ||||
| -rw-r--r-- | src/Makefile.am.drumgizmo | 2 | ||||
| -rw-r--r-- | src/drumgizmo.cc | 6 | ||||
| -rw-r--r-- | src/inputfilter.h | 50 | ||||
| -rw-r--r-- | src/inputprocessor.cc | 47 | ||||
| -rw-r--r-- | src/inputprocessor.h | 20 | ||||
| -rw-r--r-- | src/instrument.cc | 44 | ||||
| -rw-r--r-- | src/latencyfilter.cc | 44 | ||||
| -rw-r--r-- | src/latencyfilter.h | 45 | ||||
| -rw-r--r-- | src/staminafilter.cc | 80 | ||||
| -rw-r--r-- | src/staminafilter.h | 51 | 
13 files changed, 351 insertions, 70 deletions
| diff --git a/include/event.h b/include/event.h index f8bced3..afb1db4 100644 --- a/include/event.h +++ b/include/event.h @@ -24,17 +24,20 @@   *  along with DrumGizmo; if not, write to the Free Software   *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.   */ -#ifndef __DRUMGIZMO_EVENT_H__ -#define __DRUMGIZMO_EVENT_H__ +#pragma once +#include <cstddef> + +// TODO: Make enum class +//! Event types  #define TYPE_ONSET 0  #define TYPE_STOP  1 -typedef struct { -  size_t type; -  size_t instrument; -  size_t offset; -  float velocity; -} event_t; - -#endif/*__DRUMGIZMO_EVENT_H__*/ +//! POD datatype for input event transport. +struct event_t +{ +	std::size_t type; //!< The type of the event. +	std::size_t instrument; //!< The instrument number. +	std::size_t offset; //!< The offset position in the input buffer +	float velocity; //!< The velocity if the type is a note on [0; 1] +}; diff --git a/plugin/Makefile.mingw32.in b/plugin/Makefile.mingw32.in index d218430..7a9d412 100644 --- a/plugin/Makefile.mingw32.in +++ b/plugin/Makefile.mingw32.in @@ -28,6 +28,7 @@ DG_SRC = \  	@top_srcdir@/src/inputprocessor.cc \  	@top_srcdir@/src/instrument.cc \  	@top_srcdir@/src/instrumentparser.cc \ +	@top_srcdir@/src/latencyfilter.cc \  	@top_srcdir@/src/memchecker.cc \  	@top_srcdir@/src/midimapparser.cc \  	@top_srcdir@/src/midimapper.cc \ @@ -38,6 +39,7 @@ DG_SRC = \  	@top_srcdir@/src/sample.cc \  	@top_srcdir@/src/semaphore.cc \  	@top_srcdir@/src/saxparser.cc \ +	@top_srcdir@/src/staminafilter.cc \  	@top_srcdir@/src/thread.cc \  	@top_srcdir@/src/versionstr.cc  DG_CFLAGS = -I@top_srcdir@ -I@top_srcdir@/include -I@top_srcdir@/src \ diff --git a/src/Makefile.am b/src/Makefile.am index 4d167af..f149aa5 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -22,6 +22,9 @@ EXTRA_DIST = \  	events.h \  	instrument.h \  	instrumentparser.h \ +	inputfiler.h \ +	inputprocessor.h \ +	latencyfilter.h \  	memchecker.h \  	midimapparser.h \  	midimapper.h \ @@ -34,6 +37,7 @@ EXTRA_DIST = \  	sample.h \  	saxparser.h \  	semaphore.h \ +	staminafilter.h \  	thread.h \  	velocity.h \  	versionstr.h \ @@ -59,6 +63,8 @@ EXTRA_DIST = \  	events.cc \  	instrument.cc \  	instrumentparser.cc \ +	inputprocessor.cc \ +	latencyfilter.cc \  	memchecker.cc \  	midimapparser.cc \  	midimapper.cc \ @@ -68,6 +74,7 @@ EXTRA_DIST = \  	sample.cc \  	saxparser.cc \  	semaphore.cc \ +	staminafilter.cc \  	thread.cc \  	velocity.cc \  	versionstr.cc diff --git a/src/Makefile.am.drumgizmo b/src/Makefile.am.drumgizmo index af822f4..9a5b211 100644 --- a/src/Makefile.am.drumgizmo +++ b/src/Makefile.am.drumgizmo @@ -20,6 +20,7 @@ DRUMGIZMO_SOURCES = \  	$(top_srcdir)/src/inputprocessor.cc \  	$(top_srcdir)/src/instrument.cc \  	$(top_srcdir)/src/instrumentparser.cc \ +	$(top_srcdir)/src/latencyfilter.cc \  	$(top_srcdir)/src/memchecker.cc \  	$(top_srcdir)/src/midimapparser.cc \  	$(top_srcdir)/src/midimapper.cc \ @@ -30,6 +31,7 @@ DRUMGIZMO_SOURCES = \  	$(top_srcdir)/src/sample.cc \  	$(top_srcdir)/src/semaphore.cc \  	$(top_srcdir)/src/saxparser.cc \ +	$(top_srcdir)/src/staminafilter.cc \  	$(top_srcdir)/src/thread.cc \  	$(top_srcdir)/src/versionstr.cc diff --git a/src/drumgizmo.cc b/src/drumgizmo.cc index a1278a1..e07b7a1 100644 --- a/src/drumgizmo.cc +++ b/src/drumgizmo.cc @@ -54,7 +54,7 @@ DrumGizmo::DrumGizmo(Settings& settings,  	, oe(o)  	, ie(i)  	, kit() -	, input_processor(kit, activeevents) +	, input_processor(settings, kit, activeevents)  	, framesize(0)  	, freewheel(false)  	, events{} @@ -162,12 +162,14 @@ bool DrumGizmo::run(size_t pos, sample_t *samples, size_t nsamples)  	ie.run(pos, nsamples, events);  	double resample_ratio = resamplers.getRatio(); -	bool active_events_left = input_processor.process(events, pos, resample_ratio); +	bool active_events_left = +		input_processor.process(events, pos, resample_ratio);  	if(!active_events_left)  	{  		return false;  	} +  	events.clear();  	// diff --git a/src/inputfilter.h b/src/inputfilter.h new file mode 100644 index 0000000..26f7294 --- /dev/null +++ b/src/inputfilter.h @@ -0,0 +1,50 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/*************************************************************************** + *            inputfilter.h + * + *  Tue Jun 14 20:42:52 CEST 2016 + *  Copyright 2016 Bent Bisballe Nyeng + *  deva@aasimon.org + ****************************************************************************/ + +/* + *  This file is part of DrumGizmo. + * + *  DrumGizmo is free software; you can redistribute it and/or modify + *  it under the terms of the GNU Lesser General Public License as published by + *  the Free Software Foundation; either version 3 of the License, or + *  (at your option) any later version. + * + *  DrumGizmo is distributed in the hope that it will be useful, + *  but WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *  GNU Lesser General Public License for more details. + * + *  You should have received a copy of the GNU Lesser General Public License + *  along with DrumGizmo; if not, write to the Free Software + *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA. + */ +#pragma once + +#include <event.h> + +//! An abstract filter component for the InputProcessor class filter chain. +class InputFilter +{ +public: +	//! Implement to filter a single event. +	//! \param[in,out] event The event being processed. The filter method +	//!  might alter any of the event parameters. +	//! \param pos The absolute position of the buffer in which the event in +	//!  event was received. Add event.pos to it to get the absolute position of +	//!  the event in the stream. +	//! \return true to keep the event, false to discard it. +	virtual bool filter(event_t& event, std::size_t pos) = 0; + +	//! Returns the filter delay in samples. +	//! Overload if needed. +	virtual std::size_t getLatency() const +	{ +		return 0; +	} +}; diff --git a/src/inputprocessor.cc b/src/inputprocessor.cc index b83855f..b59f0e5 100644 --- a/src/inputprocessor.cc +++ b/src/inputprocessor.cc @@ -32,17 +32,28 @@  #include "instrument.h" -InputProcessor::InputProcessor(DrumKit& kit, std::list<Event*>* activeevents) +#include "staminafilter.h" +#include "latencyfilter.h" + +#include "cpp11fix.h" + +InputProcessor::InputProcessor(Settings& settings, +                               DrumKit& kit, +                               std::list<Event*>* activeevents)  	: 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));  } -bool InputProcessor::process(const std::vector<event_t>& events, size_t pos, double resample_ratio) +bool InputProcessor::process(std::vector<event_t>& events, +                             std::size_t pos, +                             double resample_ratio)  { -	for(const auto& event: events) +	for(auto& event: events)  	{  		if(event.type == TYPE_ONSET)  		{ @@ -63,16 +74,26 @@ bool InputProcessor::process(const std::vector<event_t>& events, size_t pos, dou  std::size_t InputProcessor::getLatency() const  { -	return 0; +	std::size_t latency = 0; + +	for(const auto& filter : filters) +	{ +		latency += filter->getLatency(); +	} + +	return latency;  } -bool InputProcessor::processOnset(const event_t& event, size_t pos, double resample_ratio) +bool InputProcessor::processOnset(event_t& event, +                                  std::size_t pos, +                                  double resample_ratio)  { -	if(!kit.isValid()) { +	if(!kit.isValid()) +	{  		return false;  	} -	size_t ev_instr = event.instrument; +	std::size_t ev_instr = event.instrument;  	Instrument* instr = nullptr;  	if(ev_instr < kit.instruments.size()) @@ -109,6 +130,14 @@ bool InputProcessor::processOnset(const event_t& event, size_t pos, double resam  		}  	} +	for(auto& filter : filters) +	{ +		if(!filter->filter(event, event.offset + pos)) +		{ +			return false; // Skip event completely +		} +	} +  	Sample* sample = instr->sample(event.velocity, event.offset + pos);  	if(sample == nullptr) @@ -136,7 +165,7 @@ bool InputProcessor::processOnset(const event_t& event, size_t pos, double resam  	return true;  } -bool InputProcessor::processStop(const event_t& event) +bool InputProcessor::processStop(event_t& event)  {  	if(event.type == TYPE_STOP)  	{ diff --git a/src/inputprocessor.h b/src/inputprocessor.h index 83a4f5b..13ac4ad 100644 --- a/src/inputprocessor.h +++ b/src/inputprocessor.h @@ -28,17 +28,25 @@  #include <vector>  #include <list> +#include <memory> + +#include <event.h>  #include "drumkit.h"  #include "events.h" -#include <event.h> +#include "inputfilter.h" + +class Settings;  class InputProcessor  {  public: -	InputProcessor(DrumKit& kit, std::list<Event*>* activeevents); +	InputProcessor(Settings& settings, +	               DrumKit& kit, +	               std::list<Event*>* activeevents); -	bool process(const std::vector<event_t>& events, size_t pos, +	bool process(std::vector<event_t>& events, +	             std::size_t pos,  	             double resample_ratio);  	std::size_t getLatency() const; @@ -48,6 +56,8 @@ private:  	std::list<Event*>* activeevents;  	bool is_stopping; ///< Is set to true when a TYPE_STOP event has been seen. -	bool processOnset(const event_t& event, size_t pos, double resample_ratio); -	bool processStop(const event_t& event); +	bool processOnset(event_t& event, std::size_t pos, double resample_ratio); +	bool processStop(event_t& event); + +	std::vector<std::unique_ptr<InputFilter>> filters;  }; diff --git a/src/instrument.cc b/src/instrument.cc index 8c78f40..5c96c6d 100644 --- a/src/instrument.cc +++ b/src/instrument.cc @@ -56,46 +56,8 @@ bool Instrument::isValid() const  Sample* Instrument::sample(level_t level, size_t pos)  { -	// Read out all values from settings. -	auto enable_velocity_randomiser = settings.enable_velocity_randomiser.load(); -	auto velocity_randomiser_weight = settings.velocity_randomiser_weight.load(); -	auto samplerate = settings.samplerate.load(); -	auto velocity_modifier_falloff = settings.velocity_modifier_falloff.load(); -	auto enable_velocity_modifier = settings.enable_velocity_modifier.load(); -	auto velocity_modifier_weight = settings.velocity_modifier_weight.load(); -  	Sample *sample = nullptr; -	if(enable_velocity_modifier == false) -	{ -		mod = 1.0; -		lastpos = 0; -	} - -	if(enable_velocity_randomiser) -	{ -		float r = rand.floatInRange(-1.0 * velocity_randomiser_weight, -		                            velocity_randomiser_weight); -		level += r; -		if(level > 1.0) -		{ -			level = 1.0; -		} -		if(level < 0.0) -		{ -			level = 0.0; -		} -	} - -	if(enable_velocity_modifier) -	{ -		mod += (pos - lastpos) / (samplerate * velocity_modifier_falloff); -		if(mod > 1.0) -		{ -			mod = 1.0; -		} -	} -  	if(version >= VersionStr("2.0"))  	{  		// Version 2.0 @@ -113,12 +75,6 @@ Sample* Instrument::sample(level_t level, size_t pos)  		sample = rand.choose(s);  	} -	if(enable_velocity_modifier) -	{ -		lastpos = pos; -		mod *= velocity_modifier_weight; -	} -  	return sample;  } diff --git a/src/latencyfilter.cc b/src/latencyfilter.cc new file mode 100644 index 0000000..b3ef44d --- /dev/null +++ b/src/latencyfilter.cc @@ -0,0 +1,44 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/*************************************************************************** + *            latencyfilter.cc + * + *  Fri Jun 10 22:42:53 CEST 2016 + *  Copyright 2016 Bent Bisballe Nyeng + *  deva@aasimon.org + ****************************************************************************/ + +/* + *  This file is part of DrumGizmo. + * + *  DrumGizmo is free software; you can redistribute it and/or modify + *  it under the terms of the GNU Lesser General Public License as published by + *  the Free Software Foundation; either version 3 of the License, or + *  (at your option) any later version. + * + *  DrumGizmo is distributed in the hope that it will be useful, + *  but WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *  GNU Lesser General Public License for more details. + * + *  You should have received a copy of the GNU Lesser General Public License + *  along with DrumGizmo; if not, write to the Free Software + *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA. + */ +#include "latencyfilter.h" + +LatencyFilter::LatencyFilter(Settings& settings) +	: settings(settings) +{ +} + +bool LatencyFilter::filter(event_t& events, size_t pos) +{ +	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; +} diff --git a/src/latencyfilter.h b/src/latencyfilter.h new file mode 100644 index 0000000..9b7bdd1 --- /dev/null +++ b/src/latencyfilter.h @@ -0,0 +1,45 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/*************************************************************************** + *            latencyfilter.h + * + *  Fri Jun 10 22:42:52 CEST 2016 + *  Copyright 2016 Bent Bisballe Nyeng + *  deva@aasimon.org + ****************************************************************************/ + +/* + *  This file is part of DrumGizmo. + * + *  DrumGizmo is free software; you can redistribute it and/or modify + *  it under the terms of the GNU Lesser General Public License as published by + *  the Free Software Foundation; either version 3 of the License, or + *  (at your option) any later version. + * + *  DrumGizmo is distributed in the hope that it will be useful, + *  but WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *  GNU Lesser General Public License for more details. + * + *  You should have received a copy of the GNU Lesser General Public License + *  along with DrumGizmo; if not, write to the Free Software + *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA. + */ +#pragma once + +#include "inputfilter.h" + +class Settings; + +class LatencyFilter +	: public InputFilter +{ +public: +	LatencyFilter(Settings& settings); + +	bool filter(event_t& events, size_t pos) override; + +	std::size_t getLatency() const override; + +private: +	Settings& settings; +}; diff --git a/src/staminafilter.cc b/src/staminafilter.cc new file mode 100644 index 0000000..a8f6a86 --- /dev/null +++ b/src/staminafilter.cc @@ -0,0 +1,80 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/*************************************************************************** + *            staminafilter.cc + * + *  Sat Jun 11 08:49:36 CEST 2016 + *  Copyright 2016 Bent Bisballe Nyeng + *  deva@aasimon.org + ****************************************************************************/ + +/* + *  This file is part of DrumGizmo. + * + *  DrumGizmo is free software; you can redistribute it and/or modify + *  it under the terms of the GNU Lesser General Public License as published by + *  the Free Software Foundation; either version 3 of the License, or + *  (at your option) any later version. + * + *  DrumGizmo is distributed in the hope that it will be useful, + *  but WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *  GNU Lesser General Public License for more details. + * + *  You should have received a copy of the GNU Lesser General Public License + *  along with DrumGizmo; if not, write to the Free Software + *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA. + */ +#include "staminafilter.h" + +#include "settings.h" + +StaminaFilter::StaminaFilter(Settings& settings) +	: settings(settings) +{ +} + +bool StaminaFilter::filter(event_t& event, size_t pos) +{ +	// Read out all values from settings. +	auto samplerate = settings.samplerate.load(); +	auto velocity_modifier_falloff = settings.velocity_modifier_falloff.load(); +	auto enable_velocity_modifier = settings.enable_velocity_modifier.load(); +	auto velocity_modifier_weight = settings.velocity_modifier_weight.load(); + +	if(modifiers.find(event.instrument) == modifiers.end()) +	{ +		// On first lookup make sure we have sane values. +		auto& pair = modifiers[event.instrument]; +		pair.first = 1.0f; +		pair.second = 0; +	} + +	auto& pair = modifiers[event.instrument]; +	auto& mod = pair.first; +	auto& lastpos = pair.second; + +	if(enable_velocity_modifier == false) +	{ +		mod = 1.0f; +		lastpos = 0; +	} + +	if(enable_velocity_modifier) +	{ +		mod += (pos - lastpos) / (samplerate * velocity_modifier_falloff); +		if(mod > 1.0f) +		{ +			mod = 1.0f; +		} +	} + +	event.velocity *= mod; + +	if(enable_velocity_modifier) +	{ +		lastpos = pos; +		mod *= velocity_modifier_weight; +	} + +	return true; +} diff --git a/src/staminafilter.h b/src/staminafilter.h new file mode 100644 index 0000000..36ee5f1 --- /dev/null +++ b/src/staminafilter.h @@ -0,0 +1,51 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/*************************************************************************** + *            staminafilter.h + * + *  Sat Jun 11 08:49:36 CEST 2016 + *  Copyright 2016 Bent Bisballe Nyeng + *  deva@aasimon.org + ****************************************************************************/ + +/* + *  This file is part of DrumGizmo. + * + *  DrumGizmo is free software; you can redistribute it and/or modify + *  it under the terms of the GNU Lesser General Public License as published by + *  the Free Software Foundation; either version 3 of the License, or + *  (at your option) any later version. + * + *  DrumGizmo is distributed in the hope that it will be useful, + *  but WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *  GNU Lesser General Public License for more details. + * + *  You should have received a copy of the GNU Lesser General Public License + *  along with DrumGizmo; if not, write to the Free Software + *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA. + */ +#pragma once + +#include <cstddef> +#include <map> +#include <utility> + +#include "inputfilter.h" + +class Settings; + +class StaminaFilter +	: public InputFilter +{ +public: +	StaminaFilter(Settings& settings); + +	bool filter(event_t& event, std::size_t pos) override; + +	// Note getLatency not overloaded because this filter doesn't add latency. + +private: +	Settings& settings; + +	std::map<std::size_t, std::pair<float, std::size_t>> modifiers; +}; | 
