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.

439 lines
8.9KB

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