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.

124 lines
3.3KB

  1. /* Copyright 2016, Ableton AG, Berlin. All rights reserved.
  2. *
  3. * This program is free software: you can redistribute it and/or modify
  4. * it under the terms of the GNU General Public License as published by
  5. * the Free Software Foundation, either version 2 of the License, or
  6. * (at your option) any later version.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU General Public License
  14. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  15. *
  16. * If you would like to incorporate Link into a proprietary software application,
  17. * please contact <link-devs@ableton.com>.
  18. */
  19. #pragma once
  20. #include <ableton/platforms/asio/AsioWrapper.hpp>
  21. #include <ableton/util/Injected.hpp>
  22. namespace ableton
  23. {
  24. namespace discovery
  25. {
  26. inline asio::ip::udp::endpoint multicastEndpoint()
  27. {
  28. return {asio::ip::address_v4::from_string("224.76.78.75"), 20808};
  29. }
  30. // Type tags for dispatching between unicast and multicast packets
  31. struct MulticastTag
  32. {
  33. };
  34. struct UnicastTag
  35. {
  36. };
  37. template <typename IoContext, std::size_t MaxPacketSize>
  38. class IpV4Interface
  39. {
  40. public:
  41. using Socket = typename util::Injected<IoContext>::type::template Socket<MaxPacketSize>;
  42. IpV4Interface(util::Injected<IoContext> io, const asio::ip::address_v4& addr)
  43. : mIo(std::move(io))
  44. , mMulticastReceiveSocket(mIo->template openMulticastSocket<MaxPacketSize>(addr))
  45. , mSendSocket(mIo->template openUnicastSocket<MaxPacketSize>(addr))
  46. {
  47. }
  48. IpV4Interface(const IpV4Interface&) = delete;
  49. IpV4Interface& operator=(const IpV4Interface&) = delete;
  50. IpV4Interface(IpV4Interface&& rhs)
  51. : mIo(std::move(rhs.mIo))
  52. , mMulticastReceiveSocket(std::move(rhs.mMulticastReceiveSocket))
  53. , mSendSocket(std::move(rhs.mSendSocket))
  54. {
  55. }
  56. std::size_t send(
  57. const uint8_t* const pData, const size_t numBytes, const asio::ip::udp::endpoint& to)
  58. {
  59. return mSendSocket.send(pData, numBytes, to);
  60. }
  61. template <typename Handler>
  62. void receive(Handler handler, UnicastTag)
  63. {
  64. mSendSocket.receive(SocketReceiver<UnicastTag, Handler>{std::move(handler)});
  65. }
  66. template <typename Handler>
  67. void receive(Handler handler, MulticastTag)
  68. {
  69. mMulticastReceiveSocket.receive(
  70. SocketReceiver<MulticastTag, Handler>(std::move(handler)));
  71. }
  72. asio::ip::udp::endpoint endpoint() const
  73. {
  74. return mSendSocket.endpoint();
  75. }
  76. private:
  77. template <typename Tag, typename Handler>
  78. struct SocketReceiver
  79. {
  80. SocketReceiver(Handler handler)
  81. : mHandler(std::move(handler))
  82. {
  83. }
  84. template <typename It>
  85. void operator()(
  86. const asio::ip::udp::endpoint& from, const It messageBegin, const It messageEnd)
  87. {
  88. mHandler(Tag{}, from, messageBegin, messageEnd);
  89. }
  90. Handler mHandler;
  91. };
  92. util::Injected<IoContext> mIo;
  93. Socket mMulticastReceiveSocket;
  94. Socket mSendSocket;
  95. };
  96. template <std::size_t MaxPacketSize, typename IoContext>
  97. IpV4Interface<IoContext, MaxPacketSize> makeIpV4Interface(
  98. util::Injected<IoContext> io, const asio::ip::address_v4& addr)
  99. {
  100. return {std::move(io), addr};
  101. }
  102. } // namespace discovery
  103. } // namespace ableton