root/jack2/trunk/jackmp/linux/firewire/JackFFADODriver.cpp

Revision 4032, 35.4 kB (checked in by sletz, 2 months ago)

Arnold Krille irewire snooping patch.

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