Add the LFO plotting tool
This commit is contained in:
parent
eab53ba05a
commit
0d316399db
3 changed files with 122 additions and 0 deletions
|
|
@ -94,6 +94,9 @@ target_link_libraries(sfizz_plot_curve PRIVATE sfizz::sfizz)
|
||||||
add_executable(sfizz_plot_wavetables PlotWavetables.cpp)
|
add_executable(sfizz_plot_wavetables PlotWavetables.cpp)
|
||||||
target_link_libraries(sfizz_plot_wavetables PRIVATE sfizz::sfizz)
|
target_link_libraries(sfizz_plot_wavetables PRIVATE sfizz::sfizz)
|
||||||
|
|
||||||
|
add_executable(sfizz_plot_lfo PlotLFO.cpp)
|
||||||
|
target_link_libraries(sfizz_plot_lfo PRIVATE sfizz::sfizz)
|
||||||
|
|
||||||
add_executable(sfizz_file_instrument FileInstrument.cpp)
|
add_executable(sfizz_file_instrument FileInstrument.cpp)
|
||||||
target_link_libraries(sfizz_file_instrument PRIVATE sfizz::sfizz)
|
target_link_libraries(sfizz_file_instrument PRIVATE sfizz::sfizz)
|
||||||
|
|
||||||
|
|
|
||||||
100
tests/PlotLFO.cpp
Normal file
100
tests/PlotLFO.cpp
Normal file
|
|
@ -0,0 +1,100 @@
|
||||||
|
// 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/Synth.h"
|
||||||
|
#include "sfizz/LFO.h"
|
||||||
|
#include "sfizz/LFODescription.h"
|
||||||
|
#include <absl/types/span.h>
|
||||||
|
#include <vector>
|
||||||
|
#include <iostream>
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
//==============================================================================
|
||||||
|
|
||||||
|
static constexpr double sampleRate = 44100.0; // sample rate used to compute
|
||||||
|
static constexpr double duration = 5.0; // length in seconds
|
||||||
|
|
||||||
|
/**
|
||||||
|
Print usage information
|
||||||
|
*/
|
||||||
|
static void usage()
|
||||||
|
{
|
||||||
|
std::cerr << "Usage: sfizz_plot_lfo <file.sfz>" "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::vector<sfz::LFODescription> lfoDescriptionFromSfzFile(const fs::path &sfzPath, bool &success)
|
||||||
|
{
|
||||||
|
sfz::Synth synth;
|
||||||
|
|
||||||
|
if (!synth.loadSfzFile(sfzPath)) {
|
||||||
|
std::cerr << "Cannot load the SFZ file.\n";
|
||||||
|
success = false;
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (synth.getNumRegions() != 1) {
|
||||||
|
std::cerr << "The SFZ file must contain exactly one region.\n";
|
||||||
|
success = false;
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
success = true;
|
||||||
|
return synth.getRegionView(0)->lfos;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Program which loads LFO configuration and generates plot data for the given duration.
|
||||||
|
*/
|
||||||
|
int main(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
if (argc < 2 || argc > 2) {
|
||||||
|
usage();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fs::path sfzPath = argv[1];
|
||||||
|
bool success = false;
|
||||||
|
const std::vector<sfz::LFODescription> desc = lfoDescriptionFromSfzFile(sfzPath, success);
|
||||||
|
if (!success)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
size_t numLfos = desc.size();
|
||||||
|
std::vector<sfz::LFO> lfos(numLfos);
|
||||||
|
|
||||||
|
for (size_t l = 0; l < numLfos; ++l) {
|
||||||
|
lfos[l].setSampleRate(sampleRate);
|
||||||
|
lfos[l].configure(&desc[l]);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t numFrames = (size_t)std::ceil(sampleRate * duration);
|
||||||
|
std::vector<float> outputMemory(numLfos * numFrames);
|
||||||
|
|
||||||
|
std::vector<absl::Span<float>> lfoOutputs(numLfos);
|
||||||
|
for (size_t l = 0; l < numLfos; ++l) {
|
||||||
|
lfoOutputs[l] = absl::MakeSpan(&outputMemory[l * numFrames], numFrames);
|
||||||
|
lfos[l].process(lfoOutputs[l]);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < numFrames; ++i) {
|
||||||
|
std::cout << (i / sampleRate);
|
||||||
|
for (size_t l = 0; l < numLfos; ++l)
|
||||||
|
std::cout << ' ' << lfoOutputs[l][i];
|
||||||
|
std::cout << '\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
19
tests/TestFiles/lfo_subwave.sfz
Normal file
19
tests/TestFiles/lfo_subwave.sfz
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
<region>
|
||||||
|
sample=*noise
|
||||||
|
lokey=0
|
||||||
|
hikey=127
|
||||||
|
cutoff=1000.0
|
||||||
|
fil_type=brf_2p
|
||||||
|
lfo1_cutoff=1200.0
|
||||||
|
//
|
||||||
|
lfo1_freq=1
|
||||||
|
lfo1_phase=0.5
|
||||||
|
lfo1_wave=3
|
||||||
|
lfo1_delay=0.5
|
||||||
|
lfo1_fade=0.5
|
||||||
|
lfo1_wave2=1
|
||||||
|
lfo1_offset2=0.2
|
||||||
|
lfo1_ratio2=0.7
|
||||||
|
lfo1_scale2=0.3
|
||||||
|
//
|
||||||
|
lfo2_freq=0.5
|
||||||
Loading…
Add table
Reference in a new issue