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.

985 lines
31KB

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