diff --git a/notes b/notes index 7bcd271..0c4ee9e 100644 --- a/notes +++ b/notes @@ -35,12 +35,7 @@ TODO { about-license info } - more ui options for laptop stuff { - - invert scrollwheel (knobs) - maybe scroll sensitivity - } - - add common oscillators to a nodelib header + > add common oscillators to a nodelib header revert-to-saved menu action diff --git a/xybrid/nodelib/basics.h b/xybrid/nodelib/basics.h index e7d81db..c11fb55 100644 --- a/xybrid/nodelib/basics.h +++ b/xybrid/nodelib/basics.h @@ -8,14 +8,14 @@ class QCborValue; namespace Xybrid::NodeLib { // more precision than probably fits in a double, but it certainly shouldn't hurt - const constexpr double PI = 3.141592653589793238462643383279502884197169399375105820974; - const constexpr double SEMI = 1.059463094359295264561825294946341700779204317494185628559; + const inline constexpr double PI = 3.141592653589793238462643383279502884197169399375105820974; + const inline constexpr double SEMI = 1.059463094359295264561825294946341700779204317494185628559; /// Multiplier to compensate for the balance equation - // (1.0 / cos(PI*0.25)) - const constexpr double PAN_MULT = 1.414213562373095048801688724209698078569671875376948073176; + /// (1.0 / cos(PI*0.25)) + const inline constexpr double PAN_MULT = 1.414213562373095048801688724209698078569671875376948073176; /// Sane mimimum transition time to avoid clip artifacts - const constexpr double shortStep = 0.0025; + const inline constexpr double shortStep = 0.0025; struct ADSR { double a = 0.0, d = 0.0, s = 1.0, r = 0.0; diff --git a/xybrid/nodelib/osc.h b/xybrid/nodelib/osc.h new file mode 100644 index 0000000..a766ec1 --- /dev/null +++ b/xybrid/nodelib/osc.h @@ -0,0 +1,10 @@ +#pragma once + +#include "util/ext.h" + +namespace Xybrid::NodeLib { + namespace Oscillator { + // + } + namespace Osc = Oscillator; +} diff --git a/xybrid/nodes/instrument/2x03.cpp b/xybrid/nodes/instrument/2x03.cpp index 2ed4067..6d601ae 100644 --- a/xybrid/nodes/instrument/2x03.cpp +++ b/xybrid/nodes/instrument/2x03.cpp @@ -18,6 +18,7 @@ using namespace Xybrid::Audio; using namespace Xybrid::UI; #include "util/strings.h" +#include "util/ext.h" #include @@ -49,12 +50,8 @@ namespace { return m; }(); - // silence qtcreator warnings about gcc optimize attributes -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wattributes" - // polyBLEP algorithm (pulse antialiasing), slightly modified from https://www.kvraudio.com/forum/viewtopic.php?t=375517 - [[gnu::optimize("O3")]] double polyblep(double t, double dt) { + force_opt double polyblep(double t, double dt) { // 0 <= t < 1 if (t < dt) { t /= dt; @@ -69,7 +66,7 @@ namespace { return 0.0; } - [[gnu::optimize("O3")]] double oscPulse(double phase, double delta, double duty = 0.5) { + force_opt double oscPulse(double phase, double delta, double duty = 0.5) { //double duty = 0.5 + std::cos(time * 2.5) * (1 - 0.125*2) * 0.5; double d = 1.0; if (std::fmod(phase, 1.0) >= duty) d = -1.0; @@ -78,13 +75,13 @@ namespace { return d - (duty-0.5)*2; // DC offset compensation } - [[gnu::optimize("O3")]] double oscTri(double phase) { + force_opt double oscTri(double phase) { phase = std::fmod(phase + 0.75, 1.0); phase = phase * 0.2 + (std::floor(phase*32.0) / 32.0) * 0.8; return std::abs(phase*2.0 - 1.0)*2.0 - 1.0; } - [[gnu::optimize("O3")]] double oscSaw(double phase, double delta) { + force_opt double oscSaw(double phase, double delta) { phase = std::fmod(phase + 0.5, 1.0); double d = phase * 0.2 + (std::floor(phase*7.0) / 7.0 + (0.5/7.0)) * 0.8; d = d * 2.0 - 1.0; @@ -92,7 +89,6 @@ namespace { return d; } -#pragma GCC diagnostic pop } I2x03::I2x03() { diff --git a/xybrid/nodes/instrument/thicc.cpp b/xybrid/nodes/instrument/thicc.cpp index 07f062d..7a0cc21 100644 --- a/xybrid/nodes/instrument/thicc.cpp +++ b/xybrid/nodes/instrument/thicc.cpp @@ -18,6 +18,7 @@ using namespace Xybrid::Audio; using namespace Xybrid::UI; #include "util/strings.h" +#include "util/ext.h" #include #include @@ -47,12 +48,8 @@ namespace { return b * p + a * (1.0 - p); } - // silence qtcreator warnings about gcc optimize attributes -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wattributes" - // polyBLEP algorithm (pulse antialiasing), slightly modified from https://www.kvraudio.com/forum/viewtopic.php?t=375517 - [[gnu::optimize("O3")]] double polyblep(double t, double dt) { + force_opt double polyblep(double t, double dt) { // 0 <= t < 1 if (t < dt) { t /= dt; @@ -67,7 +64,7 @@ namespace { return 0.0; } - [[gnu::optimize("O3")]] inline double push(double in, double mod, double factor) { + force_opt inline double push(double in, double mod, double factor) { double s = in < 0 ? -1 : 1; in *= s; //if (mod < 0) mod = 1.0/-mod; @@ -76,7 +73,7 @@ namespace { return std::pow(in, mod)*s; } - [[gnu::optimize("O3")]] double oscSaw(double phase, double delta, double mod) { + force_opt double oscSaw(double phase, double delta, double mod) { phase = std::fmod(phase + 0.5, 1.0); double d = phase;// * 0.2 + (std::floor(phase*7.0) / 7.0 + (0.5/7.0)) * 0.8; d = d * 2.0 - 1.0; @@ -85,9 +82,9 @@ namespace { return d; } - [[gnu::optimize("O3")]] double oscSine(double phase, double, double mod) { return push(std::sin(phase*PI*2), -mod, 5); } + force_opt double oscSine(double phase, double, double mod) { return push(std::sin(phase*PI*2), -mod, 5); } - [[gnu::optimize("O3")]] double oscPulse(double phase, double delta, double mod) { + force_opt double oscPulse(double phase, double delta, double mod) { double duty = (mod+1.0)/2.0; double d = 1.0; if (std::fmod(phase, 1.0) >= duty) d = -1.0; @@ -96,9 +93,6 @@ namespace { return d; } - -#pragma GCC diagnostic pop - // for clang on freebsd (and possibly other non-apple llvm sources) it seems we need to specify more. // wave function list(s) const constexpr std::array waveFunc = { diff --git a/xybrid/util/ext.h b/xybrid/util/ext.h index bc0b651..cf93835 100644 --- a/xybrid/util/ext.h +++ b/xybrid/util/ext.h @@ -3,6 +3,26 @@ #include +// gcc only, no clang to complain here pls +#if defined(__GNUC__) && !defined(__clang__) +#define force_opt __attribute__((optimize("3"))) +#endif + +// things that work for gcc and clang +#if defined(__GNUC__) || defined(__clang__) +#define force_inline [[gnu::always_inline]] +#endif + +// and empty defs for these if not available for current compiler +#ifndef force_inline +#define force_inline +#endif + +#ifndef force_opt +#define force_opt +#endif + + template inline constexpr TO hard_cast(FROM f) { static_assert(std::is_pointer_v && std::is_pointer_v); return reinterpret_cast( reinterpret_cast(f) );