Audio plugin host https://kx.studio/carla
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

225 lines
5.9KB

  1. #include <ostream>
  2. #include <rtosc/ports.h>
  3. using namespace rtosc;
  4. /*
  5. * root :
  6. * - 'parameters' : [parameter...]
  7. * - 'actions' : [action...]
  8. * parameter :
  9. * - 'path' : path-id
  10. * - 'name' : string
  11. * - 'shortname' : string [OPTIONAL]
  12. * - 'tooltip' : string [OPTIONAL]
  13. * - 'type' : type
  14. * - 'domain' : range [OPTIONAL]
  15. * - 'options' : [option...] [OPTIONAL]
  16. * type : {'int', 'float', 'boolean'}
  17. * action :
  18. * - 'path' : path-id
  19. * - 'args' : [arg...]
  20. * arg :
  21. * - 'type' : type
  22. * - 'domain' : range [OPTIONAL]
  23. * option :
  24. * - 'id' : id-number
  25. * - 'value' : string-rep
  26. */
  27. void walk_ports2(const rtosc::Ports *base,
  28. char *name_buffer,
  29. size_t buffer_size,
  30. void *data,
  31. rtosc::port_walker_t walker);
  32. using std::ostream;
  33. using std::string;
  34. static int enum_min(Port::MetaContainer meta)
  35. {
  36. int min = 0;
  37. for(auto m:meta)
  38. if(strstr(m.title, "map "))
  39. min = atoi(m.title+4);
  40. for(auto m:meta)
  41. if(strstr(m.title, "map "))
  42. min = min>atoi(m.title+4) ? atoi(m.title+4) : min;
  43. return min;
  44. }
  45. static int enum_max(Port::MetaContainer meta)
  46. {
  47. int max = 0;
  48. for(auto m:meta)
  49. if(strstr(m.title, "map "))
  50. max = atoi(m.title+4);
  51. for(auto m:meta)
  52. if(strstr(m.title, "map "))
  53. max = max<atoi(m.title+4) ? atoi(m.title+4) : max;
  54. return max;
  55. }
  56. static ostream &add_options(ostream &o, Port::MetaContainer meta)
  57. {
  58. string sym_names = "xyzabcdefghijklmnopqrstuvw";
  59. int sym_idx = 0;
  60. bool has_options = false;
  61. for(auto m:meta)
  62. if(strstr(m.title, "map "))
  63. has_options = true;
  64. for(auto m:meta)
  65. if(strcmp(m.title, "documentation") &&
  66. strcmp(m.title, "parameter") &&
  67. strcmp(m.title, "max") &&
  68. strcmp(m.title, "min"))
  69. printf("m.title = <%s>\n", m.title);
  70. if(!has_options)
  71. return o;
  72. o << " <hints>\n";
  73. for(auto m:meta) {
  74. if(strstr(m.title, "map ")) {
  75. o << " <point symbol=\"" << sym_names[sym_idx++] << "\" value=\"";
  76. o << m.title+4 << "\">" << m.value << "</point>\n";
  77. }
  78. }
  79. o << " </hints>\n";
  80. return o;
  81. }
  82. /*
  83. * parameter :
  84. * - 'path' : path-id
  85. * - 'name' : string
  86. * - 'shortname' : string [OPTIONAL]
  87. * - 'tooltip' : string [OPTIONAL]
  88. * - 'type' : type
  89. * - 'domain' : range [OPTIONAL]
  90. */
  91. static bool first = true;
  92. void dump_param_cb(const rtosc::Port *p, const char *full_name, void *v)
  93. {
  94. typedef std::vector<std::pair<int,string>> opts;
  95. std::ostream &o = *(std::ostream*)v;
  96. auto meta = p->meta();
  97. const char *args = strchr(p->name, ':');
  98. auto mparameter = meta.find("parameter");
  99. auto mdoc = meta.find("documentation");
  100. auto msname = meta.find("shortname");
  101. opts options;
  102. string doc;
  103. string name = p->name;;
  104. {
  105. size_t pos = 0;
  106. if((pos = name.find_first_of(":")) != string::npos)
  107. name = name.substr(0, pos);
  108. }
  109. //Escape Characters
  110. if(mdoc != p->meta().end()) {
  111. while(*mdoc.value) {
  112. if(*mdoc.value == '\n')
  113. doc += "\\n";
  114. else if(*mdoc.value == '\"')
  115. doc += "\\\"";
  116. else
  117. doc += *mdoc.value;
  118. mdoc.value++;
  119. }
  120. }
  121. if(meta.find("internal") != meta.end())
  122. return;
  123. char type = 0;
  124. if(mparameter != p->meta().end()) {
  125. if(args) {
  126. if(strchr(args, 'f'))
  127. type = 'f';
  128. else if(strchr(args, 'i'))
  129. type = 'i';
  130. else if(strchr(args, 'c'))
  131. type = 'c';
  132. else if(strchr(args, 'T'))
  133. type = 't';
  134. else if(strchr(args, 's'))
  135. type = 's';
  136. }
  137. if(!type) {
  138. fprintf(stderr, "rtosc port dumper: Cannot handle '%s'\n", full_name);
  139. fprintf(stderr, " args = <%s>\n", args);
  140. return;
  141. }
  142. } else {
  143. //fprintf(stderr, "Skipping \"%s\"\n", name);
  144. //if(args) {
  145. // fprintf(stderr, " type = %s\n", args);
  146. //}
  147. return;
  148. }
  149. const char *min = meta["min"];
  150. const char *max = meta["max"];
  151. for(auto m:meta) {
  152. if(strlen(m.title) >= 5 && !bcmp(m.title, "map ", 4)) {
  153. int id = atoi(m.title+4);
  154. std::string val = m.value;
  155. options.push_back(std::make_pair(id, val));
  156. }
  157. }
  158. if(!first)
  159. o << ",\n";
  160. else
  161. first = false;
  162. o << " {\n";
  163. o << " \"path\" : \"" << full_name << "\",\n";
  164. if(msname != meta.end())
  165. o << " \"shortname\": \"" << msname.value << "\",\n";
  166. o << " \"name\" : \"" << name << "\",\n";
  167. o << " \"tooltip\" : \"" << doc << "\",\n";
  168. o << " \"type\" : \"" << type << "\"";
  169. if(min && max)
  170. o << ",\n \"range\" : [" << min << "," << max << "]";
  171. if(!options.empty()) {
  172. o << ",\n \"options\" : [\n";
  173. int N = options.size();
  174. for(int i=0; i<N; ++i) {
  175. o << " {\n";
  176. o << " \"id\" : " << options[i].first << ",\n";
  177. o << " \"value\" : \"" << options[i].second << "\"\n";
  178. o << " }";
  179. if(i != N-1)
  180. o << ",";
  181. o << "\n";
  182. }
  183. o << " ]";
  184. }
  185. o << "\n }";
  186. }
  187. void dump_json(std::ostream &o, const rtosc::Ports &p)
  188. {
  189. first = true;
  190. o << "{\n";
  191. o << " \"parameter\" : [\n";
  192. char buffer[1024];
  193. memset(buffer, 0, sizeof(buffer));
  194. walk_ports2(&p, buffer, 1024, &o, dump_param_cb);
  195. o << "\n ],\n";
  196. o << " \"actions\" : [\n";
  197. //walk_ports2(formatter.p, buffer, 1024, &o, dump_action_cb);
  198. o << " ]\n";
  199. o << "}";
  200. }