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
361 ffado_driver_t *
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;
836 jack_driver_desc_filler_t filler;
837 jack_driver_param_value_t value;
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
_ffado_driver
Definition: ffado_driver.h:161
Jack::JackThreadedDriver
The base class for threaded drivers using a "decorator" pattern. Threaded drivers are used with block...
Definition: JackThreadedDriver.h:34
Jack::JackLockedEngine
Locked Engine, access to methods is serialized using a mutex.
Definition: JackLockedEngine.h:78
jack_driver_param_value_t
Definition: driver_interface.h:64
_ffado_capture_channel
Definition: ffado_driver.h:142
Jack::JackPosixSemaphore
Inter process synchronization using POSIX semaphore.
Definition: JackPosixSemaphore.h:36
_jack_driver_nt
Definition: driver.h:275
jack_error
SERVER_EXPORT void jack_error(const char *fmt,...)
Definition: JackError.cpp:92
_jack_latency_range::min
jack_nframes_t min
Definition: types.h:270
_jack_driver
Definition: driver.h:87
_ffado_playback_channel
Definition: ffado_driver.h:150
_jack_latency_range
Definition: types.h:265
_jack_latency_range::max
jack_nframes_t max
Definition: types.h:274
_ffado_jack_settings
Definition: ffado_driver.h:117
jack_driver_desc_filler_t
Definition: driver_interface.h:142
Jack::JackDriverClientInterface
The base interface for drivers clients.
Definition: JackDriver.h:114
jack_driver_param_t
Definition: driver_interface.h:125
_JSList
Definition: linux/alsa/jslist.h:35
jack_log
SERVER_EXPORT void jack_log(const char *fmt,...)
Definition: JackError.cpp:108
Jack::JackFFADODriver
The FFADO driver.
Definition: JackFFADODriver.h:39
jack_driver_desc_t
Definition: driver_interface.h:132