|
- /*
- * Carla Plugin Host
- * Copyright (C) 2011-2019 Filipe Coelho <falktx@falktx.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * For a full copy of the GNU General Public License see the doc/GPL.txt file.
- */
-
- #include "CarlaEngineOsc.hpp"
-
- #ifdef HAVE_LIBLO
-
- #include "CarlaEngine.hpp"
-
- CARLA_BACKEND_START_NAMESPACE
-
- // -----------------------------------------------------------------------
-
- CarlaEngineOsc::CarlaEngineOsc(CarlaEngine* const engine) noexcept
- : fEngine(engine),
- fControlDataTCP(),
- fControlDataUDP(),
- fName(),
- fServerPathTCP(),
- fServerPathUDP(),
- fServerTCP(nullptr),
- fServerUDP(nullptr)
- {
- CARLA_SAFE_ASSERT(engine != nullptr);
- carla_debug("CarlaEngineOsc::CarlaEngineOsc(%p)", engine);
- }
-
- CarlaEngineOsc::~CarlaEngineOsc() noexcept
- {
- CARLA_SAFE_ASSERT(fName.isEmpty());
- CARLA_SAFE_ASSERT(fServerPathTCP.isEmpty());
- CARLA_SAFE_ASSERT(fServerPathUDP.isEmpty());
- CARLA_SAFE_ASSERT(fServerTCP == nullptr);
- CARLA_SAFE_ASSERT(fServerUDP == nullptr);
- carla_debug("CarlaEngineOsc::~CarlaEngineOsc()");
- }
-
- // -----------------------------------------------------------------------
-
- void CarlaEngineOsc::init(const char* const name, int tcpPort, int udpPort) noexcept
- {
- CARLA_SAFE_ASSERT_RETURN(fName.isEmpty(),);
- CARLA_SAFE_ASSERT_RETURN(fServerPathTCP.isEmpty(),);
- CARLA_SAFE_ASSERT_RETURN(fServerPathUDP.isEmpty(),);
- CARLA_SAFE_ASSERT_RETURN(fServerTCP == nullptr,);
- CARLA_SAFE_ASSERT_RETURN(fServerUDP == nullptr,);
- CARLA_SAFE_ASSERT_RETURN(name != nullptr && name[0] != '\0',);
- carla_debug("CarlaEngineOsc::init(\"%s\")", name);
-
- fName = name;
- fName.toBasic();
-
- if (fEngine->getType() != kEngineTypePlugin)
- {
- const char* const tcpPortEnv = std::getenv("CARLA_OSC_TCP_PORT");
- const char* const udpPortEnv = std::getenv("CARLA_OSC_UDP_PORT");
-
- if (tcpPortEnv != nullptr)
- tcpPort = std::atoi(tcpPortEnv);
- if (udpPortEnv != nullptr)
- udpPort = std::atoi(udpPortEnv);
- }
-
- // port == 0 means to pick a random one
- // port < 0 will get osc disabled
-
- static const int kRetryAttempts = 5;
-
- // ----------------------------------------------------------------------------------------------------------------
-
- if (tcpPort == 0)
- {
- for (int i=0; i < kRetryAttempts && fServerTCP == nullptr; ++i)
- fServerTCP = lo_server_new_with_proto(nullptr, LO_TCP, osc_error_handler_TCP);
- }
- else if (tcpPort >= 1024)
- {
- char strBuf[0xff];
-
- for (int i=0; i < kRetryAttempts && tcpPort < 32767 && fServerTCP == nullptr; ++i, ++tcpPort)
- {
- std::snprintf(strBuf, 0xff-1, "%d", tcpPort);
- strBuf[0xff-1] = '\0';
-
- fServerTCP = lo_server_new_with_proto(strBuf, LO_TCP, osc_error_handler_TCP);
- }
- }
-
- if (fServerTCP != nullptr)
- {
- if (char* const tmpServerPathTCP = lo_server_get_url(fServerTCP))
- {
- fServerPathTCP = tmpServerPathTCP;
- fServerPathTCP += fName;
- std::free(tmpServerPathTCP);
- }
-
- lo_server_add_method(fServerTCP, nullptr, nullptr, osc_message_handler_TCP, this);
- carla_debug("OSC TCP server running and listening at %s", fServerPathTCP.buffer());
- }
-
- // ----------------------------------------------------------------------------------------------------------------
-
- if (udpPort == 0)
- {
- for (int i=0; i < kRetryAttempts && fServerUDP == nullptr; ++i)
- fServerUDP = lo_server_new_with_proto(nullptr, LO_UDP, osc_error_handler_UDP);
- }
- else if (udpPort >= 1024)
- {
- char strBuf[0xff];
-
- for (int i=0; i < kRetryAttempts && udpPort < 32768 && fServerUDP == nullptr; ++i, ++udpPort)
- {
- std::snprintf(strBuf, 0xff-1, "%d", udpPort);
- strBuf[0xff-1] = '\0';
-
- fServerUDP = lo_server_new_with_proto(strBuf, LO_UDP, osc_error_handler_UDP);
- }
- }
-
- if (fServerUDP != nullptr)
- {
- if (char* const tmpServerPathUDP = lo_server_get_url(fServerUDP))
- {
- fServerPathUDP = tmpServerPathUDP;
- fServerPathUDP += fName;
- std::free(tmpServerPathUDP);
- }
-
- lo_server_add_method(fServerUDP, nullptr, nullptr, osc_message_handler_UDP, this);
- carla_debug("OSC UDP server running and listening at %s", fServerPathUDP.buffer());
- }
-
- // ----------------------------------------------------------------------------------------------------------------
-
- CARLA_SAFE_ASSERT(fName.isNotEmpty());
- }
-
- void CarlaEngineOsc::idle() const noexcept
- {
- if (fServerTCP != nullptr)
- {
- for (;;)
- {
- try {
- if (lo_server_recv_noblock(fServerTCP, 0) == 0)
- break;
- } CARLA_SAFE_EXCEPTION_CONTINUE("OSC idle TCP")
- }
- }
-
- if (fServerUDP != nullptr)
- {
- for (;;)
- {
- try {
- if (lo_server_recv_noblock(fServerUDP, 0) == 0)
- break;
- } CARLA_SAFE_EXCEPTION_CONTINUE("OSC idle UDP")
- }
- }
- }
-
- void CarlaEngineOsc::close() noexcept
- {
- carla_debug("CarlaEngineOsc::close()");
-
- if (fControlDataTCP.target != nullptr)
- sendExit();
-
- fName.clear();
-
- if (fServerTCP != nullptr)
- {
- lo_server_del_method(fServerTCP, nullptr, nullptr);
- lo_server_free(fServerTCP);
- fServerTCP = nullptr;
- }
-
- if (fServerUDP != nullptr)
- {
- lo_server_del_method(fServerUDP, nullptr, nullptr);
- lo_server_free(fServerUDP);
- fServerUDP = nullptr;
- }
-
- fServerPathTCP.clear();
- fServerPathUDP.clear();
-
- fControlDataTCP.clear();
- fControlDataUDP.clear();
- }
-
- // -----------------------------------------------------------------------
-
- CARLA_BACKEND_END_NAMESPACE
-
- #endif // HAVE_LIBLO
|