PageRenderTime 51ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/jack-1.9.8/jack-1.9.8/linux/firewire/JackFFADODriver.cpp

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