Jack2  1.9.9
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  memset(&driver->device_options, 0, sizeof(driver->device_options));
407  driver->device_options.sample_rate = params->sample_rate;
408  driver->device_options.period_size = params->period_size;
409  driver->device_options.nb_buffers = params->buffer_size;
410  driver->device_options.verbose = params->verbose_level;
411  driver->capture_frame_latency = params->capture_frame_latency;
412  driver->playback_frame_latency = params->playback_frame_latency;
413  driver->device_options.snoop_mode = params->snoop_mode;
414 
415  debugPrint(DEBUG_LEVEL_STARTUP, " Driver compiled on %s %s", __DATE__, __TIME__);
416  debugPrint(DEBUG_LEVEL_STARTUP, " Created driver %s", name);
417  debugPrint(DEBUG_LEVEL_STARTUP, " period_size: %d", driver->device_options.period_size);
418  debugPrint(DEBUG_LEVEL_STARTUP, " period_usecs: %d", driver->period_usecs);
419  debugPrint(DEBUG_LEVEL_STARTUP, " sample rate: %d", driver->device_options.sample_rate);
420  debugPrint(DEBUG_LEVEL_STARTUP, " verbose level: %d", driver->device_options.verbose);
421 
422  return (ffado_driver_t *) driver;
423 }
424 
425 void
426 JackFFADODriver::ffado_driver_delete (ffado_driver_t *driver)
427 {
428  free (driver);
429 }
430 
431 int JackFFADODriver::Attach()
432 {
433  JackPort* port;
434  jack_port_id_t port_index;
435  char buf[REAL_JACK_PORT_NAME_SIZE];
436  char portname[REAL_JACK_PORT_NAME_SIZE];
437 
438  ffado_driver_t* driver = (ffado_driver_t*)fDriver;
439 
440  jack_log("JackFFADODriver::Attach fBufferSize %ld fSampleRate %ld", fEngineControl->fBufferSize, fEngineControl->fSampleRate);
441 
442  g_verbose = (fEngineControl->fVerbose ? 1 : 0);
443 
444  /* preallocate some buffers such that they don't have to be allocated
445  in RT context (or from the stack)
446  */
447  /* the null buffer is a buffer that contains one period of silence */
448  driver->nullbuffer = (ffado_sample_t *)calloc(driver->period_size, sizeof(ffado_sample_t));
449  if (driver->nullbuffer == NULL) {
450  printError("could not allocate memory for null buffer");
451  return -1;
452  }
453  /* calloc should do this, but it can't hurt to be sure */
454  memset(driver->nullbuffer, 0, driver->period_size*sizeof(ffado_sample_t));
455 
456  /* the scratch buffer is a buffer of one period that can be used as dummy memory */
457  driver->scratchbuffer = (ffado_sample_t *)calloc(driver->period_size, sizeof(ffado_sample_t));
458  if (driver->scratchbuffer == NULL) {
459  printError("could not allocate memory for scratch buffer");
460  return -1;
461  }
462 
463  /* packetizer thread options */
464  driver->device_options.realtime = (fEngineControl->fRealTime ? 1 : 0);
465 
466  driver->device_options.packetizer_priority = fEngineControl->fServerPriority +
467  FFADO_RT_PRIORITY_PACKETIZER_RELATIVE;
468  if (driver->device_options.packetizer_priority > 98) {
469  driver->device_options.packetizer_priority = 98;
470  }
471 
472  // initialize the thread
473  driver->dev = ffado_streaming_init(driver->device_info, driver->device_options);
474 
475  if (!driver->dev) {
476  printError("FFADO: Error creating virtual device");
477  return -1;
478  }
479 
480  if (driver->device_options.realtime) {
481  printMessage("Streaming thread running with Realtime scheduling, priority %d",
482  driver->device_options.packetizer_priority);
483  } else {
484  printMessage("Streaming thread running without Realtime scheduling");
485  }
486 
487  ffado_streaming_set_audio_datatype(driver->dev, ffado_audio_datatype_float);
488 
489  /* ports */
490 
491  // capture
492  driver->capture_nchannels = ffado_streaming_get_nb_capture_streams(driver->dev);
493  driver->capture_channels = (ffado_capture_channel_t *)calloc(driver->capture_nchannels, sizeof(ffado_capture_channel_t));
494  if (driver->capture_channels == NULL) {
495  printError("could not allocate memory for capture channel list");
496  return -1;
497  }
498 
499  fCaptureChannels = 0;
500  for (channel_t chn = 0; chn < driver->capture_nchannels; chn++) {
501  ffado_streaming_get_capture_stream_name(driver->dev, chn, portname, sizeof(portname));
502 
503  driver->capture_channels[chn].stream_type = ffado_streaming_get_capture_stream_type(driver->dev, chn);
504  if (driver->capture_channels[chn].stream_type == ffado_stream_type_audio) {
505  snprintf(buf, sizeof(buf), "firewire_pcm:%s_in", portname);
506  printMessage ("Registering audio capture port %s", buf);
507  if (fEngine->PortRegister(fClientControl.fRefNum, buf,
508  JACK_DEFAULT_AUDIO_TYPE,
509  CaptureDriverFlags,
510  fEngineControl->fBufferSize, &port_index) < 0) {
511  jack_error("driver: cannot register port for %s", buf);
512  return -1;
513  }
514 
515  // setup port parameters
516  if (ffado_streaming_set_capture_stream_buffer(driver->dev, chn, NULL)) {
517  printError(" cannot configure initial port buffer for %s", buf);
518  }
519  ffado_streaming_capture_stream_onoff(driver->dev, chn, 0);
520 
521  port = fGraphManager->GetPort(port_index);
522  // capture port aliases (jackd1 style port names)
523  snprintf(buf, sizeof(buf), "%s:capture_%i", fClientControl.fName, (int) chn + 1);
524  port->SetAlias(buf);
525  fCapturePortList[chn] = port_index;
526  jack_log("JackFFADODriver::Attach fCapturePortList[i] %ld ", port_index);
527  fCaptureChannels++;
528  } else if (driver->capture_channels[chn].stream_type == ffado_stream_type_midi) {
529  snprintf(buf, sizeof(buf), "firewire_pcm:%s_in", portname);
530  printMessage ("Registering midi capture port %s", buf);
531  if (fEngine->PortRegister(fClientControl.fRefNum, buf,
532  JACK_DEFAULT_MIDI_TYPE,
533  CaptureDriverFlags,
534  fEngineControl->fBufferSize, &port_index) < 0) {
535  jack_error("driver: cannot register port for %s", buf);
536  return -1;
537  }
538 
539  // setup port parameters
540  if (ffado_streaming_set_capture_stream_buffer(driver->dev, chn, NULL)) {
541  printError(" cannot configure initial port buffer for %s", buf);
542  }
543  if (ffado_streaming_capture_stream_onoff(driver->dev, chn, 0)) {
544  printError(" cannot enable port %s", buf);
545  }
546 
547  driver->capture_channels[chn].midi_input = new JackFFADOMidiInputPort();
548  // setup the midi buffer
549  driver->capture_channels[chn].midi_buffer = (uint32_t *)calloc(driver->period_size, sizeof(uint32_t));
550 
551  fCapturePortList[chn] = port_index;
552  jack_log("JackFFADODriver::Attach fCapturePortList[i] %ld ", port_index);
553  fCaptureChannels++;
554  } else {
555  printMessage ("Don't register capture port %s", portname);
556  }
557  }
558 
559  // playback
560  driver->playback_nchannels = ffado_streaming_get_nb_playback_streams(driver->dev);
561  driver->playback_channels = (ffado_playback_channel_t *)calloc(driver->playback_nchannels, sizeof(ffado_playback_channel_t));
562  if (driver->playback_channels == NULL) {
563  printError("could not allocate memory for playback channel list");
564  return -1;
565  }
566 
567  fPlaybackChannels = 0;
568  for (channel_t chn = 0; chn < driver->playback_nchannels; chn++) {
569  ffado_streaming_get_playback_stream_name(driver->dev, chn, portname, sizeof(portname));
570 
571  driver->playback_channels[chn].stream_type = ffado_streaming_get_playback_stream_type(driver->dev, chn);
572 
573  if (driver->playback_channels[chn].stream_type == ffado_stream_type_audio) {
574  snprintf(buf, sizeof(buf), "firewire_pcm:%s_out", portname);
575  printMessage ("Registering audio playback port %s", buf);
576  if (fEngine->PortRegister(fClientControl.fRefNum, buf,
577  JACK_DEFAULT_AUDIO_TYPE,
578  PlaybackDriverFlags,
579  fEngineControl->fBufferSize, &port_index) < 0) {
580  jack_error("driver: cannot register port for %s", buf);
581  return -1;
582  }
583 
584  // setup port parameters
585  if (ffado_streaming_set_playback_stream_buffer(driver->dev, chn, NULL)) {
586  printError(" cannot configure initial port buffer for %s", buf);
587  }
588  if (ffado_streaming_playback_stream_onoff(driver->dev, chn, 0)) {
589  printError(" cannot enable port %s", buf);
590  }
591 
592  port = fGraphManager->GetPort(port_index);
593  // Add one buffer more latency if "async" mode is used...
594  // playback port aliases (jackd1 style port names)
595  snprintf(buf, sizeof(buf), "%s:playback_%i", fClientControl.fName, (int) chn + 1);
596  port->SetAlias(buf);
597  fPlaybackPortList[chn] = port_index;
598  jack_log("JackFFADODriver::Attach fPlaybackPortList[i] %ld ", port_index);
599  fPlaybackChannels++;
600  } else if (driver->playback_channels[chn].stream_type == ffado_stream_type_midi) {
601  snprintf(buf, sizeof(buf), "firewire_pcm:%s_out", portname);
602  printMessage ("Registering midi playback port %s", buf);
603 
604  if (fEngine->PortRegister(fClientControl.fRefNum, buf,
605  JACK_DEFAULT_MIDI_TYPE,
606  PlaybackDriverFlags,
607  fEngineControl->fBufferSize, &port_index) < 0) {
608  jack_error("driver: cannot register port for %s", buf);
609  return -1;
610  }
611 
612  // setup port parameters
613  if (ffado_streaming_set_playback_stream_buffer(driver->dev, chn, NULL)) {
614  printError(" cannot configure initial port buffer for %s", buf);
615  }
616  if (ffado_streaming_playback_stream_onoff(driver->dev, chn, 0)) {
617  printError(" cannot enable port %s", buf);
618  }
619  // setup the midi buffer
620 
621  // This constructor optionally accepts arguments for the
622  // non-realtime buffer size and the realtime buffer size. Ideally,
623  // these would become command-line options for the FFADO driver.
624  driver->playback_channels[chn].midi_output = new JackFFADOMidiOutputPort();
625 
626  driver->playback_channels[chn].midi_buffer = (uint32_t *)calloc(driver->period_size, sizeof(uint32_t));
627 
628  fPlaybackPortList[chn] = port_index;
629  jack_log("JackFFADODriver::Attach fPlaybackPortList[i] %ld ", port_index);
630  fPlaybackChannels++;
631  } else {
632  printMessage ("Don't register playback port %s", portname);
633  }
634  }
635 
636  UpdateLatencies();
637 
638  assert(fCaptureChannels < DRIVER_PORT_NUM);
639  assert(fPlaybackChannels < DRIVER_PORT_NUM);
640 
641  if (ffado_streaming_prepare(driver->dev)) {
642  printError("Could not prepare streaming device!");
643  return -1;
644  }
645 
646  // this makes no sense...
647  assert(fCaptureChannels + fPlaybackChannels > 0);
648  return 0;
649 }
650 
651 int JackFFADODriver::Detach()
652 {
653  channel_t chn;
654  ffado_driver_t* driver = (ffado_driver_t*)fDriver;
655  jack_log("JackFFADODriver::Detach");
656 
657  // finish the libfreebob streaming
658  ffado_streaming_finish(driver->dev);
659  driver->dev = NULL;
660 
661  // free all internal buffers
662  for (chn = 0; chn < driver->capture_nchannels; chn++) {
663  if (driver->capture_channels[chn].midi_buffer)
664  free(driver->capture_channels[chn].midi_buffer);
665  if (driver->capture_channels[chn].midi_input)
666  delete ((JackFFADOMidiInputPort *) (driver->capture_channels[chn].midi_input));
667  }
668  free(driver->capture_channels);
669 
670  for (chn = 0; chn < driver->playback_nchannels; chn++) {
671  if (driver->playback_channels[chn].midi_buffer)
672  free(driver->playback_channels[chn].midi_buffer);
673  if (driver->playback_channels[chn].midi_output)
674  delete ((JackFFADOMidiOutputPort *) (driver->playback_channels[chn].midi_output));
675  }
676  free(driver->playback_channels);
677 
678  free(driver->nullbuffer);
679  free(driver->scratchbuffer);
680 
681  return JackAudioDriver::Detach(); // Generic JackAudioDriver Detach
682 }
683 
684 int JackFFADODriver::Open(ffado_jack_settings_t *params)
685 {
686  // Generic JackAudioDriver Open
687  if (JackAudioDriver::Open(
688  params->period_size, params->sample_rate,
689  params->playback_ports, params->playback_ports,
690  0, 0, 0, "", "",
691  params->capture_frame_latency, params->playback_frame_latency) != 0) {
692  return -1;
693  }
694 
695  fDriver = (jack_driver_t *)ffado_driver_new ("ffado_pcm", params);
696 
697  if (fDriver) {
698  // FFADO driver may have changed the in/out values
699  //fCaptureChannels = ((ffado_driver_t *)fDriver)->capture_nchannels_audio;
700  //fPlaybackChannels = ((ffado_driver_t *)fDriver)->playback_nchannels_audio;
701  return 0;
702  } else {
703  JackAudioDriver::Close();
704  return -1;
705  }
706 }
707 
708 int JackFFADODriver::Close()
709 {
710  // Generic audio driver close
711  int res = JackAudioDriver::Close();
712 
713  ffado_driver_delete((ffado_driver_t*)fDriver);
714  return res;
715 }
716 
717 int JackFFADODriver::Start()
718 {
719  int res = JackAudioDriver::Start();
720  if (res >= 0) {
721  res = ffado_driver_start((ffado_driver_t *)fDriver);
722  if (res < 0) {
723  JackAudioDriver::Stop();
724  }
725  }
726  return res;
727 }
728 
729 int JackFFADODriver::Stop()
730 {
731  int res = ffado_driver_stop((ffado_driver_t *)fDriver);
732  if (JackAudioDriver::Stop() < 0) {
733  res = -1;
734  }
735  return res;
736 }
737 
738 int JackFFADODriver::Read()
739 {
740  printEnter();
741 
742  /* Taken from ffado_driver_run_cycle */
743  ffado_driver_t* driver = (ffado_driver_t*)fDriver;
744  int wait_status = 0;
745  fDelayedUsecs = 0.f;
746 
747 retry:
748 
749  jack_nframes_t nframes = ffado_driver_wait(driver, -1, &wait_status,
750  &fDelayedUsecs);
751 
752  if ((wait_status < 0)) {
753  printError( "wait status < 0! (= %d)", wait_status);
754  return -1;
755  }
756 
757  if (nframes == 0) {
758  /* we detected an xrun and restarted: notify
759  * clients about the delay.
760  */
761  jack_log("FFADO XRun");
762  NotifyXRun(fBeginDateUst, fDelayedUsecs);
763  goto retry; /* recoverable error*/
764  }
765 
766  if (nframes != fEngineControl->fBufferSize)
767  jack_log("JackFFADODriver::Read warning nframes = %ld", nframes);
768 
769  // Has to be done before read
770  JackDriver::CycleIncTime();
771 
772  printExit();
773  return ffado_driver_read((ffado_driver_t *)fDriver, fEngineControl->fBufferSize);
774 }
775 
776 int JackFFADODriver::Write()
777 {
778  printEnter();
779  int res = ffado_driver_write((ffado_driver_t *)fDriver, fEngineControl->fBufferSize);
780  printExit();
781  return res;
782 }
783 
784 void
785 JackFFADODriver::jack_driver_init (jack_driver_t *driver)
786 {
787  memset (driver, 0, sizeof (*driver));
788 
789  driver->attach = 0;
790  driver->detach = 0;
791  driver->write = 0;
792  driver->read = 0;
793  driver->null_cycle = 0;
794  driver->bufsize = 0;
795  driver->start = 0;
796  driver->stop = 0;
797 }
798 
799 void
800 JackFFADODriver::jack_driver_nt_init (jack_driver_nt_t * driver)
801 {
802  memset (driver, 0, sizeof (*driver));
803 
804  jack_driver_init ((jack_driver_t *) driver);
805 
806  driver->attach = 0;
807  driver->detach = 0;
808  driver->bufsize = 0;
809  driver->stop = 0;
810  driver->start = 0;
811 
812  driver->nt_bufsize = 0;
813  driver->nt_start = 0;
814  driver->nt_stop = 0;
815  driver->nt_attach = 0;
816  driver->nt_detach = 0;
817  driver->nt_run_cycle = 0;
818 }
819 
820 } // end of namespace
821 
822 
823 #ifdef __cplusplus
824 extern "C"
825 {
826 #endif
827 
828  SERVER_EXPORT const jack_driver_desc_t *
829  driver_get_descriptor () {
830  jack_driver_desc_t * desc;
833 
834  desc = jack_driver_descriptor_construct("firewire", JackDriverMaster, "Linux FFADO API based audio backend", &filler);
835 
836  strcpy(value.str, "hw:0");
837  jack_driver_descriptor_add_parameter(
838  desc,
839  &filler,
840  "device",
841  'd',
842  JackDriverParamString,
843  &value,
844  NULL,
845  "The FireWire device to use.",
846  "The FireWire device to use. Please consult the FFADO documentation for more info.");
847 
848  value.ui = 1024;
849  jack_driver_descriptor_add_parameter(desc, &filler, "period", 'p', JackDriverParamUInt, &value, NULL, "Frames per period", NULL);
850 
851  value.ui = 3;
852  jack_driver_descriptor_add_parameter(desc, &filler, "nperiods", 'n', JackDriverParamUInt, &value, NULL, "Number of periods of playback latency", NULL);
853 
854  value.ui = 48000U;
855  jack_driver_descriptor_add_parameter(desc, &filler, "rate", 'r', JackDriverParamUInt, &value, NULL, "Sample rate", NULL);
856 
857  value.i = 0;
858  jack_driver_descriptor_add_parameter(desc, &filler, "capture", 'C', JackDriverParamBool, &value, NULL, "Provide capture ports.", NULL);
859  jack_driver_descriptor_add_parameter(desc, &filler, "playback", 'P', JackDriverParamBool, &value, NULL, "Provide playback ports.", NULL);
860 
861  value.i = 1;
862  jack_driver_descriptor_add_parameter(desc, &filler, "duplex", 'D', JackDriverParamBool, &value, NULL, "Provide both capture and playback ports.", NULL);
863 
864  value.ui = 0;
865  jack_driver_descriptor_add_parameter(desc, &filler, "input-latency", 'I', JackDriverParamUInt, &value, NULL, "Extra input latency (frames)", NULL);
866  jack_driver_descriptor_add_parameter(desc, &filler, "output-latency", 'O', JackDriverParamUInt, &value, NULL, "Extra output latency (frames)", NULL);
867 
868  value.ui = 0;
869  jack_driver_descriptor_add_parameter(desc, &filler, "inchannels", 'i', JackDriverParamUInt, &value, NULL, "Number of input channels to provide (note: currently ignored)", NULL);
870  jack_driver_descriptor_add_parameter(desc, &filler, "outchannels", 'o', JackDriverParamUInt, &value, NULL, "Number of output channels to provide (note: currently ignored)", NULL);
871 
872  value.ui = 3;
873  jack_driver_descriptor_add_parameter(desc, &filler, "verbose", 'v', JackDriverParamUInt, &value, NULL, "libffado verbose level", NULL);
874 
875  value.i = 0;
876  jack_driver_descriptor_add_parameter(desc, &filler, "snoop", 'X', JackDriverParamBool, &value, NULL, "Snoop firewire traffic", NULL);
877 
878  return desc;
879  }
880 
881  SERVER_EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLockedEngine* engine, Jack::JackSynchro* table, const JSList* params) {
882  const JSList * node;
883  const jack_driver_param_t * param;
884 
885  ffado_jack_settings_t cmlparams;
886 
887  char *device_name=(char*)"hw:0";
888 
889  cmlparams.period_size_set = 0;
890  cmlparams.sample_rate_set = 0;
891  cmlparams.buffer_size_set = 0;
892 
893  /* default values */
894  cmlparams.period_size = 1024;
895  cmlparams.sample_rate = 48000;
896  cmlparams.buffer_size = 3;
897  cmlparams.playback_ports = 0;
898  cmlparams.capture_ports = 0;
899  cmlparams.playback_frame_latency = 0;
900  cmlparams.capture_frame_latency = 0;
901 
902  cmlparams.verbose_level = 0;
903 
904  cmlparams.slave_mode = 0;
905  cmlparams.snoop_mode = 0;
906  cmlparams.device_info = NULL;
907 
908  for (node = params; node; node = jack_slist_next (node)) {
909  param = (jack_driver_param_t *) node->data;
910 
911  switch (param->character) {
912  case 'd':
913  device_name = const_cast<char*>(param->value.str);
914  break;
915  case 'p':
916  cmlparams.period_size = param->value.ui;
917  cmlparams.period_size_set = 1;
918  break;
919  case 'n':
920  cmlparams.buffer_size = param->value.ui;
921  cmlparams.buffer_size_set = 1;
922  break;
923  case 'r':
924  cmlparams.sample_rate = param->value.ui;
925  cmlparams.sample_rate_set = 1;
926  break;
927  case 'i':
928  cmlparams.capture_ports = param->value.ui;
929  break;
930  case 'o':
931  cmlparams.playback_ports = param->value.ui;
932  break;
933  case 'I':
934  cmlparams.capture_frame_latency = param->value.ui;
935  break;
936  case 'O':
937  cmlparams.playback_frame_latency = param->value.ui;
938  break;
939  case 'x':
940  cmlparams.slave_mode = param->value.ui;
941  break;
942  case 'X':
943  cmlparams.snoop_mode = param->value.i;
944  break;
945  case 'v':
946  cmlparams.verbose_level = param->value.ui;
947  }
948  }
949 
950  /* duplex is the default */
951  if (!cmlparams.playback_ports && !cmlparams.capture_ports) {
952  cmlparams.playback_ports = 1;
953  cmlparams.capture_ports = 1;
954  }
955 
956  // temporary
957  cmlparams.device_info = device_name;
958 
959  Jack::JackFFADODriver* ffado_driver = new Jack::JackFFADODriver("system", "firewire_pcm", engine, table);
960  Jack::JackDriverClientInterface* threaded_driver = new Jack::JackThreadedDriver(ffado_driver);
961  // Special open for FFADO driver...
962  if (ffado_driver->Open(&cmlparams) == 0) {
963  return threaded_driver;
964  } else {
965  delete threaded_driver; // Delete the decorated driver
966  return NULL;
967  }
968  }
969 
970 #ifdef __cplusplus
971 }
972 #endif
973 
974 
The base class for threaded drivers using a &quot;decorator&quot; pattern. Threaded drivers are used with block...
Inter process synchronization using using Mach semaphore.
Locked Engine, access to methods is serialized using a mutex.
SERVER_EXPORT void jack_error(const char *fmt,...)
Definition: JackError.cpp:91
jack_nframes_t min
Definition: types.h:268
jack_nframes_t max
Definition: types.h:272
The base interface for drivers clients.
Definition: JackDriver.h:122
SERVER_EXPORT void jack_log(const char *fmt,...)
Definition: JackError.cpp:107
The FFADO driver.