diff --git a/include/app.hpp b/include/app.hpp index dbcc6fe2..6db43862 100644 --- a/include/app.hpp +++ b/include/app.hpp @@ -34,10 +34,10 @@ struct SVGPanel; // module //////////////////// -// A 1HPx3U module should be 15x380. Thus the width of a module should be a factor of 15. -#define RACK_GRID_WIDTH 15 -#define RACK_GRID_HEIGHT 380 -static const Vec RACK_GRID_SIZE = Vec(15, 380); +// A 1HPx3U module should be 15x380 pixels. Thus the width of a module should be a factor of 15. +static const float RACK_GRID_WIDTH = 15; +static const float RACK_GRID_HEIGHT = 380; +static const Vec RACK_GRID_SIZE = Vec(RACK_GRID_WIDTH, RACK_GRID_HEIGHT); struct ModuleWidget : OpaqueWidget { diff --git a/include/dsp/digital.hpp b/include/dsp/digital.hpp index 599f626a..6b937491 100644 --- a/include/dsp/digital.hpp +++ b/include/dsp/digital.hpp @@ -1,6 +1,6 @@ #pragma once -#include "math.hpp" +#include "util/math.hpp" namespace rack { diff --git a/include/dsp/functions.hpp b/include/dsp/functions.hpp new file mode 100644 index 00000000..4359b906 --- /dev/null +++ b/include/dsp/functions.hpp @@ -0,0 +1,46 @@ +#pragma once + +#include + + +namespace rack { + + +inline float sinc(float x) { + if (x == 0.f) + return 1.f; + x *= M_PI; + return sinf(x) / x; +} + +inline float quadraticBipolar(float x) { + float x2 = x*x; + return (x >= 0.f) ? x2 : -x2; +} + +inline float cubic(float x) { + return x*x*x; +} + +inline float quarticBipolar(float x) { + float y = x*x*x*x; + return (x >= 0.f) ? y : -y; +} + +inline float quintic(float x) { + // optimal with --fast-math + return x*x*x*x*x; +} + +inline float sqrtBipolar(float x) { + return (x >= 0.f) ? sqrtf(x) : -sqrtf(-x); +} + +/** This is pretty much a scaled sinh */ +inline float exponentialBipolar(float b, float x) { + const float a = b - 1.f / b; + return (powf(b, x) - powf(b, -x)) / a; +} + + +} // namespace rack diff --git a/include/dsp/minblep.hpp b/include/dsp/minblep.hpp index 23d88574..caa25f78 100644 --- a/include/dsp/minblep.hpp +++ b/include/dsp/minblep.hpp @@ -1,6 +1,6 @@ #pragma once -#include "math.hpp" +#include "util/math.hpp" namespace rack { diff --git a/include/dsp/ringbuffer.hpp b/include/dsp/ringbuffer.hpp index a34d59e7..8ac80300 100644 --- a/include/dsp/ringbuffer.hpp +++ b/include/dsp/ringbuffer.hpp @@ -1,7 +1,7 @@ #pragma once #include -#include "math.hpp" +#include "util/math.hpp" namespace rack { diff --git a/include/events.hpp b/include/events.hpp index 12d95b04..48a6bedb 100644 --- a/include/events.hpp +++ b/include/events.hpp @@ -1,7 +1,7 @@ #pragma once #include -#include "math.hpp" +#include "util/math.hpp" namespace rack { diff --git a/include/rack.hpp b/include/rack.hpp index d3e78007..89f2f243 100644 --- a/include/rack.hpp +++ b/include/rack.hpp @@ -1,7 +1,7 @@ #pragma once #include "util.hpp" -#include "math.hpp" +#include "util/math.hpp" #include "asset.hpp" #include "plugin.hpp" #include "engine.hpp" diff --git a/include/math.hpp b/include/util/math.hpp similarity index 80% rename from include/math.hpp rename to include/util/math.hpp index 9fc9ffe7..102048ce 100644 --- a/include/math.hpp +++ b/include/util/math.hpp @@ -8,7 +8,7 @@ namespace rack { //////////////////// -// integer functions +// basic integer functions (suffixed with "i") //////////////////// inline int mini(int a, int b) { @@ -19,22 +19,28 @@ inline int maxi(int a, int b) { return a > b ? a : b; } -/** Limits a value between a minimum and maximum */ +/** Limits a value between a minimum and maximum +*/ inline int clampi(int x, int min, int max) { - return x > max ? max : x < min ? min : x; + if (min <= max) + return maxi(mini(x, max), min); + else + return maxi(mini(x, min), max); } inline int absi(int a) { - return a >= 0 ? a : -a; + return (a >= 0) ? a : -a; } -// Euclidean modulus, always returns 0 <= mod < base for positive base -// Assumes this architecture's division is non-Euclidean +/** Euclidean modulus, always returns 0 <= mod < base for positive base. +*/ inline int eucmodi(int a, int base) { int mod = a % base; - return mod < 0 ? mod + base : mod; + return (mod >= 0) ? mod + base : mod; } +/** Returns floor(log_2(n)), or 0 if n == 1. +*/ inline int log2i(int n) { int i = 0; while (n >>= 1) { @@ -48,21 +54,21 @@ inline bool ispow2i(int n) { } //////////////////// -// float functions +// basic float functions (suffixed with "f") //////////////////// inline float absf(float x) { return (x < 0.f) ? -x : x; } -/** Returns 1.0 for positive numbers and -1.0 for negative numbers (including positive/negative zero) */ +/** Returns 1.f for positive numbers and -1.f for negative numbers (including positive/negative zero) */ inline float sgnf(float x) { return copysignf(1.f, x); } inline float eucmodf(float a, float base) { float mod = fmodf(a, base); - return (mod < 0.f) ? mod + base : mod; + return (mod < 0.f) ? mod : mod + base; } inline float nearf(float a, float b, float epsilon = 1e-6) { @@ -81,7 +87,7 @@ inline float clampf(float x, float min, float max) { /** If the magnitude of x if less than eps, return 0 */ inline float chopf(float x, float eps) { - return -eps < x && x < eps ? 0.0 : x; + return (-eps < x && x < eps) ? 0.f : x; } inline float rescalef(float x, float xMin, float xMax, float yMin, float yMax) { @@ -92,41 +98,6 @@ inline float crossf(float a, float b, float frac) { return a + frac * (b - a); } -inline float quadraticBipolar(float x) { - float x2 = x*x; - return x >= 0.0 ? x2 : -x2; -} - -inline float cubic(float x) { - return x*x*x; -} - -inline float quarticBipolar(float x) { - return x >= 0.0 ? x*x*x*x : -x*x*x*x; -} - -inline float quintic(float x) { - // optimal with --fast-math - return x*x*x*x*x; -} - -inline float sqrtBipolar(float x) { - return x >= 0.0 ? sqrtf(x) : -sqrtf(-x); -} - -/** This is pretty much a scaled sinh */ -inline float exponentialBipolar(float b, float x) { - const float a = b - 1.0 / b; - return (powf(b, x) - powf(b, -x)) / a; -} - -inline float sincf(float x) { - if (x == 0.0) - return 1.0; - x *= M_PI; - return sinf(x) / x; -} - /** Linearly interpolate an array `p` with index `x` Assumes that the array at `p` is of length at least floor(x)+1. */ @@ -146,7 +117,7 @@ inline void cmultf(float *cr, float *ci, float ar, float ai, float br, float bi) } //////////////////// -// 2D float vector +// 2D vector and rectangle //////////////////// struct Rect; @@ -154,7 +125,7 @@ struct Rect; struct Vec { float x, y; - Vec() : x(0.0), y(0.0) {} + Vec() : x(0.f), y(0.f) {} Vec(float x, float y) : x(x), y(y) {} Vec neg() { @@ -203,7 +174,7 @@ struct Vec { return x == b.x && y == b.y; } bool isZero() { - return x == 0.0 && y == 0.0; + return x == 0.f && y == 0.f; } bool isFinite() { return std::isfinite(x) && std::isfinite(y); @@ -241,13 +212,13 @@ struct Rect { return pos.isEqual(r.pos) && size.isEqual(r.size); } Vec getCenter() { - return pos.plus(size.mult(0.5)); + return pos.plus(size.mult(0.5f)); } Vec getTopRight() { - return pos.plus(Vec(size.x, 0.0)); + return pos.plus(Vec(size.x, 0.f)); } Vec getBottomLeft() { - return pos.plus(Vec(0.0, size.y)); + return pos.plus(Vec(0.f, size.y)); } Vec getBottomRight() { return pos.plus(size); diff --git a/include/util.hpp b/include/util/util.hpp similarity index 66% rename from include/util.hpp rename to include/util/util.hpp index b504bcfe..ac201198 100644 --- a/include/util.hpp +++ b/include/util/util.hpp @@ -64,46 +64,6 @@ T *construct(F f, V v, Args... args) { } -//////////////////// -// RNG -//////////////////// - -/** Seeds the RNG with the current time */ -void randomInit(); -uint32_t randomu32(); -uint64_t randomu64(); -/** Returns a uniform random float in the interval [0.0, 1.0) */ -float randomf(); -/** Returns a normal random number with mean 0 and std dev 1 */ -float randomNormal(); - -//////////////////// -// String functions -//////////////////// - -/** Converts a printf format string and optional arguments into a std::string */ -std::string stringf(const char *format, ...); -std::string lowercase(std::string s); -std::string uppercase(std::string s); - -/** Truncates and adds "..." to a string, not exceeding `len` characters */ -std::string ellipsize(std::string s, size_t len); -bool startsWith(std::string str, std::string prefix); - -std::string extractDirectory(std::string path); -std::string extractFilename(std::string path); -std::string extractExtension(std::string path); - -//////////////////// -// Operating system functions -//////////////////// - -/** Opens a URL, also happens to work with PDFs and folders. -Shell injection is possible, so make sure the URL is trusted or hard coded. -May block, so open in a new thread. -*/ -void openBrowser(std::string url); - //////////////////// // Thread functions //////////////////// diff --git a/include/widgets.hpp b/include/widgets.hpp index 6ebfaec6..72f91c6b 100644 --- a/include/widgets.hpp +++ b/include/widgets.hpp @@ -6,7 +6,8 @@ #include "../ext/oui-blendish/blendish.h" #include "../ext/nanosvg/src/nanosvg.h" -#include "math.hpp" +#include "util/math.hpp" +#include "util/vec.hpp" #include "util.hpp" #include "events.hpp" diff --git a/src/app/ModuleWidget.cpp b/src/app/ModuleWidget.cpp index 393aee5b..9c9beeac 100644 --- a/src/app/ModuleWidget.cpp +++ b/src/app/ModuleWidget.cpp @@ -185,30 +185,7 @@ void ModuleWidget::randomize() { void ModuleWidget::draw(NVGcontext *vg) { nvgScissor(vg, 0, 0, box.size.x, box.size.y); - Widget::draw(vg); - - // CPU usage text - if (0) { - float cpuTime = module ? module->cpuTime : 0.0; - std::string text = stringf("%.1f%%", cpuTime * 100.0); - - nvgSave(vg); - nvgBeginPath(vg); - nvgRect(vg, 0.0, 0.0, box.size.x, BND_WIDGET_HEIGHT); - nvgFillColor(vg, nvgRGBf(0.0, 0.0, 0.0)); - nvgFill(vg); - - nvgBeginPath(vg); - cpuTime = clampf(cpuTime, 0.0, 1.0); - nvgRect(vg, 0.0, 0.0, box.size.x * cpuTime, BND_WIDGET_HEIGHT); - nvgFillColor(vg, nvgHSL(0.33 * cubic(1.0 - cpuTime), 1.0, 0.4)); - nvgFill(vg); - - bndMenuItem(vg, 0.0, 0.0, box.size.x, BND_WIDGET_HEIGHT, BND_DEFAULT, -1, text.c_str()); - nvgRestore(vg); - } - nvgResetScissor(vg); } diff --git a/src/audio.cpp b/src/audio.cpp index 1e652afd..78b6977f 100644 --- a/src/audio.cpp +++ b/src/audio.cpp @@ -1,5 +1,5 @@ #include "util.hpp" -#include "math.hpp" +#include "util/math.hpp" #include "audio.hpp"