00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <iostream>
00025 #include <unistd.h>
00026 #include <math.h>
00027 #include <stdio.h>
00028 #include <memory.h>
00029 #include <unistd.h>
00030 #include <stdlib.h>
00031 #include <errno.h>
00032 #include <stdarg.h>
00033 #include <signal.h>
00034 #include <sys/types.h>
00035 #include <sys/time.h>
00036 #include <regex.h>
00037 #include <string.h>
00038
00039 #include "JackFFADODriver.h"
00040 #include "JackFFADOMidiInputPort.h"
00041 #include "JackFFADOMidiOutputPort.h"
00042 #include "JackEngineControl.h"
00043 #include "JackClientControl.h"
00044 #include "JackPort.h"
00045 #include "JackGraphManager.h"
00046 #include "JackCompilerDeps.h"
00047 #include "JackLockedEngine.h"
00048
00049
00050
00051 #ifndef FFADO_API_VERSION
00052 extern "C" int ffado_streaming_set_period_size(ffado_device_t *dev,
00053 unsigned int period) __attribute__((__weak__));
00054 #endif
00055
00056 namespace Jack
00057 {
00058
00059
00060
00061 #define FIREWIRE_REQUIRED_FFADO_API_VERSION 8
00062 #define FIREWIRE_REQUIRED_FFADO_API_VERSION_FOR_SETBUFSIZE 9
00063
00064 #define jack_get_microseconds GetMicroSeconds
00065
00066 int
00067 JackFFADODriver::ffado_driver_read (ffado_driver_t * driver, jack_nframes_t nframes)
00068 {
00069 channel_t chn;
00070 jack_default_audio_sample_t* buf = NULL;
00071
00072 printEnter();
00073 for (chn = 0; chn < driver->capture_nchannels; chn++) {
00074
00075 if (fGraphManager->GetConnectionsNum(fCapturePortList[chn]) == 0) {
00076 buf = (jack_default_audio_sample_t*)driver->scratchbuffer;
00077
00078 ffado_streaming_set_capture_stream_buffer(driver->dev, chn, (char *)(buf));
00079
00080
00081 ffado_streaming_capture_stream_onoff(driver->dev, chn, 0);
00082 } else {
00083 if (driver->capture_channels[chn].stream_type == ffado_stream_type_audio) {
00084 buf = (jack_default_audio_sample_t*)fGraphManager->GetBuffer(fCapturePortList[chn], nframes);
00085
00086
00087 if (!buf) buf = (jack_default_audio_sample_t*)driver->scratchbuffer;
00088
00089 ffado_streaming_set_capture_stream_buffer(driver->dev, chn, (char *)(buf));
00090 ffado_streaming_capture_stream_onoff(driver->dev, chn, 1);
00091 } else if (driver->capture_channels[chn].stream_type == ffado_stream_type_midi) {
00092 ffado_streaming_set_capture_stream_buffer(driver->dev, chn,
00093 (char *)(driver->capture_channels[chn].midi_buffer));
00094 ffado_streaming_capture_stream_onoff(driver->dev, chn, 1);
00095 } else {
00096 ffado_streaming_set_capture_stream_buffer(driver->dev, chn, (char *)(driver->scratchbuffer));
00097
00098 ffado_streaming_capture_stream_onoff(driver->dev, chn, 0);
00099 }
00100 }
00101 }
00102
00103
00104 ffado_streaming_transfer_capture_buffers(driver->dev);
00105
00106
00107 for (chn = 0; chn < driver->capture_nchannels; chn++) {
00108 if (driver->capture_channels[chn].stream_type == ffado_stream_type_midi) {
00109 JackFFADOMidiInputPort *midi_input = (JackFFADOMidiInputPort *) driver->capture_channels[chn].midi_input;
00110 JackMidiBuffer *buffer = (JackMidiBuffer *) fGraphManager->GetBuffer(fCapturePortList[chn], nframes);
00111 midi_input->Process(buffer, driver->capture_channels[chn].midi_buffer, nframes);
00112 }
00113 }
00114
00115 printExit();
00116 return 0;
00117 }
00118
00119 int
00120 JackFFADODriver::ffado_driver_write (ffado_driver_t * driver, jack_nframes_t nframes)
00121 {
00122 channel_t chn;
00123 jack_default_audio_sample_t* buf;
00124 printEnter();
00125
00126 driver->process_count++;
00127
00128 for (chn = 0; chn < driver->playback_nchannels; chn++) {
00129 if (fGraphManager->GetConnectionsNum(fPlaybackPortList[chn]) == 0) {
00130 buf = (jack_default_audio_sample_t*)driver->nullbuffer;
00131
00132 ffado_streaming_set_playback_stream_buffer(driver->dev, chn, (char *)(buf));
00133
00134
00135 ffado_streaming_playback_stream_onoff(driver->dev, chn, 0);
00136 } else {
00137 if (driver->playback_channels[chn].stream_type == ffado_stream_type_audio) {
00138 buf = (jack_default_audio_sample_t*)fGraphManager->GetBuffer(fPlaybackPortList[chn], nframes);
00139
00140 if (!buf) buf = (jack_default_audio_sample_t*)driver->nullbuffer;
00141 ffado_streaming_set_playback_stream_buffer(driver->dev, chn, (char *)(buf));
00142 ffado_streaming_playback_stream_onoff(driver->dev, chn, 1);
00143 } else if (driver->playback_channels[chn].stream_type == ffado_stream_type_midi) {
00144 uint32_t *midi_buffer = driver->playback_channels[chn].midi_buffer;
00145 memset(midi_buffer, 0, nframes * sizeof(uint32_t));
00146 buf = (jack_default_audio_sample_t *) fGraphManager->GetBuffer(fPlaybackPortList[chn], nframes);
00147 ffado_streaming_set_playback_stream_buffer(driver->dev, chn, (char *)(midi_buffer));
00148 ffado_streaming_playback_stream_onoff(driver->dev, chn, buf ? 1 : 0);
00149 JackFFADOMidiOutputPort *midi_output = (JackFFADOMidiOutputPort *) driver->playback_channels[chn].midi_output;
00150 midi_output->Process((JackMidiBuffer *) buf, midi_buffer, nframes);
00151
00152 } else {
00153 ffado_streaming_set_playback_stream_buffer(driver->dev, chn, (char *)(driver->nullbuffer));
00154 ffado_streaming_playback_stream_onoff(driver->dev, chn, 0);
00155 }
00156 }
00157 }
00158 ffado_streaming_transfer_playback_buffers(driver->dev);
00159 printExit();
00160 return 0;
00161 }
00162
00163 jack_nframes_t
00164 JackFFADODriver::ffado_driver_wait (ffado_driver_t *driver, int extra_fd, int *status,
00165 float *delayed_usecs)
00166 {
00167 jack_time_t wait_enter;
00168 jack_time_t wait_ret;
00169 ffado_wait_response response;
00170
00171 printEnter();
00172
00173 wait_enter = jack_get_microseconds ();
00174 if (wait_enter > driver->wait_next) {
00175
00176
00177
00178
00179
00180 driver->wait_next = 0;
00181 driver->wait_late++;
00182 }
00183
00184
00185
00186
00187 response = ffado_streaming_wait(driver->dev);
00188
00189 wait_ret = jack_get_microseconds ();
00190
00191 if (driver->wait_next && wait_ret > driver->wait_next) {
00192 *delayed_usecs = wait_ret - driver->wait_next;
00193 }
00194 driver->wait_last = wait_ret;
00195 driver->wait_next = wait_ret + driver->period_usecs;
00196
00197
00198 if(response == ffado_wait_ok) {
00199
00200 *status = 0;
00201 } else if (response == ffado_wait_xrun) {
00202
00203 *status = 0;
00204 return 0;
00205 } else if (response == ffado_wait_error) {
00206
00207
00208 jack_error("JackFFADODriver::ffado_driver_wait - unhandled xrun");
00209 *status = -1;
00210 return 0;
00211 } else if (response == ffado_wait_shutdown) {
00212
00213
00214 jack_error("JackFFADODriver::ffado_driver_wait - shutdown requested "
00215 "(device unplugged?)");
00216 *status = -1;
00217 return 0;
00218 } else {
00219
00220
00221 jack_error("JackFFADODriver::ffado_driver_wait - unexpected error "
00222 "code '%d' returned from 'ffado_streaming_wait'", response);
00223 *status = -1;
00224 return 0;
00225 }
00226
00227 fBeginDateUst = wait_ret;
00228
00229 printExit();
00230 return driver->period_size;
00231 }
00232
00233 int
00234 JackFFADODriver::ffado_driver_start (ffado_driver_t *driver)
00235 {
00236 int retval = 0;
00237
00238 if ((retval = ffado_streaming_start(driver->dev))) {
00239 printError("Could not start streaming threads");
00240
00241 return retval;
00242 }
00243 return 0;
00244 }
00245
00246 int
00247 JackFFADODriver::ffado_driver_stop (ffado_driver_t *driver)
00248 {
00249 int retval = 0;
00250
00251 if ((retval = ffado_streaming_stop(driver->dev))) {
00252 printError("Could not stop streaming threads");
00253 return retval;
00254 }
00255
00256 return 0;
00257 }
00258
00259 int
00260 JackFFADODriver::ffado_driver_restart (ffado_driver_t *driver)
00261 {
00262 if (Stop())
00263 return -1;
00264 return Start();
00265 }
00266
00267 void
00268 JackFFADODriver::UpdateLatencies(void)
00269 {
00270 jack_latency_range_t range;
00271 ffado_driver_t* driver = (ffado_driver_t*)fDriver;
00272
00273 for (int i = 0; i < fCaptureChannels; i++) {
00274 range.min = range.max = driver->period_size + driver->capture_frame_latency;
00275 fGraphManager->GetPort(fCapturePortList[i])->SetLatencyRange(JackCaptureLatency, &range);
00276 }
00277
00278 for (int i = 0; i < fPlaybackChannels; i++) {
00279
00280 range.min = range.max = (driver->period_size *
00281 (driver->device_options.nb_buffers - 1)) +
00282 ((fEngineControl->fSyncMode) ? 0 : fEngineControl->fBufferSize) + driver->playback_frame_latency;
00283 fGraphManager->GetPort(fPlaybackPortList[i])->SetLatencyRange(JackPlaybackLatency, &range);
00284
00285 if (fWithMonitorPorts) {
00286 range.min = range.max =driver->period_size;
00287 fGraphManager->GetPort(fMonitorPortList[i])->SetLatencyRange(JackCaptureLatency, &range);
00288 }
00289 }
00290 }
00291
00292 int
00293 JackFFADODriver::SetBufferSize (jack_nframes_t nframes)
00294 {
00295 ffado_driver_t* driver = (ffado_driver_t*)fDriver;
00296 signed int chn;
00297
00298
00299
00300 if (ffado_get_api_version() < FIREWIRE_REQUIRED_FFADO_API_VERSION_FOR_SETBUFSIZE ||
00301 ffado_streaming_set_period_size == NULL) {
00302 printError("unsupported on current version of FFADO; please upgrade FFADO");
00303 return -1;
00304 }
00305
00306 driver->period_size = nframes;
00307 driver->period_usecs =
00308 (jack_time_t) floor ((((float) nframes) / driver->sample_rate)
00309 * 1000000.0f);
00310
00311
00312
00313 driver->nullbuffer = (ffado_sample_t*) calloc(driver->period_size, sizeof(ffado_sample_t));
00314 if(driver->nullbuffer == NULL) {
00315 printError("could not allocate memory for null buffer");
00316 return -1;
00317 }
00318 driver->scratchbuffer = (ffado_sample_t*) calloc(driver->period_size, sizeof(ffado_sample_t));
00319 if(driver->scratchbuffer == NULL) {
00320 printError("could not allocate memory for scratch buffer");
00321 return -1;
00322 }
00323
00324
00325 for (chn = 0; chn < driver->capture_nchannels; chn++) {
00326 if(driver->capture_channels[chn].stream_type == ffado_stream_type_midi) {
00327
00328 if (driver->capture_channels[chn].midi_buffer != NULL)
00329 free(driver->capture_channels[chn].midi_buffer);
00330 driver->capture_channels[chn].midi_buffer = (ffado_sample_t*) calloc(driver->period_size, sizeof(uint32_t));
00331 }
00332 }
00333 for (chn = 0; chn < driver->playback_nchannels; chn++) {
00334 if(driver->playback_channels[chn].stream_type == ffado_stream_type_midi) {
00335 if (driver->playback_channels[chn].midi_buffer != NULL)
00336 free(driver->playback_channels[chn].midi_buffer);
00337 driver->playback_channels[chn].midi_buffer = (ffado_sample_t*) calloc(driver->period_size, sizeof(uint32_t));
00338 }
00339 }
00340
00341
00342 if (ffado_streaming_set_period_size(driver->dev, nframes) != 0) {
00343 printError("could not alter FFADO device period size");
00344 return -1;
00345 }
00346
00347
00348
00349 sleep(1);
00350
00351
00352 JackAudioDriver::SetBufferSize(nframes);
00353
00354 UpdateLatencies();
00355
00356 return 0;
00357 }
00358
00359 typedef void (*JackDriverFinishFunction) (jack_driver_t *);
00360
00361 ffado_driver_t *
00362 JackFFADODriver::ffado_driver_new (const char *name,
00363 ffado_jack_settings_t *params)
00364 {
00365 ffado_driver_t *driver;
00366
00367 assert(params);
00368
00369 if (ffado_get_api_version() < FIREWIRE_REQUIRED_FFADO_API_VERSION) {
00370 printError("Incompatible libffado version! (%s)", ffado_get_version());
00371 return NULL;
00372 }
00373
00374 printMessage("Starting FFADO backend (%s)", ffado_get_version());
00375
00376 driver = (ffado_driver_t*)calloc (1, sizeof (ffado_driver_t));
00377
00378
00379 jack_driver_nt_init ((jack_driver_nt_t *) driver);
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393 memcpy(&driver->settings, params, sizeof(ffado_jack_settings_t));
00394
00395
00396 driver->sample_rate = params->sample_rate;
00397 driver->period_size = params->period_size;
00398 fBeginDateUst = 0;
00399
00400 driver->period_usecs =
00401 (jack_time_t) floor ((((float) driver->period_size) * 1000000.0f) / driver->sample_rate);
00402
00403
00404 driver->engine = NULL;
00405
00406 memset(&driver->device_options, 0, sizeof(driver->device_options));
00407 driver->device_options.sample_rate = params->sample_rate;
00408 driver->device_options.period_size = params->period_size;
00409 driver->device_options.nb_buffers = params->buffer_size;
00410 driver->device_options.verbose = params->verbose_level;
00411 driver->capture_frame_latency = params->capture_frame_latency;
00412 driver->playback_frame_latency = params->playback_frame_latency;
00413 driver->device_options.snoop_mode = params->snoop_mode;
00414
00415 debugPrint(DEBUG_LEVEL_STARTUP, " Driver compiled on %s %s", __DATE__, __TIME__);
00416 debugPrint(DEBUG_LEVEL_STARTUP, " Created driver %s", name);
00417 debugPrint(DEBUG_LEVEL_STARTUP, " period_size: %d", driver->device_options.period_size);
00418 debugPrint(DEBUG_LEVEL_STARTUP, " period_usecs: %d", driver->period_usecs);
00419 debugPrint(DEBUG_LEVEL_STARTUP, " sample rate: %d", driver->device_options.sample_rate);
00420 debugPrint(DEBUG_LEVEL_STARTUP, " verbose level: %d", driver->device_options.verbose);
00421
00422 return (ffado_driver_t *) driver;
00423 }
00424
00425 void
00426 JackFFADODriver::ffado_driver_delete (ffado_driver_t *driver)
00427 {
00428 free (driver);
00429 }
00430
00431 int JackFFADODriver::Attach()
00432 {
00433 JackPort* port;
00434 jack_port_id_t port_index;
00435 char buf[REAL_JACK_PORT_NAME_SIZE];
00436 char portname[REAL_JACK_PORT_NAME_SIZE];
00437
00438 ffado_driver_t* driver = (ffado_driver_t*)fDriver;
00439
00440 jack_log("JackFFADODriver::Attach fBufferSize %ld fSampleRate %ld", fEngineControl->fBufferSize, fEngineControl->fSampleRate);
00441
00442 g_verbose = (fEngineControl->fVerbose ? 1 : 0);
00443
00444
00445
00446
00447
00448 driver->nullbuffer = (ffado_sample_t *)calloc(driver->period_size, sizeof(ffado_sample_t));
00449 if (driver->nullbuffer == NULL) {
00450 printError("could not allocate memory for null buffer");
00451 return -1;
00452 }
00453
00454 memset(driver->nullbuffer, 0, driver->period_size*sizeof(ffado_sample_t));
00455
00456
00457 driver->scratchbuffer = (ffado_sample_t *)calloc(driver->period_size, sizeof(ffado_sample_t));
00458 if (driver->scratchbuffer == NULL) {
00459 printError("could not allocate memory for scratch buffer");
00460 return -1;
00461 }
00462
00463
00464 driver->device_options.realtime = (fEngineControl->fRealTime ? 1 : 0);
00465
00466 driver->device_options.packetizer_priority = fEngineControl->fServerPriority +
00467 FFADO_RT_PRIORITY_PACKETIZER_RELATIVE;
00468 if (driver->device_options.packetizer_priority > 98) {
00469 driver->device_options.packetizer_priority = 98;
00470 }
00471
00472
00473 driver->dev = ffado_streaming_init(driver->device_info, driver->device_options);
00474
00475 if (!driver->dev) {
00476 printError("FFADO: Error creating virtual device");
00477 return -1;
00478 }
00479
00480 if (driver->device_options.realtime) {
00481 printMessage("Streaming thread running with Realtime scheduling, priority %d",
00482 driver->device_options.packetizer_priority);
00483 } else {
00484 printMessage("Streaming thread running without Realtime scheduling");
00485 }
00486
00487 ffado_streaming_set_audio_datatype(driver->dev, ffado_audio_datatype_float);
00488
00489
00490
00491
00492 driver->capture_nchannels = ffado_streaming_get_nb_capture_streams(driver->dev);
00493 driver->capture_channels = (ffado_capture_channel_t *)calloc(driver->capture_nchannels, sizeof(ffado_capture_channel_t));
00494 if (driver->capture_channels == NULL) {
00495 printError("could not allocate memory for capture channel list");
00496 return -1;
00497 }
00498
00499 fCaptureChannels = 0;
00500 for (channel_t chn = 0; chn < driver->capture_nchannels; chn++) {
00501 ffado_streaming_get_capture_stream_name(driver->dev, chn, portname, sizeof(portname));
00502
00503 driver->capture_channels[chn].stream_type = ffado_streaming_get_capture_stream_type(driver->dev, chn);
00504 if (driver->capture_channels[chn].stream_type == ffado_stream_type_audio) {
00505 snprintf(buf, sizeof(buf), "firewire_pcm:%s_in", portname);
00506 printMessage ("Registering audio capture port %s", buf);
00507 if (fEngine->PortRegister(fClientControl.fRefNum, buf,
00508 JACK_DEFAULT_AUDIO_TYPE,
00509 CaptureDriverFlags,
00510 fEngineControl->fBufferSize, &port_index) < 0) {
00511 jack_error("driver: cannot register port for %s", buf);
00512 return -1;
00513 }
00514
00515
00516 if (ffado_streaming_set_capture_stream_buffer(driver->dev, chn, NULL)) {
00517 printError(" cannot configure initial port buffer for %s", buf);
00518 }
00519 ffado_streaming_capture_stream_onoff(driver->dev, chn, 0);
00520
00521 port = fGraphManager->GetPort(port_index);
00522
00523 snprintf(buf, sizeof(buf), "%s:capture_%i", fClientControl.fName, (int) chn + 1);
00524 port->SetAlias(buf);
00525 fCapturePortList[chn] = port_index;
00526 jack_log("JackFFADODriver::Attach fCapturePortList[i] %ld ", port_index);
00527 fCaptureChannels++;
00528 } else if (driver->capture_channels[chn].stream_type == ffado_stream_type_midi) {
00529 snprintf(buf, sizeof(buf), "firewire_pcm:%s_in", portname);
00530 printMessage ("Registering midi capture port %s", buf);
00531 if (fEngine->PortRegister(fClientControl.fRefNum, buf,
00532 JACK_DEFAULT_MIDI_TYPE,
00533 CaptureDriverFlags,
00534 fEngineControl->fBufferSize, &port_index) < 0) {
00535 jack_error("driver: cannot register port for %s", buf);
00536 return -1;
00537 }
00538
00539
00540 if (ffado_streaming_set_capture_stream_buffer(driver->dev, chn, NULL)) {
00541 printError(" cannot configure initial port buffer for %s", buf);
00542 }
00543 if (ffado_streaming_capture_stream_onoff(driver->dev, chn, 0)) {
00544 printError(" cannot enable port %s", buf);
00545 }
00546
00547 driver->capture_channels[chn].midi_input = new JackFFADOMidiInputPort();
00548
00549 driver->capture_channels[chn].midi_buffer = (uint32_t *)calloc(driver->period_size, sizeof(uint32_t));
00550
00551 fCapturePortList[chn] = port_index;
00552 jack_log("JackFFADODriver::Attach fCapturePortList[i] %ld ", port_index);
00553 fCaptureChannels++;
00554 } else {
00555 printMessage ("Don't register capture port %s", portname);
00556 }
00557 }
00558
00559
00560 driver->playback_nchannels = ffado_streaming_get_nb_playback_streams(driver->dev);
00561 driver->playback_channels = (ffado_playback_channel_t *)calloc(driver->playback_nchannels, sizeof(ffado_playback_channel_t));
00562 if (driver->playback_channels == NULL) {
00563 printError("could not allocate memory for playback channel list");
00564 return -1;
00565 }
00566
00567 fPlaybackChannels = 0;
00568 for (channel_t chn = 0; chn < driver->playback_nchannels; chn++) {
00569 ffado_streaming_get_playback_stream_name(driver->dev, chn, portname, sizeof(portname));
00570
00571 driver->playback_channels[chn].stream_type = ffado_streaming_get_playback_stream_type(driver->dev, chn);
00572
00573 if (driver->playback_channels[chn].stream_type == ffado_stream_type_audio) {
00574 snprintf(buf, sizeof(buf), "firewire_pcm:%s_out", portname);
00575 printMessage ("Registering audio playback port %s", buf);
00576 if (fEngine->PortRegister(fClientControl.fRefNum, buf,
00577 JACK_DEFAULT_AUDIO_TYPE,
00578 PlaybackDriverFlags,
00579 fEngineControl->fBufferSize, &port_index) < 0) {
00580 jack_error("driver: cannot register port for %s", buf);
00581 return -1;
00582 }
00583
00584
00585 if (ffado_streaming_set_playback_stream_buffer(driver->dev, chn, NULL)) {
00586 printError(" cannot configure initial port buffer for %s", buf);
00587 }
00588 if (ffado_streaming_playback_stream_onoff(driver->dev, chn, 0)) {
00589 printError(" cannot enable port %s", buf);
00590 }
00591
00592 port = fGraphManager->GetPort(port_index);
00593
00594
00595 snprintf(buf, sizeof(buf), "%s:playback_%i", fClientControl.fName, (int) chn + 1);
00596 port->SetAlias(buf);
00597 fPlaybackPortList[chn] = port_index;
00598 jack_log("JackFFADODriver::Attach fPlaybackPortList[i] %ld ", port_index);
00599 fPlaybackChannels++;
00600 } else if (driver->playback_channels[chn].stream_type == ffado_stream_type_midi) {
00601 snprintf(buf, sizeof(buf), "firewire_pcm:%s_out", portname);
00602 printMessage ("Registering midi playback port %s", buf);
00603
00604 if (fEngine->PortRegister(fClientControl.fRefNum, buf,
00605 JACK_DEFAULT_MIDI_TYPE,
00606 PlaybackDriverFlags,
00607 fEngineControl->fBufferSize, &port_index) < 0) {
00608 jack_error("driver: cannot register port for %s", buf);
00609 return -1;
00610 }
00611
00612
00613 if (ffado_streaming_set_playback_stream_buffer(driver->dev, chn, NULL)) {
00614 printError(" cannot configure initial port buffer for %s", buf);
00615 }
00616 if (ffado_streaming_playback_stream_onoff(driver->dev, chn, 0)) {
00617 printError(" cannot enable port %s", buf);
00618 }
00619
00620
00621
00622
00623
00624 driver->playback_channels[chn].midi_output = new JackFFADOMidiOutputPort();
00625
00626 driver->playback_channels[chn].midi_buffer = (uint32_t *)calloc(driver->period_size, sizeof(uint32_t));
00627
00628 fPlaybackPortList[chn] = port_index;
00629 jack_log("JackFFADODriver::Attach fPlaybackPortList[i] %ld ", port_index);
00630 fPlaybackChannels++;
00631 } else {
00632 printMessage ("Don't register playback port %s", portname);
00633 }
00634 }
00635
00636 UpdateLatencies();
00637
00638 assert(fCaptureChannels < DRIVER_PORT_NUM);
00639 assert(fPlaybackChannels < DRIVER_PORT_NUM);
00640
00641 if (ffado_streaming_prepare(driver->dev)) {
00642 printError("Could not prepare streaming device!");
00643 return -1;
00644 }
00645
00646
00647 assert(fCaptureChannels + fPlaybackChannels > 0);
00648 return 0;
00649 }
00650
00651 int JackFFADODriver::Detach()
00652 {
00653 channel_t chn;
00654 ffado_driver_t* driver = (ffado_driver_t*)fDriver;
00655 jack_log("JackFFADODriver::Detach");
00656
00657
00658 ffado_streaming_finish(driver->dev);
00659 driver->dev = NULL;
00660
00661
00662 for (chn = 0; chn < driver->capture_nchannels; chn++) {
00663 if (driver->capture_channels[chn].midi_buffer)
00664 free(driver->capture_channels[chn].midi_buffer);
00665 if (driver->capture_channels[chn].midi_input)
00666 delete ((JackFFADOMidiInputPort *) (driver->capture_channels[chn].midi_input));
00667 }
00668 free(driver->capture_channels);
00669
00670 for (chn = 0; chn < driver->playback_nchannels; chn++) {
00671 if (driver->playback_channels[chn].midi_buffer)
00672 free(driver->playback_channels[chn].midi_buffer);
00673 if (driver->playback_channels[chn].midi_output)
00674 delete ((JackFFADOMidiOutputPort *) (driver->playback_channels[chn].midi_output));
00675 }
00676 free(driver->playback_channels);
00677
00678 free(driver->nullbuffer);
00679 free(driver->scratchbuffer);
00680
00681 return JackAudioDriver::Detach();
00682 }
00683
00684 int JackFFADODriver::Open(ffado_jack_settings_t *params)
00685 {
00686
00687 if (JackAudioDriver::Open(
00688 params->period_size, params->sample_rate,
00689 params->playback_ports, params->playback_ports,
00690 0, 0, 0, "", "",
00691 params->capture_frame_latency, params->playback_frame_latency) != 0) {
00692 return -1;
00693 }
00694
00695 fDriver = (jack_driver_t *)ffado_driver_new ("ffado_pcm", params);
00696
00697 if (fDriver) {
00698
00699
00700
00701 return 0;
00702 } else {
00703 JackAudioDriver::Close();
00704 return -1;
00705 }
00706 }
00707
00708 int JackFFADODriver::Close()
00709 {
00710
00711 int res = JackAudioDriver::Close();
00712
00713 ffado_driver_delete((ffado_driver_t*)fDriver);
00714 return res;
00715 }
00716
00717 int JackFFADODriver::Start()
00718 {
00719 int res = JackAudioDriver::Start();
00720 if (res >= 0) {
00721 res = ffado_driver_start((ffado_driver_t *)fDriver);
00722 if (res < 0) {
00723 JackAudioDriver::Stop();
00724 }
00725 }
00726 return res;
00727 }
00728
00729 int JackFFADODriver::Stop()
00730 {
00731 int res = ffado_driver_stop((ffado_driver_t *)fDriver);
00732 if (JackAudioDriver::Stop() < 0) {
00733 res = -1;
00734 }
00735 return res;
00736 }
00737
00738 int JackFFADODriver::Read()
00739 {
00740 printEnter();
00741
00742
00743 ffado_driver_t* driver = (ffado_driver_t*)fDriver;
00744 int wait_status = 0;
00745 fDelayedUsecs = 0.f;
00746
00747 retry:
00748
00749 jack_nframes_t nframes = ffado_driver_wait(driver, -1, &wait_status,
00750 &fDelayedUsecs);
00751
00752 if ((wait_status < 0)) {
00753 printError( "wait status < 0! (= %d)", wait_status);
00754 return -1;
00755 }
00756
00757 if (nframes == 0) {
00758
00759
00760
00761 jack_log("FFADO XRun");
00762 NotifyXRun(fBeginDateUst, fDelayedUsecs);
00763 goto retry;
00764 }
00765
00766 if (nframes != fEngineControl->fBufferSize)
00767 jack_log("JackFFADODriver::Read warning nframes = %ld", nframes);
00768
00769
00770 JackDriver::CycleIncTime();
00771
00772 printExit();
00773 return ffado_driver_read((ffado_driver_t *)fDriver, fEngineControl->fBufferSize);
00774 }
00775
00776 int JackFFADODriver::Write()
00777 {
00778 printEnter();
00779 int res = ffado_driver_write((ffado_driver_t *)fDriver, fEngineControl->fBufferSize);
00780 printExit();
00781 return res;
00782 }
00783
00784 void
00785 JackFFADODriver::jack_driver_init (jack_driver_t *driver)
00786 {
00787 memset (driver, 0, sizeof (*driver));
00788
00789 driver->attach = 0;
00790 driver->detach = 0;
00791 driver->write = 0;
00792 driver->read = 0;
00793 driver->null_cycle = 0;
00794 driver->bufsize = 0;
00795 driver->start = 0;
00796 driver->stop = 0;
00797 }
00798
00799 void
00800 JackFFADODriver::jack_driver_nt_init (jack_driver_nt_t * driver)
00801 {
00802 memset (driver, 0, sizeof (*driver));
00803
00804 jack_driver_init ((jack_driver_t *) driver);
00805
00806 driver->attach = 0;
00807 driver->detach = 0;
00808 driver->bufsize = 0;
00809 driver->stop = 0;
00810 driver->start = 0;
00811
00812 driver->nt_bufsize = 0;
00813 driver->nt_start = 0;
00814 driver->nt_stop = 0;
00815 driver->nt_attach = 0;
00816 driver->nt_detach = 0;
00817 driver->nt_run_cycle = 0;
00818 }
00819
00820 }
00821
00822
00823 #ifdef __cplusplus
00824 extern "C"
00825 {
00826 #endif
00827
00828 SERVER_EXPORT const jack_driver_desc_t *
00829 driver_get_descriptor () {
00830 jack_driver_desc_t * desc;
00831 jack_driver_desc_filler_t filler;
00832 jack_driver_param_value_t value;
00833
00834 desc = jack_driver_descriptor_construct("firewire", JackDriverMaster, "Linux FFADO API based audio backend", &filler);
00835
00836 strcpy(value.str, "hw:0");
00837 jack_driver_descriptor_add_parameter(
00838 desc,
00839 &filler,
00840 "device",
00841 'd',
00842 JackDriverParamString,
00843 &value,
00844 NULL,
00845 "The FireWire device to use.",
00846 "The FireWire device to use. Please consult the FFADO documentation for more info.");
00847
00848 value.ui = 1024;
00849 jack_driver_descriptor_add_parameter(desc, &filler, "period", 'p', JackDriverParamUInt, &value, NULL, "Frames per period", NULL);
00850
00851 value.ui = 3;
00852 jack_driver_descriptor_add_parameter(desc, &filler, "nperiods", 'n', JackDriverParamUInt, &value, NULL, "Number of periods of playback latency", NULL);
00853
00854 value.ui = 48000U;
00855 jack_driver_descriptor_add_parameter(desc, &filler, "rate", 'r', JackDriverParamUInt, &value, NULL, "Sample rate", NULL);
00856
00857 value.i = 0;
00858 jack_driver_descriptor_add_parameter(desc, &filler, "capture", 'C', JackDriverParamBool, &value, NULL, "Provide capture ports.", NULL);
00859 jack_driver_descriptor_add_parameter(desc, &filler, "playback", 'P', JackDriverParamBool, &value, NULL, "Provide playback ports.", NULL);
00860
00861 value.i = 1;
00862 jack_driver_descriptor_add_parameter(desc, &filler, "duplex", 'D', JackDriverParamBool, &value, NULL, "Provide both capture and playback ports.", NULL);
00863
00864 value.ui = 0;
00865 jack_driver_descriptor_add_parameter(desc, &filler, "input-latency", 'I', JackDriverParamUInt, &value, NULL, "Extra input latency (frames)", NULL);
00866 jack_driver_descriptor_add_parameter(desc, &filler, "output-latency", 'O', JackDriverParamUInt, &value, NULL, "Extra output latency (frames)", NULL);
00867
00868 value.ui = 0;
00869 jack_driver_descriptor_add_parameter(desc, &filler, "inchannels", 'i', JackDriverParamUInt, &value, NULL, "Number of input channels to provide (note: currently ignored)", NULL);
00870 jack_driver_descriptor_add_parameter(desc, &filler, "outchannels", 'o', JackDriverParamUInt, &value, NULL, "Number of output channels to provide (note: currently ignored)", NULL);
00871
00872 value.ui = 3;
00873 jack_driver_descriptor_add_parameter(desc, &filler, "verbose", 'v', JackDriverParamUInt, &value, NULL, "libffado verbose level", NULL);
00874
00875 value.i = 0;
00876 jack_driver_descriptor_add_parameter(desc, &filler, "snoop", 'X', JackDriverParamBool, &value, NULL, "Snoop firewire traffic", NULL);
00877
00878 return desc;
00879 }
00880
00881 SERVER_EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLockedEngine* engine, Jack::JackSynchro* table, const JSList* params) {
00882 const JSList * node;
00883 const jack_driver_param_t * param;
00884
00885 ffado_jack_settings_t cmlparams;
00886
00887 char *device_name=(char*)"hw:0";
00888
00889 cmlparams.period_size_set = 0;
00890 cmlparams.sample_rate_set = 0;
00891 cmlparams.buffer_size_set = 0;
00892
00893
00894 cmlparams.period_size = 1024;
00895 cmlparams.sample_rate = 48000;
00896 cmlparams.buffer_size = 3;
00897 cmlparams.playback_ports = 0;
00898 cmlparams.capture_ports = 0;
00899 cmlparams.playback_frame_latency = 0;
00900 cmlparams.capture_frame_latency = 0;
00901
00902 cmlparams.verbose_level = 0;
00903
00904 cmlparams.slave_mode = 0;
00905 cmlparams.snoop_mode = 0;
00906 cmlparams.device_info = NULL;
00907
00908 for (node = params; node; node = jack_slist_next (node)) {
00909 param = (jack_driver_param_t *) node->data;
00910
00911 switch (param->character) {
00912 case 'd':
00913 device_name = const_cast<char*>(param->value.str);
00914 break;
00915 case 'p':
00916 cmlparams.period_size = param->value.ui;
00917 cmlparams.period_size_set = 1;
00918 break;
00919 case 'n':
00920 cmlparams.buffer_size = param->value.ui;
00921 cmlparams.buffer_size_set = 1;
00922 break;
00923 case 'r':
00924 cmlparams.sample_rate = param->value.ui;
00925 cmlparams.sample_rate_set = 1;
00926 break;
00927 case 'i':
00928 cmlparams.capture_ports = param->value.ui;
00929 break;
00930 case 'o':
00931 cmlparams.playback_ports = param->value.ui;
00932 break;
00933 case 'I':
00934 cmlparams.capture_frame_latency = param->value.ui;
00935 break;
00936 case 'O':
00937 cmlparams.playback_frame_latency = param->value.ui;
00938 break;
00939 case 'x':
00940 cmlparams.slave_mode = param->value.ui;
00941 break;
00942 case 'X':
00943 cmlparams.snoop_mode = param->value.i;
00944 break;
00945 case 'v':
00946 cmlparams.verbose_level = param->value.ui;
00947 }
00948 }
00949
00950
00951 if (!cmlparams.playback_ports && !cmlparams.capture_ports) {
00952 cmlparams.playback_ports = 1;
00953 cmlparams.capture_ports = 1;
00954 }
00955
00956
00957 cmlparams.device_info = device_name;
00958
00959 Jack::JackFFADODriver* ffado_driver = new Jack::JackFFADODriver("system", "firewire_pcm", engine, table);
00960 Jack::JackDriverClientInterface* threaded_driver = new Jack::JackThreadedDriver(ffado_driver);
00961
00962 if (ffado_driver->Open(&cmlparams) == 0) {
00963 return threaded_driver;
00964 } else {
00965 delete threaded_driver;
00966 return NULL;
00967 }
00968 }
00969
00970 #ifdef __cplusplus
00971 }
00972 #endif
00973
00974