33 #include <sys/types.h>
38 #include "JackFFADODriver.h"
39 #include "JackFFADOMidiInputPort.h"
40 #include "JackFFADOMidiOutputPort.h"
41 #include "JackEngineControl.h"
42 #include "JackClientControl.h"
44 #include "JackGraphManager.h"
45 #include "JackCompilerDeps.h"
46 #include "JackLockedEngine.h"
51 #define FIREWIRE_REQUIRED_FFADO_API_VERSION 8
53 #define jack_get_microseconds GetMicroSeconds
56 JackFFADODriver::ffado_driver_read (
ffado_driver_t * driver, jack_nframes_t nframes)
59 jack_default_audio_sample_t* buf = NULL;
62 for (chn = 0; chn < driver->capture_nchannels; chn++) {
64 if (fGraphManager->GetConnectionsNum(fCapturePortList[chn]) == 0) {
65 buf = (jack_default_audio_sample_t*)driver->scratchbuffer;
67 ffado_streaming_set_capture_stream_buffer(driver->dev, chn, (
char *)(buf));
70 ffado_streaming_capture_stream_onoff(driver->dev, chn, 0);
72 if (driver->capture_channels[chn].stream_type == ffado_stream_type_audio) {
73 buf = (jack_default_audio_sample_t*)fGraphManager->GetBuffer(fCapturePortList[chn], nframes);
76 if (!buf) buf = (jack_default_audio_sample_t*)driver->scratchbuffer;
78 ffado_streaming_set_capture_stream_buffer(driver->dev, chn, (
char *)(buf));
79 ffado_streaming_capture_stream_onoff(driver->dev, chn, 1);
80 }
else if (driver->capture_channels[chn].stream_type == ffado_stream_type_midi) {
81 ffado_streaming_set_capture_stream_buffer(driver->dev, chn,
82 (
char *)(driver->capture_channels[chn].midi_buffer));
83 ffado_streaming_capture_stream_onoff(driver->dev, chn, 1);
85 ffado_streaming_set_capture_stream_buffer(driver->dev, chn, (
char *)(driver->scratchbuffer));
87 ffado_streaming_capture_stream_onoff(driver->dev, chn, 0);
93 ffado_streaming_transfer_capture_buffers(driver->dev);
96 for (chn = 0; chn < driver->capture_nchannels; chn++) {
97 if (driver->capture_channels[chn].stream_type == ffado_stream_type_midi) {
98 JackFFADOMidiInputPort *midi_input = (JackFFADOMidiInputPort *) driver->capture_channels[chn].midi_input;
99 JackMidiBuffer *buffer = (JackMidiBuffer *) fGraphManager->GetBuffer(fCapturePortList[chn], nframes);
100 midi_input->Process(buffer, driver->capture_channels[chn].midi_buffer, nframes);
109 JackFFADODriver::ffado_driver_write (
ffado_driver_t * driver, jack_nframes_t nframes)
112 jack_default_audio_sample_t* buf;
115 driver->process_count++;
117 for (chn = 0; chn < driver->playback_nchannels; chn++) {
118 if (fGraphManager->GetConnectionsNum(fPlaybackPortList[chn]) == 0) {
119 buf = (jack_default_audio_sample_t*)driver->nullbuffer;
121 ffado_streaming_set_playback_stream_buffer(driver->dev, chn, (
char *)(buf));
124 ffado_streaming_playback_stream_onoff(driver->dev, chn, 0);
126 if (driver->playback_channels[chn].stream_type == ffado_stream_type_audio) {
127 buf = (jack_default_audio_sample_t*)fGraphManager->GetBuffer(fPlaybackPortList[chn], nframes);
129 if (!buf) buf = (jack_default_audio_sample_t*)driver->nullbuffer;
130 ffado_streaming_set_playback_stream_buffer(driver->dev, chn, (
char *)(buf));
131 ffado_streaming_playback_stream_onoff(driver->dev, chn, 1);
132 }
else if (driver->playback_channels[chn].stream_type == ffado_stream_type_midi) {
133 uint32_t *midi_buffer = driver->playback_channels[chn].midi_buffer;
134 memset(midi_buffer, 0, nframes *
sizeof(uint32_t));
135 buf = (jack_default_audio_sample_t *) fGraphManager->GetBuffer(fPlaybackPortList[chn], nframes);
136 ffado_streaming_set_playback_stream_buffer(driver->dev, chn, (
char *)(midi_buffer));
137 ffado_streaming_playback_stream_onoff(driver->dev, chn, buf ? 1 : 0);
138 JackFFADOMidiOutputPort *midi_output = (JackFFADOMidiOutputPort *) driver->playback_channels[chn].midi_output;
139 midi_output->Process((JackMidiBuffer *) buf, midi_buffer, nframes);
142 ffado_streaming_set_playback_stream_buffer(driver->dev, chn, (
char *)(driver->nullbuffer));
143 ffado_streaming_playback_stream_onoff(driver->dev, chn, 0);
147 ffado_streaming_transfer_playback_buffers(driver->dev);
153 JackFFADODriver::ffado_driver_wait (
ffado_driver_t *driver,
int extra_fd,
int *status,
154 float *delayed_usecs)
156 jack_time_t wait_enter;
157 jack_time_t wait_ret;
158 ffado_wait_response response;
162 wait_enter = jack_get_microseconds ();
163 if (wait_enter > driver->wait_next) {
169 driver->wait_next = 0;
176 response = ffado_streaming_wait(driver->dev);
178 wait_ret = jack_get_microseconds ();
180 if (driver->wait_next && wait_ret > driver->wait_next) {
181 *delayed_usecs = wait_ret - driver->wait_next;
183 driver->wait_last = wait_ret;
184 driver->wait_next = wait_ret + driver->period_usecs;
187 if(response == ffado_wait_ok) {
190 }
else if (response == ffado_wait_xrun) {
194 }
else if (response == ffado_wait_error) {
197 jack_error(
"JackFFADODriver::ffado_driver_wait - unhandled xrun");
200 }
else if (response == ffado_wait_shutdown) {
203 jack_error(
"JackFFADODriver::ffado_driver_wait - shutdown requested "
204 "(device unplugged?)");
210 jack_error(
"JackFFADODriver::ffado_driver_wait - unexpected error "
211 "code '%d' returned from 'ffado_streaming_wait'", response);
216 fBeginDateUst = wait_ret;
219 return driver->period_size;
227 if ((retval = ffado_streaming_start(driver->dev))) {
228 printError(
"Could not start streaming threads");
240 if ((retval = ffado_streaming_stop(driver->dev))) {
241 printError(
"Could not stop streaming threads");
257 JackFFADODriver::SetBufferSize (jack_nframes_t nframes)
259 printError(
"Buffer size change requested but not supported!!!");
277 JackFFADODriver::ffado_driver_new (
const char *name,
284 if (ffado_get_api_version() != FIREWIRE_REQUIRED_FFADO_API_VERSION) {
285 printError(
"Incompatible libffado version! (%s)", ffado_get_version());
289 printMessage(
"Starting FFADO backend (%s)", ffado_get_version());
311 driver->sample_rate = params->sample_rate;
312 driver->period_size = params->period_size;
315 driver->period_usecs =
316 (jack_time_t) floor ((((
float) driver->period_size) * 1000000.0f) / driver->sample_rate);
319 driver->engine = NULL;
321 memset(&driver->device_options, 0,
sizeof(driver->device_options));
322 driver->device_options.sample_rate = params->sample_rate;
323 driver->device_options.period_size = params->period_size;
324 driver->device_options.nb_buffers = params->buffer_size;
325 driver->device_options.verbose = params->verbose_level;
326 driver->capture_frame_latency = params->capture_frame_latency;
327 driver->playback_frame_latency = params->playback_frame_latency;
328 driver->device_options.snoop_mode = params->snoop_mode;
330 debugPrint(DEBUG_LEVEL_STARTUP,
" Driver compiled on %s %s", __DATE__, __TIME__);
331 debugPrint(DEBUG_LEVEL_STARTUP,
" Created driver %s", name);
332 debugPrint(DEBUG_LEVEL_STARTUP,
" period_size: %d", driver->device_options.period_size);
333 debugPrint(DEBUG_LEVEL_STARTUP,
" period_usecs: %d", driver->period_usecs);
334 debugPrint(DEBUG_LEVEL_STARTUP,
" sample rate: %d", driver->device_options.sample_rate);
335 debugPrint(DEBUG_LEVEL_STARTUP,
" verbose level: %d", driver->device_options.verbose);
346 int JackFFADODriver::Attach()
349 jack_port_id_t port_index;
350 char buf[REAL_JACK_PORT_NAME_SIZE];
351 char portname[REAL_JACK_PORT_NAME_SIZE];
356 jack_log(
"JackFFADODriver::Attach fBufferSize %ld fSampleRate %ld", fEngineControl->fBufferSize, fEngineControl->fSampleRate);
358 g_verbose = (fEngineControl->fVerbose ? 1 : 0);
364 driver->nullbuffer = (ffado_sample_t *)calloc(driver->period_size,
sizeof(ffado_sample_t));
365 if (driver->nullbuffer == NULL) {
366 printError(
"could not allocate memory for null buffer");
370 memset(driver->nullbuffer, 0, driver->period_size*
sizeof(ffado_sample_t));
373 driver->scratchbuffer = (ffado_sample_t *)calloc(driver->period_size,
sizeof(ffado_sample_t));
374 if (driver->scratchbuffer == NULL) {
375 printError(
"could not allocate memory for scratch buffer");
380 driver->device_options.realtime = (fEngineControl->fRealTime ? 1 : 0);
382 driver->device_options.packetizer_priority = fEngineControl->fServerPriority +
383 FFADO_RT_PRIORITY_PACKETIZER_RELATIVE;
384 if (driver->device_options.packetizer_priority > 98) {
385 driver->device_options.packetizer_priority = 98;
389 driver->dev = ffado_streaming_init(driver->device_info, driver->device_options);
392 printError(
"FFADO: Error creating virtual device");
396 if (driver->device_options.realtime) {
397 printMessage(
"Streaming thread running with Realtime scheduling, priority %d",
398 driver->device_options.packetizer_priority);
400 printMessage(
"Streaming thread running without Realtime scheduling");
403 ffado_streaming_set_audio_datatype(driver->dev, ffado_audio_datatype_float);
408 driver->capture_nchannels = ffado_streaming_get_nb_capture_streams(driver->dev);
410 if (driver->capture_channels == NULL) {
411 printError(
"could not allocate memory for capture channel list");
415 fCaptureChannels = 0;
416 for (channel_t chn = 0; chn < driver->capture_nchannels; chn++) {
417 ffado_streaming_get_capture_stream_name(driver->dev, chn, portname,
sizeof(portname));
419 driver->capture_channels[chn].stream_type = ffado_streaming_get_capture_stream_type(driver->dev, chn);
420 if (driver->capture_channels[chn].stream_type == ffado_stream_type_audio) {
421 snprintf(buf,
sizeof(buf),
"firewire_pcm:%s_in", portname);
422 printMessage (
"Registering audio capture port %s", buf);
423 if (fEngine->PortRegister(fClientControl.fRefNum, buf,
424 JACK_DEFAULT_AUDIO_TYPE,
426 fEngineControl->fBufferSize, &port_index) < 0) {
427 jack_error(
"driver: cannot register port for %s", buf);
432 if (ffado_streaming_set_capture_stream_buffer(driver->dev, chn, NULL)) {
433 printError(
" cannot configure initial port buffer for %s", buf);
435 ffado_streaming_capture_stream_onoff(driver->dev, chn, 0);
437 port = fGraphManager->GetPort(port_index);
438 range.
min = range.
max = driver->period_size + driver->capture_frame_latency;
439 port->SetLatencyRange(JackCaptureLatency, &range);
441 snprintf(buf,
sizeof(buf),
"%s:capture_%i", fClientControl.fName, (
int) chn + 1);
443 fCapturePortList[chn] = port_index;
444 jack_log(
"JackFFADODriver::Attach fCapturePortList[i] %ld ", port_index);
446 }
else if (driver->capture_channels[chn].stream_type == ffado_stream_type_midi) {
447 snprintf(buf,
sizeof(buf),
"firewire_pcm:%s_in", portname);
448 printMessage (
"Registering midi capture port %s", buf);
449 if (fEngine->PortRegister(fClientControl.fRefNum, buf,
450 JACK_DEFAULT_MIDI_TYPE,
452 fEngineControl->fBufferSize, &port_index) < 0) {
453 jack_error(
"driver: cannot register port for %s", buf);
458 if (ffado_streaming_set_capture_stream_buffer(driver->dev, chn, NULL)) {
459 printError(
" cannot configure initial port buffer for %s", buf);
461 if (ffado_streaming_capture_stream_onoff(driver->dev, chn, 0)) {
462 printError(
" cannot enable port %s", buf);
465 driver->capture_channels[chn].midi_input =
new JackFFADOMidiInputPort();
467 driver->capture_channels[chn].midi_buffer = (uint32_t *)calloc(driver->period_size,
sizeof(uint32_t));
469 port = fGraphManager->GetPort(port_index);
470 range.
min = range.
max = driver->period_size + driver->capture_frame_latency;
471 port->SetLatencyRange(JackCaptureLatency, &range);
472 fCapturePortList[chn] = port_index;
473 jack_log(
"JackFFADODriver::Attach fCapturePortList[i] %ld ", port_index);
476 printMessage (
"Don't register capture port %s", portname);
481 driver->playback_nchannels = ffado_streaming_get_nb_playback_streams(driver->dev);
483 if (driver->playback_channels == NULL) {
484 printError(
"could not allocate memory for playback channel list");
488 fPlaybackChannels = 0;
489 for (channel_t chn = 0; chn < driver->playback_nchannels; chn++) {
490 ffado_streaming_get_playback_stream_name(driver->dev, chn, portname,
sizeof(portname));
492 driver->playback_channels[chn].stream_type = ffado_streaming_get_playback_stream_type(driver->dev, chn);
494 if (driver->playback_channels[chn].stream_type == ffado_stream_type_audio) {
495 snprintf(buf,
sizeof(buf),
"firewire_pcm:%s_out", portname);
496 printMessage (
"Registering audio playback port %s", buf);
497 if (fEngine->PortRegister(fClientControl.fRefNum, buf,
498 JACK_DEFAULT_AUDIO_TYPE,
500 fEngineControl->fBufferSize, &port_index) < 0) {
501 jack_error(
"driver: cannot register port for %s", buf);
506 if (ffado_streaming_set_playback_stream_buffer(driver->dev, chn, NULL)) {
507 printError(
" cannot configure initial port buffer for %s", buf);
509 if (ffado_streaming_playback_stream_onoff(driver->dev, chn, 0)) {
510 printError(
" cannot enable port %s", buf);
513 port = fGraphManager->GetPort(port_index);
515 range.
min = range.
max = (driver->period_size * (driver->device_options.nb_buffers - 1)) + ((fEngineControl->fSyncMode) ? 0 : fEngineControl->fBufferSize) + driver->playback_frame_latency;
516 port->SetLatencyRange(JackPlaybackLatency, &range);
518 snprintf(buf,
sizeof(buf),
"%s:playback_%i", fClientControl.fName, (
int) chn + 1);
520 fPlaybackPortList[chn] = port_index;
521 jack_log(
"JackFFADODriver::Attach fPlaybackPortList[i] %ld ", port_index);
523 }
else if (driver->playback_channels[chn].stream_type == ffado_stream_type_midi) {
524 snprintf(buf,
sizeof(buf),
"firewire_pcm:%s_out", portname);
525 printMessage (
"Registering midi playback port %s", buf);
527 if (fEngine->PortRegister(fClientControl.fRefNum, buf,
528 JACK_DEFAULT_MIDI_TYPE,
530 fEngineControl->fBufferSize, &port_index) < 0) {
531 jack_error(
"driver: cannot register port for %s", buf);
536 if (ffado_streaming_set_playback_stream_buffer(driver->dev, chn, NULL)) {
537 printError(
" cannot configure initial port buffer for %s", buf);
539 if (ffado_streaming_playback_stream_onoff(driver->dev, chn, 0)) {
540 printError(
" cannot enable port %s", buf);
547 driver->playback_channels[chn].midi_output =
new JackFFADOMidiOutputPort();
549 driver->playback_channels[chn].midi_buffer = (uint32_t *)calloc(driver->period_size,
sizeof(uint32_t));
551 port = fGraphManager->GetPort(port_index);
552 range.
min = range.
max = (driver->period_size * (driver->device_options.nb_buffers - 1)) + ((fEngineControl->fSyncMode) ? 0 : fEngineControl->fBufferSize) + driver->playback_frame_latency;
553 port->SetLatencyRange(JackPlaybackLatency, &range);
554 fPlaybackPortList[chn] = port_index;
555 jack_log(
"JackFFADODriver::Attach fPlaybackPortList[i] %ld ", port_index);
558 printMessage (
"Don't register playback port %s", portname);
562 assert(fCaptureChannels < DRIVER_PORT_NUM);
563 assert(fPlaybackChannels < DRIVER_PORT_NUM);
565 if (ffado_streaming_prepare(driver->dev)) {
566 printError(
"Could not prepare streaming device!");
571 assert(fCaptureChannels + fPlaybackChannels > 0);
575 int JackFFADODriver::Detach()
579 jack_log(
"JackFFADODriver::Detach");
582 ffado_streaming_finish(driver->dev);
586 for (chn = 0; chn < driver->capture_nchannels; chn++) {
587 if (driver->capture_channels[chn].midi_buffer)
588 free(driver->capture_channels[chn].midi_buffer);
589 if (driver->capture_channels[chn].midi_input)
590 delete ((JackFFADOMidiInputPort *) (driver->capture_channels[chn].midi_input));
592 free(driver->capture_channels);
594 for (chn = 0; chn < driver->playback_nchannels; chn++) {
595 if (driver->playback_channels[chn].midi_buffer)
596 free(driver->playback_channels[chn].midi_buffer);
597 if (driver->playback_channels[chn].midi_output)
598 delete ((JackFFADOMidiOutputPort *) (driver->playback_channels[chn].midi_output));
600 free(driver->playback_channels);
602 free(driver->nullbuffer);
603 free(driver->scratchbuffer);
605 return JackAudioDriver::Detach();
611 if (JackAudioDriver::Open(
612 params->period_size, params->sample_rate,
613 params->playback_ports, params->playback_ports,
615 params->capture_frame_latency, params->playback_frame_latency) != 0) {
619 fDriver = (
jack_driver_t *)ffado_driver_new (
"ffado_pcm", params);
627 JackAudioDriver::Close();
632 int JackFFADODriver::Close()
635 int res = JackAudioDriver::Close();
641 int JackFFADODriver::Start()
643 int res = JackAudioDriver::Start();
647 JackAudioDriver::Stop();
653 int JackFFADODriver::Stop()
656 if (JackAudioDriver::Stop() < 0) {
662 int JackFFADODriver::Read()
673 jack_nframes_t nframes = ffado_driver_wait(driver, -1, &wait_status,
676 if ((wait_status < 0)) {
677 printError(
"wait status < 0! (= %d)", wait_status);
686 NotifyXRun(fBeginDateUst, fDelayedUsecs);
690 if (nframes != fEngineControl->fBufferSize)
691 jack_log(
"JackFFADODriver::Read warning nframes = %ld", nframes);
694 JackDriver::CycleIncTime();
697 return ffado_driver_read((
ffado_driver_t *)fDriver, fEngineControl->fBufferSize);
700 int JackFFADODriver::Write()
703 int res = ffado_driver_write((
ffado_driver_t *)fDriver, fEngineControl->fBufferSize);
711 memset (driver, 0,
sizeof (*driver));
717 driver->null_cycle = 0;
726 memset (driver, 0,
sizeof (*driver));
736 driver->nt_bufsize = 0;
737 driver->nt_start = 0;
739 driver->nt_attach = 0;
740 driver->nt_detach = 0;
741 driver->nt_run_cycle = 0;
753 driver_get_descriptor () {
758 desc = jack_driver_descriptor_construct(
"firewire", JackDriverMaster,
"Linux FFADO API based audio backend", &filler);
760 strcpy(value.str,
"hw:0");
761 jack_driver_descriptor_add_parameter(
766 JackDriverParamString,
769 "The FireWire device to use.",
770 "The FireWire device to use. Please consult the FFADO documentation for more info.");
773 jack_driver_descriptor_add_parameter(desc, &filler,
"period",
'p', JackDriverParamUInt, &value, NULL,
"Frames per period", NULL);
776 jack_driver_descriptor_add_parameter(desc, &filler,
"nperiods",
'n', JackDriverParamUInt, &value, NULL,
"Number of periods of playback latency", NULL);
779 jack_driver_descriptor_add_parameter(desc, &filler,
"rate",
'r', JackDriverParamUInt, &value, NULL,
"Sample rate", NULL);
782 jack_driver_descriptor_add_parameter(desc, &filler,
"capture",
'C', JackDriverParamBool, &value, NULL,
"Provide capture ports.", NULL);
783 jack_driver_descriptor_add_parameter(desc, &filler,
"playback",
'P', JackDriverParamBool, &value, NULL,
"Provide playback ports.", NULL);
786 jack_driver_descriptor_add_parameter(desc, &filler,
"duplex",
'D', JackDriverParamBool, &value, NULL,
"Provide both capture and playback ports.", NULL);
789 jack_driver_descriptor_add_parameter(desc, &filler,
"input-latency",
'I', JackDriverParamUInt, &value, NULL,
"Extra input latency (frames)", NULL);
790 jack_driver_descriptor_add_parameter(desc, &filler,
"output-latency",
'O', JackDriverParamUInt, &value, NULL,
"Extra output latency (frames)", NULL);
793 jack_driver_descriptor_add_parameter(desc, &filler,
"inchannels",
'i', JackDriverParamUInt, &value, NULL,
"Number of input channels to provide (note: currently ignored)", NULL);
794 jack_driver_descriptor_add_parameter(desc, &filler,
"outchannels",
'o', JackDriverParamUInt, &value, NULL,
"Number of output channels to provide (note: currently ignored)", NULL);
797 jack_driver_descriptor_add_parameter(desc, &filler,
"verbose",
'v', JackDriverParamUInt, &value, NULL,
"libffado verbose level", NULL);
800 jack_driver_descriptor_add_parameter(desc, &filler,
"snoop",
'X', JackDriverParamBool, &value, NULL,
"Snoop firewire traffic", NULL);
811 char *device_name=(
char*)
"hw:0";
813 cmlparams.period_size_set = 0;
814 cmlparams.sample_rate_set = 0;
815 cmlparams.buffer_size_set = 0;
818 cmlparams.period_size = 1024;
819 cmlparams.sample_rate = 48000;
820 cmlparams.buffer_size = 3;
821 cmlparams.playback_ports = 0;
822 cmlparams.capture_ports = 0;
823 cmlparams.playback_frame_latency = 0;
824 cmlparams.capture_frame_latency = 0;
826 cmlparams.verbose_level = 0;
828 cmlparams.slave_mode = 0;
829 cmlparams.snoop_mode = 0;
830 cmlparams.device_info = NULL;
832 for (node = params; node; node = jack_slist_next (node)) {
835 switch (param->character) {
837 device_name =
const_cast<char*
>(param->value.str);
840 cmlparams.period_size = param->value.ui;
841 cmlparams.period_size_set = 1;
844 cmlparams.buffer_size = param->value.ui;
845 cmlparams.buffer_size_set = 1;
848 cmlparams.sample_rate = param->value.ui;
849 cmlparams.sample_rate_set = 1;
852 cmlparams.capture_ports = param->value.ui;
855 cmlparams.playback_ports = param->value.ui;
858 cmlparams.capture_frame_latency = param->value.ui;
861 cmlparams.playback_frame_latency = param->value.ui;
864 cmlparams.slave_mode = param->value.ui;
867 cmlparams.snoop_mode = param->value.i;
870 cmlparams.verbose_level = param->value.ui;
875 if (!cmlparams.playback_ports && !cmlparams.capture_ports) {
876 cmlparams.playback_ports = 1;
877 cmlparams.capture_ports = 1;
881 cmlparams.device_info = device_name;
886 if (ffado_driver->Open(&cmlparams) == 0) {
887 return threaded_driver;
889 delete threaded_driver;