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.

949 lines
29KB

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