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.

442 lines
9.0KB

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