// SPDX-License-Identifier: BSD-2-Clause // This code is part of the sfizz library and is licensed under a BSD 2-clause // license. You should have receive a LICENSE.md file along with the code. // If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz /** This program generates the data file of a LFO output recorded for a fixed duration. The file contains columns for each LFO in the SFZ region. The columns are: Time, Lfo1, ... LfoN One can use Gnuplot to display this data. Example: sfizz_plot_lfo file.sfz > lfo.dat gnuplot plot "lfo.dat" using 1:2 with lines */ #include "sfizz/Curve.h" #include "sfizz/parser/Parser.h" #include "absl/strings/numbers.h" #include "absl/types/span.h" #include #include //============================================================================== /** * @brief Print usage information */ static void usage() { std::cerr << "Usage: sfizz_plot_curve [file.sfz]" << "\n"; } /** * @brief Parser listener which extracts the configuration of curves */ class CurveParserListener : public sfz::Parser::Listener { public: explicit CurveParserListener(sfz::CurveSet& curveSet) : curveSet(curveSet) { } void onParseFullBlock(const std::string& header, const std::vector& members) override { if (header == "curve") curveSet.addCurveFromHeader(members); } private: sfz::CurveSet& curveSet; }; /** * @brief Program which loads LFO configuration and generates plot data for the given duration. */ int main(int argc, char* argv[]) { if (argc < 2 || argc > 3) return usage(), 1; int curveIndex = -1; if (!absl::SimpleAtoi(argv[1], &curveIndex)) return usage(), 1; std::string filePath; if (argc > 2) filePath = argv[2]; /// sfz::CurveSet curveSet = sfz::CurveSet::createPredefined(); if (!filePath.empty()) { sfz::Parser parser; CurveParserListener listener(curveSet); parser.setListener(&listener); parser.parseFile(filePath); if (parser.getErrorCount() > 0) { std::cerr << "Cannot load SFZ: " << filePath << "\n"; return 1; } } /// const sfz::Curve& curve = curveSet.getCurve(curveIndex); constexpr unsigned numSamples = 1024; // number of points to evaluate for (unsigned i = 0; i < numSamples; ++i) { float x = i * (1.0f / (numSamples - 1)); std::cout << x << ' ' << curve.evalNormalized(x) << '\n'; } return 0; }