| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * Carla Native Plugins | * Carla Native Plugins | ||||
| * Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com> | |||||
| * Copyright (C) 2012-2016 Filipe Coelho <falktx@falktx.com> | |||||
| * | * | ||||
| * This program is free software; you can redistribute it and/or | * This program is free software; you can redistribute it and/or | ||||
| * modify it under the terms of the GNU General Public License as | * modify it under the terms of the GNU General Public License as | ||||
| @@ -22,7 +22,6 @@ | |||||
| # define errx(...) {} | # define errx(...) {} | ||||
| # define warnx(...) {} | # define warnx(...) {} | ||||
| # define rindex strrchr | # define rindex strrchr | ||||
| using std::isnan; | |||||
| #else | #else | ||||
| # include <err.h> | # include <err.h> | ||||
| #endif | #endif | ||||
| @@ -44,10 +44,10 @@ static const Ports partPorts = { | |||||
| rRecurs(kit, 16, "Kit"),//NUM_KIT_ITEMS | rRecurs(kit, 16, "Kit"),//NUM_KIT_ITEMS | ||||
| rRecursp(partefx, 3, "Part Effect"), | rRecursp(partefx, 3, "Part Effect"), | ||||
| rRecur(ctl, "Controller"), | rRecur(ctl, "Controller"), | ||||
| rToggle(Penabled, "Part enable"), | |||||
| rToggle(Penabled, rShort("enable"), "Part enable"), | |||||
| #undef rChangeCb | #undef rChangeCb | ||||
| #define rChangeCb obj->setPvolume(obj->Pvolume); | #define rChangeCb obj->setPvolume(obj->Pvolume); | ||||
| rParamZyn(Pvolume, "Part Volume"), | |||||
| rParamZyn(Pvolume, rShort("Vol"), "Part Volume"), | |||||
| #undef rChangeCb | #undef rChangeCb | ||||
| #define rChangeCb obj->setPpanning(obj->Ppanning); | #define rChangeCb obj->setPpanning(obj->Ppanning); | ||||
| rParamZyn(Ppanning, "Set Panning"), | rParamZyn(Ppanning, "Set Panning"), | ||||
| @@ -56,9 +56,9 @@ static const Ports partPorts = { | |||||
| rParamI(Pkeylimit, rProp(parameter), rMap(min,0), rMap(max, POLYPHONY), "Key limit per part"), | rParamI(Pkeylimit, rProp(parameter), rMap(min,0), rMap(max, POLYPHONY), "Key limit per part"), | ||||
| #undef rChangeCb | #undef rChangeCb | ||||
| #define rChangeCb | #define rChangeCb | ||||
| rParamZyn(Pminkey, "Min Used Key"), | |||||
| rParamZyn(Pmaxkey, "Max Used Key"), | |||||
| rParamZyn(Pkeyshift, "Part keyshift"), | |||||
| rParamZyn(Pminkey, rShort("min"), "Min Used Key"), | |||||
| rParamZyn(Pmaxkey, rShort("max"), "Max Used Key"), | |||||
| rParamZyn(Pkeyshift, rShort("shift"), "Part keyshift"), | |||||
| rParamZyn(Prcvchn, "Active MIDI channel"), | rParamZyn(Prcvchn, "Active MIDI channel"), | ||||
| rParamZyn(Pvelsns, "Velocity sensing"), | rParamZyn(Pvelsns, "Velocity sensing"), | ||||
| rParamZyn(Pveloffs, "Velocity offset"), | rParamZyn(Pveloffs, "Velocity offset"), | ||||
| @@ -0,0 +1,191 @@ | |||||
| #include <ostream> | |||||
| #include <rtosc/ports.h> | |||||
| using namespace rtosc; | |||||
| /* | |||||
| * root : | |||||
| * - 'parameters' : [parameter...] | |||||
| * - 'actions' : [action...] | |||||
| * parameter : | |||||
| * - 'path' : path-id | |||||
| * - 'name' : string | |||||
| * - 'shortname' : string [OPTIONAL] | |||||
| * - 'tooltip' : string [OPTIONAL] | |||||
| * - 'type' : type | |||||
| * - 'domain' : range [OPTIONAL] | |||||
| * type : {'int', 'float', 'boolean'} | |||||
| * action : | |||||
| * - 'path' : path-id | |||||
| * - 'args' : [arg...] | |||||
| * arg : | |||||
| * - 'type' : type | |||||
| * - 'domain' : range [OPTIONAL] | |||||
| */ | |||||
| void walk_ports2(const rtosc::Ports *base, | |||||
| char *name_buffer, | |||||
| size_t buffer_size, | |||||
| void *data, | |||||
| rtosc::port_walker_t walker); | |||||
| using std::ostream; | |||||
| using std::string; | |||||
| static int enum_min(Port::MetaContainer meta) | |||||
| { | |||||
| int min = 0; | |||||
| for(auto m:meta) | |||||
| if(strstr(m.title, "map ")) | |||||
| min = atoi(m.title+4); | |||||
| for(auto m:meta) | |||||
| if(strstr(m.title, "map ")) | |||||
| min = min>atoi(m.title+4) ? atoi(m.title+4) : min; | |||||
| return min; | |||||
| } | |||||
| static int enum_max(Port::MetaContainer meta) | |||||
| { | |||||
| int max = 0; | |||||
| for(auto m:meta) | |||||
| if(strstr(m.title, "map ")) | |||||
| max = atoi(m.title+4); | |||||
| for(auto m:meta) | |||||
| if(strstr(m.title, "map ")) | |||||
| max = max<atoi(m.title+4) ? atoi(m.title+4) : max; | |||||
| return max; | |||||
| } | |||||
| static ostream &add_options(ostream &o, Port::MetaContainer meta) | |||||
| { | |||||
| string sym_names = "xyzabcdefghijklmnopqrstuvw"; | |||||
| int sym_idx = 0; | |||||
| bool has_options = false; | |||||
| for(auto m:meta) | |||||
| if(strstr(m.title, "map ")) | |||||
| has_options = true; | |||||
| for(auto m:meta) | |||||
| if(strcmp(m.title, "documentation") && | |||||
| strcmp(m.title, "parameter") && | |||||
| strcmp(m.title, "max") && | |||||
| strcmp(m.title, "min")) | |||||
| printf("m.title = <%s>\n", m.title); | |||||
| if(!has_options) | |||||
| return o; | |||||
| o << " <hints>\n"; | |||||
| for(auto m:meta) { | |||||
| if(strstr(m.title, "map ")) { | |||||
| o << " <point symbol=\"" << sym_names[sym_idx++] << "\" value=\""; | |||||
| o << m.title+4 << "\">" << m.value << "</point>\n"; | |||||
| } | |||||
| } | |||||
| o << " </hints>\n"; | |||||
| return o; | |||||
| } | |||||
| /* | |||||
| * parameter : | |||||
| * - 'path' : path-id | |||||
| * - 'name' : string | |||||
| * - 'shortname' : string [OPTIONAL] | |||||
| * - 'tooltip' : string [OPTIONAL] | |||||
| * - 'type' : type | |||||
| * - 'domain' : range [OPTIONAL] | |||||
| */ | |||||
| static bool first = true; | |||||
| void dump_param_cb(const rtosc::Port *p, const char *name, void *v) | |||||
| { | |||||
| std::ostream &o = *(std::ostream*)v; | |||||
| auto meta = p->meta(); | |||||
| const char *args = strchr(p->name, ':'); | |||||
| auto mparameter = meta.find("parameter"); | |||||
| auto mdoc = meta.find("documentation"); | |||||
| auto msname = meta.find("shortname"); | |||||
| string doc; | |||||
| //Escape Characters | |||||
| if(mdoc != p->meta().end()) { | |||||
| while(*mdoc.value) { | |||||
| if(*mdoc.value == '\n') | |||||
| doc += "\\n"; | |||||
| else if(*mdoc.value == '\"') | |||||
| doc += "\\\""; | |||||
| else | |||||
| doc += *mdoc.value; | |||||
| mdoc.value++; | |||||
| } | |||||
| } | |||||
| if(meta.find("internal") != meta.end()) | |||||
| return; | |||||
| char type = 0; | |||||
| if(mparameter != p->meta().end()) { | |||||
| if(args) { | |||||
| if(strchr(args, 'f')) | |||||
| type = 'f'; | |||||
| else if(strchr(args, 'i')) | |||||
| type = 'i'; | |||||
| else if(strchr(args, 'c')) | |||||
| type = 'c'; | |||||
| else if(strchr(args, 'T')) | |||||
| type = 't'; | |||||
| else if(strchr(args, 's')) | |||||
| type = 's'; | |||||
| } | |||||
| if(!type) { | |||||
| fprintf(stderr, "rtosc port dumper: Cannot handle '%s'\n", name); | |||||
| fprintf(stderr, " args = <%s>\n", args); | |||||
| return; | |||||
| } | |||||
| } else { | |||||
| //fprintf(stderr, "Skipping \"%s\"\n", name); | |||||
| //if(args) { | |||||
| // fprintf(stderr, " type = %s\n", args); | |||||
| //} | |||||
| return; | |||||
| } | |||||
| const char *min = meta["min"]; | |||||
| const char *max = meta["max"]; | |||||
| if(!first) | |||||
| o << ",\n"; | |||||
| else | |||||
| first = false; | |||||
| o << " {\n"; | |||||
| o << " \"path\" : \"" << name << "\",\n"; | |||||
| if(msname != meta.end()) | |||||
| o << " \"shortname\": \"" << msname.value << "\",\n"; | |||||
| o << " \"name\" : \"" << p->name << "\",\n"; | |||||
| o << " \"tooltip\" : \"" << doc << "\",\n"; | |||||
| o << " \"type\" : \"" << type << "\""; | |||||
| if(min && max) | |||||
| o << ",\n \"range\" : [" << min << "," << max << "]\n"; | |||||
| else | |||||
| o << "\n"; | |||||
| o << " }"; | |||||
| } | |||||
| void dump_json(std::ostream &o, const rtosc::Ports &p) | |||||
| { | |||||
| first = true; | |||||
| o << "{\n"; | |||||
| o << " \"parameter\" : [\n"; | |||||
| char buffer[1024]; | |||||
| memset(buffer, 0, sizeof(buffer)); | |||||
| walk_ports2(&p, buffer, 1024, &o, dump_param_cb); | |||||
| o << "\n ],\n"; | |||||
| o << " \"actions\" : [\n"; | |||||
| //walk_ports2(formatter.p, buffer, 1024, &o, dump_action_cb); | |||||
| o << " ]\n"; | |||||
| o << "}"; | |||||
| } | |||||
| @@ -16,6 +16,7 @@ | |||||
| #include "../globals.h" | #include "../globals.h" | ||||
| #include "../Misc/Util.h" | #include "../Misc/Util.h" | ||||
| #include "../Misc/XMLwrapper.h" | #include "../Misc/XMLwrapper.h" | ||||
| #include "../Misc/Time.h" | |||||
| #include "LFOParams.h" | #include "LFOParams.h" | ||||
| #include <rtosc/port-sugar.h> | #include <rtosc/port-sugar.h> | ||||
| @@ -29,19 +30,21 @@ using namespace rtosc; | |||||
| static const rtosc::Ports _ports = { | static const rtosc::Ports _ports = { | ||||
| rSelf(LFOParams), | rSelf(LFOParams), | ||||
| rPaste, | rPaste, | ||||
| rParamF(Pfreq, rLinear(0.0,1.0), "frequency of LFO\n" | |||||
| rParamF(Pfreq, rShort("freq"), rLinear(0.0,1.0), "frequency of LFO\n" | |||||
| "lfo frequency = (2^(10*Pfreq)-1)/12 * stretch\n" | "lfo frequency = (2^(10*Pfreq)-1)/12 * stretch\n" | ||||
| "true frequency is [0,85.33] Hz"), | "true frequency is [0,85.33] Hz"), | ||||
| rParamZyn(Pintensity, "Intensity of LFO"), | |||||
| rParamZyn(Pstartphase, rSpecial(random), "Starting Phase"), | |||||
| rOption(PLFOtype, rOptions(sine, triangle, square, ramp-up, ramp-down, | |||||
| rParamZyn(Pintensity, rShort("depth"), "Intensity of LFO"), | |||||
| rParamZyn(Pstartphase, rShort("start"), rSpecial(random), "Starting Phase"), | |||||
| rOption(PLFOtype, rShort("type"), rOptions(sine, triangle, square, ramp-up, ramp-down, | |||||
| exponential-down1, exponential-down2), "Shape of LFO"), | exponential-down1, exponential-down2), "Shape of LFO"), | ||||
| rParamZyn(Prandomness, rSpecial(disable), "Amplitude Randomness (calculated uniformly at each cycle)"), | |||||
| rParamZyn(Pfreqrand, rSpecial(disable), "Frequency Randomness (calculated uniformly at each cycle)"), | |||||
| rParamZyn(Pdelay, rSpecial(disable), "Delay before LFO start\n" | |||||
| rParamZyn(Prandomness, rShort("a.r."), rSpecial(disable), | |||||
| "Amplitude Randomness (calculated uniformly at each cycle)"), | |||||
| rParamZyn(Pfreqrand, rShort("f.r."), rSpecial(disable), | |||||
| "Frequency Randomness (calculated uniformly at each cycle)"), | |||||
| rParamZyn(Pdelay, rShort("delay"), rSpecial(disable), "Delay before LFO start\n" | |||||
| "0..4 second delay"), | "0..4 second delay"), | ||||
| rToggle(Pcontinous, "Enable for global operation"), | |||||
| rParamZyn(Pstretch, rCentered, "Note frequency stretch"), | |||||
| rToggle(Pcontinous, rShort("c"), "Enable for global operation"), | |||||
| rParamZyn(Pstretch, rShort("str"), rCentered, "Note frequency stretch"), | |||||
| }; | }; | ||||
| #undef rChangeCb | #undef rChangeCb | ||||
| @@ -168,7 +168,7 @@ int main(int argc, char *argv[]) | |||||
| "swap", 2, NULL, 'S' | "swap", 2, NULL, 'S' | ||||
| }, | }, | ||||
| { | { | ||||
| "no-gui", 2, NULL, 'U' | |||||
| "no-gui", 0, NULL, 'U' | |||||
| }, | }, | ||||
| { | { | ||||
| "dummy", 2, NULL, 'Y' | "dummy", 2, NULL, 'Y' | ||||
| @@ -206,6 +206,9 @@ int main(int argc, char *argv[]) | |||||
| { | { | ||||
| "dump-oscdoc", 2, NULL, 'd' | "dump-oscdoc", 2, NULL, 'd' | ||||
| }, | }, | ||||
| { | |||||
| "dump-json-schema", 2, NULL, 'D' | |||||
| }, | |||||
| { | { | ||||
| "ui-title", 1, NULL, 'u' | "ui-title", 1, NULL, 'u' | ||||
| }, | }, | ||||
| @@ -226,7 +229,7 @@ int main(int argc, char *argv[]) | |||||
| /**\todo check this process for a small memory leak*/ | /**\todo check this process for a small memory leak*/ | ||||
| opt = getopt_long(argc, | opt = getopt_long(argc, | ||||
| argv, | argv, | ||||
| "l:L:r:b:o:I:O:N:e:P:A:u:hvapSDUY", | |||||
| "l:L:r:b:o:I:O:N:e:P:A:u:D:hvapSDUY", | |||||
| opts, | opts, | ||||
| &option_index); | &option_index); | ||||
| char *optarguments = optarg; | char *optarguments = optarg; | ||||
| @@ -338,6 +341,15 @@ int main(int argc, char *argv[]) | |||||
| outfile << s; | outfile << s; | ||||
| } | } | ||||
| break; | break; | ||||
| case 'D': | |||||
| if(optarguments) | |||||
| { | |||||
| ofstream outfile(optarguments); | |||||
| void dump_json(std::ostream &o, | |||||
| const rtosc::Ports &p); | |||||
| dump_json(outfile, Master::ports); | |||||
| } | |||||
| break; | |||||
| case 'u': | case 'u': | ||||
| if(optarguments) | if(optarguments) | ||||
| ui_title = optarguments; | ui_title = optarguments; | ||||
| @@ -723,6 +723,11 @@ void rtosc::walk_ports(const Ports *base, | |||||
| void *data, | void *data, | ||||
| port_walker_t walker) | port_walker_t walker) | ||||
| { | { | ||||
| //only walk valid ports | |||||
| if(!base) | |||||
| return; | |||||
| assert(name_buffer); | assert(name_buffer); | ||||
| //XXX buffer_size is not properly handled yet | //XXX buffer_size is not properly handled yet | ||||
| if(name_buffer[0] == 0) | if(name_buffer[0] == 0) | ||||
| @@ -794,6 +799,9 @@ void walk_ports2(const rtosc::Ports *base, | |||||
| void *data, | void *data, | ||||
| rtosc::port_walker_t walker) | rtosc::port_walker_t walker) | ||||
| { | { | ||||
| if(!base) | |||||
| return; | |||||
| assert(name_buffer); | assert(name_buffer); | ||||
| //XXX buffer_size is not properly handled yet | //XXX buffer_size is not properly handled yet | ||||
| if(name_buffer[0] == 0) | if(name_buffer[0] == 0) | ||||
| @@ -71,7 +71,6 @@ static char tmp[256]; | |||||
| void UndoHistoryImpl::rewind(const char *msg) | void UndoHistoryImpl::rewind(const char *msg) | ||||
| { | { | ||||
| memset(tmp, 0, sizeof(tmp)); | memset(tmp, 0, sizeof(tmp)); | ||||
| printf("rewind('%s')\n", msg); | |||||
| rtosc_arg_t arg = rtosc_argument(msg,1); | rtosc_arg_t arg = rtosc_argument(msg,1); | ||||
| rtosc_amessage(tmp, 256, rtosc_argument(msg,0).s, | rtosc_amessage(tmp, 256, rtosc_argument(msg,0).s, | ||||
| rtosc_argument_string(msg)+2, | rtosc_argument_string(msg)+2, | ||||
| @@ -81,9 +80,7 @@ void UndoHistoryImpl::rewind(const char *msg) | |||||
| void UndoHistoryImpl::replay(const char *msg) | void UndoHistoryImpl::replay(const char *msg) | ||||
| { | { | ||||
| printf("replay...'%s'\n", msg); | |||||
| rtosc_arg_t arg = rtosc_argument(msg,2); | rtosc_arg_t arg = rtosc_argument(msg,2); | ||||
| printf("replay address: '%s'\n", rtosc_argument(msg, 0).s); | |||||
| int len = rtosc_amessage(tmp, 256, rtosc_argument(msg,0).s, | int len = rtosc_amessage(tmp, 256, rtosc_argument(msg,0).s, | ||||
| rtosc_argument_string(msg)+2, | rtosc_argument_string(msg)+2, | ||||
| &arg); | &arg); | ||||
| @@ -141,8 +138,6 @@ void UndoHistory::seekHistory(int distance) | |||||
| if(!distance) | if(!distance) | ||||
| return; | return; | ||||
| printf("distance == '%d'\n", distance); | |||||
| printf("history_pos == '%ld'\n", impl->history_pos); | |||||
| //TODO account for traveling back in time | //TODO account for traveling back in time | ||||
| if(distance<0) | if(distance<0) | ||||
| while(distance++) | while(distance++) | ||||
| @@ -1,5 +1,5 @@ | |||||
| /* | /* | ||||
| * Copyright (c) 2013 Mark McCurry | |||||
| * Copyright (c) 2016 Mark McCurry | |||||
| * | * | ||||
| * Permission is hereby granted, free of charge, to any person obtaining a | * Permission is hereby granted, free of charge, to any person obtaining a | ||||
| * copy of this software and associated documentation files (the "Software"), | * copy of this software and associated documentation files (the "Software"), | ||||
| @@ -211,6 +211,9 @@ template<class T> constexpr T spice(T*t) {return *t;} | |||||
| #define rOpt(numeric,symbolic) rMap(map numeric, symbolic) | #define rOpt(numeric,symbolic) rMap(map numeric, symbolic) | ||||
| #define rOptions(...) OPTIONS(__VA_ARGS__) | #define rOptions(...) OPTIONS(__VA_ARGS__) | ||||
| //Zest Metadata | |||||
| #define rShort(name) ":shortname\0=" name "\0" | |||||
| //Callback Implementations | //Callback Implementations | ||||
| #define rBOIL_BEGIN [](const char *msg, rtosc::RtData &data) { \ | #define rBOIL_BEGIN [](const char *msg, rtosc::RtData &data) { \ | ||||