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.

453 lines
9.2KB

  1. #include "bridge.hpp"
  2. #include "midi.hpp"
  3. #include "string.hpp"
  4. #include "dsp/ringbuffer.hpp"
  5. #include <unistd.h>
  6. #if defined ARCH_WIN
  7. #include <winsock2.h>
  8. #else
  9. #include <sys/socket.h>
  10. #include <netinet/in.h>
  11. #include <arpa/inet.h>
  12. #include <netinet/tcp.h>
  13. #include <fcntl.h>
  14. #endif
  15. #include <thread>
  16. namespace rack {
  17. struct BridgeMidiDriver;
  18. struct BridgeClientConnection;
  19. static BridgeClientConnection *connections[BRIDGE_NUM_PORTS] = {};
  20. static audio::Port *audioListeners[BRIDGE_NUM_PORTS] = {};
  21. static std::thread serverThread;
  22. static bool serverRunning = false;
  23. static BridgeMidiDriver *driver = NULL;
  24. struct BridgeMidiInputDevice : midi::InputDevice {
  25. };
  26. struct BridgeMidiDriver : midi::Driver {
  27. BridgeMidiInputDevice devices[16];
  28. std::string getName() override {return "Bridge";}
  29. std::vector<int> getInputDeviceIds() override {
  30. std::vector<int> deviceIds;
  31. for (int i = 0; i < 16; i++) {
  32. deviceIds.push_back(i);
  33. }
  34. return deviceIds;
  35. }
  36. std::string getInputDeviceName(int deviceId) override {
  37. if (deviceId < 0)
  38. return "";
  39. return string::f("Port %d", deviceId + 1);
  40. }
  41. midi::InputDevice *subscribeInput(int deviceId, midi::Input *input) override {
  42. if (!(0 <= deviceId && deviceId < 16))
  43. return NULL;
  44. devices[deviceId].subscribe(input);
  45. return &devices[deviceId];
  46. }
  47. void unsubscribeInput(int deviceId, midi::Input *input) override {
  48. if (!(0 <= deviceId && deviceId < 16))
  49. return;
  50. devices[deviceId].unsubscribe(input);
  51. }
  52. };
  53. struct BridgeClientConnection {
  54. int client;
  55. bool ready = false;
  56. int port = -1;
  57. int sampleRate = 0;
  58. ~BridgeClientConnection() {
  59. setPort(-1);
  60. }
  61. /** Returns true if successful */
  62. bool send(const void *buffer, int length) {
  63. if (length <= 0)
  64. return false;
  65. #if defined ARCH_LIN
  66. int flags = MSG_NOSIGNAL;
  67. #else
  68. int flags = 0;
  69. #endif
  70. ssize_t remaining = 0;
  71. while (remaining < length) {
  72. ssize_t actual = ::send(client, (const char*) buffer, length, flags);
  73. if (actual <= 0) {
  74. ready = false;
  75. return false;
  76. }
  77. remaining += actual;
  78. }
  79. return true;
  80. }
  81. template <typename T>
  82. bool send(T x) {
  83. return send(&x, sizeof(x));
  84. }
  85. /** Returns true if successful */
  86. bool recv(void *buffer, int length) {
  87. if (length <= 0)
  88. return false;
  89. #if defined ARCH_LIN
  90. int flags = MSG_NOSIGNAL;
  91. #else
  92. int flags = 0;
  93. #endif
  94. ssize_t remaining = 0;
  95. while (remaining < length) {
  96. ssize_t actual = ::recv(client, (char*) buffer + remaining, length - remaining, flags);
  97. if (actual <= 0) {
  98. ready = false;
  99. return false;
  100. }
  101. remaining += actual;
  102. }
  103. return true;
  104. }
  105. template <typename T>
  106. bool recv(T *x) {
  107. return recv(x, sizeof(*x));
  108. }
  109. void flush() {
  110. // Turn off Nagle
  111. int flag = 1;
  112. setsockopt(client, IPPROTO_TCP, TCP_NODELAY, (char*) &flag, sizeof(int));
  113. // Turn on Nagle
  114. flag = 0;
  115. setsockopt(client, IPPROTO_TCP, TCP_NODELAY, (char*) &flag, sizeof(int));
  116. }
  117. void run() {
  118. INFO("Bridge client connected");
  119. // Check hello key
  120. uint32_t hello = -1;
  121. recv<uint32_t>(&hello);
  122. if (hello != BRIDGE_HELLO) {
  123. INFO("Bridge client protocol mismatch %x %x", hello, BRIDGE_HELLO);
  124. return;
  125. }
  126. // Process commands until no longer ready
  127. ready = true;
  128. while (ready) {
  129. step();
  130. }
  131. INFO("Bridge client closed");
  132. }
  133. /** Accepts a command from the client */
  134. void step() {
  135. uint8_t command;
  136. if (!recv<uint8_t>(&command)) {
  137. return;
  138. }
  139. switch (command) {
  140. default:
  141. case NO_COMMAND: {
  142. WARN("Bridge client: bad command %d detected, closing", command);
  143. ready = false;
  144. } break;
  145. case QUIT_COMMAND: {
  146. ready = false;
  147. } break;
  148. case PORT_SET_COMMAND: {
  149. uint8_t port = -1;
  150. recv<uint8_t>(&port);
  151. setPort(port);
  152. } break;
  153. case MIDI_MESSAGE_COMMAND: {
  154. midi::Message message;
  155. if (!recv(&message, 3)) {
  156. return;
  157. }
  158. processMidi(message);
  159. } break;
  160. case AUDIO_SAMPLE_RATE_SET_COMMAND: {
  161. uint32_t sampleRate = 0;
  162. recv<uint32_t>(&sampleRate);
  163. setSampleRate(sampleRate);
  164. } break;
  165. case AUDIO_PROCESS_COMMAND: {
  166. uint32_t frames = 0;
  167. recv<uint32_t>(&frames);
  168. if (frames == 0 || frames > (1<<16)) {
  169. ready = false;
  170. return;
  171. }
  172. float input[BRIDGE_INPUTS * frames];
  173. if (!recv(&input, BRIDGE_INPUTS * frames * sizeof(float))) {
  174. DEBUG("Failed to receive");
  175. return;
  176. }
  177. float output[BRIDGE_OUTPUTS * frames];
  178. memset(&output, 0, sizeof(output));
  179. processStream(input, output, frames);
  180. if (!send(&output, BRIDGE_OUTPUTS * frames * sizeof(float))) {
  181. DEBUG("Failed to send");
  182. return;
  183. }
  184. // flush();
  185. } break;
  186. }
  187. }
  188. void setPort(int port) {
  189. // Unbind from existing port
  190. if (0 <= this->port && connections[this->port] == this) {
  191. connections[this->port] = NULL;
  192. }
  193. // Bind to new port
  194. if ((0 <= port && port < BRIDGE_NUM_PORTS) && !connections[port]) {
  195. this->port = port;
  196. connections[this->port] = this;
  197. refreshAudio();
  198. }
  199. else {
  200. this->port = -1;
  201. }
  202. }
  203. void processMidi(midi::Message message) {
  204. if (!(0 <= port && port < BRIDGE_NUM_PORTS))
  205. return;
  206. if (!driver)
  207. return;
  208. driver->devices[port].onMessage(message);
  209. }
  210. void setSampleRate(int sampleRate) {
  211. this->sampleRate = sampleRate;
  212. refreshAudio();
  213. }
  214. void processStream(const float *input, float *output, int frames) {
  215. if (!(0 <= port && port < BRIDGE_NUM_PORTS))
  216. return;
  217. if (!audioListeners[port])
  218. return;
  219. audioListeners[port]->setBlockSize(frames);
  220. audioListeners[port]->processStream(input, output, frames);
  221. }
  222. void refreshAudio() {
  223. if (!(0 <= port && port < BRIDGE_NUM_PORTS))
  224. return;
  225. if (connections[port] != this)
  226. return;
  227. if (!audioListeners[port])
  228. return;
  229. audioListeners[port]->setSampleRate(sampleRate);
  230. }
  231. };
  232. static void clientRun(int client) {
  233. DEFER({
  234. #if defined ARCH_WIN
  235. if (shutdown(client, SD_SEND)) {
  236. WARN("Bridge client shutdown() failed");
  237. }
  238. if (closesocket(client)) {
  239. WARN("Bridge client closesocket() failed");
  240. }
  241. #else
  242. if (close(client)) {
  243. WARN("Bridge client close() failed");
  244. }
  245. #endif
  246. });
  247. #if defined ARCH_MAC
  248. // Avoid SIGPIPE
  249. int flag = 1;
  250. if (setsockopt(client, SOL_SOCKET, SO_NOSIGPIPE, &flag, sizeof(int))) {
  251. WARN("Bridge client setsockopt() failed");
  252. return;
  253. }
  254. #endif
  255. // Disable non-blocking
  256. #if defined ARCH_WIN
  257. unsigned long blockingMode = 0;
  258. if (ioctlsocket(client, FIONBIO, &blockingMode)) {
  259. WARN("Bridge client ioctlsocket() failed");
  260. return;
  261. }
  262. #else
  263. if (fcntl(client, F_SETFL, fcntl(client, F_GETFL, 0) & ~O_NONBLOCK)) {
  264. WARN("Bridge client fcntl() failed");
  265. return;
  266. }
  267. #endif
  268. BridgeClientConnection connection;
  269. connection.client = client;
  270. connection.run();
  271. }
  272. static void serverConnect() {
  273. // Initialize sockets
  274. #if defined ARCH_WIN
  275. WSADATA wsaData;
  276. if (WSAStartup(MAKEWORD(2, 2), &wsaData)) {
  277. WARN("Bridge server WSAStartup() failed");
  278. return;
  279. }
  280. DEFER({
  281. WSACleanup();
  282. });
  283. #endif
  284. // Get address
  285. struct sockaddr_in addr;
  286. memset(&addr, 0, sizeof(addr));
  287. addr.sin_family = AF_INET;
  288. addr.sin_port = htons(BRIDGE_PORT);
  289. #if defined ARCH_WIN
  290. addr.sin_addr.s_addr = inet_addr(BRIDGE_HOST);
  291. #else
  292. inet_pton(AF_INET, BRIDGE_HOST, &addr.sin_addr);
  293. #endif
  294. // Open socket
  295. int server = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  296. if (server < 0) {
  297. WARN("Bridge server socket() failed");
  298. return;
  299. }
  300. DEFER({
  301. if (close(server)) {
  302. WARN("Bridge server close() failed");
  303. return;
  304. }
  305. INFO("Bridge server closed");
  306. });
  307. #if defined ARCH_MAC || defined ARCH_LIN
  308. int reuseAddrFlag = 1;
  309. setsockopt(server, SOL_SOCKET, SO_REUSEADDR, &reuseAddrFlag, sizeof(reuseAddrFlag));
  310. #endif
  311. // Bind socket to address
  312. if (bind(server, (struct sockaddr*) &addr, sizeof(addr))) {
  313. WARN("Bridge server bind() failed");
  314. return;
  315. }
  316. // Listen for clients
  317. if (listen(server, 20)) {
  318. WARN("Bridge server listen() failed");
  319. return;
  320. }
  321. INFO("Bridge server started");
  322. // Enable non-blocking
  323. #if defined ARCH_WIN
  324. unsigned long blockingMode = 1;
  325. if (ioctlsocket(server, FIONBIO, &blockingMode)) {
  326. WARN("Bridge server ioctlsocket() failed");
  327. return;
  328. }
  329. #else
  330. int flags = fcntl(server, F_GETFL, 0);
  331. fcntl(server, F_SETFL, flags | O_NONBLOCK);
  332. #endif
  333. // Accept clients
  334. while (serverRunning) {
  335. int client = accept(server, NULL, NULL);
  336. if (client < 0) {
  337. // Wait a bit before attempting to accept another client
  338. std::this_thread::sleep_for(std::chrono::duration<double>(0.1));
  339. continue;
  340. }
  341. // Launch client thread
  342. std::thread clientThread(clientRun, client);
  343. clientThread.detach();
  344. }
  345. }
  346. static void serverRun() {
  347. while (serverRunning) {
  348. std::this_thread::sleep_for(std::chrono::duration<double>(0.1));
  349. serverConnect();
  350. }
  351. }
  352. void bridgeInit() {
  353. serverRunning = true;
  354. serverThread = std::thread(serverRun);
  355. driver = new BridgeMidiDriver;
  356. midi::addDriver(BRIDGE_DRIVER, driver);
  357. }
  358. void bridgeDestroy() {
  359. serverRunning = false;
  360. serverThread.join();
  361. }
  362. void bridgeAudioSubscribe(int port, audio::Port *audio) {
  363. if (!(0 <= port && port < BRIDGE_NUM_PORTS))
  364. return;
  365. // Check if an Audio is already subscribed on the port
  366. if (audioListeners[port])
  367. return;
  368. audioListeners[port] = audio;
  369. if (connections[port])
  370. connections[port]->refreshAudio();
  371. }
  372. void bridgeAudioUnsubscribe(int port, audio::Port *audio) {
  373. if (!(0 <= port && port < BRIDGE_NUM_PORTS))
  374. return;
  375. if (audioListeners[port] != audio)
  376. return;
  377. audioListeners[port] = NULL;
  378. }
  379. } // namespace rack