diff options
-rw-r--r-- | plugin/Makefile.mingw32.in | 1 | ||||
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/inputprocessor.cc | 2 | ||||
-rw-r--r-- | src/sample_selection.cc | 24 | ||||
-rw-r--r-- | src/velocityfilter.cc | 50 | ||||
-rw-r--r-- | src/velocityfilter.h | 53 |
6 files changed, 114 insertions, 18 deletions
diff --git a/plugin/Makefile.mingw32.in b/plugin/Makefile.mingw32.in index 4655e21..610d5e9 100644 --- a/plugin/Makefile.mingw32.in +++ b/plugin/Makefile.mingw32.in @@ -39,6 +39,7 @@ DG_SRC = \ @top_srcdir@/src/semaphore.cc \ @top_srcdir@/src/staminafilter.cc \ @top_srcdir@/src/thread.cc \ + @top_srcdir@/src/velocityfilter.cc \ @top_srcdir@/src/versionstr.cc DG_CFLAGS = -I@top_srcdir@ -I@top_srcdir@/src \ -I@top_srcdir@/pugixml/src \ diff --git a/src/Makefile.am b/src/Makefile.am index 3da5d0f..7833b2d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -41,6 +41,7 @@ nodist_libdg_la_SOURCES = \ semaphore.cc \ staminafilter.cc \ thread.cc \ + velocityfilter.cc \ versionstr.cc EXTRA_DIST = \ @@ -88,4 +89,5 @@ EXTRA_DIST = \ staminafilter.h \ syncedsettings.h \ thread.h \ + velocityfilter.cc \ versionstr.h diff --git a/src/inputprocessor.cc b/src/inputprocessor.cc index 3e779f6..b5b887f 100644 --- a/src/inputprocessor.cc +++ b/src/inputprocessor.cc @@ -34,6 +34,7 @@ #include "staminafilter.h" #include "latencyfilter.h" +#include "velocityfilter.h" #include "cpp11fix.h" @@ -49,6 +50,7 @@ InputProcessor::InputProcessor(Settings& settings, // Build filter list filters.emplace_back(std::make_unique<StaminaFilter>(settings)); filters.emplace_back(std::make_unique<LatencyFilter>(settings, random)); + filters.emplace_back(std::make_unique<VelocityFilter>(settings, random, kit.instruments)); } bool InputProcessor::process(std::vector<event_t>& events, diff --git a/src/sample_selection.cc b/src/sample_selection.cc index ce50cfa..d4f78d7 100644 --- a/src/sample_selection.cc +++ b/src/sample_selection.cc @@ -62,15 +62,6 @@ const Sample* SampleSelection::get(level_t level, std::size_t pos) return nullptr; // No samples to choose from. } - auto power_max = powerlist.getMaxPower(); - auto power_min = powerlist.getMinPower(); - float power_span = power_max - power_min; - - float mean = level - .5f/127.f; // XXX: this should actually be done when reading the events - float stddev = settings.velocity_stddev.load(); - // the 20.0f we determined empirically - float lvl = power_min + rand.normalDistribution(mean, stddev / 20.0f) * power_span; - std::size_t index_opt = 0; float power_opt{0.f}; float value_opt{std::numeric_limits<float>::max()}; @@ -79,20 +70,17 @@ const Sample* SampleSelection::get(level_t level, std::size_t pos) float close_opt = 0.; float diverse_opt = 0.; - DEBUG(rand, "level: %f, lvl: %f (mean: %.2f, stddev: %.2f," - "power_min: %f, power_max: %f)\n", level, lvl, mean, stddev, power_min, power_max); - const float f_close = settings.sample_selection_f_close.load(); const float f_diverse = settings.sample_selection_f_diverse.load(); const float f_random = settings.sample_selection_f_random.load(); // start with most promising power value and then stop when reaching far values // which cannot become opt anymore - auto closest_it = std::lower_bound(samples.begin(), samples.end(), lvl); + auto closest_it = std::lower_bound(samples.begin(), samples.end(), level); std::size_t up_index = std::distance(samples.begin(), closest_it); std::size_t down_index = (up_index == 0 ? 0 : up_index - 1); - float up_value_lb = (up_index < samples.size() ? f_close*pow2(samples[up_index].power-lvl) : std::numeric_limits<float>::max()); - float down_value_lb = (up_index != 0 ? f_close*pow2(samples[down_index].power-lvl) : std::numeric_limits<float>::max()); + float up_value_lb = (up_index < samples.size() ? f_close*pow2(samples[up_index].power-level) : std::numeric_limits<float>::max()); + float down_value_lb = (up_index != 0 ? f_close*pow2(samples[down_index].power-level) : std::numeric_limits<float>::max()); std::size_t count = 0; do @@ -104,7 +92,7 @@ const Sample* SampleSelection::get(level_t level, std::size_t pos) if (up_index != samples.size()-1) { ++up_index; - up_value_lb = f_close*pow2(samples[up_index].power-lvl); + up_value_lb = f_close*pow2(samples[up_index].power-level); } else { @@ -117,7 +105,7 @@ const Sample* SampleSelection::get(level_t level, std::size_t pos) if (down_index != 0) { --down_index; - down_value_lb = f_close*pow2(samples[down_index].power-lvl); + down_value_lb = f_close*pow2(samples[down_index].power-level); } else { @@ -126,7 +114,7 @@ const Sample* SampleSelection::get(level_t level, std::size_t pos) } auto random = rand.floatInRange(0.,1.); - auto close = samples[current_index].power - lvl; + auto close = samples[current_index].power - level; auto diverse = (float)settings.samplerate/std::max<std::size_t>(pos - last[current_index], 1); auto value = f_close*pow2(close) + f_diverse*pow2(diverse) + f_random*random; diff --git a/src/velocityfilter.cc b/src/velocityfilter.cc new file mode 100644 index 0000000..e774843 --- /dev/null +++ b/src/velocityfilter.cc @@ -0,0 +1,50 @@ +/* -*- Mode: c++ -*- */ +/*************************************************************************** + * velocityfilter.cc + * + * Sun May 12 16:01:41 CEST 2019 + * Copyright 2019 André Nusser + * andre.nusser@googlemail.com + ****************************************************************************/ + +/* + * 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 "velocityfilter.h" + +#include "random.h" +#include "settings.h" + +VelocityFilter::VelocityFilter(Settings& settings, Random& random, Instruments const& instruments) + : settings(settings), random(random), instruments(instruments) +{ +} + +bool VelocityFilter::filter(event_t& event, size_t pos) +{ + auto power_max = instruments[event.instrument]->getMaxPower(); + auto power_min = instruments[event.instrument]->getMinPower(); + float power_span = power_max - power_min; + + float mean = event.velocity - .5f/127.f; // XXX: this should actually be done when reading the events + float stddev = settings.velocity_stddev.load(); + // the 20.0f we determined empirically + float lvl = power_min + random.normalDistribution(mean, stddev / 20.0f) * power_span; + + event.velocity = lvl; + return true; +} diff --git a/src/velocityfilter.h b/src/velocityfilter.h new file mode 100644 index 0000000..6b6d567 --- /dev/null +++ b/src/velocityfilter.h @@ -0,0 +1,53 @@ +/* -*- Mode: c++ -*- */ +/*************************************************************************** + * velocityfilter.h + * + * Sun May 12 16:01:41 CEST 2019 + * Copyright 2019 André Nusser + * andre.nusser@googlemail.com + ****************************************************************************/ + +/* + * 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" +#include "instrument.h" + +struct Settings; +class Random; + +class VelocityFilter + : public InputFilter +{ +public: + VelocityFilter(Settings& settings, Random& random, Instruments const& instruments); + + bool filter(event_t& event, std::size_t pos) override; + + // Note getLatency not overloaded because this filter doesn't add latency. + +private: + Settings& settings; + Random& random; + Instruments const& instruments; +}; |