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.

1057 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. }
  77. static int
  78. ffado_driver_attach (ffado_driver_t *driver)
  79. {
  80. char buf[64];
  81. char buf2[64];
  82. channel_t chn;
  83. jack_port_t *port=NULL;
  84. int port_flags;
  85. g_verbose=driver->engine->verbose;
  86. if (driver->engine->set_buffer_size (driver->engine, driver->period_size)) {
  87. jack_error ("FFADO: cannot set engine buffer size to %d (check MIDI)", driver->period_size);
  88. return -1;
  89. }
  90. driver->engine->set_sample_rate (driver->engine, driver->sample_rate);
  91. /* preallocate some buffers such that they don't have to be allocated
  92. in RT context (or from the stack)
  93. */
  94. /* the null buffer is a buffer that contains one period of silence */
  95. driver->nullbuffer = calloc(driver->period_size, sizeof(ffado_sample_t));
  96. if(driver->nullbuffer == NULL) {
  97. printError("could not allocate memory for null buffer");
  98. return -1;
  99. }
  100. /* calloc should do this, but it can't hurt to be sure */
  101. memset(driver->nullbuffer, 0, driver->period_size*sizeof(ffado_sample_t));
  102. /* the scratch buffer is a buffer of one period that can be used as dummy memory */
  103. driver->scratchbuffer = calloc(driver->period_size, sizeof(ffado_sample_t));
  104. if(driver->scratchbuffer == NULL) {
  105. printError("could not allocate memory for scratch buffer");
  106. return -1;
  107. }
  108. /* packetizer thread options */
  109. driver->device_options.realtime=(driver->engine->control->real_time? 1 : 0);
  110. driver->device_options.packetizer_priority = driver->engine->rtpriority;
  111. if (driver->device_options.packetizer_priority > 98) {
  112. driver->device_options.packetizer_priority = 98;
  113. }
  114. if (driver->device_options.packetizer_priority < 1) {
  115. driver->device_options.packetizer_priority = 1;
  116. }
  117. driver->dev = ffado_streaming_init(driver->device_info, driver->device_options);
  118. if(!driver->dev) {
  119. printError("Error creating FFADO streaming device");
  120. return -1;
  121. }
  122. if (driver->device_options.realtime) {
  123. printMessage("Streaming thread running with Realtime scheduling, priority %d",
  124. driver->device_options.packetizer_priority);
  125. } else {
  126. printMessage("Streaming thread running without Realtime scheduling");
  127. }
  128. ffado_streaming_set_audio_datatype(driver->dev, ffado_audio_datatype_float);
  129. /* ports */
  130. port_flags = JackPortIsOutput|JackPortIsPhysical|JackPortIsTerminal;
  131. driver->capture_nchannels=ffado_streaming_get_nb_capture_streams(driver->dev);
  132. driver->capture_channels=calloc(driver->capture_nchannels, sizeof(ffado_capture_channel_t));
  133. if(driver->capture_channels==NULL) {
  134. printError("could not allocate memory for capture channel list");
  135. return -1;
  136. }
  137. for (chn = 0; chn < driver->capture_nchannels; chn++) {
  138. ffado_streaming_get_capture_stream_name(driver->dev, chn, buf, sizeof(buf) - 1);
  139. driver->capture_channels[chn].stream_type=ffado_streaming_get_capture_stream_type(driver->dev, chn);
  140. if(driver->capture_channels[chn].stream_type == ffado_stream_type_audio) {
  141. snprintf(buf2, 64, "C%d_%s",(int)chn,buf); // needed to avoid duplicate names
  142. printMessage ("Registering audio capture port %s", buf2);
  143. if ((port = jack_port_register (driver->client, buf2,
  144. JACK_DEFAULT_AUDIO_TYPE,
  145. port_flags, 0)) == NULL) {
  146. printError (" cannot register port for %s", buf2);
  147. break;
  148. }
  149. driver->capture_ports =
  150. jack_slist_append (driver->capture_ports, port);
  151. // setup port parameters
  152. if (ffado_streaming_set_capture_stream_buffer(driver->dev, chn, NULL)) {
  153. printError(" cannot configure initial port buffer for %s", buf2);
  154. }
  155. if(ffado_streaming_capture_stream_onoff(driver->dev, chn, 1)) {
  156. printError(" cannot enable port %s", buf2);
  157. }
  158. } else if(driver->capture_channels[chn].stream_type == ffado_stream_type_midi) {
  159. snprintf(buf2, 64, "C%d_%s",(int)chn,buf); // needed to avoid duplicate names
  160. printMessage ("Registering midi capture port %s", buf2);
  161. if ((port = jack_port_register (driver->client, buf2,
  162. JACK_DEFAULT_MIDI_TYPE,
  163. port_flags, 0)) == NULL) {
  164. printError (" cannot register port for %s", buf2);
  165. break;
  166. }
  167. driver->capture_ports =
  168. jack_slist_append (driver->capture_ports, port);
  169. // setup port parameters
  170. if (ffado_streaming_set_capture_stream_buffer(driver->dev, chn, NULL)) {
  171. printError(" cannot configure initial port buffer for %s", buf2);
  172. }
  173. if(ffado_streaming_capture_stream_onoff(driver->dev, chn, 1)) {
  174. printError(" cannot enable port %s", buf2);
  175. }
  176. // setup midi unpacker
  177. midi_unpack_init(&driver->capture_channels[chn].midi_unpack);
  178. midi_unpack_reset(&driver->capture_channels[chn].midi_unpack);
  179. // setup the midi buffer
  180. driver->capture_channels[chn].midi_buffer = calloc(driver->period_size, sizeof(uint32_t));
  181. } else {
  182. printMessage ("Don't register capture port %s", buf);
  183. // we have to add a NULL entry in the list to be able to loop over the channels in the read/write routines
  184. driver->capture_ports =
  185. jack_slist_append (driver->capture_ports, NULL);
  186. }
  187. }
  188. port_flags = JackPortIsInput|JackPortIsPhysical|JackPortIsTerminal;
  189. driver->playback_nchannels=ffado_streaming_get_nb_playback_streams(driver->dev);
  190. driver->playback_channels=calloc(driver->playback_nchannels, sizeof(ffado_playback_channel_t));
  191. if(driver->playback_channels==NULL) {
  192. printError("could not allocate memory for playback channel list");
  193. return -1;
  194. }
  195. for (chn = 0; chn < driver->playback_nchannels; chn++) {
  196. ffado_streaming_get_playback_stream_name(driver->dev, chn, buf, sizeof(buf) - 1);
  197. driver->playback_channels[chn].stream_type=ffado_streaming_get_playback_stream_type(driver->dev, chn);
  198. if(driver->playback_channels[chn].stream_type == ffado_stream_type_audio) {
  199. snprintf(buf2, 64, "P%d_%s",(int)chn,buf); // needed to avoid duplicate names
  200. printMessage ("Registering audio playback port %s", buf2);
  201. if ((port = jack_port_register (driver->client, buf2,
  202. JACK_DEFAULT_AUDIO_TYPE,
  203. port_flags, 0)) == NULL) {
  204. printError(" cannot register port for %s", buf2);
  205. break;
  206. }
  207. driver->playback_ports =
  208. jack_slist_append (driver->playback_ports, port);
  209. // setup port parameters
  210. if (ffado_streaming_set_playback_stream_buffer(driver->dev, chn, NULL)) {
  211. printError(" cannot configure initial port buffer for %s", buf2);
  212. }
  213. if(ffado_streaming_playback_stream_onoff(driver->dev, chn, 1)) {
  214. printError(" cannot enable port %s", buf2);
  215. }
  216. } else if(driver->playback_channels[chn].stream_type == ffado_stream_type_midi) {
  217. snprintf(buf2, 64, "P%d_%s",(int)chn,buf); // needed to avoid duplicate names
  218. printMessage ("Registering midi playback port %s", buf2);
  219. if ((port = jack_port_register (driver->client, buf2,
  220. JACK_DEFAULT_MIDI_TYPE,
  221. port_flags, 0)) == NULL) {
  222. printError(" cannot register port for %s", buf2);
  223. break;
  224. }
  225. driver->playback_ports =
  226. jack_slist_append (driver->playback_ports, port);
  227. // setup port parameters
  228. if (ffado_streaming_set_playback_stream_buffer(driver->dev, chn, NULL)) {
  229. printError(" cannot configure initial port buffer for %s", buf2);
  230. }
  231. if(ffado_streaming_playback_stream_onoff(driver->dev, chn, 1)) {
  232. printError(" cannot enable port %s", buf2);
  233. }
  234. // setup midi packer
  235. midi_pack_reset(&driver->playback_channels[chn].midi_pack);
  236. // setup the midi buffer
  237. driver->playback_channels[chn].midi_buffer = calloc(driver->period_size, sizeof(uint32_t));
  238. } else {
  239. printMessage ("Don't register playback port %s", buf);
  240. // we have to add a NULL entry in the list to be able to loop over the channels in the read/write routines
  241. driver->playback_ports =
  242. jack_slist_append (driver->playback_ports, NULL);
  243. }
  244. }
  245. if(ffado_streaming_prepare(driver->dev)) {
  246. printError("Could not prepare streaming device!");
  247. return -1;
  248. }
  249. return jack_activate (driver->client);
  250. }
  251. static int
  252. ffado_driver_detach (ffado_driver_t *driver)
  253. {
  254. JSList *node;
  255. unsigned int chn;
  256. if (driver->engine == NULL) {
  257. return 0;
  258. }
  259. for (node = driver->capture_ports; node;
  260. node = jack_slist_next (node)) {
  261. // Don't try to unregister NULL entries added for non-audio
  262. // ffado ports by ffado_driver_attach().
  263. if (node->data != NULL) {
  264. jack_port_unregister (driver->client,
  265. ((jack_port_t *) node->data));
  266. }
  267. }
  268. jack_slist_free (driver->capture_ports);
  269. driver->capture_ports = 0;
  270. for (node = driver->playback_ports; node;
  271. node = jack_slist_next (node)) {
  272. if (node->data != NULL) {
  273. jack_port_unregister (driver->client,
  274. ((jack_port_t *) node->data));
  275. }
  276. }
  277. jack_slist_free (driver->playback_ports);
  278. driver->playback_ports = 0;
  279. ffado_streaming_finish(driver->dev);
  280. driver->dev=NULL;
  281. for (chn = 0; chn < driver->capture_nchannels; chn++) {
  282. if(driver->capture_channels[chn].midi_buffer)
  283. free(driver->capture_channels[chn].midi_buffer);
  284. }
  285. free(driver->capture_channels);
  286. for (chn = 0; chn < driver->playback_nchannels; chn++) {
  287. if(driver->playback_channels[chn].midi_buffer)
  288. free(driver->playback_channels[chn].midi_buffer);
  289. }
  290. free(driver->playback_channels);
  291. free(driver->nullbuffer);
  292. free(driver->scratchbuffer);
  293. return 0;
  294. }
  295. static int
  296. ffado_driver_read (ffado_driver_t * driver, jack_nframes_t nframes)
  297. {
  298. channel_t chn;
  299. int nb_connections;
  300. JSList *node;
  301. jack_port_t* port;
  302. printEnter();
  303. for (chn = 0, node = driver->capture_ports; node; node = jack_slist_next (node), chn++) {
  304. if(driver->capture_channels[chn].stream_type == ffado_stream_type_audio) {
  305. port = (jack_port_t *) node->data;
  306. nb_connections = jack_port_connected (port);
  307. /* if there are no connections, use the dummy buffer and disable the stream */
  308. if(nb_connections) {
  309. ffado_streaming_capture_stream_onoff(driver->dev, chn, 1);
  310. ffado_streaming_set_capture_stream_buffer(driver->dev, chn, (char *)(jack_port_get_buffer (port, nframes)));
  311. } else {
  312. ffado_streaming_capture_stream_onoff(driver->dev, chn, 0);
  313. ffado_streaming_set_capture_stream_buffer(driver->dev, chn, (char *)(driver->scratchbuffer));
  314. }
  315. } else if (driver->capture_channels[chn].stream_type == ffado_stream_type_midi) {
  316. port = (jack_port_t *) node->data;
  317. nb_connections = jack_port_connected (port);
  318. if(nb_connections) {
  319. ffado_streaming_capture_stream_onoff(driver->dev, chn, 1);
  320. } else {
  321. ffado_streaming_capture_stream_onoff(driver->dev, chn, 0);
  322. }
  323. /* always set a buffer */
  324. ffado_streaming_set_capture_stream_buffer(driver->dev, chn,
  325. (char *)(driver->capture_channels[chn].midi_buffer));
  326. } else { /* ensure a valid buffer */
  327. ffado_streaming_set_capture_stream_buffer(driver->dev, chn, (char *)(driver->scratchbuffer));
  328. ffado_streaming_capture_stream_onoff(driver->dev, chn, 0);
  329. }
  330. }
  331. /* now transfer the buffers */
  332. ffado_streaming_transfer_capture_buffers(driver->dev);
  333. /* process the midi data */
  334. for (chn = 0, node = driver->capture_ports; node; node = jack_slist_next (node), chn++) {
  335. if (driver->capture_channels[chn].stream_type == ffado_stream_type_midi) {
  336. jack_default_audio_sample_t* buf;
  337. int i;
  338. int done;
  339. uint32_t *midi_buffer = driver->capture_channels[chn].midi_buffer;
  340. midi_unpack_t *midi_unpack = &driver->capture_channels[chn].midi_unpack;
  341. port = (jack_port_t *) node->data;
  342. nb_connections = jack_port_connected (port);
  343. buf = jack_port_get_buffer (port, nframes);
  344. /* if the returned buffer is invalid, discard the midi data */
  345. jack_midi_clear_buffer(buf);
  346. /* no connections means no processing */
  347. if(nb_connections == 0) continue;
  348. /* else unpack
  349. note that libffado guarantees that midi bytes are on 8-byte aligned indexes */
  350. for(i = 0; i < nframes; i += 8) {
  351. if(midi_buffer[i] & 0xFF000000) {
  352. done = midi_unpack_buf(midi_unpack, (unsigned char *)(midi_buffer+i), 1, buf, i);
  353. if (done != 1) {
  354. printError("MIDI buffer overflow in channel %d\n", chn);
  355. break;
  356. }
  357. }
  358. }
  359. }
  360. }
  361. printExit();
  362. return 0;
  363. }
  364. static int
  365. ffado_driver_write (ffado_driver_t * driver, jack_nframes_t nframes)
  366. {
  367. channel_t chn;
  368. int nb_connections;
  369. JSList *node;
  370. jack_port_t *port;
  371. printEnter();
  372. driver->process_count++;
  373. if (driver->engine->freewheeling) {
  374. return 0;
  375. }
  376. for (chn = 0, node = driver->playback_ports; node; node = jack_slist_next (node), chn++) {
  377. if(driver->playback_channels[chn].stream_type == ffado_stream_type_audio) {
  378. port = (jack_port_t *) node->data;
  379. nb_connections = jack_port_connected (port);
  380. /* use the silent buffer + disable if there are no connections */
  381. if(nb_connections) {
  382. ffado_streaming_playback_stream_onoff(driver->dev, chn, 1);
  383. ffado_streaming_set_playback_stream_buffer(driver->dev, chn, (char *)(jack_port_get_buffer (port, nframes)));
  384. } else {
  385. ffado_streaming_playback_stream_onoff(driver->dev, chn, 0);
  386. ffado_streaming_set_playback_stream_buffer(driver->dev, chn, (char *)(driver->nullbuffer));
  387. }
  388. } else if (driver->playback_channels[chn].stream_type == ffado_stream_type_midi) {
  389. jack_default_audio_sample_t* buf;
  390. int nevents;
  391. int i;
  392. midi_pack_t *midi_pack = &driver->playback_channels[chn].midi_pack;
  393. uint32_t *midi_buffer = driver->playback_channels[chn].midi_buffer;
  394. int min_next_pos = 0;
  395. port = (jack_port_t *) node->data;
  396. nb_connections = jack_port_connected (port);
  397. /* skip if no connections */
  398. if(nb_connections == 0) {
  399. ffado_streaming_set_playback_stream_buffer(driver->dev, chn, (char *)(driver->nullbuffer));
  400. ffado_streaming_playback_stream_onoff(driver->dev, chn, 0);
  401. continue;
  402. }
  403. memset(midi_buffer, 0, nframes * sizeof(uint32_t));
  404. ffado_streaming_set_playback_stream_buffer(driver->dev, chn, (char *)(midi_buffer));
  405. ffado_streaming_playback_stream_onoff(driver->dev, chn, 1);
  406. /* check if we still have to process bytes from the previous period */
  407. /*
  408. if(driver->playback_channels[chn].nb_overflow_bytes) {
  409. printMessage("have to process %d bytes from previous period", driver->playback_channels[chn].nb_overflow_bytes);
  410. }
  411. */
  412. for (i=0; i<driver->playback_channels[chn].nb_overflow_bytes; ++i) {
  413. midi_buffer[min_next_pos] = 0x01000000 | (driver->playback_channels[chn].overflow_buffer[i] & 0xFF);
  414. min_next_pos += 8;
  415. }
  416. driver->playback_channels[chn].nb_overflow_bytes=0;
  417. /* process the events in this period */
  418. buf = jack_port_get_buffer (port, nframes);
  419. nevents = jack_midi_get_event_count(buf);
  420. for (i=0; i<nevents; ++i) {
  421. int j;
  422. jack_midi_event_t event;
  423. jack_midi_event_get(&event, buf, i);
  424. midi_pack_event(midi_pack, &event);
  425. /* floor the initial position to be a multiple of 8 */
  426. int pos = event.time & 0xFFFFFFF8;
  427. for(j = 0; j < event.size; j++) {
  428. /* make sure we don't overwrite a previous byte */
  429. while(pos < min_next_pos && pos < nframes) {
  430. /* printMessage("have to correct pos to %d", pos); */
  431. pos += 8;
  432. }
  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. }
  445. /* exit since we can't transmit anything anymore.
  446. the rate should be controlled */
  447. if(i < nevents-1) {
  448. printError("%d midi events lost due to period crossing", nevents-i-1);
  449. }
  450. break;
  451. } else {
  452. midi_buffer[pos] = 0x01000000 | (event.buffer[j] & 0xFF);
  453. pos += 8;
  454. min_next_pos = pos;
  455. }
  456. }
  457. }
  458. } else { /* ensure a valid buffer */
  459. ffado_streaming_set_playback_stream_buffer(driver->dev, chn, (char *)(driver->nullbuffer));
  460. ffado_streaming_playback_stream_onoff(driver->dev, chn, 0);
  461. }
  462. }
  463. ffado_streaming_transfer_playback_buffers(driver->dev);
  464. printExit();
  465. return 0;
  466. }
  467. //static inline jack_nframes_t
  468. static jack_nframes_t
  469. ffado_driver_wait (ffado_driver_t *driver, int extra_fd, int *status,
  470. float *delayed_usecs)
  471. {
  472. jack_time_t wait_enter;
  473. jack_time_t wait_ret;
  474. ffado_wait_response response;
  475. printEnter();
  476. wait_enter = driver->engine->get_microseconds ();
  477. if (wait_enter > driver->wait_next) {
  478. /*
  479. * This processing cycle was delayed past the
  480. * next due interrupt! Do not account this as
  481. * a wakeup delay:
  482. */
  483. driver->wait_next = 0;
  484. driver->wait_late++;
  485. }
  486. // *status = -2; interrupt
  487. // *status = -3; timeout
  488. // *status = -4; extra FD
  489. response = ffado_streaming_wait(driver->dev);
  490. wait_ret = driver->engine->get_microseconds ();
  491. if (driver->wait_next && wait_ret > driver->wait_next) {
  492. *delayed_usecs = wait_ret - driver->wait_next;
  493. }
  494. driver->wait_last = wait_ret;
  495. driver->wait_next = wait_ret + driver->period_usecs;
  496. driver->engine->transport_cycle_start (driver->engine, wait_ret);
  497. if (response == ffado_wait_ok) {
  498. // all good
  499. *status=0;
  500. } else if (response == ffado_wait_xrun) {
  501. // xrun happened, but it's handled
  502. *status=0;
  503. return 0;
  504. } else if (response == ffado_wait_error) {
  505. // an error happened (unhandled xrun)
  506. // this should be fatal
  507. *status=-1;
  508. return 0;
  509. } else if (response == ffado_wait_shutdown) {
  510. // we are to shutdown the ffado system
  511. // this should be fatal
  512. *status=-1;
  513. return 0;
  514. } else {
  515. // we don't know about this response code
  516. printError("unknown wait response (%d) from ffado", response);
  517. // this should be fatal
  518. *status=-1;
  519. return 0;
  520. }
  521. driver->last_wait_ust = wait_ret;
  522. // FIXME: this should do something more useful
  523. *delayed_usecs = 0;
  524. printExit();
  525. return driver->period_size;
  526. }
  527. static int
  528. ffado_driver_run_cycle (ffado_driver_t *driver)
  529. {
  530. jack_engine_t *engine = driver->engine;
  531. int wait_status=0;
  532. float delayed_usecs=0.0;
  533. jack_nframes_t nframes = ffado_driver_wait (driver, -1,
  534. &wait_status, &delayed_usecs);
  535. if ((wait_status < 0)) {
  536. printError( "wait status < 0! (= %d)",wait_status);
  537. return -1;
  538. }
  539. if ((nframes == 0)) {
  540. /* we detected an xrun and restarted: notify
  541. * clients about the delay. */
  542. printMessage("xrun detected");
  543. engine->delay (engine, delayed_usecs);
  544. return 0;
  545. }
  546. return engine->run_cycle (engine, nframes, delayed_usecs);
  547. }
  548. /*
  549. * in a null cycle we should discard the input and write silence to the outputs
  550. */
  551. static int
  552. ffado_driver_null_cycle (ffado_driver_t* driver, jack_nframes_t nframes)
  553. {
  554. channel_t chn;
  555. JSList *node;
  556. ffado_streaming_stream_type stream_type;
  557. printEnter();
  558. if (driver->engine->freewheeling) {
  559. return 0;
  560. }
  561. // write silence to buffer
  562. for (chn = 0, node = driver->playback_ports; node; node = jack_slist_next (node), chn++) {
  563. stream_type=ffado_streaming_get_playback_stream_type(driver->dev, chn);
  564. if(stream_type == ffado_stream_type_audio) {
  565. ffado_streaming_set_playback_stream_buffer(driver->dev, chn, (char *)(driver->nullbuffer));
  566. }
  567. }
  568. ffado_streaming_transfer_playback_buffers(driver->dev);
  569. // read & discard from input ports
  570. for (chn = 0, node = driver->capture_ports; node; node = jack_slist_next (node), chn++) {
  571. stream_type=ffado_streaming_get_capture_stream_type(driver->dev, chn);
  572. if(stream_type == ffado_stream_type_audio) {
  573. ffado_streaming_set_capture_stream_buffer(driver->dev, chn, (char *)(driver->scratchbuffer));
  574. }
  575. }
  576. ffado_streaming_transfer_capture_buffers(driver->dev);
  577. printExit();
  578. return 0;
  579. }
  580. static int
  581. ffado_driver_start (ffado_driver_t *driver)
  582. {
  583. int retval=0;
  584. if((retval=ffado_streaming_start(driver->dev))) {
  585. printError("Could not start streaming threads: %d", retval);
  586. return retval;
  587. }
  588. return 0;
  589. }
  590. static int
  591. ffado_driver_stop (ffado_driver_t *driver)
  592. {
  593. int retval=0;
  594. if((retval=ffado_streaming_stop(driver->dev))) {
  595. printError("Could not stop streaming threads");
  596. return retval;
  597. }
  598. return 0;
  599. }
  600. static int
  601. ffado_driver_bufsize (ffado_driver_t* driver, jack_nframes_t nframes)
  602. {
  603. signed int chn;
  604. // The speed of this function isn't critical; we can afford the
  605. // time to check the FFADO API version.
  606. if (ffado_get_api_version() < FIREWIRE_REQUIRED_FFADO_API_VERSION_FOR_SETBUFSIZE ||
  607. ffado_streaming_set_period_size == NULL) {
  608. printError("unsupported on current version of FFADO; please upgrade FFADO");
  609. return -1;
  610. }
  611. driver->period_size = nframes;
  612. driver->period_usecs =
  613. (jack_time_t) floor ((((float) nframes) / driver->sample_rate)
  614. * 1000000.0f);
  615. // Reallocate the null and scratch buffers.
  616. driver->nullbuffer = calloc(driver->period_size, sizeof(ffado_sample_t));
  617. if(driver->nullbuffer == NULL) {
  618. printError("could not allocate memory for null buffer");
  619. return -1;
  620. }
  621. driver->scratchbuffer = calloc(driver->period_size, sizeof(ffado_sample_t));
  622. if(driver->scratchbuffer == NULL) {
  623. printError("could not allocate memory for scratch buffer");
  624. return -1;
  625. }
  626. // MIDI buffers need reallocating
  627. for (chn = 0; chn < driver->capture_nchannels; chn++) {
  628. if(driver->capture_channels[chn].stream_type == ffado_stream_type_midi) {
  629. // setup the midi buffer
  630. if (driver->capture_channels[chn].midi_buffer != NULL)
  631. free(driver->capture_channels[chn].midi_buffer);
  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. driver->playback_channels[chn].midi_buffer = calloc(driver->period_size, sizeof(uint32_t));
  640. }
  641. }
  642. // Notify FFADO of the period size change
  643. if (ffado_streaming_set_period_size(driver->dev, nframes) != 0) {
  644. printError("could not alter FFADO device period size");
  645. return -1;
  646. }
  647. // This is needed to give the shadow variables a chance to
  648. // properly update to the changes.
  649. sleep(1);
  650. /* tell the engine to change its buffer size */
  651. if (driver->engine->set_buffer_size (driver->engine, nframes)) {
  652. jack_error ("FFADO: cannot set engine buffer size to %d (check MIDI)", nframes);
  653. return -1;
  654. }
  655. return 0;
  656. }
  657. typedef void (*JackDriverFinishFunction) (jack_driver_t *);
  658. ffado_driver_t *
  659. ffado_driver_new (jack_client_t * client,
  660. char *name,
  661. ffado_jack_settings_t *params)
  662. {
  663. ffado_driver_t *driver;
  664. if(ffado_get_api_version() < FIREWIRE_REQUIRED_FFADO_API_VERSION) {
  665. printError("Incompatible libffado version! (%s)", ffado_get_version());
  666. return NULL;
  667. }
  668. printMessage("Starting firewire backend (%s)", ffado_get_version());
  669. driver = calloc (1, sizeof (ffado_driver_t));
  670. /* Setup the jack interfaces */
  671. jack_driver_nt_init ((jack_driver_nt_t *) driver);
  672. driver->nt_attach = (JackDriverNTAttachFunction) ffado_driver_attach;
  673. driver->nt_detach = (JackDriverNTDetachFunction) ffado_driver_detach;
  674. driver->nt_start = (JackDriverNTStartFunction) ffado_driver_start;
  675. driver->nt_stop = (JackDriverNTStopFunction) ffado_driver_stop;
  676. driver->nt_run_cycle = (JackDriverNTRunCycleFunction) ffado_driver_run_cycle;
  677. driver->null_cycle = (JackDriverNullCycleFunction) ffado_driver_null_cycle;
  678. driver->write = (JackDriverReadFunction) ffado_driver_write;
  679. driver->read = (JackDriverReadFunction) ffado_driver_read;
  680. driver->nt_bufsize = (JackDriverNTBufSizeFunction) ffado_driver_bufsize;
  681. /* copy command line parameter contents to the driver structure */
  682. memcpy(&driver->settings,params,sizeof(ffado_jack_settings_t));
  683. /* prepare all parameters */
  684. driver->sample_rate = params->sample_rate;
  685. driver->period_size = params->period_size;
  686. driver->last_wait_ust = 0;
  687. driver->period_usecs =
  688. (jack_time_t) floor ((((float) driver->period_size) * 1000000.0f) / driver->sample_rate);
  689. driver->client = client;
  690. driver->engine = NULL;
  691. jack_set_latency_callback (client, ffado_latency_callback, driver);
  692. memset(&driver->device_options,0,sizeof(driver->device_options));
  693. driver->device_options.sample_rate=params->sample_rate;
  694. driver->device_options.period_size=params->period_size;
  695. driver->device_options.nb_buffers=params->buffer_size;
  696. driver->capture_frame_latency = params->capture_frame_latency;
  697. driver->playback_frame_latency = params->playback_frame_latency;
  698. driver->device_options.slave_mode=params->slave_mode;
  699. driver->device_options.snoop_mode=params->snoop_mode;
  700. driver->device_options.verbose=params->verbose_level;
  701. driver->device_info.nb_device_spec_strings=1;
  702. driver->device_info.device_spec_strings=calloc(1, sizeof(char *));
  703. driver->device_info.device_spec_strings[0]=strdup(params->device_info);
  704. debugPrint(DEBUG_LEVEL_STARTUP, " Driver compiled on %s %s for FFADO %s (API version %d)",
  705. __DATE__, __TIME__, ffado_get_version(), ffado_get_api_version());
  706. debugPrint(DEBUG_LEVEL_STARTUP, " Created driver %s", name);
  707. debugPrint(DEBUG_LEVEL_STARTUP, " period_size: %d", driver->period_size);
  708. debugPrint(DEBUG_LEVEL_STARTUP, " period_usecs: %d", driver->period_usecs);
  709. debugPrint(DEBUG_LEVEL_STARTUP, " sample rate: %d", driver->sample_rate);
  710. return (ffado_driver_t *) driver;
  711. }
  712. static void
  713. ffado_driver_delete (ffado_driver_t *driver)
  714. {
  715. unsigned int i;
  716. jack_driver_nt_finish ((jack_driver_nt_t *) driver);
  717. for (i=0; i < driver->device_info.nb_device_spec_strings; i++) {
  718. free (driver->device_info.device_spec_strings[i]);
  719. }
  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. {
  841. param = (jack_driver_param_t *) node->data;
  842. switch (param->character)
  843. {
  844. case 'd':
  845. device_name = strdup (param->value.str);
  846. break;
  847. case 'p':
  848. cmlparams.period_size = param->value.ui;
  849. cmlparams.period_size_set = 1;
  850. break;
  851. case 'n':
  852. cmlparams.buffer_size = param->value.ui;
  853. cmlparams.buffer_size_set = 1;
  854. break;
  855. case 'r':
  856. cmlparams.sample_rate = param->value.ui;
  857. cmlparams.sample_rate_set = 1;
  858. break;
  859. case 'i':
  860. cmlparams.capture_ports = param->value.ui;
  861. break;
  862. case 'o':
  863. cmlparams.playback_ports = param->value.ui;
  864. break;
  865. case 'I':
  866. cmlparams.capture_frame_latency = param->value.ui;
  867. break;
  868. case 'O':
  869. cmlparams.playback_frame_latency = param->value.ui;
  870. break;
  871. case 'x':
  872. cmlparams.slave_mode = param->value.ui;
  873. break;
  874. case 'X':
  875. cmlparams.snoop_mode = param->value.ui;
  876. break;
  877. case 'v':
  878. cmlparams.verbose_level = param->value.ui;
  879. break;
  880. }
  881. }
  882. // temporary
  883. cmlparams.device_info = device_name;
  884. driver=(jack_driver_t *)ffado_driver_new (client, "ffado_pcm", &cmlparams);
  885. return driver;
  886. }
  887. void
  888. driver_finish (jack_driver_t *driver)
  889. {
  890. ffado_driver_t *drv=(ffado_driver_t *) driver;
  891. // If jack hasn't called the detach method, do it now. As of jack 0.101.1
  892. // the detach method was not being called explicitly on closedown, and
  893. // we need it to at least deallocate the iso resources.
  894. if (drv->dev != NULL)
  895. ffado_driver_detach(drv);
  896. ffado_driver_delete (drv);
  897. }