summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSander Vocke <sandervocke@gmail.com>2024-07-26 21:57:32 +0200
committerSander Vocke <sandervocke@gmail.com>2024-07-27 14:54:55 +0200
commitf6660bc51fe8c02ff7c3b6188e8437c67712bddf (patch)
treebb8074fcbff6f1a4a6e242941b3cf494ebe4d6cc /src
parent019d478818950f7880d2c0f80d8fc8f963e9736b (diff)
Rename Powermap to CurveMap, bugfix, unit testsdevelopcurve_map
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am4
-rw-r--r--src/curvemap.cc (renamed from src/powermap.cc)122
-rw-r--r--src/curvemap.h94
-rw-r--r--src/powermap.h76
-rw-r--r--src/powermapfilter.h4
5 files changed, 172 insertions, 128 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index a8bdb59..e2a2583 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -67,7 +67,7 @@ libdg_la_SOURCES = \
$(top_srcdir)/src/midimapper.cc \
$(top_srcdir)/src/path.cc \
$(top_srcdir)/src/powerlist.cc \
- $(top_srcdir)/src/powermap.cc \
+ $(top_srcdir)/src/curvemap.cc \
$(top_srcdir)/src/powermapfilter.cc \
$(top_srcdir)/src/random.cc \
$(top_srcdir)/src/sample.cc \
@@ -126,7 +126,7 @@ EXTRA_DIST = \
path.h \
platform.h \
powerlist.h \
- powermap.h \
+ curvemap.h \
powermapfilter.h \
random.h \
range.h \
diff --git a/src/powermap.cc b/src/curvemap.cc
index 2bb45b7..073dde4 100644
--- a/src/powermap.cc
+++ b/src/curvemap.cc
@@ -24,7 +24,7 @@
* along with DrumGizmo; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-#include "powermap.h"
+#include "curvemap.h"
#include <cassert>
#include <cmath>
@@ -32,31 +32,31 @@
namespace
{
-using Power = Powermap::Power;
-using PowerPair = Powermap::PowerPair;
+using CurveValue = CurveMap::CurveValue;
+using CurveValuePair = CurveMap::CurveValuePair;
-Power h00(Power x)
+CurveValue h00(CurveValue x)
{
return (1 + 2 * x) * pow(1 - x, 2);
}
-Power h10(Power x)
+CurveValue h10(CurveValue x)
{
return x * pow(1 - x, 2);
}
-Power h01(Power x)
+CurveValue h01(CurveValue x)
{
return x * x * (3 - 2 * x);
}
-Power h11(Power x)
+CurveValue h11(CurveValue x)
{
return x * x * (x - 1);
}
-Power computeValue(const Power x, const PowerPair& P0, const PowerPair& P1,
- const Power m0, const Power m1)
+CurveValue computeValue(const CurveValue x, const CurveValuePair& P0, const CurveValuePair& P1,
+ const CurveValue m0, const CurveValue m1)
{
const auto x0 = P0.in;
const auto x1 = P1.in;
@@ -74,21 +74,22 @@ Power computeValue(const Power x, const PowerPair& P0, const PowerPair& P1,
} // end anonymous namespace
-Powermap::Powermap()
-{
- reset();
-}
+constexpr std::array<CurveValuePair, 3> CurveMap::default_fixed;
-Power Powermap::map(Power in)
+CurveValue CurveMap::map(CurveValue in)
{
assert(in >= 0. && in <= 1.);
+ if (invert)
+ {
+ in = 1.0 - in;
+ }
if (spline_needs_update)
{
updateSpline();
}
- Power out;
+ CurveValue out;
if (in < fixed[0].in)
{
out = shelf ? fixed[0].out
@@ -113,84 +114,100 @@ Power Powermap::map(Power in)
return out;
}
-void Powermap::reset()
+void CurveMap::reset()
{
- setFixed0({eps, eps});
- setFixed1({.5, .5});
- setFixed2({1 - eps, 1 - eps});
- // FIXME: better false?
- shelf = true;
+ *this = CurveMap{};
updateSpline();
}
-void Powermap::setFixed0(PowerPair new_value)
+void CurveMap::setFixed0(CurveValuePair new_value)
{
- if (fixed[0] != new_value)
+ auto prev = fixed[0];
+ fixed[0].in = clamp(new_value.in, eps, fixed[1].in - eps);
+ fixed[0].out = clamp(new_value.out, eps, fixed[1].out - eps);
+ if (fixed[0] != prev)
{
spline_needs_update = true;
- fixed[0].in = clamp(new_value.in, eps, fixed[1].in - eps);
- fixed[0].out = clamp(new_value.out, eps, fixed[1].out - eps);
}
}
-void Powermap::setFixed1(PowerPair new_value)
+void CurveMap::setFixed1(CurveValuePair new_value)
{
- if (fixed[1] != new_value)
+ auto prev = fixed[1];
+ fixed[1].in = clamp(new_value.in, fixed[0].in + eps, fixed[2].in - eps);
+ fixed[1].out = clamp(new_value.out, fixed[0].out + eps, fixed[2].out - eps);
+ if (fixed[1] != prev)
{
spline_needs_update = true;
- fixed[1].in = clamp(new_value.in, fixed[0].in + eps, fixed[2].in - eps);
- fixed[1].out = clamp(new_value.out, fixed[0].out + eps, fixed[2].out - eps);
}
}
-void Powermap::setFixed2(PowerPair new_value)
+void CurveMap::setFixed2(CurveValuePair new_value)
{
- if (fixed[2] != new_value)
+ auto prev = fixed[2];
+ fixed[2].in = clamp(new_value.in, fixed[1].in + eps, 1 - eps);
+ fixed[2].out = clamp(new_value.out, fixed[1].out + eps, 1 - eps);
+ if (fixed[2] != prev)
{
spline_needs_update = true;
- fixed[2].in = clamp(new_value.in, fixed[1].in + eps, 1 - eps);
- fixed[2].out = clamp(new_value.out, fixed[1].out + eps, 1 - eps);
}
}
-void Powermap::setShelf(bool enable)
+void CurveMap::setInvert(bool enable)
+{
+ if (invert != enable)
+ {
+ spline_needs_update = true;
+ invert = enable;
+ }
+}
+
+void CurveMap::setShelf(bool enable)
{
if (shelf != enable)
{
spline_needs_update = true;
- this->shelf = enable;
+ shelf = enable;
}
}
-PowerPair Powermap::getFixed0() const
+CurveValuePair CurveMap::getFixed0() const
{
return fixed[0];
}
-PowerPair Powermap::getFixed1() const
+CurveValuePair CurveMap::getFixed1() const
{
return fixed[1];
}
-PowerPair Powermap::getFixed2() const
+CurveValuePair CurveMap::getFixed2() const
{
return fixed[2];
}
+bool CurveMap::getInvert() const {
+ return invert;
+}
+
+bool CurveMap::getShelf() const {
+ return shelf;
+}
+
// This mostly followes the wikipedia article for monotone cubic splines:
// https://en.wikipedia.org/wiki/Monotone_cubic_interpolation
-void Powermap::updateSpline()
+void CurveMap::updateSpline()
{
assert(0. <= fixed[0].in && fixed[0].in < fixed[1].in &&
fixed[1].in < fixed[2].in && fixed[2].in <= 1.);
assert(0. <= fixed[0].out && fixed[0].out <= fixed[1].out &&
fixed[1].out <= fixed[2].out && fixed[2].out <= 1.);
- Powers X = shelf ? Powers{fixed[0].in, fixed[1].in, fixed[2].in}
- : Powers{0., fixed[0].in, fixed[1].in, fixed[2].in, 1.};
- Powers Y = shelf ? Powers{fixed[0].out, fixed[1].out, fixed[2].out}
- : Powers{0., fixed[0].out, fixed[1].out, fixed[2].out, 1.};
+ CurveValues X = shelf ? CurveValues{fixed[0].in, fixed[1].in, fixed[2].in}
+ : CurveValues{0., fixed[0].in, fixed[1].in, fixed[2].in, 1.};
+ CurveValues Y = shelf ? CurveValues{fixed[0].out, fixed[1].out, fixed[2].out}
+ : CurveValues{0., fixed[0].out, fixed[1].out, fixed[2].out, 1.};
auto slopes = calcSlopes(X, Y);
@@ -215,12 +232,12 @@ void Powermap::updateSpline()
// This follows the monotone cubic spline algorithm of Steffen, from:
// "A Simple Method for Monotonic Interpolation in One Dimension"
-std::vector<float> Powermap::calcSlopes(const Powers& X, const Powers& Y)
+std::vector<float> CurveMap::calcSlopes(const CurveValues& X, const CurveValues& Y)
{
- Powers m(X.size());
+ CurveValues m(X.size());
- Powers d(X.size() - 1);
- Powers h(X.size() - 1);
+ CurveValues d(X.size() - 1);
+ CurveValues h(X.size() - 1);
for (std::size_t i = 0; i < d.size(); ++i)
{
h[i] = X[i + 1] - X[i];
@@ -245,7 +262,16 @@ std::vector<float> Powermap::calcSlopes(const Powers& X, const Powers& Y)
return m;
}
-Power Powermap::clamp(Power in, Power min, Power max) const
+CurveValue CurveMap::clamp(CurveValue in, CurveValue min, CurveValue max) const
{
return std::max(min, std::min(in, max));
}
+
+bool CurveMap::operator==(const CurveMap& other) const
+{
+ return getFixed0() == other.getFixed0() &&
+ getFixed1() == other.getFixed1() &&
+ getFixed2() == other.getFixed2() &&
+ getShelf() == other.getShelf() &&
+ getInvert() == other.getInvert();
+}
diff --git a/src/curvemap.h b/src/curvemap.h
new file mode 100644
index 0000000..926543d
--- /dev/null
+++ b/src/curvemap.h
@@ -0,0 +1,94 @@
+/* -*- Mode: c++ -*- */
+/***************************************************************************
+ * curvemap.h
+ *
+ * Fri Apr 17 23:06:12 CEST 2020
+ * Copyright 2020 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 <array>
+#include <vector>
+
+class CurveMap
+{
+public:
+ using CurveValue = float;
+ using CurveValues = std::vector<CurveValue>;
+
+ bool operator==(const CurveMap& other) const;
+
+ struct CurveValuePair
+ {
+ CurveValue in;
+ CurveValue out;
+
+ bool operator==(const CurveValuePair& other)
+ {
+ return in == other.in || out == other.out;
+ }
+ bool operator!=(const CurveValuePair& other)
+ {
+ return !(*this == other);
+ }
+ };
+
+ CurveValue map(CurveValue in);
+ void reset();
+
+ void setFixed0(CurveValuePair new_value);
+ void setFixed1(CurveValuePair new_value);
+ void setFixed2(CurveValuePair new_value);
+ void setShelf(bool enable);
+
+ //! If enabled, inversion inverts (1 - x) the input value before mapping
+ //! it through the curve.
+ void setInvert(bool enable);
+
+ CurveValuePair getFixed0() const;
+ CurveValuePair getFixed1() const;
+ CurveValuePair getFixed2() const;
+ bool getShelf() const;
+ bool getInvert() const;
+
+private:
+ static constexpr CurveValue eps = 1e-4;
+ static constexpr std::array<CurveValuePair, 3> default_fixed {
+ CurveValuePair {eps, eps},
+ CurveValuePair {.5, .5},
+ CurveValuePair {1 - eps, 1 - eps}
+ };
+
+ // input parameters (state of this class)
+ std::array<CurveValuePair, 3> fixed { default_fixed };
+ bool shelf { true };
+ bool invert { false };
+
+ // spline parameters (deterministically computed from the input parameters)
+ bool spline_needs_update { true };
+ std::array<float, 5> m { 0, 0, 0, 0, 0 };
+
+ void updateSpline();
+ std::vector<float> calcSlopes(const CurveValues& X, const CurveValues& P);
+
+ CurveValue clamp(CurveValue in, CurveValue min, CurveValue max) const;
+}; \ No newline at end of file
diff --git a/src/powermap.h b/src/powermap.h
deleted file mode 100644
index 3a406cc..0000000
--- a/src/powermap.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/* -*- Mode: c++ -*- */
-/***************************************************************************
- * powermap.h
- *
- * Fri Apr 17 23:06:12 CEST 2020
- * Copyright 2020 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 <array>
-#include <vector>
-
-class Powermap
-{
-public:
- using Power = float;
- using Powers = std::vector<Power>;
- struct PowerPair
- {
- Power in;
- Power out;
-
- bool operator!=(const PowerPair& other)
- {
- return in != other.in || out != other.out;
- }
- };
-
- Powermap();
-
- Power map(Power in);
- void reset();
-
- void setFixed0(PowerPair new_value);
- void setFixed1(PowerPair new_value);
- void setFixed2(PowerPair new_value);
- void setShelf(bool enable);
-
- PowerPair getFixed0() const;
- PowerPair getFixed1() const;
- PowerPair getFixed2() const;
-
-private:
- // input parameters (state of this class)
- std::array<PowerPair, 3> fixed;
- bool shelf;
-
- // spline parameters (deterministically computed from the input parameters)
- bool spline_needs_update;
- std::array<float, 5> m;
- const Power eps = 1e-4;
-
- void updateSpline();
- std::vector<float> calcSlopes(const Powers& X, const Powers& P);
-
- Power clamp(Power in, Power min, Power max) const;
-};
diff --git a/src/powermapfilter.h b/src/powermapfilter.h
index 263f809..b9dfe5b 100644
--- a/src/powermapfilter.h
+++ b/src/powermapfilter.h
@@ -27,7 +27,7 @@
#pragma once
#include "inputfilter.h"
-#include "powermap.h"
+#include "curvemap.h"
struct Settings;
@@ -43,5 +43,5 @@ public:
private:
Settings& settings;
- Powermap powermap;
+ CurveMap powermap;
};