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.

437 lines
8.9KB

  1. #include "bridge.hpp"
  2. #include "util/common.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 AudioIO *audioListeners[BRIDGE_NUM_PORTS] = {};
  19. static std::thread serverThread;
  20. static bool serverRunning = false;
  21. static BridgeMidiDriver driver;
  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. MidiMessage 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(MidiMessage message) {
  173. if (!(0 <= port && port < BRIDGE_NUM_PORTS))
  174. return;
  175. driver.devices[port].onMessage(message);
  176. }
  177. void setSampleRate(int sampleRate) {
  178. this->sampleRate = sampleRate;
  179. refreshAudio();
  180. }
  181. void processStream(const float *input, float *output, int frames) {
  182. if (!(0 <= port && port < BRIDGE_NUM_PORTS))
  183. return;
  184. if (!audioListeners[port])
  185. return;
  186. audioListeners[port]->setBlockSize(frames);
  187. audioListeners[port]->processStream(input, output, frames);
  188. }
  189. void refreshAudio() {
  190. if (!(0 <= port && port < BRIDGE_NUM_PORTS))
  191. return;
  192. if (connections[port] != this)
  193. return;
  194. if (!audioListeners[port])
  195. return;
  196. audioListeners[port]->setSampleRate(sampleRate);
  197. }
  198. };
  199. static void clientRun(int client) {
  200. defer({
  201. #if ARCH_WIN
  202. if (shutdown(client, SD_SEND)) {
  203. warn("Bridge client shutdown() failed");
  204. }
  205. if (closesocket(client)) {
  206. warn("Bridge client closesocket() failed");
  207. }
  208. #else
  209. if (close(client)) {
  210. warn("Bridge client close() failed");
  211. }
  212. #endif
  213. });
  214. #if ARCH_MAC
  215. // Avoid SIGPIPE
  216. int flag = 1;
  217. if (setsockopt(client, SOL_SOCKET, SO_NOSIGPIPE, &flag, sizeof(int))) {
  218. warn("Bridge client setsockopt() failed");
  219. return;
  220. }
  221. #endif
  222. // Disable non-blocking
  223. #if ARCH_WIN
  224. unsigned long blockingMode = 0;
  225. if (ioctlsocket(client, FIONBIO, &blockingMode)) {
  226. warn("Bridge client ioctlsocket() failed");
  227. return;
  228. }
  229. #else
  230. if (fcntl(client, F_SETFL, fcntl(client, F_GETFL, 0) & ~O_NONBLOCK)) {
  231. warn("Bridge client fcntl() failed");
  232. return;
  233. }
  234. #endif
  235. BridgeClientConnection connection;
  236. connection.client = client;
  237. connection.run();
  238. }
  239. static void serverConnect() {
  240. // Initialize sockets
  241. #if ARCH_WIN
  242. WSADATA wsaData;
  243. if (WSAStartup(MAKEWORD(2, 2), &wsaData)) {
  244. warn("Bridge server WSAStartup() failed");
  245. return;
  246. }
  247. defer({
  248. WSACleanup();
  249. });
  250. #endif
  251. // Get address
  252. struct sockaddr_in addr;
  253. memset(&addr, 0, sizeof(addr));
  254. addr.sin_family = AF_INET;
  255. addr.sin_port = htons(BRIDGE_PORT);
  256. #if ARCH_WIN
  257. addr.sin_addr.s_addr = inet_addr(BRIDGE_HOST);
  258. #else
  259. inet_pton(AF_INET, BRIDGE_HOST, &addr.sin_addr);
  260. #endif
  261. // Open socket
  262. int server = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  263. if (server < 0) {
  264. warn("Bridge server socket() failed");
  265. return;
  266. }
  267. defer({
  268. if (close(server)) {
  269. warn("Bridge server close() failed");
  270. return;
  271. }
  272. info("Bridge server closed");
  273. });
  274. #if ARCH_MAC || ARCH_LIN
  275. int reuseAddrFlag = 1;
  276. setsockopt(server, SOL_SOCKET, SO_REUSEADDR, &reuseAddrFlag, sizeof(reuseAddrFlag));
  277. #endif
  278. // Bind socket to address
  279. if (bind(server, (struct sockaddr*) &addr, sizeof(addr))) {
  280. warn("Bridge server bind() failed");
  281. return;
  282. }
  283. // Listen for clients
  284. if (listen(server, 20)) {
  285. warn("Bridge server listen() failed");
  286. return;
  287. }
  288. info("Bridge server started");
  289. // Enable non-blocking
  290. #if ARCH_WIN
  291. unsigned long blockingMode = 1;
  292. if (ioctlsocket(server, FIONBIO, &blockingMode)) {
  293. warn("Bridge server ioctlsocket() failed");
  294. return;
  295. }
  296. #else
  297. int flags = fcntl(server, F_GETFL, 0);
  298. fcntl(server, F_SETFL, flags | O_NONBLOCK);
  299. #endif
  300. // Accept clients
  301. while (serverRunning) {
  302. int client = accept(server, NULL, NULL);
  303. if (client < 0) {
  304. // Wait a bit before attempting to accept another client
  305. std::this_thread::sleep_for(std::chrono::duration<double>(0.1));
  306. continue;
  307. }
  308. // Launch client thread
  309. std::thread clientThread(clientRun, client);
  310. clientThread.detach();
  311. }
  312. }
  313. static void serverRun() {
  314. while (serverRunning) {
  315. std::this_thread::sleep_for(std::chrono::duration<double>(0.1));
  316. serverConnect();
  317. }
  318. }
  319. std::vector<int> BridgeMidiDriver::getInputDeviceIds() {
  320. std::vector<int> deviceIds;
  321. for (int i = 0; i < 16; i++) {
  322. deviceIds.push_back(i);
  323. }
  324. return deviceIds;
  325. }
  326. std::string BridgeMidiDriver::getInputDeviceName(int deviceId) {
  327. return stringf("Port %d", deviceId + 1);
  328. }
  329. MidiInputDevice *BridgeMidiDriver::subscribeInputDevice(int deviceId, MidiInput *midiInput) {
  330. if (!(0 <= deviceId && deviceId < 16))
  331. return NULL;
  332. devices[deviceId].subscribe(midiInput);
  333. return &devices[deviceId];
  334. }
  335. void BridgeMidiDriver::unsubscribeInputDevice(int deviceId, MidiInput *midiInput) {
  336. if (!(0 <= deviceId && deviceId < 16))
  337. return;
  338. devices[deviceId].unsubscribe(midiInput);
  339. }
  340. void bridgeInit() {
  341. serverRunning = true;
  342. serverThread = std::thread(serverRun);
  343. }
  344. void bridgeDestroy() {
  345. serverRunning = false;
  346. serverThread.join();
  347. }
  348. void bridgeAudioSubscribe(int port, AudioIO *audio) {
  349. if (!(0 <= port && port < BRIDGE_NUM_PORTS))
  350. return;
  351. // Check if an Audio is already subscribed on the port
  352. if (audioListeners[port])
  353. return;
  354. audioListeners[port] = audio;
  355. if (connections[port])
  356. connections[port]->refreshAudio();
  357. }
  358. void bridgeAudioUnsubscribe(int port, AudioIO *audio) {
  359. if (!(0 <= port && port < BRIDGE_NUM_PORTS))
  360. return;
  361. if (audioListeners[port] != audio)
  362. return;
  363. audioListeners[port] = NULL;
  364. }
  365. BridgeMidiDriver *bridgeGetMidiDriver() {
  366. return &driver;
  367. }
  368. } // namespace rack