summaryrefslogtreecommitdiff
path: root/drumgizmo
diff options
context:
space:
mode:
Diffstat (limited to 'drumgizmo')
-rw-r--r--drumgizmo/drumgizmoc.cc702
1 files changed, 370 insertions, 332 deletions
diff --git a/drumgizmo/drumgizmoc.cc b/drumgizmo/drumgizmoc.cc
index b34b6e1..4853641 100644
--- a/drumgizmo/drumgizmoc.cc
+++ b/drumgizmo/drumgizmoc.cc
@@ -62,13 +62,12 @@ static std::string version()
static std::string copyright()
{
std::ostringstream output;
- output << "Copyright (C) 2008-2018 Bent Bisballe Nyeng - Aasimon.org.\n";
+ output << "Copyright (C) 2008-2020 DrumGizmo team - DrumGizmo.org.\n";
output << "This is free software. You may redistribute copies of it under the terms ";
output << "of\n";
output << "the GNU Lesser General Public License <http://www.gnu.org/licenses/gpl.html>.\n";
output << "There is NO WARRANTY, to the extent permitted by law.\n";
output << "\n";
- output << "Written by Bent Bisballe Nyeng (deva@aasimon.org)\n";
return output.str();
}
@@ -81,49 +80,14 @@ static std::string usage(const std::string& name)
"only available in the plugins.\n"
"==============================================================================\n"
"\n"
- "Usage: " << name << " [options] drumkitfile\n"
- "Options:\n"
- " -a, --async-load Load drumkit in the background and start the"
- " engine immediately.\n"
- " -b --bleed Set and enable master bleed\n"
-
-// stddev
-// velocity-attack
-// velocity-release
-// tightness
-// timing-regain
-// laidback
-
- " -i, --inputengine dummy|test|jackmidi|midifile Use said event "
- "input engine.\n"
- " -I, --inputparms parmlist\n"
- " Set input engine parameters.\n"
- " -o, --outputengine dummy|alsa|jackaudio|wavfile Use said audio "
- "output engine.\n"
- " -O, --outputparms parmlist Set output engine parameters.\n"
- " -e, --endpos Number of samples to process, -1: infinite.\n"
-#ifndef DISABLE_HUGIN
- " -D, --debug ddd Enable debug messages on 'ddd' see hugin "
- "documentation for details\n"
-#endif /*DISABLE_HUGIN*/
- " -r, --no-resampling Disable resampling.\n"
- " -s, --streaming Enable streaming.\n"
- " -S, --streamingparms parmlist\n"
- " Streaming options.\n"
- " -t, --timing-humanizer\n"
- " Enable moving of notes in time. Note adds latency to the output so do not\n"
- " use this with a real-time drumkit.\n"
- " -T, --timing-humanizerparms parmlist\n"
- " Timing humanizer options.\n"
- " -x, --velocity-humanizer\n"
- " Enables adapting input velocities to make it sound more realistic.\n"
- " -X, --velocity-humanizerparms parmlist\n"
- " Velocity humanizer options.\n"
- " -p, --parameters parmlist\n"
- " Parameters for sample selection algorithm."
- " -v, --version Print version information and exit.\n"
- " -h, --help Print this message and exit.\n"
- "\n"
+ "Usage: " << name << " [options] drumkitfile\n";
+ return output.str();
+}
+
+static std::string arguments()
+{
+ std::ostringstream output;
+ output <<
"Input engine parameters:\n"
" jackmidi: midimap=<midimapfile>\n"
" midifile: file=<midifile>, speed=<tempo> (default 1.0),\n"
@@ -176,7 +140,6 @@ static std::string usage(const std::string& name)
return output.str();
}
-
std::vector<ParmToken> parseParameters(std::string &parms)
{
std::vector<ParmToken> result;
@@ -231,7 +194,6 @@ std::vector<ParmToken> parseParameters(std::string &parms)
return result;
}
-
int main(int argc, char* argv[])
{
EngineFactory factory;
@@ -253,305 +215,381 @@ int main(int argc, char* argv[])
{
std::cout << version();
std::cout << usage(argv[0]);
- exit(0);
+ return 0;
}
- opt.add("async-load", no_argument, 'a', [&]() {
- async = true;
- });
-
- opt.add("bleed", required_argument, 'B', [&]() {
- float bleed = atof_nol(optarg);
- settings.enable_bleed_control = true;
- settings.master_bleed = bleed;
- });
-
- opt.add("inputengine", required_argument, 'i', [&]() {
- std::string engine = optarg;
- if(engine == "help")
- {
- std::cout << "Available Input Engines = { ";
- for(auto const& name : factory.getInputEngines())
- {
- std::cout << name << " ";
- }
- std::cout << "}\n";
- exit(0);
- }
- if(engine == "")
- {
- std::cerr << "Missing input engine" << std::endl;;
- exit(1);
- }
- ie = factory.createInput(engine);
- if(ie == NULL)
- {
- std::cerr << "Invalid input engine: " << engine << std::endl;
- exit(1);
- }
- });
-
- opt.add("inputparms", required_argument, 'I', [&]() {
- std::string parms = optarg;
- auto tokens = parseParameters(parms);
- for(auto& token : tokens)
- {
- ie->setParm(token.key, token.value);
- }
- });
-
- opt.add("outputengine", required_argument, 'o', [&]() {
- std::string engine = optarg;
- if(engine == "help")
- {
- std::cout << "Available Output Engines = { ";
- for(auto const& name : factory.getOutputEngines())
- {
- std::cout << name << " ";
- }
- std::cout << " }\n";
- exit(0);
- }
- if(engine == "")
- {
- std::cerr << "Missing output engine" << std::endl;
- exit(1);
- }
- oe = factory.createOutput(engine);
- if(ie == NULL)
- {
- std::cerr << "Invalid output engine: " << engine << std::endl;;
- exit(1);
- }
- });
-
- opt.add("outputparms", required_argument, 'O', [&]() {
- std::string parms = optarg;
- auto tokens = parseParameters(parms);
- for(auto& token : tokens)
- {
- oe->setParm(token.key, token.value);
- }
- });
-
- opt.add("endpos", required_argument, 'e', [&]() {
- try
- {
- endpos = std::stoi(optarg);
- }
- catch(...)
- {
- std::cerr << "Invalid endpos size " << optarg << std::endl;
- }
- });
+ opt.add("async-load", no_argument, 'a',
+ "Load drumkit in the background and start the engine immediately.",
+ [&]()
+ {
+ async = true;
+ return 0;
+ });
+
+ opt.add("bleed", required_argument, 'b',
+ "Set and enable master bleed.",
+ [&]()
+ {
+ float bleed = atof_nol(optarg);
+ settings.enable_bleed_control = true;
+ settings.master_bleed = bleed;
+ return 0;
+ });
+
+ opt.add("inputengine", required_argument, 'i',
+ "dummy|test|jackmidi|midifile Use said event input engine.",
+ [&]()
+ {
+ std::string engine = optarg;
+ if(engine == "help")
+ {
+ std::cout << "Available Input Engines = { ";
+ for(auto const& name : factory.getInputEngines())
+ {
+ std::cout << name << " ";
+ }
+ std::cout << "}\n";
+ exit(0);
+ }
+ if(engine == "")
+ {
+ std::cerr << "Missing input engine" << std::endl;
+ return 1;
+ }
+ ie = factory.createInput(engine);
+ if(ie == NULL)
+ {
+ std::cerr << "Invalid input engine: " << engine << std::endl;
+ return 1;
+ }
+ return 0;
+ });
+
+ opt.add("inputparms", required_argument, 'I',
+ "Set input engine parameters.",
+ [&]()
+ {
+ std::string parms = optarg;
+ auto tokens = parseParameters(parms);
+ for(auto& token : tokens)
+ {
+ ie->setParm(token.key, token.value);
+ }
+ return 0;
+ });
+
+ opt.add("outputengine", required_argument, 'o',
+ "dummy|alsa|jackaudio|wavfile Use said audio output engine.",
+ [&]()
+ {
+ std::string engine = optarg;
+ if(engine == "help")
+ {
+ std::cout << "Available Output Engines = { ";
+ for(auto const& name : factory.getOutputEngines())
+ {
+ std::cout << name << " ";
+ }
+ std::cout << " }\n";
+ exit(0);
+ }
+ if(engine == "")
+ {
+ std::cerr << "Missing output engine" << std::endl;
+ return 1;
+ }
+ oe = factory.createOutput(engine);
+ if(ie == NULL)
+ {
+ std::cerr << "Invalid output engine: " << engine << std::endl;
+ return 1;
+ }
+ return 0;
+ });
+
+ opt.add("outputparms", required_argument, 'O',
+ "Set output engine parameters.",
+ [&]()
+ {
+ std::string parms = optarg;
+ auto tokens = parseParameters(parms);
+ for(auto& token : tokens)
+ {
+ oe->setParm(token.key, token.value);
+ }
+ return 0;
+ });
+
+ opt.add("endpos", required_argument, 'e',
+ "Number of samples to process, -1: infinite.",
+ [&]()
+ {
+ try
+ {
+ endpos = std::stoi(optarg);
+ }
+ catch(...)
+ {
+ std::cerr << "Invalid endpos size " << optarg << std::endl;
+ }
+ return 0;
+ });
#ifndef DISABLE_HUGIN
- opt.add("debug", required_argument, 'D', [&]() {
- hugin_flags |= HUG_FLAG_USE_FILTER;
- hugin_filter = optarg;
- });
+ opt.add("debug", required_argument, 'D',
+ "Enable debug messages on 'ddd' see hugin documentation for details.",
+ [&]()
+ {
+ hugin_flags |= HUG_FLAG_USE_FILTER;
+ hugin_filter = optarg;
+ return 0;
+ });
#endif /*DISABLE_HUGIN*/
- opt.add("no-resampling", no_argument, 'r', [&]() {
- settings.enable_resampling = false;
- });
-
- opt.add("streaming", no_argument, 's', [&]() {
- settings.disk_cache_enable = true;
- });
-
- opt.add("streamingparms", required_argument, 'S', [&]() {
- std::string parms = optarg;
- auto tokens = parseParameters(parms);
- for(auto& token : tokens)
- {
- if(token.key == "limit")
- {
- settings.disk_cache_upper_limit = byteSizeParser(token.value);
- if(settings.disk_cache_upper_limit == 0)
- {
- std::cerr << "Invalid argument for streamparms limit: " <<
- token.value << std::endl;
- exit(1);
- }
- }
- //else if(token.key == "chunk_size")
- //{
- // settings.disk_cache_chunk_size = byteSizeParser(token.value);
- // if(settings.disk_cache_chunk_size == 0)
- // {
- // std::cerr << "Invalid argument for streamparms chunk_size: " <<
- // token.value << std::endl;
- // exit(1);
- // }
- // }
- else
- {
- std::cerr << "Unknown streamingparms argument " << token.key <<
- std::endl;
- exit(1);
- }
- }
- });
+ opt.add("no-resampling", no_argument, 'r',
+ "Disable resampling.",
+ [&]()
+ {
+ settings.enable_resampling = false;
+ return 0;
+ });
+
+ opt.add("streaming", no_argument, 's',
+ "Enable streaming.",
+ [&]()
+ {
+ settings.disk_cache_enable = true;
+ return 0;
+ });
+
+ opt.add("streamingparms", required_argument, 'S',
+ "Streaming options.",
+ [&]()
+ {
+ std::string parms = optarg;
+ auto tokens = parseParameters(parms);
+ for(auto& token : tokens)
+ {
+ if(token.key == "limit")
+ {
+ settings.disk_cache_upper_limit = byteSizeParser(token.value);
+ if(settings.disk_cache_upper_limit == 0)
+ {
+ std::cerr << "Invalid argument for streamparms limit: " <<
+ token.value << std::endl;
+ return 1;
+ }
+ }
+ //else if(token.key == "chunk_size")
+ //{
+ // settings.disk_cache_chunk_size = byteSizeParser(token.value);
+ // if(settings.disk_cache_chunk_size == 0)
+ // {
+ // std::cerr << "Invalid argument for streamparms chunk_size: " <<
+ // token.value << std::endl;
+ // return 1;
+ // }
+ // }
+ else
+ {
+ std::cerr << "Unknown streamingparms argument " << token.key <<
+ std::endl;
+ return 1;
+ }
+ }
+ return 0;
+ });
// Default is to disable timing humanizer
settings.enable_latency_modifier.store(false);
- opt.add("timing-humanizer", no_argument, 't', [&]() {
- settings.enable_latency_modifier.store(true);
- });
-
- opt.add("timing-humanizerparms", required_argument, 'T', [&]() {
- std::string parms = optarg;
- auto tokens = parseParameters(parms);
- for(auto& token : tokens)
- {
- if(token.key == "laidback")
- {
- // Input range [+/- 100] ms
- auto val = atof_nol(token.value.data());
- if(val < -100.0 || val > 100.0)
- {
- std::cerr << "laidback range is +/- 100 and is in ms.\n";
- exit(1);
- }
- settings.latency_laid_back_ms.store(val);
- }
- else if(token.key == "tightness")
- {
- // Input range [0, 1]
- auto val = atof_nol(token.value.data());
- if(val < 0.0 || val > 1.0)
- {
- std::cerr << "tightness range is [0, 1].\n";
- exit(1);
- }
- settings.latency_stddev.store((-1.0 * val + 1.0) * 20.0);
- }
- else if(token.key == "regain")
- {
- auto val = atof_nol(token.value.data());
- if(val < 0.0 || val > 1.0)
- {
- std::cerr << "regain range is [0, 1].\n";
- exit(1);
- }
- settings.latency_regain.store(val);
- }
- else
- {
- std::cerr << "Unknown timing-humanizerparms argument " << token.key << std::endl;
- exit(1);
- }
- }
- });
+ opt.add("timing-humanizer", no_argument, 't',
+ "Enable moving of notes in time.\nNOTE: Adds latency to the output so do not use this with a real-time drumkit.",
+ [&]()
+ {
+ settings.enable_latency_modifier.store(true);
+ return 0;
+ });
+
+ opt.add("timing-humanizerparms", required_argument, 'T',
+ "Timing humanizer options.",
+ [&]()
+ {
+ std::string parms = optarg;
+ auto tokens = parseParameters(parms);
+ for(auto& token : tokens)
+ {
+ if(token.key == "laidback")
+ {
+ // Input range [+/- 100] ms
+ auto val = atof_nol(token.value.data());
+ if(val < -100.0 || val > 100.0)
+ {
+ std::cerr << "laidback range is +/- 100 and is in ms.\n";
+ return 1;
+ }
+ settings.latency_laid_back_ms.store(val);
+ }
+ else if(token.key == "tightness")
+ {
+ // Input range [0, 1]
+ auto val = atof_nol(token.value.data());
+ if(val < 0.0 || val > 1.0)
+ {
+ std::cerr << "tightness range is [0, 1].\n";
+ return 1;
+ }
+ settings.latency_stddev.store((-1.0 * val + 1.0) * 20.0);
+ }
+ else if(token.key == "regain")
+ {
+ auto val = atof_nol(token.value.data());
+ if(val < 0.0 || val > 1.0)
+ {
+ std::cerr << "regain range is [0, 1].\n";
+ return 1;
+ }
+ settings.latency_regain.store(val);
+ }
+ else
+ {
+ std::cerr << "Unknown timing-humanizerparms argument " << token.key << std::endl;
+ return 1;
+ }
+ }
+ return 0;
+ });
// Default is to disable the velocity humanizer
settings.enable_velocity_modifier.store(false);
- opt.add("velocity-humanizer", no_argument, 'x', [&]() {
- settings.enable_velocity_modifier.store(true);
- });
-
- opt.add("velocity-humanizerparms", required_argument, 'X', [&]() {
- std::string parms = optarg;
- auto tokens = parseParameters(parms);
- for(auto& token : tokens)
- {
- if (token.key == "attack")
- {
- auto val = atof_nol(token.value.data());
- if(val < 0 || val > 1.0)
- {
- std::cerr << "attack range is [0, 1].\n";
- exit(1);
- }
- settings.velocity_modifier_weight.store(val);
- }
- else if (token.key == "release")
- {
- auto val = atof_nol(token.value.data());
- if(val < 0 || val > 1.0)
- {
- std::cerr << "release range is [0, 1].\n";
- exit(1);
- }
- settings.velocity_modifier_falloff.store(val);
- }
- else if(token.key == "stddev")
- {
- auto val = atof_nol(token.value.data());
- if(val < 0 || val > 4.5)
- {
- std::cerr << "stddev range is [0, 4.5].\n";
- exit(1);
- }
- settings.velocity_stddev.store(val);
- }
- else
- {
- std::cerr << "Unknown velocity-humanizerparms argument " << token.key << std::endl;
- exit(1);
- }
- }
- });
-
- opt.add("parameters", required_argument, 'p', [&]() {
- std::string parms = optarg;
- auto tokens = parseParameters(parms);
- for(auto& token : tokens)
- {
- if(token.key == "close")
- {
- auto val = atof_nol(token.value.data());
- if(val < 0 || val > 1)
- {
- std::cerr << "close range is [0, 1].\n";
- exit(1);
- }
- settings.sample_selection_f_close.store(val);
- }
- else if(token.key == "diverse")
- {
- auto val = atof_nol(token.value.data());
- if(val < 0 || val > 1)
- {
- std::cerr << "diverse range is [0, 1].\n";
- exit(1);
- }
- settings.sample_selection_f_diverse.store(val);
- }
- else if(token.key == "random")
- {
- auto val = atof_nol(token.value.data());
- if(val < 0 || val > 1)
- {
- std::cerr << "random range is [0, 1].\n";
- exit(1);
- }
- settings.sample_selection_f_random.store(val);
- }
- else
- {
- std::cerr << "Unknown parameters argument " << token.key << std::endl;
- exit(1);
- }
- }
- });
-
- opt.add("version", no_argument, 'v', [&]() {
- std::cout << version();
- std::cout << copyright();
- exit(0);
- });
-
- opt.add("help", no_argument, 'h', [&]() {
- std::cout << version();
- std::cout << usage(argv[0]);
- exit(0);
- });
-
- if(!opt.process(argc, argv))
+ opt.add("velocity-humanizer", no_argument, 'x',
+ "Enables adapting input velocities to make it sound more realistic.",
+ [&]()
+ {
+ settings.enable_velocity_modifier.store(true);
+ return 0;
+ });
+
+ opt.add("velocity-humanizerparms", required_argument, 'X',
+ "Velocity humanizer options.",
+ [&]()
+ {
+ std::string parms = optarg;
+ auto tokens = parseParameters(parms);
+ for(auto& token : tokens)
+ {
+ if (token.key == "attack")
+ {
+ auto val = atof_nol(token.value.data());
+ if(val < 0 || val > 1.0)
+ {
+ std::cerr << "attack range is [0, 1].\n";
+ return 1;
+ }
+ settings.velocity_modifier_weight.store(val);
+ }
+ else if (token.key == "release")
+ {
+ auto val = atof_nol(token.value.data());
+ if(val < 0 || val > 1.0)
+ {
+ std::cerr << "release range is [0, 1].\n";
+ return 1;
+ }
+ settings.velocity_modifier_falloff.store(val);
+ }
+ else if(token.key == "stddev")
+ {
+ auto val = atof_nol(token.value.data());
+ if(val < 0 || val > 4.5)
+ {
+ std::cerr << "stddev range is [0, 4.5].\n";
+ return 1;
+ }
+ settings.velocity_stddev.store(val);
+ }
+ else
+ {
+ std::cerr << "Unknown velocity-humanizerparms argument " << token.key << std::endl;
+ return 1;
+ }
+ }
+ return 0;
+ });
+
+ opt.add("parameters", required_argument, 'p',
+ "Parameters for sample selection algorithm.",
+ [&]()
+ {
+ std::string parms = optarg;
+ auto tokens = parseParameters(parms);
+ for(auto& token : tokens)
+ {
+ if(token.key == "close")
+ {
+ auto val = atof_nol(token.value.data());
+ if(val < 0 || val > 1)
+ {
+ std::cerr << "close range is [0, 1].\n";
+ return 1;
+ }
+ settings.sample_selection_f_close.store(val);
+ }
+ else if(token.key == "diverse")
+ {
+ auto val = atof_nol(token.value.data());
+ if(val < 0 || val > 1)
+ {
+ std::cerr << "diverse range is [0, 1].\n";
+ return 1;
+ }
+ settings.sample_selection_f_diverse.store(val);
+ }
+ else if(token.key == "random")
+ {
+ auto val = atof_nol(token.value.data());
+ if(val < 0 || val > 1)
+ {
+ std::cerr << "random range is [0, 1].\n";
+ return 1;
+ }
+ settings.sample_selection_f_random.store(val);
+ }
+ else
+ {
+ std::cerr << "Unknown parameters argument " << token.key << std::endl;
+ return 1;
+ }
+ }
+ return 0;
+ });
+
+ opt.add("version", no_argument, 'v',
+ "Print version information and exit.",
+ [&]()
+ {
+ std::cout << version();
+ std::cout << copyright();
+ exit(0);
+ return 0;
+ });
+
+ opt.add("help", no_argument, 'h',
+ "Print this message and exit.",
+ [&]()
+ {
+ std::cout << version();
+ std::cout << usage(argv[0]);
+ std::cout << "Options:\n";
+ opt.help();
+ std::cout << "\nParameters:\n";
+ std::cout << arguments();
+ exit(0);
+ return 0;
+ });
+
+ if(opt.process(argc, argv) != 0)
{
return 1;
}