diff options
Diffstat (limited to 'drivers/firewire/ffado_driver.c')
-rw-r--r-- | drivers/firewire/ffado_driver.c | 676 |
1 files changed, 339 insertions, 337 deletions
diff --git a/drivers/firewire/ffado_driver.c b/drivers/firewire/ffado_driver.c index 54c091a..02ccdf5 100644 --- a/drivers/firewire/ffado_driver.c +++ b/drivers/firewire/ffado_driver.c @@ -24,10 +24,10 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* +/* * Main Jack driver entry routines * - */ + */ #include <math.h> #include <stdio.h> @@ -50,7 +50,7 @@ #define SAMPLE_MAX_24BIT 8388608.0f #define SAMPLE_MAX_16BIT 32768.0f -static int ffado_driver_stop (ffado_driver_t *driver); +static int ffado_driver_stop(ffado_driver_t *driver); // Basic functionality requires API version 8. If version 9 or later // is present the buffers can be resized at runtime. @@ -62,30 +62,29 @@ static int ffado_driver_stop (ffado_driver_t *driver); */ #ifndef FFADO_API_VERSION extern int ffado_streaming_set_period_size(ffado_device_t *dev, - unsigned int period) __attribute__((__weak__)); + unsigned int period) __attribute__((__weak__)); #endif // enable verbose messages -static int g_verbose=0; +static int g_verbose = 0; -static void +static void ffado_latency_callback (jack_latency_callback_mode_t mode, void* arg) { - ffado_driver_t* driver = (ffado_driver_t*) arg; - jack_client_t* client = driver->client; - jack_latency_range_t range; - JSList* node; - - if (mode == JackPlaybackLatency) { - range.min = range.max = (driver->period_size * (driver->device_options.nb_buffers - 1)); - } else { - range.min = range.max = driver->period_size + driver->capture_frame_latency; - } - - for (node = client->ports; node; node = jack_slist_next (node)) { - jack_port_set_latency_range ((jack_port_t*) node->data, mode, &range); + ffado_driver_t* driver = (ffado_driver_t*)arg; + jack_client_t* client = driver->client; + jack_latency_range_t range; + JSList* node; + + if (mode == JackPlaybackLatency) { + range.min = range.max = (driver->period_size * (driver->device_options.nb_buffers - 1)); + } else { + range.min = range.max = driver->period_size + driver->capture_frame_latency; } + + for (node = client->ports; node; node = jack_slist_next (node)) + jack_port_set_latency_range ((jack_port_t*)node->data, mode, &range); } static int @@ -94,10 +93,10 @@ ffado_driver_attach (ffado_driver_t *driver) char buf[64]; char buf2[64]; channel_t chn; - jack_port_t *port=NULL; + jack_port_t *port = NULL; int port_flags; - g_verbose=driver->engine->verbose; + g_verbose = driver->engine->verbose; if (driver->engine->set_buffer_size (driver->engine, driver->period_size)) { jack_error ("FFADO: cannot set engine buffer size to %d (check MIDI)", driver->period_size); @@ -109,24 +108,24 @@ ffado_driver_attach (ffado_driver_t *driver) in RT context (or from the stack) */ /* the null buffer is a buffer that contains one period of silence */ - driver->nullbuffer = calloc(driver->period_size, sizeof(ffado_sample_t)); - if(driver->nullbuffer == NULL) { - printError("could not allocate memory for null buffer"); + driver->nullbuffer = calloc (driver->period_size, sizeof(ffado_sample_t)); + if (driver->nullbuffer == NULL) { + printError ("could not allocate memory for null buffer"); return -1; } /* calloc should do this, but it can't hurt to be sure */ - memset(driver->nullbuffer, 0, driver->period_size*sizeof(ffado_sample_t)); - + memset (driver->nullbuffer, 0, driver->period_size * sizeof(ffado_sample_t)); + /* the scratch buffer is a buffer of one period that can be used as dummy memory */ - driver->scratchbuffer = calloc(driver->period_size, sizeof(ffado_sample_t)); - if(driver->scratchbuffer == NULL) { - printError("could not allocate memory for scratch buffer"); + driver->scratchbuffer = calloc (driver->period_size, sizeof(ffado_sample_t)); + if (driver->scratchbuffer == NULL) { + printError ("could not allocate memory for scratch buffer"); return -1; } - + /* packetizer thread options */ - driver->device_options.realtime=(driver->engine->control->real_time? 1 : 0); - + driver->device_options.realtime = (driver->engine->control->real_time ? 1 : 0); + driver->device_options.packetizer_priority = driver->engine->rtpriority; if (driver->device_options.packetizer_priority > 98) { driver->device_options.packetizer_priority = 98; @@ -135,38 +134,38 @@ ffado_driver_attach (ffado_driver_t *driver) driver->device_options.packetizer_priority = 1; } - driver->dev = ffado_streaming_init(driver->device_info, driver->device_options); + driver->dev = ffado_streaming_init (driver->device_info, driver->device_options); - if(!driver->dev) { - printError("Error creating FFADO streaming device"); + if (!driver->dev) { + printError ("Error creating FFADO streaming device"); return -1; } if (driver->device_options.realtime) { - printMessage("Streaming thread running with Realtime scheduling, priority %d", - driver->device_options.packetizer_priority); + printMessage ("Streaming thread running with Realtime scheduling, priority %d", + driver->device_options.packetizer_priority); } else { - printMessage("Streaming thread running without Realtime scheduling"); + printMessage ("Streaming thread running without Realtime scheduling"); } - ffado_streaming_set_audio_datatype(driver->dev, ffado_audio_datatype_float); - + ffado_streaming_set_audio_datatype (driver->dev, ffado_audio_datatype_float); + /* ports */ - port_flags = JackPortIsOutput|JackPortIsPhysical|JackPortIsTerminal; + port_flags = JackPortIsOutput | JackPortIsPhysical | JackPortIsTerminal; - driver->capture_nchannels=ffado_streaming_get_nb_capture_streams(driver->dev); - driver->capture_channels=calloc(driver->capture_nchannels, sizeof(ffado_capture_channel_t)); - if(driver->capture_channels==NULL) { - printError("could not allocate memory for capture channel list"); + driver->capture_nchannels = ffado_streaming_get_nb_capture_streams (driver->dev); + driver->capture_channels = calloc (driver->capture_nchannels, sizeof(ffado_capture_channel_t)); + if (driver->capture_channels == NULL) { + printError ("could not allocate memory for capture channel list"); return -1; } - + for (chn = 0; chn < driver->capture_nchannels; chn++) { - ffado_streaming_get_capture_stream_name(driver->dev, chn, buf, sizeof(buf) - 1); - driver->capture_channels[chn].stream_type=ffado_streaming_get_capture_stream_type(driver->dev, chn); + ffado_streaming_get_capture_stream_name (driver->dev, chn, buf, sizeof(buf) - 1); + driver->capture_channels[chn].stream_type = ffado_streaming_get_capture_stream_type (driver->dev, chn); - if(driver->capture_channels[chn].stream_type == ffado_stream_type_audio) { - snprintf(buf2, 64, "C%d_%s",(int)chn,buf); // needed to avoid duplicate names + if (driver->capture_channels[chn].stream_type == ffado_stream_type_audio) { + snprintf (buf2, 64, "C%d_%s", (int)chn, buf); // needed to avoid duplicate names printMessage ("Registering audio capture port %s", buf2); if ((port = jack_port_register (driver->client, buf2, JACK_DEFAULT_AUDIO_TYPE, @@ -177,14 +176,14 @@ ffado_driver_attach (ffado_driver_t *driver) driver->capture_ports = jack_slist_append (driver->capture_ports, port); // setup port parameters - if (ffado_streaming_set_capture_stream_buffer(driver->dev, chn, NULL)) { - printError(" cannot configure initial port buffer for %s", buf2); + if (ffado_streaming_set_capture_stream_buffer (driver->dev, chn, NULL)) { + printError (" cannot configure initial port buffer for %s", buf2); } - if(ffado_streaming_capture_stream_onoff(driver->dev, chn, 1)) { - printError(" cannot enable port %s", buf2); + if (ffado_streaming_capture_stream_onoff (driver->dev, chn, 1)) { + printError (" cannot enable port %s", buf2); } - } else if(driver->capture_channels[chn].stream_type == ffado_stream_type_midi) { - snprintf(buf2, 64, "C%d_%s",(int)chn,buf); // needed to avoid duplicate names + } else if (driver->capture_channels[chn].stream_type == ffado_stream_type_midi) { + snprintf (buf2, 64, "C%d_%s", (int)chn, buf); // needed to avoid duplicate names printMessage ("Registering midi capture port %s", buf2); if ((port = jack_port_register (driver->client, buf2, JACK_DEFAULT_MIDI_TYPE, @@ -195,17 +194,17 @@ ffado_driver_attach (ffado_driver_t *driver) driver->capture_ports = jack_slist_append (driver->capture_ports, port); // setup port parameters - if (ffado_streaming_set_capture_stream_buffer(driver->dev, chn, NULL)) { - printError(" cannot configure initial port buffer for %s", buf2); + if (ffado_streaming_set_capture_stream_buffer (driver->dev, chn, NULL)) { + printError (" cannot configure initial port buffer for %s", buf2); } - if(ffado_streaming_capture_stream_onoff(driver->dev, chn, 1)) { - printError(" cannot enable port %s", buf2); + if (ffado_streaming_capture_stream_onoff (driver->dev, chn, 1)) { + printError (" cannot enable port %s", buf2); } // setup midi unpacker - midi_unpack_init(&driver->capture_channels[chn].midi_unpack); - midi_unpack_reset(&driver->capture_channels[chn].midi_unpack); + midi_unpack_init (&driver->capture_channels[chn].midi_unpack); + midi_unpack_reset (&driver->capture_channels[chn].midi_unpack); // setup the midi buffer - driver->capture_channels[chn].midi_buffer = calloc(driver->period_size, sizeof(uint32_t)); + driver->capture_channels[chn].midi_buffer = calloc (driver->period_size, sizeof(uint32_t)); } else { printMessage ("Don't register capture port %s", buf); @@ -214,62 +213,62 @@ ffado_driver_attach (ffado_driver_t *driver) jack_slist_append (driver->capture_ports, NULL); } } - - port_flags = JackPortIsInput|JackPortIsPhysical|JackPortIsTerminal; - driver->playback_nchannels=ffado_streaming_get_nb_playback_streams(driver->dev); - driver->playback_channels=calloc(driver->playback_nchannels, sizeof(ffado_playback_channel_t)); - if(driver->playback_channels==NULL) { - printError("could not allocate memory for playback channel list"); + port_flags = JackPortIsInput | JackPortIsPhysical | JackPortIsTerminal; + + driver->playback_nchannels = ffado_streaming_get_nb_playback_streams (driver->dev); + driver->playback_channels = calloc (driver->playback_nchannels, sizeof(ffado_playback_channel_t)); + if (driver->playback_channels == NULL) { + printError ("could not allocate memory for playback channel list"); return -1; } for (chn = 0; chn < driver->playback_nchannels; chn++) { - ffado_streaming_get_playback_stream_name(driver->dev, chn, buf, sizeof(buf) - 1); - driver->playback_channels[chn].stream_type=ffado_streaming_get_playback_stream_type(driver->dev, chn); - - if(driver->playback_channels[chn].stream_type == ffado_stream_type_audio) { - snprintf(buf2, 64, "P%d_%s",(int)chn,buf); // needed to avoid duplicate names + ffado_streaming_get_playback_stream_name (driver->dev, chn, buf, sizeof(buf) - 1); + driver->playback_channels[chn].stream_type = ffado_streaming_get_playback_stream_type (driver->dev, chn); + + if (driver->playback_channels[chn].stream_type == ffado_stream_type_audio) { + snprintf (buf2, 64, "P%d_%s", (int)chn, buf); // needed to avoid duplicate names printMessage ("Registering audio playback port %s", buf2); if ((port = jack_port_register (driver->client, buf2, JACK_DEFAULT_AUDIO_TYPE, port_flags, 0)) == NULL) { - printError(" cannot register port for %s", buf2); + printError (" cannot register port for %s", buf2); break; } driver->playback_ports = jack_slist_append (driver->playback_ports, port); // setup port parameters - if (ffado_streaming_set_playback_stream_buffer(driver->dev, chn, NULL)) { - printError(" cannot configure initial port buffer for %s", buf2); + if (ffado_streaming_set_playback_stream_buffer (driver->dev, chn, NULL)) { + printError (" cannot configure initial port buffer for %s", buf2); } - if(ffado_streaming_playback_stream_onoff(driver->dev, chn, 1)) { - printError(" cannot enable port %s", buf2); + if (ffado_streaming_playback_stream_onoff (driver->dev, chn, 1)) { + printError (" cannot enable port %s", buf2); } - } else if(driver->playback_channels[chn].stream_type == ffado_stream_type_midi) { - snprintf(buf2, 64, "P%d_%s",(int)chn,buf); // needed to avoid duplicate names + } else if (driver->playback_channels[chn].stream_type == ffado_stream_type_midi) { + snprintf (buf2, 64, "P%d_%s", (int)chn, buf); // needed to avoid duplicate names printMessage ("Registering midi playback port %s", buf2); if ((port = jack_port_register (driver->client, buf2, JACK_DEFAULT_MIDI_TYPE, port_flags, 0)) == NULL) { - printError(" cannot register port for %s", buf2); + printError (" cannot register port for %s", buf2); break; } driver->playback_ports = jack_slist_append (driver->playback_ports, port); // setup port parameters - if (ffado_streaming_set_playback_stream_buffer(driver->dev, chn, NULL)) { - printError(" cannot configure initial port buffer for %s", buf2); + if (ffado_streaming_set_playback_stream_buffer (driver->dev, chn, NULL)) { + printError (" cannot configure initial port buffer for %s", buf2); } - if(ffado_streaming_playback_stream_onoff(driver->dev, chn, 1)) { - printError(" cannot enable port %s", buf2); + if (ffado_streaming_playback_stream_onoff (driver->dev, chn, 1)) { + printError (" cannot enable port %s", buf2); } // setup midi packer - midi_pack_reset(&driver->playback_channels[chn].midi_pack); + midi_pack_reset (&driver->playback_channels[chn].midi_pack); // setup the midi buffer - driver->playback_channels[chn].midi_buffer = calloc(driver->period_size, sizeof(uint32_t)); + driver->playback_channels[chn].midi_buffer = calloc (driver->period_size, sizeof(uint32_t)); } else { printMessage ("Don't register playback port %s", buf); @@ -279,15 +278,15 @@ ffado_driver_attach (ffado_driver_t *driver) } } - if(ffado_streaming_prepare(driver->dev)) { - printError("Could not prepare streaming device!"); + if (ffado_streaming_prepare (driver->dev)) { + printError ("Could not prepare streaming device!"); return -1; } return jack_activate (driver->client); } -static int +static int ffado_driver_detach (ffado_driver_t *driver) { JSList *node; @@ -303,41 +302,41 @@ ffado_driver_detach (ffado_driver_t *driver) // ffado ports by ffado_driver_attach(). if (node->data != NULL) { jack_port_unregister (driver->client, - ((jack_port_t *) node->data)); + ((jack_port_t*)node->data)); } } jack_slist_free (driver->capture_ports); driver->capture_ports = 0; - + for (node = driver->playback_ports; node; node = jack_slist_next (node)) { - if (node->data != NULL) { - jack_port_unregister (driver->client, - ((jack_port_t *) node->data)); - } + if (node->data != NULL) { + jack_port_unregister (driver->client, + ((jack_port_t*)node->data)); + } } jack_slist_free (driver->playback_ports); driver->playback_ports = 0; - ffado_streaming_finish(driver->dev); - driver->dev=NULL; + ffado_streaming_finish (driver->dev); + driver->dev = NULL; - for (chn = 0; chn < driver->capture_nchannels; chn++) { - if(driver->capture_channels[chn].midi_buffer) - free(driver->capture_channels[chn].midi_buffer); - } - free(driver->capture_channels); - - for (chn = 0; chn < driver->playback_nchannels; chn++) { - if(driver->playback_channels[chn].midi_buffer) - free(driver->playback_channels[chn].midi_buffer); - } - free(driver->playback_channels); - - free(driver->nullbuffer); - free(driver->scratchbuffer); + for (chn = 0; chn < driver->capture_nchannels; chn++) + if (driver->capture_channels[chn].midi_buffer) { + free (driver->capture_channels[chn].midi_buffer); + } + free (driver->capture_channels); + + for (chn = 0; chn < driver->playback_nchannels; chn++) + if (driver->playback_channels[chn].midi_buffer) { + free (driver->playback_channels[chn].midi_buffer); + } + free (driver->playback_channels); + + free (driver->nullbuffer); + free (driver->scratchbuffer); return 0; } @@ -348,40 +347,40 @@ ffado_driver_read (ffado_driver_t * driver, jack_nframes_t nframes) int nb_connections; JSList *node; jack_port_t* port; - - printEnter(); + + printEnter (); for (chn = 0, node = driver->capture_ports; node; node = jack_slist_next (node), chn++) { - if(driver->capture_channels[chn].stream_type == ffado_stream_type_audio) { - port = (jack_port_t *) node->data; + if (driver->capture_channels[chn].stream_type == ffado_stream_type_audio) { + port = (jack_port_t*)node->data; nb_connections = jack_port_connected (port); /* if there are no connections, use the dummy buffer and disable the stream */ - if(nb_connections) { - ffado_streaming_capture_stream_onoff(driver->dev, chn, 1); - ffado_streaming_set_capture_stream_buffer(driver->dev, chn, (char *)(jack_port_get_buffer (port, nframes))); + if (nb_connections) { + ffado_streaming_capture_stream_onoff (driver->dev, chn, 1); + ffado_streaming_set_capture_stream_buffer (driver->dev, chn, (char*)(jack_port_get_buffer (port, nframes))); } else { - ffado_streaming_capture_stream_onoff(driver->dev, chn, 0); - ffado_streaming_set_capture_stream_buffer(driver->dev, chn, (char *)(driver->scratchbuffer)); + ffado_streaming_capture_stream_onoff (driver->dev, chn, 0); + ffado_streaming_set_capture_stream_buffer (driver->dev, chn, (char*)(driver->scratchbuffer)); } } else if (driver->capture_channels[chn].stream_type == ffado_stream_type_midi) { - port = (jack_port_t *) node->data; + port = (jack_port_t*)node->data; nb_connections = jack_port_connected (port); - if(nb_connections) { - ffado_streaming_capture_stream_onoff(driver->dev, chn, 1); + if (nb_connections) { + ffado_streaming_capture_stream_onoff (driver->dev, chn, 1); } else { - ffado_streaming_capture_stream_onoff(driver->dev, chn, 0); + ffado_streaming_capture_stream_onoff (driver->dev, chn, 0); } /* always set a buffer */ - ffado_streaming_set_capture_stream_buffer(driver->dev, chn, - (char *)(driver->capture_channels[chn].midi_buffer)); + ffado_streaming_set_capture_stream_buffer (driver->dev, chn, + (char*)(driver->capture_channels[chn].midi_buffer)); } else { /* ensure a valid buffer */ - ffado_streaming_set_capture_stream_buffer(driver->dev, chn, (char *)(driver->scratchbuffer)); - ffado_streaming_capture_stream_onoff(driver->dev, chn, 0); + ffado_streaming_set_capture_stream_buffer (driver->dev, chn, (char*)(driver->scratchbuffer)); + ffado_streaming_capture_stream_onoff (driver->dev, chn, 0); } } /* now transfer the buffers */ - ffado_streaming_transfer_capture_buffers(driver->dev); + ffado_streaming_transfer_capture_buffers (driver->dev); /* process the midi data */ for (chn = 0, node = driver->capture_ports; node; node = jack_slist_next (node), chn++) { @@ -391,23 +390,25 @@ ffado_driver_read (ffado_driver_t * driver, jack_nframes_t nframes) int done; uint32_t *midi_buffer = driver->capture_channels[chn].midi_buffer; midi_unpack_t *midi_unpack = &driver->capture_channels[chn].midi_unpack; - port = (jack_port_t *) node->data; + port = (jack_port_t*)node->data; nb_connections = jack_port_connected (port); buf = jack_port_get_buffer (port, nframes); /* if the returned buffer is invalid, discard the midi data */ - jack_midi_clear_buffer(buf); + jack_midi_clear_buffer (buf); /* no connections means no processing */ - if(nb_connections == 0) continue; + if (nb_connections == 0) { + continue; + } /* else unpack note that libffado guarantees that midi bytes are on 8-byte aligned indexes */ - for(i = 0; i < nframes; i += 8) { - if(midi_buffer[i] & 0xFF000000) { - done = midi_unpack_buf(midi_unpack, (unsigned char *)(midi_buffer+i), 1, buf, i); + for (i = 0; i < nframes; i += 8) { + if (midi_buffer[i] & 0xFF000000) { + done = midi_unpack_buf (midi_unpack, (unsigned char*)(midi_buffer + i), 1, buf, i); if (done != 1) { - printError("MIDI buffer overflow in channel %d\n", chn); + printError ("MIDI buffer overflow in channel %d\n", chn); break; } } @@ -415,7 +416,7 @@ ffado_driver_read (ffado_driver_t * driver, jack_nframes_t nframes) } } - printExit(); + printExit (); return 0; } @@ -426,25 +427,26 @@ ffado_driver_write (ffado_driver_t * driver, jack_nframes_t nframes) int nb_connections; JSList *node; jack_port_t *port; - printEnter(); - + + printEnter (); + driver->process_count++; if (driver->engine->freewheeling) { return 0; } for (chn = 0, node = driver->playback_ports; node; node = jack_slist_next (node), chn++) { - if(driver->playback_channels[chn].stream_type == ffado_stream_type_audio) { - port = (jack_port_t *) node->data; + if (driver->playback_channels[chn].stream_type == ffado_stream_type_audio) { + port = (jack_port_t*)node->data; nb_connections = jack_port_connected (port); /* use the silent buffer + disable if there are no connections */ - if(nb_connections) { - ffado_streaming_playback_stream_onoff(driver->dev, chn, 1); - ffado_streaming_set_playback_stream_buffer(driver->dev, chn, (char *)(jack_port_get_buffer (port, nframes))); + if (nb_connections) { + ffado_streaming_playback_stream_onoff (driver->dev, chn, 1); + ffado_streaming_set_playback_stream_buffer (driver->dev, chn, (char*)(jack_port_get_buffer (port, nframes))); } else { - ffado_streaming_playback_stream_onoff(driver->dev, chn, 0); - ffado_streaming_set_playback_stream_buffer(driver->dev, chn, (char *)(driver->nullbuffer)); + ffado_streaming_playback_stream_onoff (driver->dev, chn, 0); + ffado_streaming_set_playback_stream_buffer (driver->dev, chn, (char*)(driver->nullbuffer)); } } else if (driver->playback_channels[chn].stream_type == ffado_stream_type_midi) { jack_default_audio_sample_t* buf; @@ -454,68 +456,66 @@ ffado_driver_write (ffado_driver_t * driver, jack_nframes_t nframes) uint32_t *midi_buffer = driver->playback_channels[chn].midi_buffer; int min_next_pos = 0; - port = (jack_port_t *) node->data; + port = (jack_port_t*)node->data; nb_connections = jack_port_connected (port); /* skip if no connections */ - if(nb_connections == 0) { - ffado_streaming_set_playback_stream_buffer(driver->dev, chn, (char *)(driver->nullbuffer)); - ffado_streaming_playback_stream_onoff(driver->dev, chn, 0); + if (nb_connections == 0) { + ffado_streaming_set_playback_stream_buffer (driver->dev, chn, (char*)(driver->nullbuffer)); + ffado_streaming_playback_stream_onoff (driver->dev, chn, 0); continue; } - memset(midi_buffer, 0, nframes * sizeof(uint32_t)); - ffado_streaming_set_playback_stream_buffer(driver->dev, chn, (char *)(midi_buffer)); - ffado_streaming_playback_stream_onoff(driver->dev, chn, 1); + memset (midi_buffer, 0, nframes * sizeof(uint32_t)); + ffado_streaming_set_playback_stream_buffer (driver->dev, chn, (char*)(midi_buffer)); + ffado_streaming_playback_stream_onoff (driver->dev, chn, 1); /* check if we still have to process bytes from the previous period */ /* - if(driver->playback_channels[chn].nb_overflow_bytes) { - printMessage("have to process %d bytes from previous period", driver->playback_channels[chn].nb_overflow_bytes); - } - */ - for (i=0; i<driver->playback_channels[chn].nb_overflow_bytes; ++i) { + if(driver->playback_channels[chn].nb_overflow_bytes) { + printMessage("have to process %d bytes from previous period", driver->playback_channels[chn].nb_overflow_bytes); + } + */ + for (i = 0; i < driver->playback_channels[chn].nb_overflow_bytes; ++i) { midi_buffer[min_next_pos] = 0x01000000 | (driver->playback_channels[chn].overflow_buffer[i] & 0xFF); min_next_pos += 8; } - driver->playback_channels[chn].nb_overflow_bytes=0; - + driver->playback_channels[chn].nb_overflow_bytes = 0; + /* process the events in this period */ buf = jack_port_get_buffer (port, nframes); - nevents = jack_midi_get_event_count(buf); + nevents = jack_midi_get_event_count (buf); - for (i=0; i<nevents; ++i) { + for (i = 0; i < nevents; ++i) { int j; jack_midi_event_t event; - jack_midi_event_get(&event, buf, i); + jack_midi_event_get (&event, buf, i); - midi_pack_event(midi_pack, &event); + midi_pack_event (midi_pack, &event); /* floor the initial position to be a multiple of 8 */ int pos = event.time & 0xFFFFFFF8; - for(j = 0; j < event.size; j++) { + for (j = 0; j < event.size; j++) { /* make sure we don't overwrite a previous byte */ - while(pos < min_next_pos && pos < nframes) { + while (pos < min_next_pos && pos < nframes) /* printMessage("have to correct pos to %d", pos); */ pos += 8; - } - if(pos >= nframes) { + if (pos >= nframes) { int f; /* printMessage("midi message crosses period boundary"); */ driver->playback_channels[chn].nb_overflow_bytes = event.size - j; - if(driver->playback_channels[chn].nb_overflow_bytes > MIDI_OVERFLOW_BUFFER_SIZE) { - printError("too much midi bytes cross period boundary"); + if (driver->playback_channels[chn].nb_overflow_bytes > MIDI_OVERFLOW_BUFFER_SIZE) { + printError ("too much midi bytes cross period boundary"); driver->playback_channels[chn].nb_overflow_bytes = MIDI_OVERFLOW_BUFFER_SIZE; } /* save the bytes that still have to be transmitted in the next period */ - for(f = 0; f < driver->playback_channels[chn].nb_overflow_bytes; f++) { - driver->playback_channels[chn].overflow_buffer[f] = event.buffer[j+f]; - } - /* exit since we can't transmit anything anymore. - the rate should be controlled */ - if(i < nevents-1) { - printError("%d midi events lost due to period crossing", nevents-i-1); + for (f = 0; f < driver->playback_channels[chn].nb_overflow_bytes; f++) + driver->playback_channels[chn].overflow_buffer[f] = event.buffer[j + f]; + /* exit since we can't transmit anything anymore. + the rate should be controlled */ + if (i < nevents - 1) { + printError ("%d midi events lost due to period crossing", nevents - i - 1); } break; } else { @@ -526,35 +526,35 @@ ffado_driver_write (ffado_driver_t * driver, jack_nframes_t nframes) } } } else { /* ensure a valid buffer */ - ffado_streaming_set_playback_stream_buffer(driver->dev, chn, (char *)(driver->nullbuffer)); - ffado_streaming_playback_stream_onoff(driver->dev, chn, 0); + ffado_streaming_set_playback_stream_buffer (driver->dev, chn, (char*)(driver->nullbuffer)); + ffado_streaming_playback_stream_onoff (driver->dev, chn, 0); } } - ffado_streaming_transfer_playback_buffers(driver->dev); + ffado_streaming_transfer_playback_buffers (driver->dev); - printExit(); + printExit (); return 0; } -//static inline jack_nframes_t -static jack_nframes_t +//static inline jack_nframes_t +static jack_nframes_t ffado_driver_wait (ffado_driver_t *driver, int extra_fd, int *status, float *delayed_usecs) { - jack_time_t wait_enter; - jack_time_t wait_ret; - ffado_wait_response response; - - printEnter(); + jack_time_t wait_enter; + jack_time_t wait_ret; + ffado_wait_response response; + + printEnter (); wait_enter = driver->engine->get_microseconds (); if (wait_enter > driver->wait_next) { /* - * This processing cycle was delayed past the - * next due interrupt! Do not account this as - * a wakeup delay: - */ + * This processing cycle was delayed past the + * next due interrupt! Do not account this as + * a wakeup delay: + */ driver->wait_next = 0; driver->wait_late++; } @@ -562,10 +562,10 @@ ffado_driver_wait (ffado_driver_t *driver, int extra_fd, int *status, // *status = -3; timeout // *status = -4; extra FD - response = ffado_streaming_wait(driver->dev); - + response = ffado_streaming_wait (driver->dev); + wait_ret = driver->engine->get_microseconds (); - + if (driver->wait_next && wait_ret > driver->wait_next) { *delayed_usecs = wait_ret - driver->wait_next; } @@ -574,26 +574,26 @@ ffado_driver_wait (ffado_driver_t *driver, int extra_fd, int *status, driver->engine->transport_cycle_start (driver->engine, wait_ret); if (response == ffado_wait_ok) { // all good - *status=0; + *status = 0; } else if (response == ffado_wait_xrun) { // xrun happened, but it's handled - *status=0; + *status = 0; return 0; } else if (response == ffado_wait_error) { // an error happened (unhandled xrun) // this should be fatal - *status=-1; + *status = -1; return 0; } else if (response == ffado_wait_shutdown) { // we are to shutdown the ffado system // this should be fatal - *status=-1; + *status = -1; return 0; } else { // we don't know about this response code - printError("unknown wait response (%d) from ffado", response); + printError ("unknown wait response (%d) from ffado", response); // this should be fatal - *status=-1; + *status = -1; return 0; } @@ -601,8 +601,8 @@ ffado_driver_wait (ffado_driver_t *driver, int extra_fd, int *status, // FIXME: this should do something more useful *delayed_usecs = 0; - - printExit(); + + printExit (); return driver->period_size; } @@ -611,25 +611,25 @@ static int ffado_driver_run_cycle (ffado_driver_t *driver) { jack_engine_t *engine = driver->engine; - int wait_status=0; - float delayed_usecs=0.0; + int wait_status = 0; + float delayed_usecs = 0.0; jack_nframes_t nframes = ffado_driver_wait (driver, -1, - &wait_status, &delayed_usecs); - + &wait_status, &delayed_usecs); + if ((wait_status < 0)) { - printError( "wait status < 0! (= %d)",wait_status); + printError ( "wait status < 0! (= %d)", wait_status); return -1; } - + if ((nframes == 0)) { /* we detected an xrun and restarted: notify * clients about the delay. */ - printMessage("xrun detected"); + printMessage ("xrun detected"); engine->delay (engine, delayed_usecs); return 0; - } - + } + return engine->run_cycle (engine, nframes, delayed_usecs); } @@ -643,42 +643,42 @@ ffado_driver_null_cycle (ffado_driver_t* driver, jack_nframes_t nframes) JSList *node; ffado_streaming_stream_type stream_type; - printEnter(); - + printEnter (); + if (driver->engine->freewheeling) { return 0; } // write silence to buffer for (chn = 0, node = driver->playback_ports; node; node = jack_slist_next (node), chn++) { - stream_type=ffado_streaming_get_playback_stream_type(driver->dev, chn); + stream_type = ffado_streaming_get_playback_stream_type (driver->dev, chn); - if(stream_type == ffado_stream_type_audio) { - ffado_streaming_set_playback_stream_buffer(driver->dev, chn, (char *)(driver->nullbuffer)); + if (stream_type == ffado_stream_type_audio) { + ffado_streaming_set_playback_stream_buffer (driver->dev, chn, (char*)(driver->nullbuffer)); } } - ffado_streaming_transfer_playback_buffers(driver->dev); - + ffado_streaming_transfer_playback_buffers (driver->dev); + // read & discard from input ports for (chn = 0, node = driver->capture_ports; node; node = jack_slist_next (node), chn++) { - stream_type=ffado_streaming_get_capture_stream_type(driver->dev, chn); - if(stream_type == ffado_stream_type_audio) { - ffado_streaming_set_capture_stream_buffer(driver->dev, chn, (char *)(driver->scratchbuffer)); + stream_type = ffado_streaming_get_capture_stream_type (driver->dev, chn); + if (stream_type == ffado_stream_type_audio) { + ffado_streaming_set_capture_stream_buffer (driver->dev, chn, (char*)(driver->scratchbuffer)); } } - ffado_streaming_transfer_capture_buffers(driver->dev); + ffado_streaming_transfer_capture_buffers (driver->dev); - printExit(); + printExit (); return 0; } static int ffado_driver_start (ffado_driver_t *driver) { - int retval=0; + int retval = 0; - if((retval=ffado_streaming_start(driver->dev))) { - printError("Could not start streaming threads: %d", retval); + if ((retval = ffado_streaming_start (driver->dev))) { + printError ("Could not start streaming threads: %d", retval); return retval; } @@ -689,10 +689,10 @@ ffado_driver_start (ffado_driver_t *driver) static int ffado_driver_stop (ffado_driver_t *driver) { - int retval=0; - - if((retval=ffado_streaming_stop(driver->dev))) { - printError("Could not stop streaming threads"); + int retval = 0; + + if ((retval = ffado_streaming_stop (driver->dev))) { + printError ("Could not stop streaming threads"); return retval; } @@ -706,55 +706,57 @@ ffado_driver_bufsize (ffado_driver_t* driver, jack_nframes_t nframes) // The speed of this function isn't critical; we can afford the // time to check the FFADO API version. - if (ffado_get_api_version() < FIREWIRE_REQUIRED_FFADO_API_VERSION_FOR_SETBUFSIZE || - ffado_streaming_set_period_size == NULL) { - printError("unsupported on current version of FFADO; please upgrade FFADO"); - return -1; + if (ffado_get_api_version () < FIREWIRE_REQUIRED_FFADO_API_VERSION_FOR_SETBUFSIZE || + ffado_streaming_set_period_size == NULL) { + printError ("unsupported on current version of FFADO; please upgrade FFADO"); + return -1; } driver->period_size = nframes; driver->period_usecs = - (jack_time_t) floor ((((float) nframes) / driver->sample_rate) - * 1000000.0f); + (jack_time_t)floor ((((float)nframes) / driver->sample_rate) + * 1000000.0f); // Reallocate the null and scratch buffers. - driver->nullbuffer = calloc(driver->period_size, sizeof(ffado_sample_t)); - if(driver->nullbuffer == NULL) { - printError("could not allocate memory for null buffer"); + driver->nullbuffer = calloc (driver->period_size, sizeof(ffado_sample_t)); + if (driver->nullbuffer == NULL) { + printError ("could not allocate memory for null buffer"); return -1; } - driver->scratchbuffer = calloc(driver->period_size, sizeof(ffado_sample_t)); - if(driver->scratchbuffer == NULL) { - printError("could not allocate memory for scratch buffer"); + driver->scratchbuffer = calloc (driver->period_size, sizeof(ffado_sample_t)); + if (driver->scratchbuffer == NULL) { + printError ("could not allocate memory for scratch buffer"); return -1; } // MIDI buffers need reallocating for (chn = 0; chn < driver->capture_nchannels; chn++) { - if(driver->capture_channels[chn].stream_type == ffado_stream_type_midi) { + if (driver->capture_channels[chn].stream_type == ffado_stream_type_midi) { // setup the midi buffer - if (driver->capture_channels[chn].midi_buffer != NULL) - free(driver->capture_channels[chn].midi_buffer); - driver->capture_channels[chn].midi_buffer = calloc(driver->period_size, sizeof(uint32_t)); + if (driver->capture_channels[chn].midi_buffer != NULL) { + free (driver->capture_channels[chn].midi_buffer); + } + driver->capture_channels[chn].midi_buffer = calloc (driver->period_size, sizeof(uint32_t)); } } for (chn = 0; chn < driver->playback_nchannels; chn++) { - if(driver->playback_channels[chn].stream_type == ffado_stream_type_midi) { - if (driver->playback_channels[chn].midi_buffer != NULL) - free(driver->playback_channels[chn].midi_buffer); - driver->playback_channels[chn].midi_buffer = calloc(driver->period_size, sizeof(uint32_t)); + if (driver->playback_channels[chn].stream_type == ffado_stream_type_midi) { + if (driver->playback_channels[chn].midi_buffer != NULL) { + free (driver->playback_channels[chn].midi_buffer); + } + driver->playback_channels[chn].midi_buffer = calloc (driver->period_size, sizeof(uint32_t)); } } // Notify FFADO of the period size change - if (ffado_streaming_set_period_size(driver->dev, nframes) != 0) { - printError("could not alter FFADO device period size"); - return -1; + if (ffado_streaming_set_period_size (driver->dev, nframes) != 0) { + printError ("could not alter FFADO device period size"); + return -1; } // This is needed to give the shadow variables a chance to // properly update to the changes. - sleep(1); + sleep (1); /* tell the engine to change its buffer size */ if (driver->engine->set_buffer_size (driver->engine, nframes)) { @@ -762,10 +764,10 @@ ffado_driver_bufsize (ffado_driver_t* driver, jack_nframes_t nframes) return -1; } - return 0; + return 0; } -typedef void (*JackDriverFinishFunction) (jack_driver_t *); +typedef void (*JackDriverFinishFunction)(jack_driver_t *); ffado_driver_t * ffado_driver_new (jack_client_t * client, @@ -774,66 +776,66 @@ ffado_driver_new (jack_client_t * client, { ffado_driver_t *driver; - if(ffado_get_api_version() < FIREWIRE_REQUIRED_FFADO_API_VERSION) { - printError("Incompatible libffado version! (%s)", ffado_get_version()); + if (ffado_get_api_version () < FIREWIRE_REQUIRED_FFADO_API_VERSION) { + printError ("Incompatible libffado version! (%s)", ffado_get_version ()); return NULL; } - printMessage("Starting firewire backend (%s)", ffado_get_version()); + printMessage ("Starting firewire backend (%s)", ffado_get_version ()); - driver = calloc (1, sizeof (ffado_driver_t)); + driver = calloc (1, sizeof(ffado_driver_t)); - /* Setup the jack interfaces */ - jack_driver_nt_init ((jack_driver_nt_t *) driver); + /* Setup the jack interfaces */ + jack_driver_nt_init ((jack_driver_nt_t*)driver); + + driver->nt_attach = (JackDriverNTAttachFunction)ffado_driver_attach; + driver->nt_detach = (JackDriverNTDetachFunction)ffado_driver_detach; + driver->nt_start = (JackDriverNTStartFunction)ffado_driver_start; + driver->nt_stop = (JackDriverNTStopFunction)ffado_driver_stop; + driver->nt_run_cycle = (JackDriverNTRunCycleFunction)ffado_driver_run_cycle; + driver->null_cycle = (JackDriverNullCycleFunction)ffado_driver_null_cycle; + driver->write = (JackDriverReadFunction)ffado_driver_write; + driver->read = (JackDriverReadFunction)ffado_driver_read; + driver->nt_bufsize = (JackDriverNTBufSizeFunction)ffado_driver_bufsize; - driver->nt_attach = (JackDriverNTAttachFunction) ffado_driver_attach; - driver->nt_detach = (JackDriverNTDetachFunction) ffado_driver_detach; - driver->nt_start = (JackDriverNTStartFunction) ffado_driver_start; - driver->nt_stop = (JackDriverNTStopFunction) ffado_driver_stop; - driver->nt_run_cycle = (JackDriverNTRunCycleFunction) ffado_driver_run_cycle; - driver->null_cycle = (JackDriverNullCycleFunction) ffado_driver_null_cycle; - driver->write = (JackDriverReadFunction) ffado_driver_write; - driver->read = (JackDriverReadFunction) ffado_driver_read; - driver->nt_bufsize = (JackDriverNTBufSizeFunction) ffado_driver_bufsize; - /* copy command line parameter contents to the driver structure */ - memcpy(&driver->settings,params,sizeof(ffado_jack_settings_t)); - + memcpy (&driver->settings, params, sizeof(ffado_jack_settings_t)); + /* prepare all parameters */ driver->sample_rate = params->sample_rate; driver->period_size = params->period_size; driver->last_wait_ust = 0; - + driver->period_usecs = - (jack_time_t) floor ((((float) driver->period_size) * 1000000.0f) / driver->sample_rate); + (jack_time_t)floor ((((float)driver->period_size) * 1000000.0f) / driver->sample_rate); driver->client = client; driver->engine = NULL; - jack_set_latency_callback (client, ffado_latency_callback, driver); + jack_set_latency_callback (client, ffado_latency_callback, driver); - memset(&driver->device_options,0,sizeof(driver->device_options)); - driver->device_options.sample_rate=params->sample_rate; - driver->device_options.period_size=params->period_size; - driver->device_options.nb_buffers=params->buffer_size; + memset (&driver->device_options, 0, sizeof(driver->device_options)); + driver->device_options.sample_rate = params->sample_rate; + driver->device_options.period_size = params->period_size; + driver->device_options.nb_buffers = params->buffer_size; driver->capture_frame_latency = params->capture_frame_latency; driver->playback_frame_latency = params->playback_frame_latency; - driver->device_options.slave_mode=params->slave_mode; - driver->device_options.snoop_mode=params->snoop_mode; - driver->device_options.verbose=params->verbose_level; - - driver->device_info.nb_device_spec_strings=1; - driver->device_info.device_spec_strings=calloc(1, sizeof(char *)); - driver->device_info.device_spec_strings[0]=strdup(params->device_info); - - debugPrint(DEBUG_LEVEL_STARTUP, " Driver compiled on %s %s for FFADO %s (API version %d)", - __DATE__, __TIME__, ffado_get_version(), ffado_get_api_version()); - debugPrint(DEBUG_LEVEL_STARTUP, " Created driver %s", name); - debugPrint(DEBUG_LEVEL_STARTUP, " period_size: %d", driver->period_size); - debugPrint(DEBUG_LEVEL_STARTUP, " period_usecs: %d", driver->period_usecs); - debugPrint(DEBUG_LEVEL_STARTUP, " sample rate: %d", driver->sample_rate); - - return (ffado_driver_t *) driver; + driver->device_options.slave_mode = params->slave_mode; + driver->device_options.snoop_mode = params->snoop_mode; + driver->device_options.verbose = params->verbose_level; + + driver->device_info.nb_device_spec_strings = 1; + driver->device_info.device_spec_strings = calloc (1, sizeof(char *)); + driver->device_info.device_spec_strings[0] = strdup (params->device_info); + + debugPrint (DEBUG_LEVEL_STARTUP, " Driver compiled on %s %s for FFADO %s (API version %d)", + __DATE__, __TIME__, ffado_get_version (), ffado_get_api_version ()); + debugPrint (DEBUG_LEVEL_STARTUP, " Created driver %s", name); + debugPrint (DEBUG_LEVEL_STARTUP, " period_size: %d", driver->period_size); + debugPrint (DEBUG_LEVEL_STARTUP, " period_usecs: %d", driver->period_usecs); + debugPrint (DEBUG_LEVEL_STARTUP, " sample rate: %d", driver->sample_rate); + + return (ffado_driver_t*)driver; } @@ -841,10 +843,10 @@ static void ffado_driver_delete (ffado_driver_t *driver) { unsigned int i; - jack_driver_nt_finish ((jack_driver_nt_t *) driver); - for (i=0; i < driver->device_info.nb_device_spec_strings; i++) { + + jack_driver_nt_finish ((jack_driver_nt_t*)driver); + for (i = 0; i < driver->device_info.nb_device_spec_strings; i++) free (driver->device_info.device_spec_strings[i]); - } free (driver->device_info.device_spec_strings); free (driver); } @@ -862,12 +864,12 @@ driver_get_descriptor () jack_driver_param_desc_t * params; unsigned int i; - desc = calloc (1, sizeof (jack_driver_desc_t)); + desc = calloc (1, sizeof(jack_driver_desc_t)); strcpy (desc->name, "firewire"); desc->nparams = 11; - - params = calloc (desc->nparams, sizeof (jack_driver_param_desc_t)); + + params = calloc (desc->nparams, sizeof(jack_driver_param_desc_t)); desc->params = params; i = 0; @@ -877,7 +879,7 @@ driver_get_descriptor () strcpy (params[i].value.str, "hw:0"); strcpy (params[i].short_desc, "The FireWire device to use."); strcpy (params[i].long_desc, "The FireWire device to use. Please consult the FFADO documentation for more info."); - + i++; strcpy (params[i].name, "period"); params[i].character = 'p'; @@ -885,7 +887,7 @@ driver_get_descriptor () params[i].value.ui = 1024; strcpy (params[i].short_desc, "Frames per period"); strcpy (params[i].long_desc, params[i].short_desc); - + i++; strcpy (params[i].name, "nperiods"); params[i].character = 'n'; @@ -949,7 +951,7 @@ driver_get_descriptor () params[i].value.ui = 0U; strcpy (params[i].short_desc, "Operate in snoop mode"); strcpy (params[i].long_desc, params[i].short_desc); - + i++; strcpy (params[i].name, "verbose"); params[i].character = 'v'; @@ -972,30 +974,28 @@ driver_initialize (jack_client_t *client, JSList * params) ffado_jack_settings_t cmlparams; - char *device_name="hw:0"; + char *device_name = "hw:0"; - cmlparams.period_size_set=0; - cmlparams.sample_rate_set=0; - cmlparams.buffer_size_set=0; + cmlparams.period_size_set = 0; + cmlparams.sample_rate_set = 0; + cmlparams.buffer_size_set = 0; /* default values */ - cmlparams.period_size=1024; - cmlparams.sample_rate=48000; - cmlparams.buffer_size=3; - cmlparams.playback_ports=1; - cmlparams.capture_ports=1; - cmlparams.playback_frame_latency=0; - cmlparams.capture_frame_latency=0; - cmlparams.slave_mode=0; - cmlparams.snoop_mode=0; - cmlparams.verbose_level=0; - - for (node = params; node; node = jack_slist_next (node)) - { - param = (jack_driver_param_t *) node->data; - - switch (param->character) - { + cmlparams.period_size = 1024; + cmlparams.sample_rate = 48000; + cmlparams.buffer_size = 3; + cmlparams.playback_ports = 1; + cmlparams.capture_ports = 1; + cmlparams.playback_frame_latency = 0; + cmlparams.capture_frame_latency = 0; + cmlparams.slave_mode = 0; + cmlparams.snoop_mode = 0; + cmlparams.verbose_level = 0; + + for (node = params; node; node = jack_slist_next (node)) { + param = (jack_driver_param_t*)node->data; + + switch (param->character) { case 'd': device_name = strdup (param->value.str); break; @@ -1035,10 +1035,10 @@ driver_initialize (jack_client_t *client, JSList * params) } } - // temporary - cmlparams.device_info = device_name; + // temporary + cmlparams.device_info = device_name; - driver=(jack_driver_t *)ffado_driver_new (client, "ffado_pcm", &cmlparams); + driver = (jack_driver_t*)ffado_driver_new (client, "ffado_pcm", &cmlparams); return driver; } @@ -1046,11 +1046,13 @@ driver_initialize (jack_client_t *client, JSList * params) void driver_finish (jack_driver_t *driver) { - ffado_driver_t *drv=(ffado_driver_t *) driver; + ffado_driver_t *drv = (ffado_driver_t*)driver; + // If jack hasn't called the detach method, do it now. As of jack 0.101.1 - // the detach method was not being called explicitly on closedown, and + // the detach method was not being called explicitly on closedown, and // we need it to at least deallocate the iso resources. - if (drv->dev != NULL) - ffado_driver_detach(drv); + if (drv->dev != NULL) { + ffado_driver_detach (drv); + } ffado_driver_delete (drv); } |