jack2 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.

968 lines
36KB

  1. /*
  2. Copyright (C) 2001 Paul Davis
  3. Copyright (C) 2004 Grame
  4. Copyright (C) 2007 Pieter Palmers
  5. Copyright (C) 2009 Devin Anderson
  6. This program is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2 of the License, or
  9. (at your option) any later version.
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with this program; if not, write to the Free Software
  16. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17. */
  18. #include <iostream>
  19. #include <unistd.h>
  20. #include <math.h>
  21. #include <stdio.h>
  22. #include <memory.h>
  23. #include <unistd.h>
  24. #include <stdlib.h>
  25. #include <errno.h>
  26. #include <stdarg.h>
  27. #include <signal.h>
  28. #include <sys/types.h>
  29. #include <sys/time.h>
  30. #include <regex.h>
  31. #include <string.h>
  32. #include "JackFFADODriver.h"
  33. #include "JackFFADOMidiInputPort.h"
  34. #include "JackFFADOMidiOutputPort.h"
  35. #include "JackEngineControl.h"
  36. #include "JackClientControl.h"
  37. #include "JackPort.h"
  38. #include "JackGraphManager.h"
  39. #include "JackCompilerDeps.h"
  40. namespace Jack
  41. {
  42. #define FIREWIRE_REQUIRED_FFADO_API_VERSION 8
  43. #define jack_get_microseconds GetMicroSeconds
  44. int
  45. JackFFADODriver::ffado_driver_read (ffado_driver_t * driver, jack_nframes_t nframes)
  46. {
  47. channel_t chn;
  48. jack_default_audio_sample_t* buf = NULL;
  49. printEnter();
  50. for (chn = 0; chn < driver->capture_nchannels; chn++) {
  51. // if nothing connected, don't process
  52. if (fGraphManager->GetConnectionsNum(fCapturePortList[chn]) == 0) {
  53. buf = (jack_default_audio_sample_t*)driver->scratchbuffer;
  54. // we always have to specify a valid buffer
  55. ffado_streaming_set_capture_stream_buffer(driver->dev, chn, (char *)(buf));
  56. // notify the streaming system that it can (but doesn't have to) skip
  57. // this channel
  58. ffado_streaming_capture_stream_onoff(driver->dev, chn, 0);
  59. } else {
  60. if (driver->capture_channels[chn].stream_type == ffado_stream_type_audio) {
  61. buf = (jack_default_audio_sample_t*)fGraphManager->GetBuffer(fCapturePortList[chn], nframes);
  62. /* if the returned buffer is invalid, use the dummy buffer */
  63. if (!buf) buf = (jack_default_audio_sample_t*)driver->scratchbuffer;
  64. ffado_streaming_set_capture_stream_buffer(driver->dev, chn, (char *)(buf));
  65. ffado_streaming_capture_stream_onoff(driver->dev, chn, 1);
  66. } else if (driver->capture_channels[chn].stream_type == ffado_stream_type_midi) {
  67. ffado_streaming_set_capture_stream_buffer(driver->dev, chn,
  68. (char *)(driver->capture_channels[chn].midi_buffer));
  69. ffado_streaming_capture_stream_onoff(driver->dev, chn, 1);
  70. } else { // always have a valid buffer
  71. ffado_streaming_set_capture_stream_buffer(driver->dev, chn, (char *)(driver->scratchbuffer));
  72. // don't process what we don't use
  73. ffado_streaming_capture_stream_onoff(driver->dev, chn, 0);
  74. }
  75. }
  76. }
  77. /* now transfer the buffers */
  78. ffado_streaming_transfer_capture_buffers(driver->dev);
  79. /* process the midi data */
  80. for (chn = 0; chn < driver->capture_nchannels; chn++) {
  81. if (driver->capture_channels[chn].stream_type == ffado_stream_type_midi) {
  82. JackFFADOMidiInputPort *midi_input = (JackFFADOMidiInputPort *) driver->capture_channels[chn].midi_input;
  83. JackMidiBuffer *buffer = (JackMidiBuffer *) fGraphManager->GetBuffer(fCapturePortList[chn], nframes);
  84. midi_input->Process(buffer, driver->capture_channels[chn].midi_buffer, nframes);
  85. }
  86. }
  87. printExit();
  88. return 0;
  89. }
  90. int
  91. JackFFADODriver::ffado_driver_write (ffado_driver_t * driver, jack_nframes_t nframes)
  92. {
  93. channel_t chn;
  94. jack_default_audio_sample_t* buf;
  95. printEnter();
  96. driver->process_count++;
  97. for (chn = 0; chn < driver->playback_nchannels; chn++) {
  98. if (fGraphManager->GetConnectionsNum(fPlaybackPortList[chn]) == 0) {
  99. buf = (jack_default_audio_sample_t*)driver->nullbuffer;
  100. // we always have to specify a valid buffer
  101. ffado_streaming_set_playback_stream_buffer(driver->dev, chn, (char *)(buf));
  102. // notify the streaming system that it can (but doesn't have to) skip
  103. // this channel
  104. ffado_streaming_playback_stream_onoff(driver->dev, chn, 0);
  105. } else {
  106. if (driver->playback_channels[chn].stream_type == ffado_stream_type_audio) {
  107. buf = (jack_default_audio_sample_t*)fGraphManager->GetBuffer(fPlaybackPortList[chn], nframes);
  108. /* use the silent buffer if there is no valid jack buffer */
  109. if (!buf) buf = (jack_default_audio_sample_t*)driver->nullbuffer;
  110. ffado_streaming_set_playback_stream_buffer(driver->dev, chn, (char *)(buf));
  111. ffado_streaming_playback_stream_onoff(driver->dev, chn, 1);
  112. } else if (driver->playback_channels[chn].stream_type == ffado_stream_type_midi) {
  113. uint32_t *midi_buffer = driver->playback_channels[chn].midi_buffer;
  114. memset(midi_buffer, 0, nframes * sizeof(uint32_t));
  115. buf = (jack_default_audio_sample_t *) fGraphManager->GetBuffer(fPlaybackPortList[chn], nframes);
  116. ffado_streaming_set_playback_stream_buffer(driver->dev, chn, (char *)(midi_buffer));
  117. ffado_streaming_playback_stream_onoff(driver->dev, chn, buf ? 1 : 0);
  118. JackFFADOMidiOutputPort *midi_output = (JackFFADOMidiOutputPort *) driver->playback_channels[chn].midi_output;
  119. midi_output->Process((JackMidiBuffer *) buf, midi_buffer, nframes);
  120. } else { // always have a valid buffer
  121. ffado_streaming_set_playback_stream_buffer(driver->dev, chn, (char *)(driver->nullbuffer));
  122. ffado_streaming_playback_stream_onoff(driver->dev, chn, 0);
  123. }
  124. }
  125. }
  126. ffado_streaming_transfer_playback_buffers(driver->dev);
  127. printExit();
  128. return 0;
  129. }
  130. jack_nframes_t
  131. JackFFADODriver::ffado_driver_wait (ffado_driver_t *driver, int extra_fd, int *status,
  132. float *delayed_usecs)
  133. {
  134. jack_time_t wait_enter;
  135. jack_time_t wait_ret;
  136. ffado_wait_response response;
  137. printEnter();
  138. wait_enter = jack_get_microseconds ();
  139. if (wait_enter > driver->wait_next) {
  140. /*
  141. * This processing cycle was delayed past the
  142. * next due interrupt! Do not account this as
  143. * a wakeup delay:
  144. */
  145. driver->wait_next = 0;
  146. driver->wait_late++;
  147. }
  148. // *status = -2; interrupt
  149. // *status = -3; timeout
  150. // *status = -4; extra FD
  151. response = ffado_streaming_wait(driver->dev);
  152. wait_ret = jack_get_microseconds ();
  153. if (driver->wait_next && wait_ret > driver->wait_next) {
  154. *delayed_usecs = wait_ret - driver->wait_next;
  155. }
  156. driver->wait_last = wait_ret;
  157. driver->wait_next = wait_ret + driver->period_usecs;
  158. // driver->engine->transport_cycle_start (driver->engine, wait_ret);
  159. if(response == ffado_wait_ok) {
  160. // all good
  161. *status = 0;
  162. } else if (response == ffado_wait_xrun) {
  163. // xrun happened, but it's handled
  164. *status = 0;
  165. return 0;
  166. } else if (response == ffado_wait_error) {
  167. // an error happened (unhandled xrun)
  168. // this should be fatal
  169. jack_error("JackFFADODriver::ffado_driver_wait - unhandled xrun");
  170. *status = -1;
  171. return 0;
  172. } else if (response == ffado_wait_shutdown) {
  173. // ffado requested shutdown (e.g. device unplugged)
  174. // this should be fatal
  175. jack_error("JackFFADODriver::ffado_driver_wait - shutdown requested "
  176. "(device unplugged?)");
  177. *status = -1;
  178. return 0;
  179. } else {
  180. // unknown response code. should be fatal
  181. // this should be fatal
  182. jack_error("JackFFADODriver::ffado_driver_wait - unexpected error "
  183. "code '%d' returned from 'ffado_streaming_wait'", response);
  184. *status = -1;
  185. return 0;
  186. }
  187. fBeginDateUst = wait_ret;
  188. printExit();
  189. return driver->period_size;
  190. }
  191. int
  192. JackFFADODriver::ffado_driver_start (ffado_driver_t *driver)
  193. {
  194. int retval = 0;
  195. if ((retval = ffado_streaming_start(driver->dev))) {
  196. printError("Could not start streaming threads");
  197. return retval;
  198. }
  199. return 0;
  200. }
  201. int
  202. JackFFADODriver::ffado_driver_stop (ffado_driver_t *driver)
  203. {
  204. int retval = 0;
  205. if ((retval = ffado_streaming_stop(driver->dev))) {
  206. printError("Could not stop streaming threads");
  207. return retval;
  208. }
  209. return 0;
  210. }
  211. int
  212. JackFFADODriver::ffado_driver_restart (ffado_driver_t *driver)
  213. {
  214. if (Stop())
  215. return -1;
  216. return Start();
  217. }
  218. int
  219. JackFFADODriver::SetBufferSize (jack_nframes_t nframes)
  220. {
  221. printError("Buffer size change requested but not supported!!!");
  222. /*
  223. driver->period_size = nframes;
  224. driver->period_usecs =
  225. (jack_time_t) floor ((((float) nframes) / driver->sample_rate)
  226. * 1000000.0f);
  227. */
  228. /* tell the engine to change its buffer size */
  229. //driver->engine->set_buffer_size (driver->engine, nframes);
  230. return -1; // unsupported
  231. }
  232. typedef void (*JackDriverFinishFunction) (jack_driver_t *);
  233. ffado_driver_t *
  234. JackFFADODriver::ffado_driver_new (const char *name,
  235. ffado_jack_settings_t *params)
  236. {
  237. ffado_driver_t *driver;
  238. assert(params);
  239. if (ffado_get_api_version() != FIREWIRE_REQUIRED_FFADO_API_VERSION) {
  240. printError("Incompatible libffado version! (%s)", ffado_get_version());
  241. return NULL;
  242. }
  243. printMessage("Starting FFADO backend (%s)", ffado_get_version());
  244. driver = (ffado_driver_t*)calloc (1, sizeof (ffado_driver_t));
  245. /* Setup the jack interfaces */
  246. jack_driver_nt_init ((jack_driver_nt_t *) driver);
  247. /* driver->nt_attach = (JackDriverNTAttachFunction) ffado_driver_attach;
  248. driver->nt_detach = (JackDriverNTDetachFunction) ffado_driver_detach;
  249. driver->nt_start = (JackDriverNTStartFunction) ffado_driver_start;
  250. driver->nt_stop = (JackDriverNTStopFunction) ffado_driver_stop;
  251. driver->nt_run_cycle = (JackDriverNTRunCycleFunction) ffado_driver_run_cycle;
  252. driver->null_cycle = (JackDriverNullCycleFunction) ffado_driver_null_cycle;
  253. driver->write = (JackDriverReadFunction) ffado_driver_write;
  254. driver->read = (JackDriverReadFunction) ffado_driver_read;
  255. driver->nt_bufsize = (JackDriverNTBufSizeFunction) ffado_driver_bufsize;
  256. */
  257. /* copy command line parameter contents to the driver structure */
  258. memcpy(&driver->settings, params, sizeof(ffado_jack_settings_t));
  259. /* prepare all parameters */
  260. driver->sample_rate = params->sample_rate;
  261. driver->period_size = params->period_size;
  262. fBeginDateUst = 0;
  263. driver->period_usecs =
  264. (jack_time_t) floor ((((float) driver->period_size) * 1000000.0f) / driver->sample_rate);
  265. // driver->client = client;
  266. driver->engine = NULL;
  267. memset(&driver->device_options, 0, sizeof(driver->device_options));
  268. driver->device_options.sample_rate = params->sample_rate;
  269. driver->device_options.period_size = params->period_size;
  270. driver->device_options.nb_buffers = params->buffer_size;
  271. driver->device_options.verbose = params->verbose_level;
  272. driver->capture_frame_latency = params->capture_frame_latency;
  273. driver->playback_frame_latency = params->playback_frame_latency;
  274. driver->device_options.snoop_mode = params->snoop_mode;
  275. debugPrint(DEBUG_LEVEL_STARTUP, " Driver compiled on %s %s", __DATE__, __TIME__);
  276. debugPrint(DEBUG_LEVEL_STARTUP, " Created driver %s", name);
  277. debugPrint(DEBUG_LEVEL_STARTUP, " period_size: %d", driver->device_options.period_size);
  278. debugPrint(DEBUG_LEVEL_STARTUP, " period_usecs: %d", driver->period_usecs);
  279. debugPrint(DEBUG_LEVEL_STARTUP, " sample rate: %d", driver->device_options.sample_rate);
  280. debugPrint(DEBUG_LEVEL_STARTUP, " verbose level: %d", driver->device_options.verbose);
  281. return (ffado_driver_t *) driver;
  282. }
  283. void
  284. JackFFADODriver::ffado_driver_delete (ffado_driver_t *driver)
  285. {
  286. free (driver);
  287. }
  288. int JackFFADODriver::Attach()
  289. {
  290. JackPort* port;
  291. int port_index;
  292. char buf[JACK_PORT_NAME_SIZE];
  293. char portname[JACK_PORT_NAME_SIZE];
  294. jack_latency_range_t range;
  295. ffado_driver_t* driver = (ffado_driver_t*)fDriver;
  296. jack_log("JackFFADODriver::Attach fBufferSize %ld fSampleRate %ld", fEngineControl->fBufferSize, fEngineControl->fSampleRate);
  297. g_verbose = (fEngineControl->fVerbose ? 1 : 0);
  298. /* preallocate some buffers such that they don't have to be allocated
  299. in RT context (or from the stack)
  300. */
  301. /* the null buffer is a buffer that contains one period of silence */
  302. driver->nullbuffer = (ffado_sample_t *)calloc(driver->period_size, sizeof(ffado_sample_t));
  303. if (driver->nullbuffer == NULL) {
  304. printError("could not allocate memory for null buffer");
  305. return -1;
  306. }
  307. /* calloc should do this, but it can't hurt to be sure */
  308. memset(driver->nullbuffer, 0, driver->period_size*sizeof(ffado_sample_t));
  309. /* the scratch buffer is a buffer of one period that can be used as dummy memory */
  310. driver->scratchbuffer = (ffado_sample_t *)calloc(driver->period_size, sizeof(ffado_sample_t));
  311. if (driver->scratchbuffer == NULL) {
  312. printError("could not allocate memory for scratch buffer");
  313. return -1;
  314. }
  315. /* packetizer thread options */
  316. driver->device_options.realtime = (fEngineControl->fRealTime ? 1 : 0);
  317. driver->device_options.packetizer_priority = fEngineControl->fServerPriority +
  318. FFADO_RT_PRIORITY_PACKETIZER_RELATIVE;
  319. if (driver->device_options.packetizer_priority > 98) {
  320. driver->device_options.packetizer_priority = 98;
  321. }
  322. // initialize the thread
  323. driver->dev = ffado_streaming_init(driver->device_info, driver->device_options);
  324. if (!driver->dev) {
  325. printError("FFADO: Error creating virtual device");
  326. return -1;
  327. }
  328. if (driver->device_options.realtime) {
  329. printMessage("Streaming thread running with Realtime scheduling, priority %d",
  330. driver->device_options.packetizer_priority);
  331. } else {
  332. printMessage("Streaming thread running without Realtime scheduling");
  333. }
  334. ffado_streaming_set_audio_datatype(driver->dev, ffado_audio_datatype_float);
  335. /* ports */
  336. // capture
  337. driver->capture_nchannels = ffado_streaming_get_nb_capture_streams(driver->dev);
  338. driver->capture_channels = (ffado_capture_channel_t *)calloc(driver->capture_nchannels, sizeof(ffado_capture_channel_t));
  339. if (driver->capture_channels == NULL) {
  340. printError("could not allocate memory for capture channel list");
  341. return -1;
  342. }
  343. fCaptureChannels = 0;
  344. for (channel_t chn = 0; chn < driver->capture_nchannels; chn++) {
  345. ffado_streaming_get_capture_stream_name(driver->dev, chn, portname, sizeof(portname) - 1);
  346. driver->capture_channels[chn].stream_type = ffado_streaming_get_capture_stream_type(driver->dev, chn);
  347. if (driver->capture_channels[chn].stream_type == ffado_stream_type_audio) {
  348. snprintf(buf, sizeof(buf) - 1, "firewire_pcm:%s_in", portname);
  349. printMessage ("Registering audio capture port %s", buf);
  350. if ((port_index = fGraphManager->AllocatePort(fClientControl.fRefNum, buf,
  351. JACK_DEFAULT_AUDIO_TYPE,
  352. CaptureDriverFlags,
  353. fEngineControl->fBufferSize)) == NO_PORT) {
  354. jack_error("driver: cannot register port for %s", buf);
  355. return -1;
  356. }
  357. // setup port parameters
  358. if (ffado_streaming_set_capture_stream_buffer(driver->dev, chn, NULL)) {
  359. printError(" cannot configure initial port buffer for %s", buf);
  360. }
  361. ffado_streaming_capture_stream_onoff(driver->dev, chn, 0);
  362. port = fGraphManager->GetPort(port_index);
  363. range.min = range.max = driver->period_size + driver->capture_frame_latency;
  364. port->SetLatencyRange(JackCaptureLatency, &range);
  365. // capture port aliases (jackd1 style port names)
  366. snprintf(buf, sizeof(buf) - 1, "%s:capture_%i", fClientControl.fName, (int) chn + 1);
  367. port->SetAlias(buf);
  368. fCapturePortList[chn] = port_index;
  369. jack_log("JackFFADODriver::Attach fCapturePortList[i] %ld ", port_index);
  370. fCaptureChannels++;
  371. } else if (driver->capture_channels[chn].stream_type == ffado_stream_type_midi) {
  372. snprintf(buf, sizeof(buf) - 1, "firewire_pcm:%s_in", portname);
  373. printMessage ("Registering midi capture port %s", buf);
  374. if ((port_index = fGraphManager->AllocatePort(fClientControl.fRefNum, buf,
  375. JACK_DEFAULT_MIDI_TYPE,
  376. CaptureDriverFlags,
  377. fEngineControl->fBufferSize)) == NO_PORT) {
  378. jack_error("driver: cannot register port for %s", buf);
  379. return -1;
  380. }
  381. // setup port parameters
  382. if (ffado_streaming_set_capture_stream_buffer(driver->dev, chn, NULL)) {
  383. printError(" cannot configure initial port buffer for %s", buf);
  384. }
  385. if (ffado_streaming_capture_stream_onoff(driver->dev, chn, 0)) {
  386. printError(" cannot enable port %s", buf);
  387. }
  388. driver->capture_channels[chn].midi_input = new JackFFADOMidiInputPort();
  389. // setup the midi buffer
  390. driver->capture_channels[chn].midi_buffer = (uint32_t *)calloc(driver->period_size, sizeof(uint32_t));
  391. port = fGraphManager->GetPort(port_index);
  392. range.min = range.max = driver->period_size + driver->capture_frame_latency;
  393. port->SetLatencyRange(JackCaptureLatency, &range);
  394. fCapturePortList[chn] = port_index;
  395. jack_log("JackFFADODriver::Attach fCapturePortList[i] %ld ", port_index);
  396. fCaptureChannels++;
  397. } else {
  398. printMessage ("Don't register capture port %s", portname);
  399. }
  400. }
  401. // playback
  402. driver->playback_nchannels = ffado_streaming_get_nb_playback_streams(driver->dev);
  403. driver->playback_channels = (ffado_playback_channel_t *)calloc(driver->playback_nchannels, sizeof(ffado_playback_channel_t));
  404. if (driver->playback_channels == NULL) {
  405. printError("could not allocate memory for playback channel list");
  406. return -1;
  407. }
  408. fPlaybackChannels = 0;
  409. for (channel_t chn = 0; chn < driver->playback_nchannels; chn++) {
  410. ffado_streaming_get_playback_stream_name(driver->dev, chn, portname, sizeof(portname) - 1);
  411. driver->playback_channels[chn].stream_type = ffado_streaming_get_playback_stream_type(driver->dev, chn);
  412. if (driver->playback_channels[chn].stream_type == ffado_stream_type_audio) {
  413. snprintf(buf, sizeof(buf) - 1, "firewire_pcm:%s_out", portname);
  414. printMessage ("Registering audio playback port %s", buf);
  415. if ((port_index = fGraphManager->AllocatePort(fClientControl.fRefNum, buf,
  416. JACK_DEFAULT_AUDIO_TYPE,
  417. PlaybackDriverFlags,
  418. fEngineControl->fBufferSize)) == NO_PORT) {
  419. jack_error("driver: cannot register port for %s", buf);
  420. return -1;
  421. }
  422. // setup port parameters
  423. if (ffado_streaming_set_playback_stream_buffer(driver->dev, chn, NULL)) {
  424. printError(" cannot configure initial port buffer for %s", buf);
  425. }
  426. if (ffado_streaming_playback_stream_onoff(driver->dev, chn, 0)) {
  427. printError(" cannot enable port %s", buf);
  428. }
  429. port = fGraphManager->GetPort(port_index);
  430. // Add one buffer more latency if "async" mode is used...
  431. range.min = range.max = (driver->period_size * (driver->device_options.nb_buffers - 1)) + ((fEngineControl->fSyncMode) ? 0 : fEngineControl->fBufferSize) + driver->playback_frame_latency;
  432. port->SetLatencyRange(JackPlaybackLatency, &range);
  433. // playback port aliases (jackd1 style port names)
  434. snprintf(buf, sizeof(buf) - 1, "%s:playback_%i", fClientControl.fName, (int) chn + 1);
  435. port->SetAlias(buf);
  436. fPlaybackPortList[chn] = port_index;
  437. jack_log("JackFFADODriver::Attach fPlaybackPortList[i] %ld ", port_index);
  438. fPlaybackChannels++;
  439. } else if (driver->playback_channels[chn].stream_type == ffado_stream_type_midi) {
  440. snprintf(buf, sizeof(buf) - 1, "firewire_pcm:%s_out", portname);
  441. printMessage ("Registering midi playback port %s", buf);
  442. if ((port_index = fGraphManager->AllocatePort(fClientControl.fRefNum, buf,
  443. JACK_DEFAULT_MIDI_TYPE,
  444. PlaybackDriverFlags,
  445. fEngineControl->fBufferSize)) == NO_PORT) {
  446. jack_error("driver: cannot register port for %s", buf);
  447. return -1;
  448. }
  449. // setup port parameters
  450. if (ffado_streaming_set_playback_stream_buffer(driver->dev, chn, NULL)) {
  451. printError(" cannot configure initial port buffer for %s", buf);
  452. }
  453. if (ffado_streaming_playback_stream_onoff(driver->dev, chn, 0)) {
  454. printError(" cannot enable port %s", buf);
  455. }
  456. // setup the midi buffer
  457. // This constructor optionally accepts arguments for the
  458. // non-realtime buffer size and the realtime buffer size. Ideally,
  459. // these would become command-line options for the FFADO driver.
  460. driver->playback_channels[chn].midi_output = new JackFFADOMidiOutputPort();
  461. driver->playback_channels[chn].midi_buffer = (uint32_t *)calloc(driver->period_size, sizeof(uint32_t));
  462. port = fGraphManager->GetPort(port_index);
  463. range.min = range.max = (driver->period_size * (driver->device_options.nb_buffers - 1)) + ((fEngineControl->fSyncMode) ? 0 : fEngineControl->fBufferSize) + driver->playback_frame_latency;
  464. port->SetLatencyRange(JackPlaybackLatency, &range);
  465. fPlaybackPortList[chn] = port_index;
  466. jack_log("JackFFADODriver::Attach fPlaybackPortList[i] %ld ", port_index);
  467. fPlaybackChannels++;
  468. } else {
  469. printMessage ("Don't register playback port %s", portname);
  470. }
  471. }
  472. assert(fCaptureChannels < DRIVER_PORT_NUM);
  473. assert(fPlaybackChannels < DRIVER_PORT_NUM);
  474. if (ffado_streaming_prepare(driver->dev)) {
  475. printError("Could not prepare streaming device!");
  476. return -1;
  477. }
  478. // this makes no sense...
  479. assert(fCaptureChannels + fPlaybackChannels > 0);
  480. return 0;
  481. }
  482. int JackFFADODriver::Detach()
  483. {
  484. channel_t chn;
  485. ffado_driver_t* driver = (ffado_driver_t*)fDriver;
  486. jack_log("JackFFADODriver::Detach");
  487. // finish the libfreebob streaming
  488. ffado_streaming_finish(driver->dev);
  489. driver->dev = NULL;
  490. // free all internal buffers
  491. for (chn = 0; chn < driver->capture_nchannels; chn++) {
  492. if (driver->capture_channels[chn].midi_buffer)
  493. free(driver->capture_channels[chn].midi_buffer);
  494. if (driver->capture_channels[chn].midi_input)
  495. delete ((JackFFADOMidiInputPort *) (driver->capture_channels[chn].midi_input));
  496. }
  497. free(driver->capture_channels);
  498. for (chn = 0; chn < driver->playback_nchannels; chn++) {
  499. if (driver->playback_channels[chn].midi_buffer)
  500. free(driver->playback_channels[chn].midi_buffer);
  501. if (driver->playback_channels[chn].midi_output)
  502. delete ((JackFFADOMidiOutputPort *) (driver->playback_channels[chn].midi_output));
  503. }
  504. free(driver->playback_channels);
  505. free(driver->nullbuffer);
  506. free(driver->scratchbuffer);
  507. return JackAudioDriver::Detach(); // Generic JackAudioDriver Detach
  508. }
  509. int JackFFADODriver::Open(ffado_jack_settings_t *params)
  510. {
  511. // Generic JackAudioDriver Open
  512. if (JackAudioDriver::Open(
  513. params->period_size, params->sample_rate,
  514. params->playback_ports, params->playback_ports,
  515. 0, 0, 0, "", "",
  516. params->capture_frame_latency, params->playback_frame_latency) != 0) {
  517. return -1;
  518. }
  519. fDriver = (jack_driver_t *)ffado_driver_new ("ffado_pcm", params);
  520. if (fDriver) {
  521. // FFADO driver may have changed the in/out values
  522. //fCaptureChannels = ((ffado_driver_t *)fDriver)->capture_nchannels_audio;
  523. //fPlaybackChannels = ((ffado_driver_t *)fDriver)->playback_nchannels_audio;
  524. return 0;
  525. } else {
  526. JackAudioDriver::Close();
  527. return -1;
  528. }
  529. }
  530. int JackFFADODriver::Close()
  531. {
  532. // Generic audio driver close
  533. int res = JackAudioDriver::Close();
  534. ffado_driver_delete((ffado_driver_t*)fDriver);
  535. return res;
  536. }
  537. int JackFFADODriver::Start()
  538. {
  539. int res = JackAudioDriver::Start();
  540. if (res >= 0) {
  541. res = ffado_driver_start((ffado_driver_t *)fDriver);
  542. if (res < 0) {
  543. JackAudioDriver::Stop();
  544. }
  545. }
  546. return res;
  547. }
  548. int JackFFADODriver::Stop()
  549. {
  550. int res = ffado_driver_stop((ffado_driver_t *)fDriver);
  551. if (JackAudioDriver::Stop() < 0) {
  552. res = -1;
  553. }
  554. return res;
  555. }
  556. int JackFFADODriver::Read()
  557. {
  558. printEnter();
  559. /* Taken from ffado_driver_run_cycle */
  560. ffado_driver_t* driver = (ffado_driver_t*)fDriver;
  561. int wait_status = 0;
  562. fDelayedUsecs = 0.f;
  563. retry:
  564. jack_nframes_t nframes = ffado_driver_wait(driver, -1, &wait_status,
  565. &fDelayedUsecs);
  566. if ((wait_status < 0)) {
  567. printError( "wait status < 0! (= %d)", wait_status);
  568. return -1;
  569. }
  570. if (nframes == 0) {
  571. /* we detected an xrun and restarted: notify
  572. * clients about the delay.
  573. */
  574. jack_log("FFADO XRun");
  575. NotifyXRun(fBeginDateUst, fDelayedUsecs);
  576. goto retry; /* recoverable error*/
  577. }
  578. if (nframes != fEngineControl->fBufferSize)
  579. jack_log("JackFFADODriver::Read warning nframes = %ld", nframes);
  580. // Has to be done before read
  581. JackDriver::CycleIncTime();
  582. printExit();
  583. return ffado_driver_read((ffado_driver_t *)fDriver, fEngineControl->fBufferSize);
  584. }
  585. int JackFFADODriver::Write()
  586. {
  587. printEnter();
  588. int res = ffado_driver_write((ffado_driver_t *)fDriver, fEngineControl->fBufferSize);
  589. printExit();
  590. return res;
  591. }
  592. void
  593. JackFFADODriver::jack_driver_init (jack_driver_t *driver)
  594. {
  595. memset (driver, 0, sizeof (*driver));
  596. driver->attach = 0;
  597. driver->detach = 0;
  598. driver->write = 0;
  599. driver->read = 0;
  600. driver->null_cycle = 0;
  601. driver->bufsize = 0;
  602. driver->start = 0;
  603. driver->stop = 0;
  604. }
  605. void
  606. JackFFADODriver::jack_driver_nt_init (jack_driver_nt_t * driver)
  607. {
  608. memset (driver, 0, sizeof (*driver));
  609. jack_driver_init ((jack_driver_t *) driver);
  610. driver->attach = 0;
  611. driver->detach = 0;
  612. driver->bufsize = 0;
  613. driver->stop = 0;
  614. driver->start = 0;
  615. driver->nt_bufsize = 0;
  616. driver->nt_start = 0;
  617. driver->nt_stop = 0;
  618. driver->nt_attach = 0;
  619. driver->nt_detach = 0;
  620. driver->nt_run_cycle = 0;
  621. }
  622. } // end of namespace
  623. #ifdef __cplusplus
  624. extern "C"
  625. {
  626. #endif
  627. SERVER_EXPORT const jack_driver_desc_t *
  628. driver_get_descriptor () {
  629. jack_driver_desc_t * desc;
  630. jack_driver_param_desc_t * params;
  631. unsigned int i;
  632. desc = (jack_driver_desc_t *)calloc (1, sizeof (jack_driver_desc_t));
  633. strcpy (desc->name, "firewire"); // size MUST be less then JACK_DRIVER_NAME_MAX + 1
  634. strcpy(desc->desc, "Linux FFADO API based audio backend"); // size MUST be less then JACK_DRIVER_PARAM_DESC + 1
  635. desc->nparams = 13;
  636. params = (jack_driver_param_desc_t *)calloc (desc->nparams, sizeof (jack_driver_param_desc_t));
  637. desc->params = params;
  638. i = 0;
  639. strcpy (params[i].name, "device");
  640. params[i].character = 'd';
  641. params[i].type = JackDriverParamString;
  642. strcpy (params[i].value.str, "hw:0");
  643. strcpy (params[i].short_desc, "The FireWire device to use.");
  644. strcpy (params[i].long_desc, "The FireWire device to use. Please consult the FFADO documentation for more info.");
  645. i++;
  646. strcpy (params[i].name, "period");
  647. params[i].character = 'p';
  648. params[i].type = JackDriverParamUInt;
  649. params[i].value.ui = 1024;
  650. strcpy (params[i].short_desc, "Frames per period");
  651. strcpy (params[i].long_desc, params[i].short_desc);
  652. i++;
  653. strcpy (params[i].name, "nperiods");
  654. params[i].character = 'n';
  655. params[i].type = JackDriverParamUInt;
  656. params[i].value.ui = 3;
  657. strcpy (params[i].short_desc, "Number of periods of playback latency");
  658. strcpy (params[i].long_desc, params[i].short_desc);
  659. i++;
  660. strcpy (params[i].name, "rate");
  661. params[i].character = 'r';
  662. params[i].type = JackDriverParamUInt;
  663. params[i].value.ui = 48000U;
  664. strcpy (params[i].short_desc, "Sample rate");
  665. strcpy (params[i].long_desc, params[i].short_desc);
  666. i++;
  667. strcpy (params[i].name, "capture");
  668. params[i].character = 'C';
  669. params[i].type = JackDriverParamBool;
  670. params[i].value.i = 0;
  671. strcpy (params[i].short_desc, "Provide capture ports.");
  672. strcpy (params[i].long_desc, params[i].short_desc);
  673. i++;
  674. strcpy (params[i].name, "playback");
  675. params[i].character = 'P';
  676. params[i].type = JackDriverParamBool;
  677. params[i].value.i = 0;
  678. strcpy (params[i].short_desc, "Provide playback ports.");
  679. strcpy (params[i].long_desc, params[i].short_desc);
  680. i++;
  681. strcpy (params[i].name, "duplex");
  682. params[i].character = 'D';
  683. params[i].type = JackDriverParamBool;
  684. params[i].value.i = 1;
  685. strcpy (params[i].short_desc, "Provide both capture and playback ports.");
  686. strcpy (params[i].long_desc, params[i].short_desc);
  687. i++;
  688. strcpy (params[i].name, "input-latency");
  689. params[i].character = 'I';
  690. params[i].type = JackDriverParamUInt;
  691. params[i].value.ui = 0;
  692. strcpy (params[i].short_desc, "Extra input latency (frames)");
  693. strcpy (params[i].long_desc, params[i].short_desc);
  694. i++;
  695. strcpy (params[i].name, "output-latency");
  696. params[i].character = 'O';
  697. params[i].type = JackDriverParamUInt;
  698. params[i].value.ui = 0;
  699. strcpy (params[i].short_desc, "Extra output latency (frames)");
  700. strcpy (params[i].long_desc, params[i].short_desc);
  701. i++;
  702. strcpy (params[i].name, "inchannels");
  703. params[i].character = 'i';
  704. params[i].type = JackDriverParamUInt;
  705. params[i].value.ui = 0;
  706. strcpy (params[i].short_desc, "Number of input channels to provide (note: currently ignored)");
  707. strcpy (params[i].long_desc, params[i].short_desc);
  708. i++;
  709. strcpy (params[i].name, "outchannels");
  710. params[i].character = 'o';
  711. params[i].type = JackDriverParamUInt;
  712. params[i].value.ui = 0;
  713. strcpy (params[i].short_desc, "Number of output channels to provide (note: currently ignored)");
  714. strcpy (params[i].long_desc, params[i].short_desc);
  715. i++;
  716. strcpy (params[i].name, "verbose");
  717. params[i].character = 'v';
  718. params[i].type = JackDriverParamUInt;
  719. params[i].value.ui = 3;
  720. strcpy (params[i].short_desc, "libffado verbose level");
  721. strcpy (params[i].long_desc, params[i].short_desc);
  722. i++;
  723. strcpy (params[i].name, "snoop");
  724. params[i].character = 'X';
  725. params[i].type = JackDriverParamBool;
  726. params[i].value.i = 0;
  727. strcpy (params[i].short_desc, "Snoop firewire traffic");
  728. strcpy (params[i].long_desc, params[i].short_desc);
  729. return desc;
  730. }
  731. SERVER_EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLockedEngine* engine, Jack::JackSynchro* table, const JSList* params) {
  732. const JSList * node;
  733. const jack_driver_param_t * param;
  734. ffado_jack_settings_t cmlparams;
  735. char *device_name=(char*)"hw:0";
  736. cmlparams.period_size_set = 0;
  737. cmlparams.sample_rate_set = 0;
  738. cmlparams.buffer_size_set = 0;
  739. /* default values */
  740. cmlparams.period_size = 1024;
  741. cmlparams.sample_rate = 48000;
  742. cmlparams.buffer_size = 3;
  743. cmlparams.playback_ports = 0;
  744. cmlparams.capture_ports = 0;
  745. cmlparams.playback_frame_latency = 0;
  746. cmlparams.capture_frame_latency = 0;
  747. cmlparams.verbose_level = 0;
  748. cmlparams.slave_mode = 0;
  749. cmlparams.snoop_mode = 0;
  750. cmlparams.device_info = NULL;
  751. for (node = params; node; node = jack_slist_next (node)) {
  752. param = (jack_driver_param_t *) node->data;
  753. switch (param->character) {
  754. case 'd':
  755. device_name = const_cast<char*>(param->value.str);
  756. break;
  757. case 'p':
  758. cmlparams.period_size = param->value.ui;
  759. cmlparams.period_size_set = 1;
  760. break;
  761. case 'n':
  762. cmlparams.buffer_size = param->value.ui;
  763. cmlparams.buffer_size_set = 1;
  764. break;
  765. case 'r':
  766. cmlparams.sample_rate = param->value.ui;
  767. cmlparams.sample_rate_set = 1;
  768. break;
  769. case 'i':
  770. cmlparams.capture_ports = param->value.ui;
  771. break;
  772. case 'o':
  773. cmlparams.playback_ports = param->value.ui;
  774. break;
  775. case 'I':
  776. cmlparams.capture_frame_latency = param->value.ui;
  777. break;
  778. case 'O':
  779. cmlparams.playback_frame_latency = param->value.ui;
  780. break;
  781. case 'x':
  782. cmlparams.slave_mode = param->value.ui;
  783. break;
  784. case 'X':
  785. cmlparams.snoop_mode = param->value.i;
  786. break;
  787. case 'v':
  788. cmlparams.verbose_level = param->value.ui;
  789. }
  790. }
  791. /* duplex is the default */
  792. if (!cmlparams.playback_ports && !cmlparams.capture_ports) {
  793. cmlparams.playback_ports = 1;
  794. cmlparams.capture_ports = 1;
  795. }
  796. // temporary
  797. cmlparams.device_info = device_name;
  798. Jack::JackFFADODriver* ffado_driver = new Jack::JackFFADODriver("system", "firewire_pcm", engine, table);
  799. Jack::JackDriverClientInterface* threaded_driver = new Jack::JackThreadedDriver(ffado_driver);
  800. // Special open for FFADO driver...
  801. if (ffado_driver->Open(&cmlparams) == 0) {
  802. return threaded_driver;
  803. } else {
  804. delete threaded_driver; // Delete the decorated driver
  805. return NULL;
  806. }
  807. }
  808. #ifdef __cplusplus
  809. }
  810. #endif