summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/event.h23
-rw-r--r--plugin/Makefile.mingw32.in2
-rw-r--r--src/Makefile.am7
-rw-r--r--src/Makefile.am.drumgizmo2
-rw-r--r--src/drumgizmo.cc6
-rw-r--r--src/inputfilter.h50
-rw-r--r--src/inputprocessor.cc47
-rw-r--r--src/inputprocessor.h20
-rw-r--r--src/instrument.cc44
-rw-r--r--src/latencyfilter.cc44
-rw-r--r--src/latencyfilter.h45
-rw-r--r--src/staminafilter.cc80
-rw-r--r--src/staminafilter.h51
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;
+};