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.

1059 lines
33KB

  1. /*
  2. * FireWire Backend for Jack
  3. * using FFADO
  4. * FFADO = Firewire (pro-)audio for linux
  5. *
  6. * http://www.ffado.org
  7. * http://www.jackaudio.org
  8. *
  9. * Copyright (C) 2005-2007 Pieter Palmers
  10. * Copyright (C) 2012 Jonathan Woithe
  11. *
  12. * This program is free software; you can redistribute it and/or modify
  13. * it under the terms of the GNU General Public License as published by
  14. * the Free Software Foundation; either version 2 of the License, or
  15. * (at your option) any later version.
  16. *
  17. * This program is distributed in the hope that it will be useful,
  18. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  20. * GNU General Public License for more details.
  21. *
  22. * You should have received a copy of the GNU General Public License
  23. * along with this program; if not, write to the Free Software
  24. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  25. */
  26. /*
  27. * Main Jack driver entry routines
  28. *
  29. */
  30. #include <math.h>
  31. #include <stdio.h>
  32. #include <memory.h>
  33. #include <unistd.h>
  34. #include <stdlib.h>
  35. #include <errno.h>
  36. #include <stdarg.h>
  37. #include <sys/mman.h>
  38. #include <jack/types.h>
  39. #include "internal.h"
  40. #include "engine.h"
  41. #include "libjack/local.h"
  42. #include <sysdeps/time.h>
  43. #include <assert.h>
  44. #include "ffado_driver.h"
  45. #define SAMPLE_MAX_24BIT 8388608.0f
  46. #define SAMPLE_MAX_16BIT 32768.0f
  47. static int ffado_driver_stop(ffado_driver_t *driver);
  48. // Basic functionality requires API version 8. If version 9 or later
  49. // is present the buffers can be resized at runtime.
  50. #define FIREWIRE_REQUIRED_FFADO_API_VERSION 8
  51. #define FIREWIRE_REQUIRED_FFADO_API_VERSION_FOR_SETBUFSIZE 9
  52. /* FFADO_API_VERSION was first defined with API_VERSION 9, so all previous
  53. * headers do not provide this define.
  54. */
  55. #ifndef FFADO_API_VERSION
  56. extern int ffado_streaming_set_period_size(ffado_device_t *dev,
  57. unsigned int period) __attribute__((__weak__));
  58. #endif
  59. // enable verbose messages
  60. static int g_verbose = 0;
  61. static void
  62. ffado_latency_callback (jack_latency_callback_mode_t mode, void* arg)
  63. {
  64. ffado_driver_t* driver = (ffado_driver_t*)arg;
  65. jack_client_t* client = driver->client;
  66. jack_latency_range_t range;
  67. JSList* node;
  68. if (mode == JackPlaybackLatency) {
  69. range.min = range.max = (driver->period_size * (driver->device_options.nb_buffers - 1));
  70. } else {
  71. range.min = range.max = driver->period_size + driver->capture_frame_latency;
  72. }
  73. for (node = client->ports; node; node = jack_slist_next (node))
  74. jack_port_set_latency_range ((jack_port_t*)node->data, mode, &range);
  75. }
  76. static int
  77. ffado_driver_attach (ffado_driver_t *driver)
  78. {
  79. char buf[64];
  80. char buf2[64];
  81. channel_t chn;
  82. jack_port_t *port = NULL;
  83. int port_flags;
  84. g_verbose = driver->engine->verbose;
  85. if (driver->engine->set_buffer_size (driver->engine, driver->period_size)) {
  86. jack_error ("FFADO: cannot set engine buffer size to %d (check MIDI)", driver->period_size);
  87. return -1;
  88. }
  89. driver->engine->set_sample_rate (driver->engine, driver->sample_rate);
  90. /* preallocate some buffers such that they don't have to be allocated
  91. in RT context (or from the stack)
  92. */
  93. /* the null buffer is a buffer that contains one period of silence */
  94. driver->nullbuffer = calloc (driver->period_size, sizeof(ffado_sample_t));
  95. if (driver->nullbuffer == NULL) {
  96. printError ("could not allocate memory for null buffer");
  97. return -1;
  98. }
  99. /* calloc should do this, but it can't hurt to be sure */
  100. memset (driver->nullbuffer, 0, driver->period_size * sizeof(ffado_sample_t));
  101. /* the scratch buffer is a buffer of one period that can be used as dummy memory */
  102. driver->scratchbuffer = calloc (driver->period_size, sizeof(ffado_sample_t));
  103. if (driver->scratchbuffer == NULL) {
  104. printError ("could not allocate memory for scratch buffer");
  105. return -1;
  106. }
  107. /* packetizer thread options */
  108. driver->device_options.realtime = (driver->engine->control->real_time ? 1 : 0);
  109. driver->device_options.packetizer_priority = driver->engine->rtpriority;
  110. if (driver->device_options.packetizer_priority > 98) {
  111. driver->device_options.packetizer_priority = 98;
  112. }
  113. if (driver->device_options.packetizer_priority < 1) {
  114. driver->device_options.packetizer_priority = 1;
  115. }
  116. driver->dev = ffado_streaming_init (driver->device_info, driver->device_options);
  117. if (!driver->dev) {
  118. printError ("Error creating FFADO streaming device");
  119. return -1;
  120. }
  121. if (driver->device_options.realtime) {
  122. printMessage ("Streaming thread running with Realtime scheduling, priority %d",
  123. driver->device_options.packetizer_priority);
  124. } else {
  125. printMessage ("Streaming thread running without Realtime scheduling");
  126. }
  127. ffado_streaming_set_audio_datatype (driver->dev, ffado_audio_datatype_float);
  128. /* ports */
  129. port_flags = JackPortIsOutput | JackPortIsPhysical | JackPortIsTerminal;
  130. driver->capture_nchannels = ffado_streaming_get_nb_capture_streams (driver->dev);
  131. driver->capture_channels = calloc (driver->capture_nchannels, sizeof(ffado_capture_channel_t));
  132. if (driver->capture_channels == NULL) {
  133. printError ("could not allocate memory for capture channel list");
  134. return -1;
  135. }
  136. for (chn = 0; chn < driver->capture_nchannels; chn++) {
  137. ffado_streaming_get_capture_stream_name (driver->dev, chn, buf, sizeof(buf) - 1);
  138. driver->capture_channels[chn].stream_type = ffado_streaming_get_capture_stream_type (driver->dev, chn);
  139. if (driver->capture_channels[chn].stream_type == ffado_stream_type_audio) {
  140. snprintf (buf2, 64, "C%d_%s", (int)chn, buf); // needed to avoid duplicate names
  141. printMessage ("Registering audio capture port %s", buf2);
  142. if ((port = jack_port_register (driver->client, buf2,
  143. JACK_DEFAULT_AUDIO_TYPE,
  144. port_flags, 0)) == NULL) {
  145. printError (" cannot register port for %s", buf2);
  146. break;
  147. }
  148. driver->capture_ports =
  149. jack_slist_append (driver->capture_ports, port);
  150. // setup port parameters
  151. if (ffado_streaming_set_capture_stream_buffer (driver->dev, chn, NULL)) {
  152. printError (" cannot configure initial port buffer for %s", buf2);
  153. }
  154. if (ffado_streaming_capture_stream_onoff (driver->dev, chn, 1)) {
  155. printError (" cannot enable port %s", buf2);
  156. }
  157. } else if (driver->capture_channels[chn].stream_type == ffado_stream_type_midi) {
  158. snprintf (buf2, 64, "C%d_%s", (int)chn, buf); // needed to avoid duplicate names
  159. printMessage ("Registering midi capture port %s", buf2);
  160. if ((port = jack_port_register (driver->client, buf2,
  161. JACK_DEFAULT_MIDI_TYPE,
  162. port_flags, 0)) == NULL) {
  163. printError (" cannot register port for %s", buf2);
  164. break;
  165. }
  166. driver->capture_ports =
  167. jack_slist_append (driver->capture_ports, port);
  168. // setup port parameters
  169. if (ffado_streaming_set_capture_stream_buffer (driver->dev, chn, NULL)) {
  170. printError (" cannot configure initial port buffer for %s", buf2);
  171. }
  172. if (ffado_streaming_capture_stream_onoff (driver->dev, chn, 1)) {
  173. printError (" cannot enable port %s", buf2);
  174. }
  175. // setup midi unpacker
  176. midi_unpack_init (&driver->capture_channels[chn].midi_unpack);
  177. midi_unpack_reset (&driver->capture_channels[chn].midi_unpack);
  178. // setup the midi buffer
  179. driver->capture_channels[chn].midi_buffer = calloc (driver->period_size, sizeof(uint32_t));
  180. } else {
  181. printMessage ("Don't register capture port %s", buf);
  182. // we have to add a NULL entry in the list to be able to loop over the channels in the read/write routines
  183. driver->capture_ports =
  184. jack_slist_append (driver->capture_ports, NULL);
  185. }
  186. }
  187. port_flags = JackPortIsInput | JackPortIsPhysical | JackPortIsTerminal;
  188. driver->playback_nchannels = ffado_streaming_get_nb_playback_streams (driver->dev);
  189. driver->playback_channels = calloc (driver->playback_nchannels, sizeof(ffado_playback_channel_t));
  190. if (driver->playback_channels == NULL) {
  191. printError ("could not allocate memory for playback channel list");
  192. return -1;
  193. }
  194. for (chn = 0; chn < driver->playback_nchannels; chn++) {
  195. ffado_streaming_get_playback_stream_name (driver->dev, chn, buf, sizeof(buf) - 1);
  196. driver->playback_channels[chn].stream_type = ffado_streaming_get_playback_stream_type (driver->dev, chn);
  197. if (driver->playback_channels[chn].stream_type == ffado_stream_type_audio) {
  198. snprintf (buf2, 64, "P%d_%s", (int)chn, buf); // needed to avoid duplicate names
  199. printMessage ("Registering audio playback port %s", buf2);
  200. if ((port = jack_port_register (driver->client, buf2,
  201. JACK_DEFAULT_AUDIO_TYPE,
  202. port_flags, 0)) == NULL) {
  203. printError (" cannot register port for %s", buf2);
  204. break;
  205. }
  206. driver->playback_ports =
  207. jack_slist_append (driver->playback_ports, port);
  208. // setup port parameters
  209. if (ffado_streaming_set_playback_stream_buffer (driver->dev, chn, NULL)) {
  210. printError (" cannot configure initial port buffer for %s", buf2);
  211. }
  212. if (ffado_streaming_playback_stream_onoff (driver->dev, chn, 1)) {
  213. printError (" cannot enable port %s", buf2);
  214. }
  215. } else if (driver->playback_channels[chn].stream_type == ffado_stream_type_midi) {
  216. snprintf (buf2, 64, "P%d_%s", (int)chn, buf); // needed to avoid duplicate names
  217. printMessage ("Registering midi playback port %s", buf2);
  218. if ((port = jack_port_register (driver->client, buf2,
  219. JACK_DEFAULT_MIDI_TYPE,
  220. port_flags, 0)) == NULL) {
  221. printError (" cannot register port for %s", buf2);
  222. break;
  223. }
  224. driver->playback_ports =
  225. jack_slist_append (driver->playback_ports, port);
  226. // setup port parameters
  227. if (ffado_streaming_set_playback_stream_buffer (driver->dev, chn, NULL)) {
  228. printError (" cannot configure initial port buffer for %s", buf2);
  229. }
  230. if (ffado_streaming_playback_stream_onoff (driver->dev, chn, 1)) {
  231. printError (" cannot enable port %s", buf2);
  232. }
  233. // setup midi packer
  234. midi_pack_reset (&driver->playback_channels[chn].midi_pack);
  235. // setup the midi buffer
  236. driver->playback_channels[chn].midi_buffer = calloc (driver->period_size, sizeof(uint32_t));
  237. } else {
  238. printMessage ("Don't register playback port %s", buf);
  239. // we have to add a NULL entry in the list to be able to loop over the channels in the read/write routines
  240. driver->playback_ports =
  241. jack_slist_append (driver->playback_ports, NULL);
  242. }
  243. }
  244. if (ffado_streaming_prepare (driver->dev)) {
  245. printError ("Could not prepare streaming device!");
  246. return -1;
  247. }
  248. return jack_activate (driver->client);
  249. }
  250. static int
  251. ffado_driver_detach (ffado_driver_t *driver)
  252. {
  253. JSList *node;
  254. unsigned int chn;
  255. if (driver->engine == NULL) {
  256. return 0;
  257. }
  258. for (node = driver->capture_ports; node;
  259. node = jack_slist_next (node)) {
  260. // Don't try to unregister NULL entries added for non-audio
  261. // ffado ports by ffado_driver_attach().
  262. if (node->data != NULL) {
  263. jack_port_unregister (driver->client,
  264. ((jack_port_t*)node->data));
  265. }
  266. }
  267. jack_slist_free (driver->capture_ports);
  268. driver->capture_ports = 0;
  269. for (node = driver->playback_ports; node;
  270. node = jack_slist_next (node)) {
  271. if (node->data != NULL) {
  272. jack_port_unregister (driver->client,
  273. ((jack_port_t*)node->data));
  274. }
  275. }
  276. jack_slist_free (driver->playback_ports);
  277. driver->playback_ports = 0;
  278. ffado_streaming_finish (driver->dev);
  279. driver->dev = NULL;
  280. for (chn = 0; chn < driver->capture_nchannels; chn++)
  281. if (driver->capture_channels[chn].midi_buffer) {
  282. free (driver->capture_channels[chn].midi_buffer);
  283. }
  284. free (driver->capture_channels);
  285. for (chn = 0; chn < driver->playback_nchannels; chn++)
  286. if (driver->playback_channels[chn].midi_buffer) {
  287. free (driver->playback_channels[chn].midi_buffer);
  288. }
  289. free (driver->playback_channels);
  290. free (driver->nullbuffer);
  291. free (driver->scratchbuffer);
  292. return 0;
  293. }
  294. static int
  295. ffado_driver_read (ffado_driver_t * driver, jack_nframes_t nframes)
  296. {
  297. channel_t chn;
  298. int nb_connections;
  299. JSList *node;
  300. jack_port_t* port;
  301. printEnter ();
  302. for (chn = 0, node = driver->capture_ports; node; node = jack_slist_next (node), chn++) {
  303. if (driver->capture_channels[chn].stream_type == ffado_stream_type_audio) {
  304. port = (jack_port_t*)node->data;
  305. nb_connections = jack_port_connected (port);
  306. /* if there are no connections, use the dummy buffer and disable the stream */
  307. if (nb_connections) {
  308. ffado_streaming_capture_stream_onoff (driver->dev, chn, 1);
  309. ffado_streaming_set_capture_stream_buffer (driver->dev, chn, (char*)(jack_port_get_buffer (port, nframes)));
  310. } else {
  311. ffado_streaming_capture_stream_onoff (driver->dev, chn, 0);
  312. ffado_streaming_set_capture_stream_buffer (driver->dev, chn, (char*)(driver->scratchbuffer));
  313. }
  314. } else if (driver->capture_channels[chn].stream_type == ffado_stream_type_midi) {
  315. port = (jack_port_t*)node->data;
  316. nb_connections = jack_port_connected (port);
  317. if (nb_connections) {
  318. ffado_streaming_capture_stream_onoff (driver->dev, chn, 1);
  319. } else {
  320. ffado_streaming_capture_stream_onoff (driver->dev, chn, 0);
  321. }
  322. /* always set a buffer */
  323. ffado_streaming_set_capture_stream_buffer (driver->dev, chn,
  324. (char*)(driver->capture_channels[chn].midi_buffer));
  325. } else { /* ensure a valid buffer */
  326. ffado_streaming_set_capture_stream_buffer (driver->dev, chn, (char*)(driver->scratchbuffer));
  327. ffado_streaming_capture_stream_onoff (driver->dev, chn, 0);
  328. }
  329. }
  330. /* now transfer the buffers */
  331. ffado_streaming_transfer_capture_buffers (driver->dev);
  332. /* process the midi data */
  333. for (chn = 0, node = driver->capture_ports; node; node = jack_slist_next (node), chn++) {
  334. if (driver->capture_channels[chn].stream_type == ffado_stream_type_midi) {
  335. jack_default_audio_sample_t* buf;
  336. int i;
  337. int done;
  338. uint32_t *midi_buffer = driver->capture_channels[chn].midi_buffer;
  339. midi_unpack_t *midi_unpack = &driver->capture_channels[chn].midi_unpack;
  340. port = (jack_port_t*)node->data;
  341. nb_connections = jack_port_connected (port);
  342. buf = jack_port_get_buffer (port, nframes);
  343. /* if the returned buffer is invalid, discard the midi data */
  344. jack_midi_clear_buffer (buf);
  345. /* no connections means no processing */
  346. if (nb_connections == 0) {
  347. continue;
  348. }
  349. /* else unpack
  350. note that libffado guarantees that midi bytes are on 8-byte aligned indexes */
  351. for (i = 0; i < nframes; i += 8) {
  352. if (midi_buffer[i] & 0xFF000000) {
  353. done = midi_unpack_buf (midi_unpack, (unsigned char*)(midi_buffer + i), 1, buf, i);
  354. if (done != 1) {
  355. printError ("MIDI buffer overflow in channel %d\n", chn);
  356. break;
  357. }
  358. }
  359. }
  360. }
  361. }
  362. printExit ();
  363. return 0;
  364. }
  365. static int
  366. ffado_driver_write (ffado_driver_t * driver, jack_nframes_t nframes)
  367. {
  368. channel_t chn;
  369. int nb_connections;
  370. JSList *node;
  371. jack_port_t *port;
  372. printEnter ();
  373. driver->process_count++;
  374. if (driver->engine->freewheeling) {
  375. return 0;
  376. }
  377. for (chn = 0, node = driver->playback_ports; node; node = jack_slist_next (node), chn++) {
  378. if (driver->playback_channels[chn].stream_type == ffado_stream_type_audio) {
  379. port = (jack_port_t*)node->data;
  380. nb_connections = jack_port_connected (port);
  381. /* use the silent buffer + disable if there are no connections */
  382. if (nb_connections) {
  383. ffado_streaming_playback_stream_onoff (driver->dev, chn, 1);
  384. ffado_streaming_set_playback_stream_buffer (driver->dev, chn, (char*)(jack_port_get_buffer (port, nframes)));
  385. } else {
  386. ffado_streaming_playback_stream_onoff (driver->dev, chn, 0);
  387. ffado_streaming_set_playback_stream_buffer (driver->dev, chn, (char*)(driver->nullbuffer));
  388. }
  389. } else if (driver->playback_channels[chn].stream_type == ffado_stream_type_midi) {
  390. jack_default_audio_sample_t* buf;
  391. int nevents;
  392. int i;
  393. midi_pack_t *midi_pack = &driver->playback_channels[chn].midi_pack;
  394. uint32_t *midi_buffer = driver->playback_channels[chn].midi_buffer;
  395. int min_next_pos = 0;
  396. port = (jack_port_t*)node->data;
  397. nb_connections = jack_port_connected (port);
  398. /* skip if no connections */
  399. if (nb_connections == 0) {
  400. ffado_streaming_set_playback_stream_buffer (driver->dev, chn, (char*)(driver->nullbuffer));
  401. ffado_streaming_playback_stream_onoff (driver->dev, chn, 0);
  402. continue;
  403. }
  404. memset (midi_buffer, 0, nframes * sizeof(uint32_t));
  405. ffado_streaming_set_playback_stream_buffer (driver->dev, chn, (char*)(midi_buffer));
  406. ffado_streaming_playback_stream_onoff (driver->dev, chn, 1);
  407. /* check if we still have to process bytes from the previous period */
  408. /*
  409. if(driver->playback_channels[chn].nb_overflow_bytes) {
  410. printMessage("have to process %d bytes from previous period", driver->playback_channels[chn].nb_overflow_bytes);
  411. }
  412. */
  413. for (i = 0; i < driver->playback_channels[chn].nb_overflow_bytes; ++i) {
  414. midi_buffer[min_next_pos] = 0x01000000 | (driver->playback_channels[chn].overflow_buffer[i] & 0xFF);
  415. min_next_pos += 8;
  416. }
  417. driver->playback_channels[chn].nb_overflow_bytes = 0;
  418. /* process the events in this period */
  419. buf = jack_port_get_buffer (port, nframes);
  420. nevents = jack_midi_get_event_count (buf);
  421. for (i = 0; i < nevents; ++i) {
  422. int j;
  423. jack_midi_event_t event;
  424. jack_midi_event_get (&event, buf, i);
  425. midi_pack_event (midi_pack, &event);
  426. /* floor the initial position to be a multiple of 8 */
  427. int pos = event.time & 0xFFFFFFF8;
  428. for (j = 0; j < event.size; j++) {
  429. /* make sure we don't overwrite a previous byte */
  430. while (pos < min_next_pos && pos < nframes)
  431. /* printMessage("have to correct pos to %d", pos); */
  432. pos += 8;
  433. if (pos >= nframes) {
  434. int f;
  435. /* printMessage("midi message crosses period boundary"); */
  436. driver->playback_channels[chn].nb_overflow_bytes = event.size - j;
  437. if (driver->playback_channels[chn].nb_overflow_bytes > MIDI_OVERFLOW_BUFFER_SIZE) {
  438. printError ("too much midi bytes cross period boundary");
  439. driver->playback_channels[chn].nb_overflow_bytes = MIDI_OVERFLOW_BUFFER_SIZE;
  440. }
  441. /* save the bytes that still have to be transmitted in the next period */
  442. for (f = 0; f < driver->playback_channels[chn].nb_overflow_bytes; f++)
  443. driver->playback_channels[chn].overflow_buffer[f] = event.buffer[j + f];
  444. /* exit since we can't transmit anything anymore.
  445. the rate should be controlled */
  446. if (i < nevents - 1) {
  447. printError ("%d midi events lost due to period crossing", nevents - i - 1);
  448. }
  449. break;
  450. } else {
  451. midi_buffer[pos] = 0x01000000 | (event.buffer[j] & 0xFF);
  452. pos += 8;
  453. min_next_pos = pos;
  454. }
  455. }
  456. }
  457. } else { /* ensure a valid buffer */
  458. ffado_streaming_set_playback_stream_buffer (driver->dev, chn, (char*)(driver->nullbuffer));
  459. ffado_streaming_playback_stream_onoff (driver->dev, chn, 0);
  460. }
  461. }
  462. ffado_streaming_transfer_playback_buffers (driver->dev);
  463. printExit ();
  464. return 0;
  465. }
  466. //static inline jack_nframes_t
  467. static jack_nframes_t
  468. ffado_driver_wait (ffado_driver_t *driver, int extra_fd, int *status,
  469. float *delayed_usecs)
  470. {
  471. jack_time_t wait_enter;
  472. jack_time_t wait_ret;
  473. ffado_wait_response response;
  474. printEnter ();
  475. wait_enter = driver->engine->get_microseconds ();
  476. if (wait_enter > driver->wait_next) {
  477. /*
  478. * This processing cycle was delayed past the
  479. * next due interrupt! Do not account this as
  480. * a wakeup delay:
  481. */
  482. driver->wait_next = 0;
  483. driver->wait_late++;
  484. }
  485. // *status = -2; interrupt
  486. // *status = -3; timeout
  487. // *status = -4; extra FD
  488. response = ffado_streaming_wait (driver->dev);
  489. wait_ret = driver->engine->get_microseconds ();
  490. if (driver->wait_next && wait_ret > driver->wait_next) {
  491. *delayed_usecs = wait_ret - driver->wait_next;
  492. }
  493. driver->wait_last = wait_ret;
  494. driver->wait_next = wait_ret + driver->period_usecs;
  495. driver->engine->transport_cycle_start (driver->engine, wait_ret);
  496. if (response == ffado_wait_ok) {
  497. // all good
  498. *status = 0;
  499. } else if (response == ffado_wait_xrun) {
  500. // xrun happened, but it's handled
  501. *status = 0;
  502. return 0;
  503. } else if (response == ffado_wait_error) {
  504. // an error happened (unhandled xrun)
  505. // this should be fatal
  506. *status = -1;
  507. return 0;
  508. } else if (response == ffado_wait_shutdown) {
  509. // we are to shutdown the ffado system
  510. // this should be fatal
  511. *status = -1;
  512. return 0;
  513. } else {
  514. // we don't know about this response code
  515. printError ("unknown wait response (%d) from ffado", response);
  516. // this should be fatal
  517. *status = -1;
  518. return 0;
  519. }
  520. driver->last_wait_ust = wait_ret;
  521. // FIXME: this should do something more useful
  522. *delayed_usecs = 0;
  523. printExit ();
  524. return driver->period_size;
  525. }
  526. static int
  527. ffado_driver_run_cycle (ffado_driver_t *driver)
  528. {
  529. jack_engine_t *engine = driver->engine;
  530. int wait_status = 0;
  531. float delayed_usecs = 0.0;
  532. jack_nframes_t nframes = ffado_driver_wait (driver, -1,
  533. &wait_status, &delayed_usecs);
  534. if ((wait_status < 0)) {
  535. printError ( "wait status < 0! (= %d)", wait_status);
  536. return -1;
  537. }
  538. if ((nframes == 0)) {
  539. /* we detected an xrun and restarted: notify
  540. * clients about the delay. */
  541. printMessage ("xrun detected");
  542. engine->delay (engine, delayed_usecs);
  543. return 0;
  544. }
  545. return engine->run_cycle (engine, nframes, delayed_usecs);
  546. }
  547. /*
  548. * in a null cycle we should discard the input and write silence to the outputs
  549. */
  550. static int
  551. ffado_driver_null_cycle (ffado_driver_t* driver, jack_nframes_t nframes)
  552. {
  553. channel_t chn;
  554. JSList *node;
  555. ffado_streaming_stream_type stream_type;
  556. printEnter ();
  557. if (driver->engine->freewheeling) {
  558. return 0;
  559. }
  560. // write silence to buffer
  561. for (chn = 0, node = driver->playback_ports; node; node = jack_slist_next (node), chn++) {
  562. stream_type = ffado_streaming_get_playback_stream_type (driver->dev, chn);
  563. if (stream_type == ffado_stream_type_audio) {
  564. ffado_streaming_set_playback_stream_buffer (driver->dev, chn, (char*)(driver->nullbuffer));
  565. }
  566. }
  567. ffado_streaming_transfer_playback_buffers (driver->dev);
  568. // read & discard from input ports
  569. for (chn = 0, node = driver->capture_ports; node; node = jack_slist_next (node), chn++) {
  570. stream_type = ffado_streaming_get_capture_stream_type (driver->dev, chn);
  571. if (stream_type == ffado_stream_type_audio) {
  572. ffado_streaming_set_capture_stream_buffer (driver->dev, chn, (char*)(driver->scratchbuffer));
  573. }
  574. }
  575. ffado_streaming_transfer_capture_buffers (driver->dev);
  576. printExit ();
  577. return 0;
  578. }
  579. static int
  580. ffado_driver_start (ffado_driver_t *driver)
  581. {
  582. int retval = 0;
  583. if ((retval = ffado_streaming_start (driver->dev))) {
  584. printError ("Could not start streaming threads: %d", retval);
  585. return retval;
  586. }
  587. return 0;
  588. }
  589. static int
  590. ffado_driver_stop (ffado_driver_t *driver)
  591. {
  592. int retval = 0;
  593. if ((retval = ffado_streaming_stop (driver->dev))) {
  594. printError ("Could not stop streaming threads");
  595. return retval;
  596. }
  597. return 0;
  598. }
  599. static int
  600. ffado_driver_bufsize (ffado_driver_t* driver, jack_nframes_t nframes)
  601. {
  602. signed int chn;
  603. // The speed of this function isn't critical; we can afford the
  604. // time to check the FFADO API version.
  605. if (ffado_get_api_version () < FIREWIRE_REQUIRED_FFADO_API_VERSION_FOR_SETBUFSIZE ||
  606. ffado_streaming_set_period_size == NULL) {
  607. printError ("unsupported on current version of FFADO; please upgrade FFADO");
  608. return -1;
  609. }
  610. driver->period_size = nframes;
  611. driver->period_usecs =
  612. (jack_time_t)floor ((((float)nframes) / driver->sample_rate)
  613. * 1000000.0f);
  614. // Reallocate the null and scratch buffers.
  615. driver->nullbuffer = calloc (driver->period_size, sizeof(ffado_sample_t));
  616. if (driver->nullbuffer == NULL) {
  617. printError ("could not allocate memory for null buffer");
  618. return -1;
  619. }
  620. driver->scratchbuffer = calloc (driver->period_size, sizeof(ffado_sample_t));
  621. if (driver->scratchbuffer == NULL) {
  622. printError ("could not allocate memory for scratch buffer");
  623. return -1;
  624. }
  625. // MIDI buffers need reallocating
  626. for (chn = 0; chn < driver->capture_nchannels; chn++) {
  627. if (driver->capture_channels[chn].stream_type == ffado_stream_type_midi) {
  628. // setup the midi buffer
  629. if (driver->capture_channels[chn].midi_buffer != NULL) {
  630. free (driver->capture_channels[chn].midi_buffer);
  631. }
  632. driver->capture_channels[chn].midi_buffer = calloc (driver->period_size, sizeof(uint32_t));
  633. }
  634. }
  635. for (chn = 0; chn < driver->playback_nchannels; chn++) {
  636. if (driver->playback_channels[chn].stream_type == ffado_stream_type_midi) {
  637. if (driver->playback_channels[chn].midi_buffer != NULL) {
  638. free (driver->playback_channels[chn].midi_buffer);
  639. }
  640. driver->playback_channels[chn].midi_buffer = calloc (driver->period_size, sizeof(uint32_t));
  641. }
  642. }
  643. // Notify FFADO of the period size change
  644. if (ffado_streaming_set_period_size (driver->dev, nframes) != 0) {
  645. printError ("could not alter FFADO device period size");
  646. return -1;
  647. }
  648. // This is needed to give the shadow variables a chance to
  649. // properly update to the changes.
  650. sleep (1);
  651. /* tell the engine to change its buffer size */
  652. if (driver->engine->set_buffer_size (driver->engine, nframes)) {
  653. jack_error ("FFADO: cannot set engine buffer size to %d (check MIDI)", nframes);
  654. return -1;
  655. }
  656. return 0;
  657. }
  658. typedef void (*JackDriverFinishFunction)(jack_driver_t *);
  659. ffado_driver_t *
  660. ffado_driver_new (jack_client_t * client,
  661. char *name,
  662. ffado_jack_settings_t *params)
  663. {
  664. ffado_driver_t *driver;
  665. if (ffado_get_api_version () < FIREWIRE_REQUIRED_FFADO_API_VERSION) {
  666. printError ("Incompatible libffado version! (%s)", ffado_get_version ());
  667. return NULL;
  668. }
  669. printMessage ("Starting firewire backend (%s)", ffado_get_version ());
  670. driver = calloc (1, sizeof(ffado_driver_t));
  671. /* Setup the jack interfaces */
  672. jack_driver_nt_init ((jack_driver_nt_t*)driver);
  673. driver->nt_attach = (JackDriverNTAttachFunction)ffado_driver_attach;
  674. driver->nt_detach = (JackDriverNTDetachFunction)ffado_driver_detach;
  675. driver->nt_start = (JackDriverNTStartFunction)ffado_driver_start;
  676. driver->nt_stop = (JackDriverNTStopFunction)ffado_driver_stop;
  677. driver->nt_run_cycle = (JackDriverNTRunCycleFunction)ffado_driver_run_cycle;
  678. driver->null_cycle = (JackDriverNullCycleFunction)ffado_driver_null_cycle;
  679. driver->write = (JackDriverReadFunction)ffado_driver_write;
  680. driver->read = (JackDriverReadFunction)ffado_driver_read;
  681. driver->nt_bufsize = (JackDriverNTBufSizeFunction)ffado_driver_bufsize;
  682. /* copy command line parameter contents to the driver structure */
  683. memcpy (&driver->settings, params, sizeof(ffado_jack_settings_t));
  684. /* prepare all parameters */
  685. driver->sample_rate = params->sample_rate;
  686. driver->period_size = params->period_size;
  687. driver->last_wait_ust = 0;
  688. driver->period_usecs =
  689. (jack_time_t)floor ((((float)driver->period_size) * 1000000.0f) / driver->sample_rate);
  690. driver->client = client;
  691. driver->engine = NULL;
  692. jack_set_latency_callback (client, ffado_latency_callback, driver);
  693. memset (&driver->device_options, 0, sizeof(driver->device_options));
  694. driver->device_options.sample_rate = params->sample_rate;
  695. driver->device_options.period_size = params->period_size;
  696. driver->device_options.nb_buffers = params->buffer_size;
  697. driver->capture_frame_latency = params->capture_frame_latency;
  698. driver->playback_frame_latency = params->playback_frame_latency;
  699. driver->device_options.slave_mode = params->slave_mode;
  700. driver->device_options.snoop_mode = params->snoop_mode;
  701. driver->device_options.verbose = params->verbose_level;
  702. driver->device_info.nb_device_spec_strings = 1;
  703. driver->device_info.device_spec_strings = calloc (1, sizeof(char *));
  704. driver->device_info.device_spec_strings[0] = strdup (params->device_info);
  705. debugPrint (DEBUG_LEVEL_STARTUP, " Driver compiled on %s %s for FFADO %s (API version %d)",
  706. __DATE__, __TIME__, ffado_get_version (), ffado_get_api_version ());
  707. debugPrint (DEBUG_LEVEL_STARTUP, " Created driver %s", name);
  708. debugPrint (DEBUG_LEVEL_STARTUP, " period_size: %d", driver->period_size);
  709. debugPrint (DEBUG_LEVEL_STARTUP, " period_usecs: %d", driver->period_usecs);
  710. debugPrint (DEBUG_LEVEL_STARTUP, " sample rate: %d", driver->sample_rate);
  711. return (ffado_driver_t*)driver;
  712. }
  713. static void
  714. ffado_driver_delete (ffado_driver_t *driver)
  715. {
  716. unsigned int i;
  717. jack_driver_nt_finish ((jack_driver_nt_t*)driver);
  718. for (i = 0; i < driver->device_info.nb_device_spec_strings; i++)
  719. free (driver->device_info.device_spec_strings[i]);
  720. free (driver->device_info.device_spec_strings);
  721. free (driver);
  722. }
  723. /*
  724. * dlopen plugin stuff
  725. */
  726. const char driver_client_name[] = "firewire_pcm";
  727. const jack_driver_desc_t *
  728. driver_get_descriptor ()
  729. {
  730. jack_driver_desc_t * desc;
  731. jack_driver_param_desc_t * params;
  732. unsigned int i;
  733. desc = calloc (1, sizeof(jack_driver_desc_t));
  734. strcpy (desc->name, "firewire");
  735. desc->nparams = 11;
  736. params = calloc (desc->nparams, sizeof(jack_driver_param_desc_t));
  737. desc->params = params;
  738. i = 0;
  739. strcpy (params[i].name, "device");
  740. params[i].character = 'd';
  741. params[i].type = JackDriverParamString;
  742. strcpy (params[i].value.str, "hw:0");
  743. strcpy (params[i].short_desc, "The FireWire device to use.");
  744. strcpy (params[i].long_desc, "The FireWire device to use. Please consult the FFADO documentation for more info.");
  745. i++;
  746. strcpy (params[i].name, "period");
  747. params[i].character = 'p';
  748. params[i].type = JackDriverParamUInt;
  749. params[i].value.ui = 1024;
  750. strcpy (params[i].short_desc, "Frames per period");
  751. strcpy (params[i].long_desc, params[i].short_desc);
  752. i++;
  753. strcpy (params[i].name, "nperiods");
  754. params[i].character = 'n';
  755. params[i].type = JackDriverParamUInt;
  756. params[i].value.ui = 3;
  757. strcpy (params[i].short_desc, "Number of periods of playback latency");
  758. strcpy (params[i].long_desc, params[i].short_desc);
  759. i++;
  760. strcpy (params[i].name, "rate");
  761. params[i].character = 'r';
  762. params[i].type = JackDriverParamUInt;
  763. params[i].value.ui = 48000U;
  764. strcpy (params[i].short_desc, "Sample rate");
  765. strcpy (params[i].long_desc, params[i].short_desc);
  766. i++;
  767. strcpy (params[i].name, "capture");
  768. params[i].character = 'i';
  769. params[i].type = JackDriverParamUInt;
  770. params[i].value.ui = 1U;
  771. strcpy (params[i].short_desc, "Provide capture ports.");
  772. strcpy (params[i].long_desc, params[i].short_desc);
  773. i++;
  774. strcpy (params[i].name, "playback");
  775. params[i].character = 'o';
  776. params[i].type = JackDriverParamUInt;
  777. params[i].value.ui = 1U;
  778. strcpy (params[i].short_desc, "Provide playback ports.");
  779. strcpy (params[i].long_desc, params[i].short_desc);
  780. i++;
  781. strcpy (params[i].name, "input-latency");
  782. params[i].character = 'I';
  783. params[i].type = JackDriverParamUInt;
  784. params[i].value.ui = 0;
  785. strcpy (params[i].short_desc, "Extra input latency (frames)");
  786. strcpy (params[i].long_desc, params[i].short_desc);
  787. i++;
  788. strcpy (params[i].name, "output-latency");
  789. params[i].character = 'O';
  790. params[i].type = JackDriverParamUInt;
  791. params[i].value.ui = 0;
  792. strcpy (params[i].short_desc, "Extra output latency (frames)");
  793. strcpy (params[i].long_desc, params[i].short_desc);
  794. i++;
  795. strcpy (params[i].name, "slave");
  796. params[i].character = 'x';
  797. params[i].type = JackDriverParamUInt;
  798. params[i].value.ui = 0U;
  799. strcpy (params[i].short_desc, "Act as a BounceDevice slave");
  800. strcpy (params[i].long_desc, params[i].short_desc);
  801. i++;
  802. strcpy (params[i].name, "slave");
  803. params[i].character = 'X';
  804. params[i].type = JackDriverParamUInt;
  805. params[i].value.ui = 0U;
  806. strcpy (params[i].short_desc, "Operate in snoop mode");
  807. strcpy (params[i].long_desc, params[i].short_desc);
  808. i++;
  809. strcpy (params[i].name, "verbose");
  810. params[i].character = 'v';
  811. params[i].type = JackDriverParamUInt;
  812. params[i].value.ui = 0U;
  813. strcpy (params[i].short_desc, "Verbose level for the firewire backend");
  814. strcpy (params[i].long_desc, params[i].short_desc);
  815. return desc;
  816. }
  817. jack_driver_t *
  818. driver_initialize (jack_client_t *client, JSList * params)
  819. {
  820. jack_driver_t *driver;
  821. const JSList * node;
  822. const jack_driver_param_t * param;
  823. ffado_jack_settings_t cmlparams;
  824. char *device_name = "hw:0";
  825. cmlparams.period_size_set = 0;
  826. cmlparams.sample_rate_set = 0;
  827. cmlparams.buffer_size_set = 0;
  828. /* default values */
  829. cmlparams.period_size = 1024;
  830. cmlparams.sample_rate = 48000;
  831. cmlparams.buffer_size = 3;
  832. cmlparams.playback_ports = 1;
  833. cmlparams.capture_ports = 1;
  834. cmlparams.playback_frame_latency = 0;
  835. cmlparams.capture_frame_latency = 0;
  836. cmlparams.slave_mode = 0;
  837. cmlparams.snoop_mode = 0;
  838. cmlparams.verbose_level = 0;
  839. for (node = params; node; node = jack_slist_next (node)) {
  840. param = (jack_driver_param_t*)node->data;
  841. switch (param->character) {
  842. case 'd':
  843. device_name = strdup (param->value.str);
  844. break;
  845. case 'p':
  846. cmlparams.period_size = param->value.ui;
  847. cmlparams.period_size_set = 1;
  848. break;
  849. case 'n':
  850. cmlparams.buffer_size = param->value.ui;
  851. cmlparams.buffer_size_set = 1;
  852. break;
  853. case 'r':
  854. cmlparams.sample_rate = param->value.ui;
  855. cmlparams.sample_rate_set = 1;
  856. break;
  857. case 'i':
  858. cmlparams.capture_ports = param->value.ui;
  859. break;
  860. case 'o':
  861. cmlparams.playback_ports = param->value.ui;
  862. break;
  863. case 'I':
  864. cmlparams.capture_frame_latency = param->value.ui;
  865. break;
  866. case 'O':
  867. cmlparams.playback_frame_latency = param->value.ui;
  868. break;
  869. case 'x':
  870. cmlparams.slave_mode = param->value.ui;
  871. break;
  872. case 'X':
  873. cmlparams.snoop_mode = param->value.ui;
  874. break;
  875. case 'v':
  876. cmlparams.verbose_level = param->value.ui;
  877. break;
  878. }
  879. }
  880. // temporary
  881. cmlparams.device_info = device_name;
  882. driver = (jack_driver_t*)ffado_driver_new (client, "ffado_pcm", &cmlparams);
  883. return driver;
  884. }
  885. void
  886. driver_finish (jack_driver_t *driver)
  887. {
  888. ffado_driver_t *drv = (ffado_driver_t*)driver;
  889. // If jack hasn't called the detach method, do it now. As of jack 0.101.1
  890. // the detach method was not being called explicitly on closedown, and
  891. // we need it to at least deallocate the iso resources.
  892. if (drv->dev != NULL) {
  893. ffado_driver_detach (drv);
  894. }
  895. ffado_driver_delete (drv);
  896. }