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.

252 lines
6.7KB

  1. /*
  2. * Carla Native Plugin API (C++)
  3. * Copyright (C) 2012-2016 Filipe Coelho <falktx@falktx.com>
  4. *
  5. * This program is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU General Public License as
  7. * published by the Free Software Foundation; either version 2 of
  8. * the License, or 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 doc/GPL.txt file.
  16. */
  17. #ifndef CARLA_NATIVE_EXTERNAL_UI_HPP_INCLUDED
  18. #define CARLA_NATIVE_EXTERNAL_UI_HPP_INCLUDED
  19. #include "CarlaNative.hpp"
  20. #include "CarlaExternalUI.hpp"
  21. /*!
  22. * @defgroup CarlaNativeAPI Carla Native API
  23. * @{
  24. */
  25. // -----------------------------------------------------------------------
  26. // Native Plugin and External UI class
  27. class NativePluginAndUiClass : public NativePluginClass,
  28. public CarlaExternalUI
  29. {
  30. public:
  31. NativePluginAndUiClass(const NativeHostDescriptor* const host, const char* const extUiPath)
  32. : NativePluginClass(host),
  33. CarlaExternalUI(),
  34. fExtUiPath(getResourceDir())
  35. {
  36. fExtUiPath += CARLA_OS_SEP_STR;
  37. fExtUiPath += extUiPath;
  38. #ifdef CARLA_OS_WIN
  39. fExtUiPath += ".exe";
  40. #endif
  41. }
  42. const char* getExtUiPath() const noexcept
  43. {
  44. return fExtUiPath;
  45. }
  46. protected:
  47. // -------------------------------------------------------------------
  48. // Plugin UI calls
  49. void uiShow(const bool show) override
  50. {
  51. if (show)
  52. {
  53. if (isPipeRunning())
  54. {
  55. const CarlaMutexLocker cml(getPipeLock());
  56. writeMessage("focus\n", 6);
  57. flushMessages();
  58. return;
  59. }
  60. carla_stdout("Trying to start UI using \"%s\"", fExtUiPath.buffer());
  61. CarlaExternalUI::setData(fExtUiPath, getSampleRate(), getUiName());
  62. if (! CarlaExternalUI::startPipeServer(true))
  63. {
  64. uiClosed();
  65. hostUiUnavailable();
  66. }
  67. }
  68. else
  69. {
  70. CarlaExternalUI::stopPipeServer(2000);
  71. }
  72. }
  73. void uiIdle() override
  74. {
  75. CarlaExternalUI::idlePipe();
  76. switch (CarlaExternalUI::getAndResetUiState())
  77. {
  78. case CarlaExternalUI::UiNone:
  79. case CarlaExternalUI::UiShow:
  80. break;
  81. case CarlaExternalUI::UiCrashed:
  82. uiClosed();
  83. hostUiUnavailable();
  84. break;
  85. case CarlaExternalUI::UiHide:
  86. uiClosed();
  87. CarlaExternalUI::stopPipeServer(1000);
  88. break;
  89. }
  90. }
  91. void uiSetParameterValue(const uint32_t index, const float value) noexcept override
  92. {
  93. CARLA_SAFE_ASSERT_RETURN(index < getParameterCount(),);
  94. // TODO writeControlMessage and others
  95. char tmpBuf[0xff+1];
  96. tmpBuf[0xff] = '\0';
  97. const CarlaMutexLocker cml(getPipeLock());
  98. const ScopedLocale csl;
  99. writeMessage("control\n", 8);
  100. {
  101. std::snprintf(tmpBuf, 0xff, "%i\n", index);
  102. writeMessage(tmpBuf);
  103. std::snprintf(tmpBuf, 0xff, "%f\n", value);
  104. writeMessage(tmpBuf);
  105. }
  106. flushMessages();
  107. }
  108. void uiSetMidiProgram(const uint8_t channel, const uint32_t bank, const uint32_t program) noexcept override
  109. {
  110. CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS,);
  111. char tmpBuf[0xff+1];
  112. tmpBuf[0xff] = '\0';
  113. const CarlaMutexLocker cml(getPipeLock());
  114. writeMessage("program\n", 8);
  115. {
  116. std::snprintf(tmpBuf, 0xff, "%i\n", channel);
  117. writeMessage(tmpBuf);
  118. std::snprintf(tmpBuf, 0xff, "%i\n", bank);
  119. writeMessage(tmpBuf);
  120. std::snprintf(tmpBuf, 0xff, "%i\n", program);
  121. writeMessage(tmpBuf);
  122. }
  123. flushMessages();
  124. }
  125. void uiSetCustomData(const char* const key, const char* const value) noexcept override
  126. {
  127. CARLA_SAFE_ASSERT_RETURN(key != nullptr && key[0] != '\0',);
  128. CARLA_SAFE_ASSERT_RETURN(value != nullptr,);
  129. const CarlaMutexLocker cml(getPipeLock());
  130. writeMessage("configure\n", 10);
  131. writeAndFixMessage(key);
  132. writeAndFixMessage(value);
  133. flushMessages();
  134. }
  135. void uiNameChanged(const char* const uiName) override
  136. {
  137. CARLA_SAFE_ASSERT_RETURN(uiName != nullptr && uiName[0] != '\0',);
  138. const CarlaMutexLocker cml(getPipeLock());
  139. writeMessage("uiTitle\n", 8);
  140. writeAndFixMessage(uiName);
  141. flushMessages();
  142. }
  143. // -------------------------------------------------------------------
  144. // Pipe Server calls
  145. bool msgReceived(const char* const msg) noexcept override
  146. {
  147. if (CarlaExternalUI::msgReceived(msg))
  148. return true;
  149. if (std::strcmp(msg, "control") == 0)
  150. {
  151. uint32_t param;
  152. float value;
  153. CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(param), true);
  154. CARLA_SAFE_ASSERT_RETURN(readNextLineAsFloat(value), true);
  155. try {
  156. uiParameterChanged(param, value);
  157. } CARLA_SAFE_EXCEPTION("uiParameterChanged");
  158. return true;
  159. }
  160. if (std::strcmp(msg, "program") == 0)
  161. {
  162. uint32_t channel, bank, program;
  163. CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(channel), true);
  164. CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(bank), true);
  165. CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(program), true);
  166. CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS, true);
  167. try {
  168. uiMidiProgramChanged(static_cast<uint8_t>(channel), bank, program);
  169. } CARLA_SAFE_EXCEPTION("uiMidiProgramChanged");
  170. return true;
  171. }
  172. if (std::strcmp(msg, "configure") == 0)
  173. {
  174. const char* key;
  175. const char* value;
  176. CARLA_SAFE_ASSERT_RETURN(readNextLineAsString(key), true);
  177. CARLA_SAFE_ASSERT_RETURN(readNextLineAsString(value), true);
  178. try {
  179. uiCustomDataChanged(key, value);
  180. } CARLA_SAFE_EXCEPTION("uiCustomDataChanged");
  181. delete[] key;
  182. delete[] value;
  183. return true;
  184. }
  185. return false;
  186. }
  187. private:
  188. CarlaString fExtUiPath;
  189. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(NativePluginAndUiClass)
  190. };
  191. /**@}*/
  192. // -----------------------------------------------------------------------
  193. #endif // CARLA_NATIVE_EXTERNAL_UI_HPP_INCLUDED