summaryrefslogtreecommitdiff
path: root/drumgizmo/drumgizmoc.cc
diff options
context:
space:
mode:
Diffstat (limited to 'drumgizmo/drumgizmoc.cc')
-rw-r--r--drumgizmo/drumgizmoc.cc113
1 files changed, 111 insertions, 2 deletions
diff --git a/drumgizmo/drumgizmoc.cc b/drumgizmo/drumgizmoc.cc
index 4853641..8eba4c9 100644
--- a/drumgizmo/drumgizmoc.cc
+++ b/drumgizmo/drumgizmoc.cc
@@ -34,7 +34,11 @@
#include <sstream>
#include <chrono>
#include <thread>
+#ifdef HAVE_WORDEXP
#include <wordexp.h>
+#else
+#include <glob.h>
+#endif
#include <hugin.hpp>
@@ -90,6 +94,7 @@ static std::string arguments()
output <<
"Input engine parameters:\n"
" jackmidi: midimap=<midimapfile>\n"
+ " alsamidi: midimap=<midimapfile>\n"
" midifile: file=<midifile>, speed=<tempo> (default 1.0),\n"
" track=<miditrack> (default -1, all tracks)\n"
" midimap=<midimapfile>, loop=<true|false>\n"
@@ -101,7 +106,8 @@ static std::string arguments()
"\n"
"Output engine parameters:\n"
" alsa: dev=<device> (default 'default'), frames=<frames> (default "
- "32)\n"
+ "32),\n"
+ " periods=<periods> (default 3)\n"
" srate=<samplerate> (default 441000)\n"
" oss: dev=<device> (default '/dev/dsp'), srate=<samplerate>,\n"
" max_fragments=<number> (default 4, see man page for more info),\n"
@@ -136,6 +142,12 @@ static std::string arguments()
" diverse: The importance given to choosing samples\n"
" which haven't been played recently. [0,1]\n"
" random: The amount of randomness added. [0,1]\n"
+ "\n"
+ "Voice limit parameters:\n"
+ " max: Maximum number of voices for each instrument before\n"
+ " old samples are ramped down. [1,30]\n"
+ " rampdown: Time it takes for an old sample to completely fall\n"
+ " silent. [0.01,2.0]\n"
"\n";
return output.str();
}
@@ -146,19 +158,31 @@ std::vector<ParmToken> parseParameters(std::string &parms)
std::string parm;
std::string val;
bool inval = false;
+#ifdef HAVE_WORDEXP
wordexp_t exp_result;
+#else
+ glob_t g;
+#endif
for(size_t i = 0; i < parms.size(); ++i)
{
if(parms[i] == ',')
{
+ #ifdef HAVE_WORDEXP
int error = wordexp(val.data(), &exp_result, 0);
+ #else
+ int error = glob(val.data(), 0, NULL, &g);
+ #endif
if(error)
{
std::cerr << "Wrong argument: ";
std::cerr << parm << " = " << val << std::endl;
exit(1);
}
+ #ifdef HAVE_WORDEXP
result.push_back({parm, exp_result.we_wordv[0]});
+ #else
+ result.push_back({parm, g.gl_pathv[0]});
+ #endif
parm = "";
val = "";
inval = false;
@@ -182,14 +206,22 @@ std::vector<ParmToken> parseParameters(std::string &parms)
}
if(parm != "")
{
+ #ifdef HAVE_WORDEXP
int error = wordexp(val.data(), &exp_result, 0);
+ #else
+ int error = glob(val.data(), 0, NULL, &g);
+ #endif
if(error)
{
std::cerr << "Wrong argument: ";
std::cerr << parm << " = " << val << std::endl;
exit(1);
}
+ #ifdef HAVE_WORDEXP
result.push_back({parm, exp_result.we_wordv[0]});
+ #else
+ result.push_back({parm, g.gl_pathv[0]});
+ #endif
}
return result;
}
@@ -237,7 +269,7 @@ int main(int argc, char* argv[])
});
opt.add("inputengine", required_argument, 'i',
- "dummy|test|jackmidi|midifile Use said event input engine.",
+ "dummy|test|jackmidi|alsamidi|midifile Use said event input engine.",
[&]()
{
std::string engine = optarg;
@@ -300,6 +332,7 @@ int main(int argc, char* argv[])
}
oe = factory.createOutput(engine);
if(ie == NULL)
+ if(oe == NULL)
{
std::cerr << "Invalid output engine: " << engine << std::endl;
return 1;
@@ -518,6 +551,54 @@ int main(int argc, char* argv[])
return 0;
});
+ // Default is to disable voice limit
+ settings.enable_voice_limit.store(false);
+
+ opt.add("voice-limit", no_argument, 'l',
+ "Enable voice limit.",
+ [&]()
+ {
+ settings.enable_voice_limit.store(true);
+ return 0;
+ });
+
+ opt.add("voice-limitparms", required_argument, 'L',
+ "Voice limit options.",
+ [&]()
+ {
+ std::string parms = optarg;
+ auto tokens = parseParameters(parms);
+ for(auto& token : tokens)
+ {
+ if(token.key == "max")
+ {
+ auto val = atof_nol(token.value.data());
+ if(val < 1.0 || val > 30.0)
+ {
+ std::cerr << "max range is [1, 30].\n";
+ return 1;
+ }
+ settings.voice_limit_max.store(val);
+ }
+ else if(token.key == "rampdown")
+ {
+ auto val = atof_nol(token.value.data());
+ if(val < 0.01 || val > 2.0)
+ {
+ std::cerr << "rampdown range is [0.01, 2.0].\n";
+ return 1;
+ }
+ settings.voice_limit_rampdown.store(val);
+ }
+ else
+ {
+ std::cerr << "Unknown voice limitparms argument " << token.key << std::endl;
+ return 1;
+ }
+ }
+ return 0;
+ });
+
opt.add("parameters", required_argument, 'p',
"Parameters for sample selection algorithm.",
[&]()
@@ -674,6 +755,34 @@ int main(int argc, char* argv[])
}
std::cout << "\ndone" << std::endl;
}
+ else
+ {
+ // Async loading in progress
+
+ // Wait until the loader has passed the kit parsing step before proceeding.
+ bool parsing_done{false};
+ while(!parsing_done)
+ {
+ std::this_thread::sleep_for(std::chrono::milliseconds(10));
+
+ switch(settings.drumkit_load_status.load())
+ {
+ case LoadStatus::Idle:
+ case LoadStatus::Parsing:
+ // Not yet past the parsing step
+ break;
+ case LoadStatus::Loading:
+ case LoadStatus::Done:
+ // Past parsing step
+ parsing_done = true;
+ break;
+ case LoadStatus::Error:
+ // Kit parser error?
+ std::cout << "\nFailed to load " << kitfile << std::endl;
+ return 1;
+ }
+ }
+ }
gizmo.setSamplerate(oe->getSamplerate());
oe->onLatencyChange(gizmo.getLatency());