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.

163 lines
5.4KB

  1. /*
  2. * Carla Plugin
  3. * Copyright (C) 2012 Filipe Coelho <falktx@falktx.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_plugin.hpp"
  18. #include <QtCore/QProcess>
  19. CARLA_BACKEND_START_NAMESPACE
  20. const char* PluginThreadMode2str(const CarlaPluginThread::PluginThreadMode mode)
  21. {
  22. switch (mode)
  23. {
  24. case CarlaPluginThread::PLUGIN_THREAD_DSSI_GUI:
  25. return "PLUGIN_THREAD_DSSI_GUI";
  26. case CarlaPluginThread::PLUGIN_THREAD_LV2_GUI:
  27. return "PLUGIN_THREAD_LV2_GUI";
  28. case CarlaPluginThread::PLUGIN_THREAD_VST_GUI:
  29. return "PLUGIN_THREAD_VST_GUI";
  30. case CarlaPluginThread::PLUGIN_THREAD_BRIDGE:
  31. return "PLUGIN_THREAD_BRIDGE";
  32. }
  33. qWarning("CarlaPluginThread::PluginThreadMode2str(%i) - invalid mode", mode);
  34. return nullptr;
  35. }
  36. CarlaPluginThread::CarlaPluginThread(CarlaBackend::CarlaEngine* const engine_, CarlaBackend::CarlaPlugin* const plugin_, const PluginThreadMode mode_, QObject* const parent)
  37. : QThread(parent),
  38. engine(engine_),
  39. plugin(plugin_),
  40. mode(mode_)
  41. {
  42. qDebug("CarlaPluginThread::CarlaPluginThread(plugin:\"%s\", engine:\"%s\", %s)", plugin->name(), engine->getName(), PluginThreadMode2str(mode));
  43. m_process = nullptr;
  44. }
  45. CarlaPluginThread::~CarlaPluginThread()
  46. {
  47. if (m_process)
  48. delete m_process;
  49. }
  50. void CarlaPluginThread::setOscData(const char* const binary, const char* const label, const char* const data1)
  51. {
  52. m_binary = QString(binary);
  53. m_label = QString(label);
  54. m_data1 = QString(data1);
  55. }
  56. void CarlaPluginThread::run()
  57. {
  58. qDebug("CarlaPluginThread::run()");
  59. if (! m_process)
  60. {
  61. m_process = new QProcess(nullptr);
  62. m_process->setProcessChannelMode(QProcess::ForwardedChannels);
  63. m_process->setProcessEnvironment(engine->getOptionsAsProcessEnvironment());
  64. }
  65. QString name(plugin->name() ? plugin->name() : "(none)");
  66. QStringList arguments;
  67. switch (mode)
  68. {
  69. case PLUGIN_THREAD_DSSI_GUI:
  70. /* osc_url */ arguments << QString("%1/%2").arg(engine->getOscServerPathUDP()).arg(plugin->id());
  71. /* filename */ arguments << plugin->filename();
  72. /* label */ arguments << m_label;
  73. /* ui-title */ arguments << QString("%1 (GUI)").arg(plugin->name());
  74. break;
  75. case PLUGIN_THREAD_LV2_GUI:
  76. /* osc_url */ arguments << QString("%1/%2").arg(engine->getOscServerPathTCP()).arg(plugin->id());
  77. /* URI */ arguments << m_label;
  78. /* ui-URI */ arguments << m_data1;
  79. /* ui-title */ arguments << QString("%1 (GUI)").arg(plugin->name());
  80. break;
  81. case PLUGIN_THREAD_VST_GUI:
  82. /* osc_url */ arguments << QString("%1/%2").arg(engine->getOscServerPathTCP()).arg(plugin->id());
  83. /* filename */ arguments << plugin->filename();
  84. /* ui-title */ arguments << QString("%1 (GUI)").arg(plugin->name());
  85. break;
  86. case PLUGIN_THREAD_BRIDGE:
  87. /* osc_url */ arguments << QString("%1/%2").arg(engine->getOscServerPathTCP()).arg(plugin->id());
  88. /* stype */ arguments << m_data1;
  89. /* filename */ arguments << plugin->filename();
  90. /* name */ arguments << name;
  91. /* label */ arguments << m_label;
  92. break;
  93. }
  94. m_process->start(m_binary, arguments);
  95. m_process->waitForStarted();
  96. switch (mode)
  97. {
  98. case PLUGIN_THREAD_DSSI_GUI:
  99. case PLUGIN_THREAD_LV2_GUI:
  100. case PLUGIN_THREAD_VST_GUI:
  101. if (plugin->waitForOscGuiShow())
  102. {
  103. m_process->waitForFinished(-1);
  104. if (m_process->exitCode() == 0)
  105. {
  106. // Hide
  107. engine->callback(CarlaBackend::CALLBACK_SHOW_GUI, plugin->id(), 0, 0, 0.0, nullptr);
  108. qWarning("CarlaPluginThread::run() - GUI closed");
  109. }
  110. else
  111. {
  112. // Kill
  113. engine->callback(CarlaBackend::CALLBACK_SHOW_GUI, plugin->id(), -1, 0, 0.0, nullptr);
  114. qWarning("CarlaPluginThread::run() - GUI crashed");
  115. break;
  116. }
  117. }
  118. else
  119. {
  120. qDebug("CarlaPluginThread::run() - GUI timeout");
  121. engine->callback(CarlaBackend::CALLBACK_SHOW_GUI, plugin->id(), 0, 0, 0.0, nullptr);
  122. }
  123. break;
  124. case PLUGIN_THREAD_BRIDGE:
  125. m_process->waitForFinished(-1);
  126. if (m_process->exitCode() != 0)
  127. {
  128. qWarning("CarlaPluginThread::run() - bridge crashed");
  129. QString errorString = QString("Plugin '%1' has crashed!\n"
  130. "Saving now will lose its current settings.\n"
  131. "Please remove this plugin, and not rely on it from this point.").arg(plugin->name());
  132. engine->setLastError(errorString.toUtf8().constData());
  133. engine->callback(CarlaBackend::CALLBACK_ERROR, plugin->id(), 0, 0, 0.0, nullptr);
  134. }
  135. break;
  136. }
  137. }
  138. CARLA_BACKEND_END_NAMESPACE