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.

214 lines
6.2KB

  1. /*
  2. * Carla Plugin Host
  3. * Copyright (C) 2011-2019 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. #include "CarlaEngineOsc.hpp"
  18. #ifdef HAVE_LIBLO
  19. #include "CarlaEngine.hpp"
  20. CARLA_BACKEND_START_NAMESPACE
  21. // -----------------------------------------------------------------------
  22. CarlaEngineOsc::CarlaEngineOsc(CarlaEngine* const engine) noexcept
  23. : fEngine(engine),
  24. fControlDataTCP(),
  25. fControlDataUDP(),
  26. fName(),
  27. fServerPathTCP(),
  28. fServerPathUDP(),
  29. fServerTCP(nullptr),
  30. fServerUDP(nullptr)
  31. {
  32. CARLA_SAFE_ASSERT(engine != nullptr);
  33. carla_debug("CarlaEngineOsc::CarlaEngineOsc(%p)", engine);
  34. }
  35. CarlaEngineOsc::~CarlaEngineOsc() noexcept
  36. {
  37. CARLA_SAFE_ASSERT(fName.isEmpty());
  38. CARLA_SAFE_ASSERT(fServerPathTCP.isEmpty());
  39. CARLA_SAFE_ASSERT(fServerPathUDP.isEmpty());
  40. CARLA_SAFE_ASSERT(fServerTCP == nullptr);
  41. CARLA_SAFE_ASSERT(fServerUDP == nullptr);
  42. carla_debug("CarlaEngineOsc::~CarlaEngineOsc()");
  43. }
  44. // -----------------------------------------------------------------------
  45. void CarlaEngineOsc::init(const char* const name, int tcpPort, int udpPort) noexcept
  46. {
  47. CARLA_SAFE_ASSERT_RETURN(fName.isEmpty(),);
  48. CARLA_SAFE_ASSERT_RETURN(fServerPathTCP.isEmpty(),);
  49. CARLA_SAFE_ASSERT_RETURN(fServerPathUDP.isEmpty(),);
  50. CARLA_SAFE_ASSERT_RETURN(fServerTCP == nullptr,);
  51. CARLA_SAFE_ASSERT_RETURN(fServerUDP == nullptr,);
  52. CARLA_SAFE_ASSERT_RETURN(name != nullptr && name[0] != '\0',);
  53. carla_debug("CarlaEngineOsc::init(\"%s\")", name);
  54. fName = name;
  55. fName.toBasic();
  56. if (fEngine->getType() != kEngineTypePlugin)
  57. {
  58. const char* const tcpPortEnv = std::getenv("CARLA_OSC_TCP_PORT");
  59. const char* const udpPortEnv = std::getenv("CARLA_OSC_UDP_PORT");
  60. if (tcpPortEnv != nullptr)
  61. tcpPort = std::atoi(tcpPortEnv);
  62. if (udpPortEnv != nullptr)
  63. udpPort = std::atoi(udpPortEnv);
  64. }
  65. // port == 0 means to pick a random one
  66. // port < 0 will get osc disabled
  67. static const int kRetryAttempts = 5;
  68. // ----------------------------------------------------------------------------------------------------------------
  69. if (tcpPort == 0)
  70. {
  71. for (int i=0; i < kRetryAttempts && fServerTCP == nullptr; ++i)
  72. fServerTCP = lo_server_new_with_proto(nullptr, LO_TCP, osc_error_handler_TCP);
  73. }
  74. else if (tcpPort >= 1024)
  75. {
  76. char strBuf[0xff];
  77. for (int i=0; i < kRetryAttempts && tcpPort < 32767 && fServerTCP == nullptr; ++i, ++tcpPort)
  78. {
  79. std::snprintf(strBuf, 0xff-1, "%d", tcpPort);
  80. strBuf[0xff-1] = '\0';
  81. fServerTCP = lo_server_new_with_proto(strBuf, LO_TCP, osc_error_handler_TCP);
  82. }
  83. }
  84. if (fServerTCP != nullptr)
  85. {
  86. if (char* const tmpServerPathTCP = lo_server_get_url(fServerTCP))
  87. {
  88. fServerPathTCP = tmpServerPathTCP;
  89. fServerPathTCP += fName;
  90. std::free(tmpServerPathTCP);
  91. }
  92. lo_server_add_method(fServerTCP, nullptr, nullptr, osc_message_handler_TCP, this);
  93. carla_debug("OSC TCP server running and listening at %s", fServerPathTCP.buffer());
  94. }
  95. // ----------------------------------------------------------------------------------------------------------------
  96. if (udpPort == 0)
  97. {
  98. for (int i=0; i < kRetryAttempts && fServerUDP == nullptr; ++i)
  99. fServerUDP = lo_server_new_with_proto(nullptr, LO_UDP, osc_error_handler_UDP);
  100. }
  101. else if (udpPort >= 1024)
  102. {
  103. char strBuf[0xff];
  104. for (int i=0; i < kRetryAttempts && udpPort < 32768 && fServerUDP == nullptr; ++i, ++udpPort)
  105. {
  106. std::snprintf(strBuf, 0xff-1, "%d", udpPort);
  107. strBuf[0xff-1] = '\0';
  108. fServerUDP = lo_server_new_with_proto(strBuf, LO_UDP, osc_error_handler_UDP);
  109. }
  110. }
  111. if (fServerUDP != nullptr)
  112. {
  113. if (char* const tmpServerPathUDP = lo_server_get_url(fServerUDP))
  114. {
  115. fServerPathUDP = tmpServerPathUDP;
  116. fServerPathUDP += fName;
  117. std::free(tmpServerPathUDP);
  118. }
  119. lo_server_add_method(fServerUDP, nullptr, nullptr, osc_message_handler_UDP, this);
  120. carla_debug("OSC UDP server running and listening at %s", fServerPathUDP.buffer());
  121. }
  122. // ----------------------------------------------------------------------------------------------------------------
  123. CARLA_SAFE_ASSERT(fName.isNotEmpty());
  124. }
  125. void CarlaEngineOsc::idle() const noexcept
  126. {
  127. if (fServerTCP != nullptr)
  128. {
  129. for (;;)
  130. {
  131. try {
  132. if (lo_server_recv_noblock(fServerTCP, 0) == 0)
  133. break;
  134. } CARLA_SAFE_EXCEPTION_CONTINUE("OSC idle TCP")
  135. }
  136. }
  137. if (fServerUDP != nullptr)
  138. {
  139. for (;;)
  140. {
  141. try {
  142. if (lo_server_recv_noblock(fServerUDP, 0) == 0)
  143. break;
  144. } CARLA_SAFE_EXCEPTION_CONTINUE("OSC idle UDP")
  145. }
  146. }
  147. }
  148. void CarlaEngineOsc::close() noexcept
  149. {
  150. carla_debug("CarlaEngineOsc::close()");
  151. if (fControlDataTCP.target != nullptr)
  152. sendExit();
  153. fName.clear();
  154. if (fServerTCP != nullptr)
  155. {
  156. lo_server_del_method(fServerTCP, nullptr, nullptr);
  157. lo_server_free(fServerTCP);
  158. fServerTCP = nullptr;
  159. }
  160. if (fServerUDP != nullptr)
  161. {
  162. lo_server_del_method(fServerUDP, nullptr, nullptr);
  163. lo_server_free(fServerUDP);
  164. fServerUDP = nullptr;
  165. }
  166. fServerPathTCP.clear();
  167. fServerPathUDP.clear();
  168. fControlDataTCP.clear();
  169. fControlDataUDP.clear();
  170. }
  171. // -----------------------------------------------------------------------
  172. CARLA_BACKEND_END_NAMESPACE
  173. #endif // HAVE_LIBLO