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
ffado_driver_read(ffado_driver_t * driver,jack_nframes_t nframes)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
ffado_driver_write(ffado_driver_t * driver,jack_nframes_t nframes)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
ffado_driver_wait(ffado_driver_t * driver,int extra_fd,int * status,float * delayed_usecs)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
ffado_driver_start(ffado_driver_t * driver)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
ffado_driver_stop(ffado_driver_t * driver)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
ffado_driver_restart(ffado_driver_t * driver)260 JackFFADODriver::ffado_driver_restart (ffado_driver_t *driver)
261 {
262     if (Stop())
263         return -1;
264     return Start();
265 }
266 
267 void
UpdateLatencies(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
SetBufferSize(jack_nframes_t nframes)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 *
ffado_driver_new(const char * name,ffado_jack_settings_t * params)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
ffado_driver_delete(ffado_driver_t * driver)431 JackFFADODriver::ffado_driver_delete (ffado_driver_t *driver)
432 {
433     free (driver);
434 }
435 
Attach()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 
Detach()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 libffado 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 
Open(ffado_jack_settings_t * params)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 
Close()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 
Start()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 
Stop()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 
Read()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 
Write()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
jack_driver_init(jack_driver_t * driver)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
jack_driver_nt_init(jack_driver_nt_t * driver)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 *
driver_get_descriptor()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 
driver_initialize(Jack::JackLockedEngine * engine,Jack::JackSynchro * table,const JSList * params)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 
980