diff options
author | Bent Bisballe Nyeng <deva@aasimon.org> | 2018-07-21 11:16:24 +0200 |
---|---|---|
committer | Bent Bisballe Nyeng <deva@aasimon.org> | 2018-07-21 11:34:22 +0200 |
commit | 3a1bfc0a6e78f006fc853c1acd2408ed9c383176 (patch) | |
tree | f8c2ce4f40c6f8846b16c507542cb51493367e2b /drumgizmo | |
parent | c80a459faf3abcbe67969664663a3b9ed82966f7 (diff) |
Add humanized timing controls to the cli.
Diffstat (limited to 'drumgizmo')
-rw-r--r-- | drumgizmo/Makefile.am | 1 | ||||
-rw-r--r-- | drumgizmo/drumgizmoc.cc | 210 | ||||
-rw-r--r-- | drumgizmo/drumgizmoc.h | 27 |
3 files changed, 141 insertions, 97 deletions
diff --git a/drumgizmo/Makefile.am b/drumgizmo/Makefile.am index 940630a..4bf578c 100644 --- a/drumgizmo/Makefile.am +++ b/drumgizmo/Makefile.am @@ -88,7 +88,6 @@ endif # HAVE_INPUT_JACKMIDI endif # HAVE_OUTPUT_JACKAUDIO EXTRA_DIST = \ - drumgizmoc.h \ jackclient.h \ enginefactory.h \ getoptpp/getoptpp.hpp \ diff --git a/drumgizmo/drumgizmoc.cc b/drumgizmo/drumgizmoc.cc index 5172666..793967b 100644 --- a/drumgizmo/drumgizmoc.cc +++ b/drumgizmo/drumgizmoc.cc @@ -38,7 +38,6 @@ #include <hugin.hpp> #include "drumgizmo.h" -#include "drumgizmoc.h" #include "enginefactory.h" #include "bytesizeparser.h" @@ -46,12 +45,11 @@ #include "nolocale.h" -typedef struct parm_token +struct ParmToken { std::string key; std::string value; -} parm_token_t; - +}; static std::string version() { @@ -60,11 +58,10 @@ static std::string version() return output.str(); } - static std::string copyright() { std::ostringstream output; - output << "Copyright (C) 2008-2011 Bent Bisballe Nyeng - Aasimon.org.\n"; + output << "Copyright (C) 2008-2018 Bent Bisballe Nyeng - Aasimon.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"; @@ -74,66 +71,85 @@ static std::string copyright() return output.str(); } - static std::string usage(std::string name) { std::ostringstream output; - output << "Usage: " << name << " [options] drumkitfile\n"; - output << "Options:\n"; - output << " -a, --async-load Load drumkit in the background and start the "; - output << " -b --bleed Set and enable master bleed"; - output << "engine immediately.\n"; - output << " -i, --inputengine dummy|test|jackmidi|midifile Use said event "; - output << "input engine.\n"; - output << " -I, --inputparms parmlist Set input engine parameters.\n"; - output << " -o, --outputengine dummy|alsa|jackaudio|wavfile Use said audio "; - output << "output engine.\n"; - output << " -O, --outputparms parmlist Set output engine parameters.\n"; - output << " -e, --endpos Number of samples to process, -1: infinite.\n"; + output << + "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 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 - output << " -D, --debug ddd Enable debug messages on 'ddd'; see hugin "; - output << "documentation for details\n"; + " -D, --debug ddd Enable debug messages on 'ddd' see hugin " + "documentation for details\n" #endif /*DISABLE_HUGIN*/ - output << " -r, --no-resampling Disable resampling.\n"; - output << " -s, --streaming Enable streaming.\n"; - output << " -S, --streamingparms Streaming options.\n"; - output << " -v, --version Print version information and exit.\n"; - output << " -h, --help Print this message and exit.\n"; - output << "\n"; - output << "Input engine parameters:\n"; - output << " jackmidi: midimap=<midimapfile>\n"; - output << " midifile: file=<midifile>, speed=<tempo> (default 1.0),\n"; - output << " track=<miditrack> (default -1, all tracks)\n"; - output << " midimap=<midimapfile>, loop=<true|false>\n"; - output << " ossmidi: midimap=<midimapfile>, dev=<device> (default '/dev/midi')\n"; - output << " test: p=<hit_propability> (default 0.1)\n"; - output << " instr=<instrument> (default -1, random instrument)\n"; - output << " len=<seconds> (default -1, forever)\n"; - output << " dummy:\n"; - output << "\n"; - output << "Output engine parameters:\n"; - output << " alsa: dev=<device> (default 'default'), frames=<frames> (default "; - output << "32)\n"; - output << " srate=<samplerate> (default 441000)\n"; - output << " oss: dev=<device> (default '/dev/dsp'), srate=<samplerate>,\n"; - output << " max_fragments=<number> (default 4, see man page for more info),\n"; - output << " fragment_size=<selector> (default 8, see man page for more info)\n"; - output << " wavfile: file=<filename> (default 'output'), srate=<samplerate> "; - output << "(default 44100)\n"; - output << " jackaudio:\n"; - output << " dummy:\n"; - output << "\n"; - output << "Streaming parameters:\n"; - output << " limit: Limit the amount of preloaded drumkit data to the size\n"; - // output << " chunk_size: chunk size in k,M,G\n" - output << "\n"; + " -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" + " -v, --version Print version information and exit.\n" + " -h, --help Print this message and exit.\n" + "\n" + "Input engine parameters:\n" + " jackmidi: 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" + " ossmidi: midimap=<midimapfile>, dev=<device> (default '/dev/midi')\n" + " test: p=<hit_propability> (default 0.1)\n" + " instr=<instrument> (default -1, random instrument)\n" + " len=<seconds> (default -1, forever)\n" + " dummy:\n" + "\n" + "Output engine parameters:\n" + " alsa: dev=<device> (default 'default'), frames=<frames> (default " + "32)\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" + " fragment_size=<selector> (default 8, see man page for more info)\n" + " wavfile: file=<filename> (default 'output'), srate=<samplerate> " + "(default 44100)\n" + " jackaudio:\n" + " dummy:\n" + "\n" + "Streaming parameters:\n" + " limit: Limit the amount of preloaded drumkit data to the size\n" + //" chunk_size: chunk size in k,M,G\n" + "\n" + "Timing humanizer parameters:\n" + " laidback: Move notes ahead or behind in time in ms [+/-100].\n" + " tightness: Control the tightness of the drummer. [0; 1].\n" + " regain: Control how fast the drummer catches up the timing. [0; 1]\n" + "\n"; return output.str(); } -std::vector<parm_token_t> parse_parameters(std::string &parms) +std::vector<ParmToken> parseParameters(std::string &parms) { - std::vector<parm_token_t> result; + std::vector<ParmToken> result; std::string parm; std::string val; bool inval = false; @@ -239,7 +255,7 @@ int main(int argc, char* argv[]) opt.add("inputparms", required_argument, 'I', [&]() { std::string parms = optarg; - auto tokens = parse_parameters(parms); + auto tokens = parseParameters(parms); for(auto &token : tokens) { ie->setParm(token.key, token.value); @@ -273,7 +289,7 @@ int main(int argc, char* argv[]) opt.add("outputparms", required_argument, 'O', [&]() { std::string parms = optarg; - auto tokens = parse_parameters(parms); + auto tokens = parseParameters(parms); for(auto &token : tokens) { oe->setParm(token.key, token.value); @@ -308,7 +324,7 @@ int main(int argc, char* argv[]) opt.add("streamingparms", required_argument, 'S', [&]() { std::string parms = optarg; - auto tokens = parse_parameters(parms); + auto tokens = parseParameters(parms); for(auto &token : tokens) { if(token.key == "limit") @@ -316,22 +332,78 @@ int main(int argc, char* argv[]) 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; + 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 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; + std::cerr << "Unknown streamingparms argument " << token.key << + std::endl; + exit(1); + } + } + }); + + // 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) * 500.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); } } diff --git a/drumgizmo/drumgizmoc.h b/drumgizmo/drumgizmoc.h deleted file mode 100644 index cc2f96c..0000000 --- a/drumgizmo/drumgizmoc.h +++ /dev/null @@ -1,27 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/*************************************************************************** - * drumgizmoc.h - * - * Mon Jan 12 00:36:37 CET 2015 - * Copyright 2015 Sergey 'Jin' Bostandzhyan - * jin@mediatomb.cc - ****************************************************************************/ - -/* - * This file is part of DrumGizmo. - * - * DrumGizmo is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * DrumGizmo is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with DrumGizmo; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ -#pragma once |