diff options
Diffstat (limited to 'source/device_formula.cpp')
-rw-r--r-- | source/device_formula.cpp | 72 |
1 files changed, 65 insertions, 7 deletions
diff --git a/source/device_formula.cpp b/source/device_formula.cpp index 5c1ca16..e21d374 100644 --- a/source/device_formula.cpp +++ b/source/device_formula.cpp @@ -1,28 +1,86 @@ +/** + * @file device_formula.cpp + * @brief Function for filling generator buffer using a mathematical formula. + * This is kept in its own file as exprtk.hpp takes forever to compile. + * + * Copyright (C) 2021 Clyne Sullivan + * + * Distributed under the GNU GPL v3 or later. You should have received a copy of + * the GNU General Public License along with this program. + * If not, see <https://www.gnu.org/licenses/>. + */ + #include "stmdsp.hpp" -#include "exprtk.hpp" #include <algorithm> +#include <random> #include <string_view> #include <vector> -std::vector<stmdsp::dacsample_t> deviceGenLoadFormulaEval(const std::string_view formulaString) +#ifndef STMDSP_DISABLE_FORMULAS + +#define exprtk_disable_comments +#define exprtk_disable_break_continue +#define exprtk_disable_sc_andor +#define exprtk_disable_return_statement +#define exprtk_disable_enhanced_features +//#define exprtk_disable_string_capabilities +#define exprtk_disable_superscalar_unroll +#define exprtk_disable_rtl_io_file +#define exprtk_disable_rtl_vecops +//#define exprtk_disable_caseinsensitivity +#include "exprtk.hpp" + +static std::random_device randomDevice; + +std::vector<stmdsp::dacsample_t> deviceGenLoadFormulaEval(const std::string& formulaString) { double x = 0; exprtk::symbol_table<double> symbol_table; + exprtk::function_compositor<double> compositor (symbol_table); exprtk::expression<double> expression; exprtk::parser<double> parser; - symbol_table.add_variable("x", x); symbol_table.add_constants(); + symbol_table.add_variable("x", x); + symbol_table.add_function("random", + [](double l, double h) -> double { + return std::uniform_real_distribution<double>(l, h)(randomDevice); + }); + compositor.add(exprtk::function_compositor<double>::function() + .name("square") + .var("X") + .expression("ceil(sin(pi*X))")); + compositor.add(exprtk::function_compositor<double>::function() + .name("triangle") + .var("X") + .expression("ceil(sin(pi*X))*(X-floor(X))+ceil(-sin(pi*X))*(-X-floor(-X))")); + compositor.add(exprtk::function_compositor<double>::function() + .name("pulse") + .var("L") + .var("X") + .expression("if(X<=L,1,0)")); expression.register_symbol_table(symbol_table); - parser.compile(std::string(formulaString), expression); + parser.compile(formulaString, expression); + + const auto genFun = [&x, &expression] { + const auto s = std::clamp(expression.value(), -1., 1.) * 2048. + 2048.; + ++x; + return static_cast<stmdsp::dacsample_t>(std::min(s, 4095.)); + }; std::vector<stmdsp::dacsample_t> samples (stmdsp::SAMPLES_MAX); + std::generate(samples.begin(), samples.end(), genFun); + return samples; +} - std::generate(samples.begin(), samples.end(), - [&] { ++x; return static_cast<stmdsp::dacsample_t>(expression.value()); }); +#else // no formula support - return samples; +std::vector<stmdsp::dacsample_t> deviceGenLoadFormulaEval(const std::string&) +{ + return {}; } +#endif // STMDSP_DISABLE_FORMULAS + |