Allow the LFO tool to set options and output FLAC

This commit is contained in:
Jean Pierre Cimalando 2020-08-13 03:48:10 +02:00
parent b46076ba3b
commit d47bca6f4e

View file

@ -18,16 +18,23 @@
#include "sfizz/Synth.h"
#include "sfizz/LFO.h"
#include "sfizz/LFODescription.h"
#include "sfizz/MathHelpers.h"
#include "cxxopts.hpp"
#include <absl/types/span.h>
#include <vector>
#include <iostream>
#include <cmath>
#ifdef _WIN32
#define ENABLE_SNDFILE_WINDOWS_PROTOTYPES 1
#endif
#include <sndfile.hh>
//==============================================================================
static double sampleRate = 1000.0; // sample rate used to compute
static double duration = 5.0; // length in seconds
static std::string outputFilename;
static bool saveFlac = false;
static std::vector<sfz::LFODescription> lfoDescriptionFromSfzFile(const fs::path &sfzPath, bool &success)
{
@ -59,6 +66,8 @@ int main(int argc, char* argv[])
options.add_options()
("s,samplerate", "Sample rate", cxxopts::value(sampleRate))
("d,duration", "Duration", cxxopts::value(duration))
("o,output", "Output file", cxxopts::value(outputFilename))
("F,flac", "Save output as FLAC", cxxopts::value(saveFlac))
("h,help", "Print usage")
;
options.positional_help("sfz-file");
@ -119,11 +128,72 @@ int main(int argc, char* argv[])
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';
if (saveFlac) {
if (outputFilename.empty()) {
std::cerr << "Please indicate the audio file to save.\n";
return 1;
}
fs::path outputPath = fs::u8path(outputFilename);
SndfileHandle snd(
#ifndef _WIN32
outputPath.c_str(),
#else
outputPath.wstring().c_str(),
#endif
SFM_WRITE, SF_FORMAT_FLAC|SF_FORMAT_PCM_16, numLfos, sampleRate);
std::unique_ptr<float[]> frame(new float[numLfos]);
size_t numClips = 0;
for (size_t i = 0; i < numFrames; ++i) {
for (size_t l = 0; l < numLfos; ++l) {
float orig = lfoOutputs[l][i];
float clamped = clamp(orig, -1.0f, 1.0f);
numClips += clamped != orig;
frame[l] = clamped;
}
snd.writef(frame.get(), 1);
}
snd.writeSync();
if (snd.error()) {
std::error_code ec;
fs::remove(outputPath, ec);
std::cerr << "Could not save audio to the output file.\n";
return 1;
}
if (numClips > 0)
std::cerr << "Warning: the audio output has been clipped on " << numClips << " frames.\n";
}
else {
std::ostream* os = &std::cout;
fs::ofstream of;
fs::path outputPath;
if (!outputFilename.empty()) {
outputPath = fs::u8path(outputFilename);
of.open(outputPath);
os = &of;
}
for (size_t i = 0; i < numFrames; ++i) {
*os << (i / sampleRate);
for (size_t l = 0; l < numLfos; ++l)
*os << ' ' << lfoOutputs[l][i];
*os << '\n';
}
if (os == &of) {
of.flush();
if (!of) {
std::error_code ec;
fs::remove(outputPath, ec);
std::cerr << "Could not save data to the output file.\n";
return 1;
}
}
}
return 0;