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