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.

455 lines
9.3KB

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