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.

977 lines
37KB

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