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.

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