jack1 codebase
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.

459 lines
14KB

  1. /*
  2. NetJack Client
  3. Copyright (C) 2008 Marc-Olivier Barre <marco@marcochapeau.org>
  4. Copyright (C) 2008 Pieter Palmers <pieterpalmers@users.sourceforge.net>
  5. Copyright (C) 2006 Torben Hohn <torbenh@gmx.de>
  6. This program is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2 of the License, or
  9. (at your option) any later version.
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with this program; if not, write to the Free Software
  16. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17. */
  18. /** @file net_source.c
  19. *
  20. * @brief This client connects a remote netjack slave to a local jackd master server
  21. */
  22. #include <stdio.h>
  23. #include <errno.h>
  24. #include <unistd.h>
  25. #include <stdlib.h>
  26. #include <string.h>
  27. #include <netinet/in.h>
  28. #include <netdb.h>
  29. #include <alloca.h>
  30. #include <jack/jack.h>
  31. #include <net_driver.h>
  32. #include <netjack_packet.h>
  33. #include <samplerate.h>
  34. JSList *capture_ports = NULL;
  35. JSList *capture_srcs = NULL;
  36. int capture_channels = 0;
  37. int capture_channels_audio = 2;
  38. int capture_channels_midi = 1;
  39. JSList *playback_ports = NULL;
  40. JSList *playback_srcs = NULL;
  41. int playback_channels = 0;
  42. int playback_channels_audio = 2;
  43. int playback_channels_midi = 1;
  44. int latency = 1;
  45. jack_nframes_t factor = 1;
  46. int bitdepth = 0;
  47. int reply_port = 0;
  48. jack_client_t *client;
  49. int outsockfd;
  50. int insockfd;
  51. struct sockaddr destaddr;
  52. struct sockaddr bindaddr;
  53. int recv_channels;
  54. int recv_smaple_format;
  55. int sync_state;
  56. jack_transport_state_t last_transport_state;
  57. int framecnt = 0;
  58. int cont_miss = 0;
  59. /**
  60. * This Function allocates all the I/O Ports which are added the lists.
  61. */
  62. void
  63. alloc_ports (int n_capture_audio, int n_playback_audio, int n_capture_midi, int n_playback_midi)
  64. {
  65. int port_flags = JackPortIsOutput;
  66. int chn;
  67. jack_port_t *port;
  68. char buf[32];
  69. capture_ports = NULL;
  70. /* Allocate audio capture channels */
  71. for (chn = 0; chn < n_capture_audio; chn++)
  72. {
  73. snprintf (buf, sizeof (buf) - 1, "capture_%u", chn + 1);
  74. port = jack_port_register (client, buf, JACK_DEFAULT_AUDIO_TYPE, port_flags, 0);
  75. if (!port)
  76. {
  77. printf( "jacknet_client: cannot register port for %s", buf);
  78. break;
  79. }
  80. capture_srcs = jack_slist_append (capture_srcs, src_new (SRC_LINEAR, 1, NULL));
  81. capture_ports = jack_slist_append (capture_ports, port);
  82. }
  83. /* Allocate midi capture channels */
  84. for (chn = n_capture_audio; chn < n_capture_midi + n_capture_audio; chn++)
  85. {
  86. snprintf (buf, sizeof (buf) - 1, "capture_%u", chn + 1);
  87. port = jack_port_register (client, buf, JACK_DEFAULT_MIDI_TYPE, port_flags, 0);
  88. if (!port)
  89. {
  90. printf ("jacknet_client: cannot register port for %s", buf);
  91. break;
  92. }
  93. capture_ports = jack_slist_append(capture_ports, port);
  94. }
  95. /* Allocate audio playback channels */
  96. port_flags = JackPortIsInput;
  97. playback_ports = NULL;
  98. for (chn = 0; chn < n_playback_audio; chn++)
  99. {
  100. snprintf (buf, sizeof (buf) - 1, "playback_%u", chn + 1);
  101. port = jack_port_register (client, buf, JACK_DEFAULT_AUDIO_TYPE, port_flags, 0);
  102. if (!port)
  103. {
  104. printf ("jacknet_client: cannot register port for %s", buf);
  105. break;
  106. }
  107. playback_srcs = jack_slist_append (playback_srcs, src_new (SRC_LINEAR, 1, NULL));
  108. playback_ports = jack_slist_append (playback_ports, port);
  109. }
  110. /* Allocate midi playback channels */
  111. for (chn = n_playback_audio; chn < n_playback_midi + n_playback_audio; chn++)
  112. {
  113. snprintf (buf, sizeof (buf) - 1, "playback_%u", chn + 1);
  114. port = jack_port_register (client, buf, JACK_DEFAULT_MIDI_TYPE, port_flags, 0);
  115. if (!port)
  116. {
  117. printf ("jacknet_client: cannot register port for %s", buf);
  118. break;
  119. }
  120. playback_ports = jack_slist_append (playback_ports, port);
  121. }
  122. }
  123. /**
  124. * The Sync callback... sync state is set elsewhere...
  125. * we will see if this is working correctly.
  126. * i dont really believe in it yet.
  127. */
  128. int
  129. sync_cb (jack_transport_state_t state, jack_position_t *pos, void *arg)
  130. {
  131. static int latency_count = 0;
  132. int retval = sync_state;
  133. if (latency_count) {
  134. latency_count--;
  135. retval = 0;
  136. }
  137. else if (state == JackTransportStarting && last_transport_state != JackTransportStarting)
  138. {
  139. retval = 0;
  140. latency_count = latency - 1;
  141. }
  142. last_transport_state = state;
  143. return retval;
  144. }
  145. /**
  146. * The process callback for this JACK application.
  147. * It is called by JACK at the appropriate times.
  148. */
  149. int
  150. process (jack_nframes_t nframes, void *arg)
  151. {
  152. jack_nframes_t net_period = (float) nframes / (float) factor;
  153. int rx_bufsize = get_sample_size (bitdepth) * capture_channels * net_period + sizeof (jacknet_packet_header);
  154. int tx_bufsize = get_sample_size (bitdepth) * playback_channels * net_period + sizeof (jacknet_packet_header);
  155. jack_default_audio_sample_t *buf;
  156. jack_port_t *port;
  157. JSList *node;
  158. channel_t chn;
  159. int size;
  160. jack_position_t local_trans_pos;
  161. uint32_t *packet_buf, *packet_bufX;
  162. /* Allocate a buffer where both In and Out Buffer will fit */
  163. packet_buf = alloca ((rx_bufsize > tx_bufsize) ? rx_bufsize : tx_bufsize);
  164. jacknet_packet_header *pkthdr = (jacknet_packet_header *) packet_buf;
  165. packet_bufX = packet_buf + sizeof (jacknet_packet_header) / sizeof (uint32_t);
  166. /* Receive
  167. * TODO: We don't want a goto there. Let's make it a real loop.
  168. */
  169. ReadAgain:
  170. if (reply_port)
  171. size = netjack_recv (insockfd, (char *) packet_buf, rx_bufsize, MSG_DONTWAIT, 1400);
  172. else
  173. size = netjack_recv (outsockfd, (char *) packet_buf, rx_bufsize, MSG_DONTWAIT, 1400);
  174. packet_header_ntoh (pkthdr);
  175. /* evaluate received data */
  176. if ((size == rx_bufsize))
  177. {
  178. cont_miss = 0;
  179. /* Check if packet has expected size */
  180. if ((framecnt - pkthdr->framecnt) > latency)
  181. {
  182. printf ("FRAMCNT_DIFF = %d ----- A Packet was lost, or came too late (try -l %d) \n", pkthdr->framecnt - framecnt, framecnt - pkthdr->framecnt);
  183. goto ReadAgain;
  184. }
  185. render_payload_to_jack_ports (bitdepth, packet_bufX, net_period, capture_ports, capture_srcs, nframes);
  186. /* Now evaluate packet header */
  187. if (sync_state != pkthdr->sync_state)
  188. printf ("sync = %d\n", pkthdr->sync_state);
  189. sync_state = pkthdr->sync_state;
  190. }
  191. else
  192. {
  193. printf ("Packet Miss: (expected: %d bytes, got: %d bytes) framecnt=%d\n", rx_bufsize, size, framecnt);
  194. cont_miss += 1;
  195. chn = 0;
  196. node = capture_ports;
  197. while (node != NULL)
  198. {
  199. int i;
  200. port = (jack_port_t *) node->data;
  201. buf = jack_port_get_buffer (port, nframes);
  202. const char *porttype = jack_port_type (port);
  203. if (strncmp (porttype, JACK_DEFAULT_AUDIO_TYPE, jack_port_type_size ()) == 0)
  204. for (i = 0; i < nframes; i++)
  205. buf[i] = 0.0;
  206. else if (strncmp (porttype, JACK_DEFAULT_MIDI_TYPE, jack_port_type_size ()) == 0)
  207. jack_midi_clear_buffer (buf);
  208. node = jack_slist_next (node);
  209. chn++;
  210. }
  211. }
  212. /* reset packet_bufX... */
  213. packet_bufX = packet_buf + sizeof (jacknet_packet_header) / sizeof (jack_default_audio_sample_t);
  214. /* send */
  215. render_jack_ports_to_payload (bitdepth, playback_ports, playback_srcs, nframes, packet_bufX, net_period);
  216. /* fill in packet hdr */
  217. pkthdr->transport_state = jack_transport_query (client, &local_trans_pos);
  218. pkthdr->transport_frame = local_trans_pos.frame;
  219. pkthdr->framecnt = framecnt;
  220. pkthdr->latency = latency;
  221. pkthdr->reply_port = reply_port;
  222. pkthdr->sample_rate = jack_get_sample_rate (client);
  223. pkthdr->period_size = nframes;
  224. /* playback for us is capture on the other side */
  225. pkthdr->capture_channels_audio = playback_channels_audio;
  226. pkthdr->playback_channels_audio = capture_channels_audio;
  227. pkthdr->capture_channels_midi = playback_channels_midi;
  228. pkthdr->playback_channels_midi = capture_channels_midi;
  229. packet_header_hton (pkthdr);
  230. if (cont_miss < 10)
  231. netjack_sendto (outsockfd, (char *) packet_buf, tx_bufsize, 0, &destaddr, sizeof (destaddr), 1400);
  232. else if (cont_miss > 50)
  233. cont_miss = 5;
  234. framecnt++;
  235. return 0;
  236. }
  237. /**
  238. * This is the shutdown callback for this JACK application.
  239. * It is called by JACK if the server ever shuts down or
  240. * decides to disconnect the client.
  241. */
  242. void
  243. jack_shutdown (void *arg)
  244. {
  245. exit (1);
  246. }
  247. void
  248. init_sockaddr_in (struct sockaddr_in *name , const char *hostname , uint16_t port)
  249. {
  250. name->sin_family = AF_INET ;
  251. name->sin_port = htons (port);
  252. if (hostname)
  253. {
  254. struct hostent *hostinfo = gethostbyname (hostname);
  255. if (hostinfo == NULL)
  256. fprintf (stderr, "init_sockaddr_in: unknown host: %s.\n", hostname);
  257. name->sin_addr = *(struct in_addr *) hostinfo->h_addr ;
  258. }
  259. else
  260. name->sin_addr.s_addr = htonl (INADDR_ANY) ;
  261. }
  262. void
  263. printUsage ()
  264. {
  265. fprintf (stderr, "usage: jack_netsource [options] -h <host peer>\n"
  266. "\n"
  267. " -n <jack name> - Reports a different name to jack\n"
  268. " -s <server name> - The name of the jack server to connect to\n"
  269. " -h <host peer> - The hostname/IP of the \"other\" machine running the jack-slave\n"
  270. " -p <port> - Select another socket than the default (3000)\n"
  271. " -P <num channels> - Number of audio playback channels\n"
  272. " -C <num channels> - Number of audio capture channels\n"
  273. " -o <num channels> - Number of midi playback channels\n"
  274. " -i <num channels> - Number of midi capture channels\n"
  275. " -l <latency in periods> - Number of packets on the wire to approach\n"
  276. " -r <reply port> - When using a firewall use this port for incoming packets\n"
  277. " -f <downsample ratio> - Downsample data in the wire by this factor\n"
  278. " -b <bitdepth> - Set transport to use 16bit or 8bit\n"
  279. "\n");
  280. }
  281. int
  282. main (int argc, char *argv[])
  283. {
  284. char *client_name, *server_name = NULL, *peer_ip;
  285. int peer_port = 3000;
  286. jack_options_t options = JackNullOption;
  287. jack_status_t status;
  288. extern char *optarg;
  289. extern int optind, optopt;
  290. int errflg=0, c;
  291. if (argc < 3)
  292. {
  293. printUsage ();
  294. return 1;
  295. }
  296. client_name = (char *) malloc (sizeof (char) * 9);
  297. peer_ip = (char *) malloc (sizeof (char) * 9);
  298. sprintf(client_name, "netsource");
  299. sprintf(peer_ip, "localhost");
  300. while ((c = getopt (argc, argv, ":n:s:h:p:C:P:i:o:l:r:f:b:")) != -1)
  301. {
  302. switch (c)
  303. {
  304. case 'n':
  305. free(client_name);
  306. client_name = (char *) malloc (sizeof (char) * strlen (optarg));
  307. strcpy (client_name, optarg);
  308. break;
  309. case 's':
  310. server_name = (char *) malloc (sizeof (char) * strlen (optarg));
  311. strcpy (server_name, optarg);
  312. options |= JackServerName;
  313. break;
  314. case 'h':
  315. free(peer_ip);
  316. peer_ip = (char *) malloc (sizeof (char) * strlen (optarg));
  317. strcpy (peer_ip, optarg);
  318. break;
  319. case 'p':
  320. peer_port = atoi (optarg);
  321. break;
  322. case 'P':
  323. playback_channels_audio = atoi (optarg);
  324. break;
  325. case 'C':
  326. capture_channels_audio = atoi (optarg);
  327. break;
  328. case 'o':
  329. playback_channels_midi = atoi (optarg);
  330. break;
  331. case 'i':
  332. capture_channels_midi = atoi (optarg);
  333. break;
  334. case 'l':
  335. latency = atoi (optarg);
  336. break;
  337. case 'r':
  338. reply_port = atoi (optarg);
  339. break;
  340. case 'f':
  341. factor = atoi (optarg);
  342. break;
  343. case 'b':
  344. bitdepth = atoi (optarg);
  345. break;
  346. case ':':
  347. fprintf (stderr, "Option -%c requires an operand\n", optopt);
  348. errflg++;
  349. break;
  350. case '?':
  351. fprintf (stderr, "Unrecognized option: -%c\n", optopt);
  352. errflg++;
  353. }
  354. }
  355. if (errflg)
  356. {
  357. printUsage ();
  358. exit (2);
  359. }
  360. capture_channels = capture_channels_audio + capture_channels_midi;
  361. playback_channels = playback_channels_audio + playback_channels_midi;
  362. outsockfd = socket (PF_INET, SOCK_DGRAM, 0);
  363. insockfd = socket (PF_INET, SOCK_DGRAM, 0);
  364. init_sockaddr_in ((struct sockaddr_in *) &destaddr, peer_ip, peer_port);
  365. if(reply_port)
  366. {
  367. init_sockaddr_in ((struct sockaddr_in *) &bindaddr, NULL, reply_port);
  368. bind (insockfd, &bindaddr, sizeof (bindaddr));
  369. }
  370. /* try to become a client of the JACK server */
  371. client = jack_client_open (client_name, options, &status, server_name);
  372. if (client == NULL)
  373. {
  374. fprintf (stderr, "jack_client_open() failed, status = 0x%2.0x\n"
  375. "Is the JACK server running ?\n", status);
  376. return 1;
  377. }
  378. /* Set up jack callbacks */
  379. jack_set_process_callback (client, process, 0);
  380. jack_set_sync_callback (client, sync_cb, 0);
  381. jack_on_shutdown (client, jack_shutdown, 0);
  382. alloc_ports (capture_channels_audio, playback_channels_audio, capture_channels_midi, playback_channels_midi);
  383. jack_nframes_t net_period = (float) jack_get_buffer_size (client) / (float) factor;
  384. int rx_bufsize = get_sample_size (bitdepth) * capture_channels * net_period + sizeof (jacknet_packet_header);
  385. global_packcache = packet_cache_new (latency + 5, rx_bufsize, 1400);
  386. /* tell the JACK server that we are ready to roll */
  387. if (jack_activate (client))
  388. {
  389. fprintf (stderr, "Cannot activate client");
  390. return 1;
  391. }
  392. /* Now sleep forever... */
  393. while (1)
  394. sleep (100);
  395. /* Never reached. Well we will be a GtkApp someday... */
  396. packet_cache_free (global_packcache);
  397. jack_client_close (client);
  398. exit (0);
  399. }