Collection of tools useful for audio production
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.

406 lines
13KB

  1. #include "canvastestapp.h"
  2. #include "ui_canvastestapp.h"
  3. #include <QMessageBox>
  4. #include <QSettings>
  5. #include <QVariant>
  6. #include <QGLWidget>
  7. struct group_name_to_id_t {
  8. int id;
  9. QString name;
  10. };
  11. struct port_name_to_id_t {
  12. int group_id;
  13. int port_id;
  14. QString name;
  15. };
  16. struct connection_to_id_t {
  17. int id;
  18. int port_out;
  19. int port_in;
  20. };
  21. static int last_group_id = 0;
  22. static int last_port_id = 0;
  23. static int last_connection_id = 0;
  24. static CanvasTestApp* main_gui = 0;
  25. static jack_client_t* jack_client = 0;
  26. static QList<group_name_to_id_t> used_group_names;
  27. static QList<port_name_to_id_t> used_port_names;
  28. static QList<connection_to_id_t> used_connections;
  29. int get_group_id(QString group_name)
  30. {
  31. for (int i=0; i < used_group_names.count(); i++)
  32. {
  33. if (used_group_names[i].name == group_name)
  34. {
  35. return used_group_names[i].id;
  36. }
  37. }
  38. return -1;
  39. }
  40. int get_port_id(QString full_port_name)
  41. {
  42. QString group_name = full_port_name.split(":").at(0);
  43. QString port_name = full_port_name.replace(group_name+":", "");
  44. int group_id = get_group_id(group_name);
  45. for (int i=0; i < used_port_names.count(); i++)
  46. {
  47. if (used_port_names[i].group_id == group_id && used_port_names[i].name == port_name)
  48. {
  49. return used_port_names[i].port_id;
  50. }
  51. }
  52. return -1;
  53. }
  54. QString get_full_port_name(int port_id)
  55. {
  56. int group_id = -1;
  57. QString group_name;
  58. QString port_name;
  59. for (int i=0; i < used_port_names.count(); i++)
  60. {
  61. if (used_port_names[i].port_id == port_id)
  62. {
  63. group_id = used_port_names[i].group_id;
  64. port_name = used_port_names[i].name;
  65. }
  66. }
  67. for (int i=0; i < used_group_names.count(); i++)
  68. {
  69. if (used_group_names[i].id == group_id)
  70. {
  71. group_name = used_group_names[i].name;
  72. }
  73. }
  74. return group_name+":"+port_name;
  75. }
  76. void canvas_callback(PatchCanvas::CallbackAction action, int value1, int value2, QString value_str)
  77. {
  78. qDebug("--------------------------- Callback called %i|%i|%i|%s", action, value1, value2, value_str.toStdString().data());
  79. switch (action)
  80. {
  81. case PatchCanvas::ACTION_PORT_INFO:
  82. QMessageBox::information(main_gui, "port info dialog", "dummy text here");
  83. break;
  84. case PatchCanvas::ACTION_PORT_RENAME:
  85. // Unused
  86. break;
  87. case PatchCanvas::ACTION_PORTS_CONNECT:
  88. jack_connect(jack_client, get_full_port_name(value1).toStdString().data(), get_full_port_name(value2).toStdString().data());
  89. break;
  90. case PatchCanvas::ACTION_PORTS_DISCONNECT:
  91. for (int i=0; i < used_connections.count(); i++)
  92. {
  93. if (used_connections[i].id == value1)
  94. {
  95. jack_disconnect(jack_client, get_full_port_name(used_connections[i].port_out).toStdString().data(), get_full_port_name(used_connections[i].port_in).toStdString().data());
  96. break;
  97. }
  98. }
  99. break;
  100. case PatchCanvas::ACTION_GROUP_INFO:
  101. QMessageBox::information(main_gui, "group info dialog", "dummy text here");
  102. break;
  103. case PatchCanvas::ACTION_GROUP_RENAME:
  104. // Unused
  105. break;
  106. case PatchCanvas::ACTION_GROUP_SPLIT:
  107. PatchCanvas::splitGroup(value1);
  108. break;
  109. case PatchCanvas::ACTION_GROUP_JOIN:
  110. PatchCanvas::joinGroup(value1);
  111. break;
  112. default:
  113. break;
  114. }
  115. }
  116. CanvasTestApp::CanvasTestApp(QWidget *parent) :
  117. QMainWindow(parent),
  118. ui(new Ui::CanvasTestApp)
  119. {
  120. ui->setupUi(this);
  121. settings = new QSettings("PatchCanvas", "Canvas-test-app");
  122. restoreGeometry(settings->value("Geometry").toByteArray());
  123. main_gui = this;
  124. used_group_names.clear();
  125. used_port_names.clear();
  126. used_connections.clear();
  127. scene = new PatchScene(this, ui->graphicsView);
  128. ui->graphicsView->setScene(scene);
  129. ui->graphicsView->setRenderHint(QPainter::Antialiasing, true);
  130. ui->graphicsView->setRenderHint(QPainter::TextAntialiasing, true);
  131. //ui->graphicsView->setRenderHint(QPainter::HighQualityAntialiasing, true);
  132. //ui->graphicsView->setViewport(new QGLWidget(ui->graphicsView));
  133. PatchCanvas::options_t options;
  134. options.auto_hide_groups = false;
  135. options.use_bezier_lines = true;
  136. options.antialiasing = PatchCanvas::ANTIALIASING_SMALL;
  137. options.eyecandy = PatchCanvas::EYECANDY_SMALL;
  138. options.theme_name = PatchCanvas::getDefaultThemeName();
  139. PatchCanvas::features_t features;
  140. features.group_info = false;
  141. features.group_rename = false;
  142. features.port_info = false;
  143. features.port_rename = false;
  144. features.handle_group_pos = true;
  145. PatchCanvas::setOptions(&options);
  146. PatchCanvas::setFeatures(&features);
  147. PatchCanvas::init(scene, canvas_callback, true);
  148. connect(this, SIGNAL(clientRegisterCallback(QString,bool)), SLOT(handle_clientRegisterCallback(QString,bool)));
  149. connect(this, SIGNAL(portRegisterCallback(int,bool)), SLOT(handle_portRegisterCallback(int,bool)));
  150. connect(this, SIGNAL(connectionCallback(int,int,bool)), SLOT(handle_connectionCallback(int,int,bool)));
  151. jack_client = jack_client_open("canvas-test-app", JackNullOption, 0);
  152. jack_set_client_registration_callback(jack_client, client_register_callback, 0);
  153. jack_set_port_registration_callback(jack_client, port_register_callback, 0);
  154. jack_set_port_connect_callback(jack_client, port_connect_callback, 0);
  155. jack_activate(jack_client);
  156. // query initial jack ports
  157. QList<QString> parsed_groups;
  158. const char** ports = jack_get_ports(jack_client, 0, 0, 0);
  159. if (ports) {
  160. for (int i=0; ports[i]; i++) {
  161. QString full_name(ports[i]);
  162. QString group_name = full_name.split(":").at(0);
  163. QString port_name = full_name.replace(group_name+":", "");
  164. int group_id = -1;
  165. if (parsed_groups.contains(group_name))
  166. {
  167. group_id = get_group_id(group_name);
  168. }
  169. else
  170. {
  171. group_id = last_group_id;
  172. group_name_to_id_t group_name_to_id;
  173. group_name_to_id.id = group_id;
  174. group_name_to_id.name = group_name;
  175. used_group_names.append(group_name_to_id);
  176. parsed_groups.append(group_name);
  177. PatchCanvas::addGroup(group_id, group_name);
  178. last_group_id++;
  179. }
  180. PatchCanvas::PortMode port_mode;
  181. PatchCanvas::PortType port_type;
  182. jack_port_t* jack_port = jack_port_by_name(jack_client, ports[i]);
  183. if (jack_port_flags(jack_port) & JackPortIsInput)
  184. port_mode = PatchCanvas::PORT_MODE_INPUT;
  185. else
  186. port_mode = PatchCanvas::PORT_MODE_OUTPUT;
  187. if (strcmp(jack_port_type(jack_port), JACK_DEFAULT_AUDIO_TYPE) == 0)
  188. port_type = PatchCanvas::PORT_TYPE_AUDIO_JACK;
  189. else
  190. port_type = PatchCanvas::PORT_TYPE_MIDI_JACK;
  191. port_name_to_id_t port_name_to_id;
  192. port_name_to_id.group_id = group_id;
  193. port_name_to_id.port_id = last_port_id;
  194. port_name_to_id.name = port_name;
  195. used_port_names.append(port_name_to_id);
  196. PatchCanvas::addPort(group_id, last_port_id, port_name, port_mode, port_type);
  197. last_port_id++;
  198. }
  199. jack_free(ports);
  200. }
  201. // query connections, after all ports are in place
  202. ports = jack_get_ports(jack_client, 0, 0, JackPortIsOutput);
  203. if (ports) {
  204. for (int i=0; ports[i]; i++) {
  205. QString this_full_name(ports[i]);
  206. int this_port_id = get_port_id(this_full_name);
  207. jack_port_t* jack_port = jack_port_by_name(jack_client, ports[i]);
  208. const char** connections = jack_port_get_connections(jack_port);
  209. if (connections) {
  210. for (int j=0; connections[j]; j++) {
  211. QString target_full_name(connections[j]);
  212. int target_port_id = get_port_id(target_full_name);
  213. connection_to_id_t connection;
  214. connection.id = last_connection_id;
  215. connection.port_out = this_port_id;
  216. connection.port_in = target_port_id;
  217. used_connections.append(connection);
  218. PatchCanvas::connectPorts(last_connection_id, this_port_id, target_port_id);
  219. last_connection_id++;
  220. }
  221. jack_free(connections);
  222. }
  223. }
  224. jack_free(ports);
  225. }
  226. }
  227. CanvasTestApp::~CanvasTestApp()
  228. {
  229. delete settings;
  230. delete scene;
  231. delete ui;
  232. }
  233. void CanvasTestApp::client_register_callback(const char* name, int register_, void*)
  234. {
  235. main_gui->emit clientRegisterCallback(QString(name), bool(register_));
  236. }
  237. void CanvasTestApp::port_register_callback(jack_port_id_t port_id_jack, int register_, void*)
  238. {
  239. main_gui->emit portRegisterCallback(port_id_jack, bool(register_));
  240. }
  241. void CanvasTestApp::port_connect_callback(jack_port_id_t port_a, jack_port_id_t port_b, int connect, void*)
  242. {
  243. main_gui->emit connectionCallback(port_a, port_b, bool(connect));
  244. }
  245. void CanvasTestApp::handle_clientRegisterCallback(QString name, bool yesno)
  246. {
  247. QString qname(name);
  248. if (yesno)
  249. {
  250. group_name_to_id_t group_name_to_id;
  251. group_name_to_id.id = last_group_id;
  252. group_name_to_id.name = qname;
  253. used_group_names.append(group_name_to_id);
  254. PatchCanvas::addGroup(last_group_id, qname);
  255. last_group_id++;
  256. }
  257. else
  258. {
  259. for (int i=0; i < used_group_names.count(); i++)
  260. {
  261. if (used_group_names[i].name == qname)
  262. {
  263. PatchCanvas::removeGroup(used_group_names[i].id);
  264. used_group_names.takeAt(i);
  265. break;
  266. }
  267. }
  268. }
  269. }
  270. void CanvasTestApp::handle_portRegisterCallback(int port, bool yesno)
  271. {
  272. jack_port_t* jack_port = jack_port_by_id(jack_client, port);
  273. QString full_name(jack_port_name(jack_port));
  274. QString group_name = full_name.split(":").at(0);
  275. QString port_name = full_name.replace(group_name+":", "");
  276. int group_id = get_group_id(group_name);
  277. if (yesno)
  278. {
  279. PatchCanvas::PortMode port_mode;
  280. PatchCanvas::PortType port_type;
  281. if (jack_port_flags(jack_port) & JackPortIsInput)
  282. port_mode = PatchCanvas::PORT_MODE_INPUT;
  283. else
  284. port_mode = PatchCanvas::PORT_MODE_OUTPUT;
  285. if (strcmp(jack_port_type(jack_port), JACK_DEFAULT_AUDIO_TYPE) == 0)
  286. port_type = PatchCanvas::PORT_TYPE_AUDIO_JACK;
  287. else
  288. port_type = PatchCanvas::PORT_TYPE_MIDI_JACK;
  289. port_name_to_id_t port_name_to_id;
  290. port_name_to_id.group_id = group_id;
  291. port_name_to_id.port_id = last_port_id;
  292. port_name_to_id.name = port_name;
  293. used_port_names.append(port_name_to_id);
  294. PatchCanvas::addPort(group_id, last_port_id, port_name, port_mode, port_type);
  295. last_port_id++;
  296. }
  297. else
  298. {
  299. for (int i=0; i < used_port_names.count(); i++)
  300. {
  301. if (used_port_names[i].group_id == group_id && used_port_names[i].name == port_name)
  302. {
  303. PatchCanvas::removePort(used_port_names[i].port_id);
  304. used_port_names.takeAt(i);
  305. break;
  306. }
  307. }
  308. }
  309. }
  310. void CanvasTestApp::handle_connectionCallback(int port_a, int port_b, bool yesno)
  311. {
  312. jack_port_t* jack_port_a = jack_port_by_id(jack_client, port_a);
  313. jack_port_t* jack_port_b = jack_port_by_id(jack_client, port_b);
  314. int port_id_a = get_port_id(QString(jack_port_name(jack_port_a)));
  315. int port_id_b = get_port_id(QString(jack_port_name(jack_port_b)));
  316. if (yesno)
  317. {
  318. connection_to_id_t connection;
  319. connection.id = last_connection_id;
  320. connection.port_out = port_id_a;
  321. connection.port_in = port_id_b;
  322. used_connections.append(connection);
  323. PatchCanvas::connectPorts(last_connection_id, port_id_a, port_id_b);
  324. last_connection_id++;
  325. }
  326. else
  327. {
  328. for (int i=0; i < used_connections.count(); i++)
  329. {
  330. if (used_connections[i].port_out == port_id_a && used_connections[i].port_in == port_id_b)
  331. {
  332. PatchCanvas::disconnectPorts(used_connections[i].id);
  333. used_connections.takeAt(i);
  334. break;
  335. }
  336. }
  337. }
  338. }
  339. void CanvasTestApp::closeEvent(QCloseEvent* event)
  340. {
  341. jack_deactivate(jack_client);
  342. jack_client_close(jack_client);
  343. PatchCanvas::clear();
  344. settings->setValue("Geometry", QVariant(saveGeometry()));
  345. QMainWindow::closeEvent(event);
  346. }