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.

233 lines
6.3KB

  1. /*
  2. * Carla Native Plugin API (C++)
  3. * Copyright (C) 2012-2022 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. #include "CarlaMIDI.h"
  22. /*!
  23. * @defgroup CarlaNativeAPI Carla Native API
  24. * @{
  25. */
  26. // -----------------------------------------------------------------------
  27. // Native Plugin and External UI class
  28. class NativePluginAndUiClass : public NativePluginClass
  29. #ifndef CARLA_OS_WASM
  30. , public CarlaExternalUI
  31. #endif
  32. {
  33. public:
  34. NativePluginAndUiClass(const NativeHostDescriptor* const host, const char* const pathToExternalUI)
  35. : NativePluginClass(host),
  36. #ifndef CARLA_OS_WASM
  37. CarlaExternalUI(),
  38. #endif
  39. fExtUiPath(getResourceDir())
  40. {
  41. fExtUiPath += CARLA_OS_SEP_STR;
  42. fExtUiPath += pathToExternalUI;
  43. #ifdef CARLA_OS_WIN
  44. fExtUiPath += ".exe";
  45. #endif
  46. }
  47. const char* getExtUiPath() const noexcept
  48. {
  49. return fExtUiPath;
  50. }
  51. #ifndef CARLA_OS_WASM
  52. protected:
  53. // -------------------------------------------------------------------
  54. // Plugin UI calls
  55. void uiShow(const bool show) override
  56. {
  57. if (show)
  58. {
  59. if (isPipeRunning())
  60. {
  61. writeFocusMessage();
  62. return;
  63. }
  64. carla_stdout("Trying to start UI using \"%s\"", fExtUiPath.buffer());
  65. CarlaExternalUI::setData(fExtUiPath, getSampleRate(), getUiName());
  66. if (! CarlaExternalUI::startPipeServer(true))
  67. {
  68. uiClosed();
  69. hostUiUnavailable();
  70. }
  71. }
  72. else
  73. {
  74. CarlaExternalUI::stopPipeServer(2000);
  75. }
  76. }
  77. void uiIdle() override
  78. {
  79. CarlaExternalUI::idlePipe();
  80. switch (CarlaExternalUI::getAndResetUiState())
  81. {
  82. case CarlaExternalUI::UiNone:
  83. case CarlaExternalUI::UiShow:
  84. break;
  85. case CarlaExternalUI::UiCrashed:
  86. uiClosed();
  87. hostUiUnavailable();
  88. break;
  89. case CarlaExternalUI::UiHide:
  90. uiClosed();
  91. CarlaExternalUI::stopPipeServer(1000);
  92. break;
  93. }
  94. }
  95. void uiSetParameterValue(const uint32_t index, const float value) noexcept override
  96. {
  97. CARLA_SAFE_ASSERT_RETURN(index < getParameterCount(),);
  98. writeControlMessage(index, value);
  99. }
  100. void uiSetMidiProgram(const uint8_t channel, const uint32_t bank, const uint32_t program) noexcept override
  101. {
  102. CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS,);
  103. writeProgramMessage(channel, bank, program);
  104. }
  105. void uiSetCustomData(const char* const key, const char* const value) noexcept override
  106. {
  107. CARLA_SAFE_ASSERT_RETURN(key != nullptr && key[0] != '\0',);
  108. CARLA_SAFE_ASSERT_RETURN(value != nullptr,);
  109. writeConfigureMessage(key, value);
  110. }
  111. void uiNameChanged(const char* const uiName) override
  112. {
  113. CARLA_SAFE_ASSERT_RETURN(uiName != nullptr && uiName[0] != '\0',);
  114. const CarlaMutexLocker cml(getPipeLock());
  115. if (! writeMessage("uiTitle\n", 8))
  116. return;
  117. if (! writeAndFixMessage(uiName))
  118. return;
  119. syncMessages();
  120. }
  121. bool uiMIDIEvent(const uint8_t size, const uint8_t data[]) override
  122. {
  123. if (size != 3)
  124. return false;
  125. const uint8_t status = MIDI_GET_STATUS_FROM_DATA(data);
  126. if (! (MIDI_IS_STATUS_NOTE_ON(status) || MIDI_IS_STATUS_NOTE_OFF(status)))
  127. return false;
  128. writeMidiNoteMessage(MIDI_IS_STATUS_NOTE_ON(status),
  129. MIDI_GET_CHANNEL_FROM_DATA(data),
  130. data[1], data[2]);
  131. return true;
  132. }
  133. // -------------------------------------------------------------------
  134. // Pipe Server calls
  135. bool msgReceived(const char* const msg) noexcept override
  136. {
  137. if (CarlaExternalUI::msgReceived(msg))
  138. return true;
  139. if (std::strcmp(msg, "control") == 0)
  140. {
  141. uint32_t param;
  142. float value;
  143. CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(param), true);
  144. CARLA_SAFE_ASSERT_RETURN(readNextLineAsFloat(value), true);
  145. try {
  146. uiParameterChanged(param, value);
  147. } CARLA_SAFE_EXCEPTION("uiParameterChanged");
  148. return true;
  149. }
  150. if (std::strcmp(msg, "program") == 0)
  151. {
  152. uint8_t channel;
  153. uint32_t bank, program;
  154. CARLA_SAFE_ASSERT_RETURN(readNextLineAsByte(channel), true);
  155. CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(bank), true);
  156. CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(program), true);
  157. CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS, true);
  158. try {
  159. uiMidiProgramChanged(static_cast<uint8_t>(channel), bank, program);
  160. } CARLA_SAFE_EXCEPTION("uiMidiProgramChanged");
  161. return true;
  162. }
  163. if (std::strcmp(msg, "configure") == 0)
  164. {
  165. const char* key;
  166. const char* value;
  167. CARLA_SAFE_ASSERT_RETURN(readNextLineAsString(key, true), true);
  168. CARLA_SAFE_ASSERT_RETURN(readNextLineAsString(value, false), true);
  169. try {
  170. uiCustomDataChanged(key, value);
  171. } CARLA_SAFE_EXCEPTION("uiCustomDataChanged");
  172. delete[] key;
  173. return true;
  174. }
  175. return false;
  176. }
  177. #endif
  178. private:
  179. CarlaString fExtUiPath;
  180. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(NativePluginAndUiClass)
  181. };
  182. /**@}*/
  183. // -----------------------------------------------------------------------
  184. #endif // CARLA_NATIVE_EXTERNAL_UI_HPP_INCLUDED