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.

246 lines
7.3KB

  1. /*
  2. * Carla Backend
  3. * Copyright (C) 2011-2012 Filipe Coelho <falktx@gmail.com>
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or
  8. * any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * For a full copy of the GNU General Public License see the COPYING file
  16. */
  17. #include "carla_threads.h"
  18. #include "carla_plugin.h"
  19. #include <QtCore/QDebug>
  20. #include <QtCore/QProcess>
  21. // -----------------------------------------------------------------------
  22. // CarlaCheckThread
  23. CarlaCheckThread::CarlaCheckThread(CarlaBackend::CarlaEngine* const engine_, QObject* const parent) :
  24. QThread(parent),
  25. engine(engine_)
  26. {
  27. qDebug("CarlaCheckThread::CarlaCheckThread(%p)", parent);
  28. }
  29. CarlaCheckThread::~CarlaCheckThread()
  30. {
  31. qDebug("CarlaCheckThread::~CarlaCheckThread()");
  32. }
  33. void CarlaCheckThread::stopNow()
  34. {
  35. m_stopNow = true;
  36. if (isRunning() && ! wait(200))
  37. {
  38. quit();
  39. if (isRunning() && ! wait(300))
  40. terminate();
  41. }
  42. }
  43. void CarlaCheckThread::run()
  44. {
  45. qDebug("CarlaCheckThread::run()");
  46. m_stopNow = false;
  47. while (engine->isRunning() && ! m_stopNow)
  48. {
  49. for (unsigned short i=0; i < CarlaBackend::MAX_PLUGINS; i++)
  50. {
  51. CarlaBackend::CarlaPlugin* const plugin = engine->getPlugin(i);
  52. if (plugin && plugin->enabled())
  53. {
  54. // -------------------------------------------------------
  55. // Process postponed events
  56. plugin->postEventsRun();
  57. // -------------------------------------------------------
  58. // Update parameters (OSC)
  59. plugin->updateOscParameterOutputs();
  60. // -------------------------------------------------------
  61. // Send peak values (OSC)
  62. if (engine->isOscControllerRegisted())
  63. {
  64. const unsigned short id = plugin->id();
  65. if (plugin->audioInCount() > 0)
  66. {
  67. engine->osc_send_set_input_peak_value(id, 1, engine->getInputPeak(id, 0));
  68. engine->osc_send_set_input_peak_value(id, 2, engine->getInputPeak(id, 1));
  69. }
  70. if (plugin->audioOutCount() > 0)
  71. {
  72. engine->osc_send_set_output_peak_value(id, 1, engine->getOutputPeak(id, 0));
  73. engine->osc_send_set_output_peak_value(id, 2, engine->getOutputPeak(id, 1));
  74. }
  75. }
  76. }
  77. }
  78. msleep(50);
  79. }
  80. }
  81. // -----------------------------------------------------------------------
  82. // CarlaPluginThread
  83. const char* PluginThreadMode2str(const CarlaPluginThread::PluginThreadMode mode)
  84. {
  85. switch (mode)
  86. {
  87. case CarlaPluginThread::PLUGIN_THREAD_DSSI_GUI:
  88. return "PLUGIN_THREAD_DSSI_GUI";
  89. case CarlaPluginThread::PLUGIN_THREAD_LV2_GUI:
  90. return "PLUGIN_THREAD_LV2_GUI";
  91. case CarlaPluginThread::PLUGIN_THREAD_VST_GUI:
  92. return "PLUGIN_THREAD_VST_GUI";
  93. case CarlaPluginThread::PLUGIN_THREAD_BRIDGE:
  94. return "PLUGIN_THREAD_BRIDGE";
  95. }
  96. qWarning("CarlaPluginThread::PluginThreadMode2str(%i) - invalid mode", mode);
  97. return nullptr;
  98. }
  99. CarlaPluginThread::CarlaPluginThread(CarlaBackend::CarlaEngine* const engine_, CarlaBackend::CarlaPlugin* const plugin_, const PluginThreadMode mode_, QObject* const parent) :
  100. QThread(parent),
  101. engine(engine_),
  102. plugin(plugin_),
  103. mode(mode_)
  104. {
  105. qDebug("CarlaPluginThread::CarlaPluginThread(plugin:\"%s\", engine:\"%s\", %s)", plugin->name(), engine->getName(), PluginThreadMode2str(mode));
  106. m_process = nullptr;
  107. }
  108. CarlaPluginThread::~CarlaPluginThread()
  109. {
  110. if (m_process)
  111. delete m_process;
  112. }
  113. void CarlaPluginThread::setOscData(const char* const binary, const char* const label, const char* const data1)
  114. {
  115. m_binary = QString(binary);
  116. m_label = QString(label);
  117. m_data1 = QString(data1);
  118. }
  119. void CarlaPluginThread::run()
  120. {
  121. qDebug("CarlaPluginThread::run()");
  122. if (m_process == nullptr)
  123. m_process = new QProcess(nullptr);
  124. m_process->setProcessChannelMode(QProcess::ForwardedChannels);
  125. QStringList arguments;
  126. switch (mode)
  127. {
  128. case PLUGIN_THREAD_DSSI_GUI:
  129. /* osc_url */ arguments << QString("%1/%2").arg(engine->getOscServerPath()).arg(plugin->id());
  130. /* filename */ arguments << plugin->filename();
  131. /* label */ arguments << m_label;
  132. /* ui-title */ arguments << QString("%1 (GUI)").arg(plugin->name());
  133. break;
  134. case PLUGIN_THREAD_LV2_GUI:
  135. /* osc_url */ arguments << QString("%1/%2").arg(engine->getOscServerPath()).arg(plugin->id());
  136. /* URI */ arguments << m_label;
  137. /* ui-URI */ arguments << m_data1;
  138. /* ui-title */ arguments << QString("%1 (GUI)").arg(plugin->name());
  139. break;
  140. case PLUGIN_THREAD_VST_GUI:
  141. /* osc_url */ arguments << QString("%1/%2").arg(engine->getOscServerPath()).arg(plugin->id());
  142. /* filename */ arguments << plugin->filename();
  143. /* label */ arguments << m_label;
  144. /* ui-title */ arguments << QString("%1 (GUI)").arg(plugin->name());
  145. break;
  146. case PLUGIN_THREAD_BRIDGE:
  147. {
  148. const char* name = plugin->name();
  149. if (! name)
  150. name = "(none)";
  151. /* osc_url */ arguments << QString("%1/%2").arg(engine->getOscServerPath()).arg(plugin->id());
  152. /* stype */ arguments << m_data1;
  153. /* filename */ arguments << plugin->filename();
  154. /* name */ arguments << name;
  155. /* label */ arguments << m_label;
  156. break;
  157. }
  158. }
  159. qDebug() << m_binary;
  160. qDebug() << arguments;
  161. m_process->start(m_binary, arguments);
  162. m_process->waitForStarted();
  163. switch (mode)
  164. {
  165. case PLUGIN_THREAD_DSSI_GUI:
  166. case PLUGIN_THREAD_LV2_GUI:
  167. case PLUGIN_THREAD_VST_GUI:
  168. if (plugin->showOscGui())
  169. {
  170. m_process->waitForFinished(-1);
  171. if (m_process->exitCode() == 0)
  172. {
  173. // Hide
  174. engine->callback(CarlaBackend::CALLBACK_SHOW_GUI, plugin->id(), 0, 0, 0.0);
  175. qWarning("CarlaPluginThread::run() - GUI closed");
  176. }
  177. else
  178. {
  179. // Kill
  180. engine->callback(CarlaBackend::CALLBACK_SHOW_GUI, plugin->id(), -1, 0, 0.0);
  181. qWarning("CarlaPluginThread::run() - GUI crashed");
  182. break;
  183. }
  184. }
  185. else
  186. {
  187. qDebug("CarlaPluginThread::run() - GUI timeout");
  188. engine->callback(CarlaBackend::CALLBACK_SHOW_GUI, plugin->id(), 0, 0, 0.0);
  189. }
  190. break;
  191. case PLUGIN_THREAD_BRIDGE:
  192. m_process->waitForFinished(-1);
  193. #ifdef DEBUG
  194. if (m_process->exitCode() == 0)
  195. qDebug("CarlaPluginThread::run() - bridge closed");
  196. else
  197. qDebug("CarlaPluginThread::run() - bridge crashed");
  198. qDebug("%s", QString(m_process->readAllStandardOutput()).toUtf8().constData());
  199. #endif
  200. break;
  201. }
  202. }