From 2e06b7b6c3affbb642de54f4648e80a268f23849 Mon Sep 17 00:00:00 2001 From: pieterpalmers Date: Mon, 15 May 2006 00:03:47 +0000 Subject: [PATCH] FreeBob backend changes: - renamed the parameters for more consistency with the other backends - made the realtime behaviour & priority of the libfreebob code dependant on the realtime state of jackd. - updated code to reflect changes in libfreebob API - minor code cleanups git-svn-id: svn+ssh://jackaudio.org/trunk/jack@947 0c269be4-1314-0410-8aa9-9f06e86f4224 --- configure.ac | 2 +- drivers/freebob/freebob_driver.c | 285 ++++++++++++++++--------------- drivers/freebob/freebob_driver.h | 54 +++--- 3 files changed, 175 insertions(+), 166 deletions(-) diff --git a/configure.ac b/configure.ac index ccab963..8741ed4 100644 --- a/configure.ac +++ b/configure.ac @@ -15,7 +15,7 @@ dnl changes are made dnl --- JACK_MAJOR_VERSION=0 JACK_MINOR_VERSION=102 -JACK_MICRO_VERSION=1 +JACK_MICRO_VERSION=2 dnl --- dnl HOWTO: updating the jack protocol version diff --git a/drivers/freebob/freebob_driver.c b/drivers/freebob/freebob_driver.c index 2d744da..1e70dc0 100644 --- a/drivers/freebob/freebob_driver.c +++ b/drivers/freebob/freebob_driver.c @@ -51,6 +51,8 @@ static int freebob_driver_stop (freebob_driver_t *driver); #ifdef FREEBOB_DRIVER_WITH_MIDI static freebob_driver_midi_handle_t *freebob_driver_midi_init(freebob_driver_t *driver); static void freebob_driver_midi_finish (freebob_driver_midi_handle_t *m); + static int freebob_driver_midi_start (freebob_driver_midi_handle_t *m); + static int freebob_driver_midi_stop (freebob_driver_midi_handle_t *m); #endif static int @@ -64,6 +66,40 @@ freebob_driver_attach (freebob_driver_t *driver) driver->engine->set_buffer_size (driver->engine, driver->period_size); driver->engine->set_sample_rate (driver->engine, driver->sample_rate); + /* packetizer thread options */ + driver->device_options.realtime=(driver->engine->control->real_time? 1 : 0); + + driver->device_options.packetizer_priority=driver->engine->control->client_priority + + FREEBOB_RT_PRIORITY_PACKETIZER_RELATIVE; + if (driver->device_options.packetizer_priority>98) { + driver->device_options.packetizer_priority=98; + } + + driver->dev=freebob_streaming_init(&driver->device_info,driver->device_options); + + if(!driver->dev) { + jack_error("FREEBOB: Error creating virtual device"); + return -1; + } + +#ifdef FREEBOB_DRIVER_WITH_MIDI + driver->midi_handle=freebob_driver_midi_init(driver); + if(!driver->midi_handle) { + jack_error("FREEBOB: Error creating midi device"); + freebob_streaming_finish(driver->dev); + driver->dev=NULL; + return -1; + } +#endif + + if (driver->device_options.realtime) { + jack_error("Streaming thread running with Realtime scheduling, priority %d", + driver->device_options.packetizer_priority); + } else { + jack_error("Streaming thread running without Realtime scheduling"); + } + + /* ports */ port_flags = JackPortIsOutput|JackPortIsPhysical|JackPortIsTerminal; driver->capture_nchannels=freebob_streaming_get_nb_capture_streams(driver->dev); @@ -154,6 +190,14 @@ freebob_driver_detach (freebob_driver_t *driver) jack_slist_free (driver->playback_ports); driver->playback_ports = 0; + freebob_streaming_finish(driver->dev); + driver->dev=NULL; + +#ifdef FREEBOB_DRIVER_WITH_MIDI + freebob_driver_midi_finish(driver->midi_handle); +#endif + driver->midi_handle=NULL; + return 0; } @@ -170,24 +214,6 @@ freebob_driver_read_from_channel (freebob_driver_t *driver, freebob_streaming_read(driver->dev, channel, buffer, nsamples); -#if 0 - int i=0; - if(channel==0) { - jack_error("Read for channel %d",channel); - for (i=0;idev); + +#ifdef FREEBOB_DRIVER_WITH_MIDI + if((retval=freebob_driver_midi_start(driver->midi_handle))) { + jack_error("Could not start MIDI threads\n"); + return retval; + } +#endif + if((retval=freebob_streaming_start(driver->dev))) { + jack_error("Could not start streaming threads\n"); +#ifdef FREEBOB_DRIVER_WITH_MIDI + freebob_driver_midi_stop(driver->midi_handle); +#endif + return retval; + } + + return 0; } static int freebob_driver_stop (freebob_driver_t *driver) { + int retval=0; jack_error("Driver stop...\n"); - return freebob_streaming_stop(driver->dev); +#ifdef FREEBOB_DRIVER_WITH_MIDI + if((retval=freebob_driver_midi_stop(driver->midi_handle))) { + jack_error("Could not stop MIDI threads\n"); + return retval; + } +#endif + if((retval=freebob_streaming_stop(driver->dev))) { + jack_error("Could not stop streaming threads\n"); + return retval; + } + + return 0; } @@ -521,8 +575,6 @@ freebob_driver_new (jack_client_t * client, freebob_jack_settings_t *params) { freebob_driver_t *driver; - freebob_device_info_t device_info; - freebob_options_t device_options; assert(params); @@ -557,52 +609,26 @@ freebob_driver_new (jack_client_t * client, driver->client = client; driver->engine = NULL; - memset(&device_options,0,sizeof(device_options)); - device_options.sample_rate=params->sample_rate; - device_options.period_size=params->period_size; - device_options.nb_buffers=params->buffer_size; - device_options.iso_buffers=params->iso_buffers; - device_options.iso_prebuffers=params->iso_prebuffers; - device_options.iso_irq_interval=params->iso_irq_interval; - device_options.node_id=params->node_id; - device_options.port=params->port; - - /* packetizer thread options */ - - device_options.realtime=FREEBOB_USE_RT; - device_options.packetizer_priority=FREEBOB_RT_PRIORITY_PACKETIZER; - - driver->dev=freebob_streaming_init(&device_info,device_options); + 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->device_options.node_id=params->node_id; + driver->device_options.port=params->port; - if(!driver->dev) { - jack_error("FREEBOB: Error creating virtual device"); - jack_driver_nt_finish ((jack_driver_nt_t *) driver); - free (driver); - return NULL; + if(!params->capture_ports) { + driver->device_options.directions |= FREEBOB_IGNORE_CAPTURE; } -#ifdef FREEBOB_DRIVER_WITH_MIDI - driver->midi_handle=freebob_driver_midi_init(driver); - if(!driver->midi_handle) { - jack_error("FREEBOB: Error creating midi device"); - jack_driver_nt_finish ((jack_driver_nt_t *) driver); - free (driver); - return NULL; + if(!params->playback_ports) { + driver->device_options.directions |= FREEBOB_IGNORE_PLAYBACK; } -#endif jack_error("FREEBOB: Driver compiled on %s %s", __DATE__, __TIME__); jack_error("FREEBOB: Created driver %s", name); jack_error(" period_size: %d", driver->period_size); jack_error(" period_usecs: %d", driver->period_usecs); jack_error(" sample rate: %d", driver->sample_rate); - if (device_options.realtime) { - jack_error(" running with Realtime scheduling, priority %d", device_options.packetizer_priority); - } else { - jack_error(" running without Realtime scheduling"); - } - - return (freebob_driver_t *) driver; @@ -611,13 +637,6 @@ freebob_driver_new (jack_client_t * client, static void freebob_driver_delete (freebob_driver_t *driver) { - - freebob_streaming_finish(driver->dev); - -#ifdef FREEBOB_DRIVER_WITH_MIDI - freebob_driver_midi_finish(driver->midi_handle); -#endif - jack_driver_nt_finish ((jack_driver_nt_t *) driver); free (driver); } @@ -868,40 +887,66 @@ static freebob_driver_midi_handle_t *freebob_driver_midi_init(freebob_driver_t * } } + m->dev=dev; + m->driver=driver; + + return m; +} +static int +freebob_driver_midi_start (freebob_driver_midi_handle_t *m) +{ + assert(m); // start threads - m->dev=dev; - m->queue_thread_priority=FREEBOB_RT_PRIORITY_MIDI; - m->queue_thread_realtime=FREEBOB_USE_RT; + m->queue_thread_realtime=(m->driver->engine->control->real_time? 1 : 0); + m->queue_thread_priority= + m->driver->engine->control->client_priority + + FREEBOB_RT_PRIORITY_MIDI_RELATIVE; + + if (m->queue_thread_priority>98) { + m->queue_thread_priority=98; + } + if (m->queue_thread_realtime) { + jack_error("MIDI threads running with Realtime scheduling, priority %d", + m->queue_thread_priority); + } else { + jack_error("MIDI threads running without Realtime scheduling"); + } if (jack_client_create_thread(NULL, &m->queue_thread, m->queue_thread_priority, m->queue_thread_realtime, freebob_driver_midi_queue_thread, (void *)m)) { jack_error("FREEBOB: cannot create midi queueing thread"); - free(m); - return NULL; + return -1; } if (jack_client_create_thread(NULL, &m->dequeue_thread, m->queue_thread_priority, m->queue_thread_realtime, freebob_driver_midi_dequeue_thread, (void *)m)) { jack_error("FREEBOB: cannot create midi dequeueing thread"); - free(m); - return NULL; + return -1; } - return m; + return 0; } -static void -freebob_driver_midi_finish (freebob_driver_midi_handle_t *m) +static int +freebob_driver_midi_stop (freebob_driver_midi_handle_t *m) { assert(m); - int i; - pthread_cancel (m->queue_thread); pthread_join (m->queue_thread, NULL); pthread_cancel (m->dequeue_thread); pthread_join (m->dequeue_thread, NULL); + return 0; + +} +static void +freebob_driver_midi_finish (freebob_driver_midi_handle_t *m) +{ + assert(m); + + int i; + // TODO: add state info here, if not stopped then stop for (i=0;inb_input_ports;i++) { free(m->input_ports[i]); @@ -933,7 +978,7 @@ driver_get_descriptor () desc = calloc (1, sizeof (jack_driver_desc_t)); strcpy (desc->name, "freebob"); - desc->nparams = 8; + desc->nparams = 6; params = calloc (desc->nparams, sizeof (jack_driver_param_desc_t)); desc->params = params; @@ -947,61 +992,45 @@ driver_get_descriptor () strcpy (params[i].long_desc, params[i].short_desc); i++; - strcpy (params[i].name, "node"); - params[i].character = 'n'; - params[i].type = JackDriverParamUInt; - params[i].value.ui = -1; - strcpy (params[i].short_desc, "Node id of the BeBoB device"); - strcpy (params[i].long_desc, "The node id of the BeBoB device on the FireWire bus\n" - "(use -1 to use scan all devices on the bus)"); - i++; - strcpy (params[i].name, "period-size"); + strcpy (params[i].name, "period"); params[i].character = 'p'; params[i].type = JackDriverParamUInt; params[i].value.ui = 512; - strcpy (params[i].short_desc, "Period size"); + strcpy (params[i].short_desc, "Frames per period"); strcpy (params[i].long_desc, params[i].short_desc); i++; - strcpy (params[i].name, "nb-buffers"); - params[i].character = 'r'; + strcpy (params[i].name, "nperiods"); + params[i].character = 'n'; params[i].type = JackDriverParamUInt; params[i].value.ui = 3; - strcpy (params[i].short_desc, "Number of periods to buffer"); + strcpy (params[i].short_desc, "Number of periods of playback latency"); strcpy (params[i].long_desc, params[i].short_desc); i++; - strcpy (params[i].name, "buffer-size"); - params[i].character = 'b'; - params[i].type = JackDriverParamUInt; - params[i].value.ui = 100U; - strcpy (params[i].short_desc, "The RAW1394 buffer size to use (in frames)"); - strcpy (params[i].long_desc, params[i].short_desc); - - i++; - strcpy (params[i].name, "prebuffer-size"); - params[i].character = 's'; + strcpy (params[i].name, "rate"); + params[i].character = 'r'; params[i].type = JackDriverParamUInt; - params[i].value.ui = 0U; - strcpy (params[i].short_desc, "The RAW1394 pre-buffer size to use (in frames)"); + params[i].value.ui = 44100U; + strcpy (params[i].short_desc, "The sample rate"); strcpy (params[i].long_desc, params[i].short_desc); i++; - strcpy (params[i].name, "irq-interval"); + strcpy (params[i].name, "capture"); params[i].character = 'i'; params[i].type = JackDriverParamUInt; - params[i].value.ui = 4U; - strcpy (params[i].short_desc, "The interrupt interval to use (in packets)"); + params[i].value.ui = 1U; + strcpy (params[i].short_desc, "Provide capture ports."); strcpy (params[i].long_desc, params[i].short_desc); i++; - strcpy (params[i].name, "samplerate"); - params[i].character = 'a'; + strcpy (params[i].name, "playback"); + params[i].character = 'o'; params[i].type = JackDriverParamUInt; - params[i].value.ui = 44100U; - strcpy (params[i].short_desc, "The sample rate"); + params[i].value.ui = 1U; + strcpy (params[i].short_desc, "Provide playback ports."); strcpy (params[i].long_desc, params[i].short_desc); - + return desc; } @@ -1019,11 +1048,6 @@ driver_initialize (jack_client_t *client, JSList * params) cmlparams.period_size_set=0; cmlparams.sample_rate_set=0; - cmlparams.fifo_size_set=0; - cmlparams.table_size_set=0; - cmlparams.iso_buffers_set=0; - cmlparams.iso_prebuffers_set=0; - cmlparams.iso_irq_interval_set=0; cmlparams.buffer_size_set=0; cmlparams.port_set=0; cmlparams.node_id_set=0; @@ -1031,12 +1055,11 @@ driver_initialize (jack_client_t *client, JSList * params) /* default values */ cmlparams.period_size=512; cmlparams.sample_rate=44100; - cmlparams.iso_buffers=100; - cmlparams.iso_prebuffers=0; - cmlparams.iso_irq_interval=4; cmlparams.buffer_size=3; cmlparams.port=0; cmlparams.node_id=-1; + cmlparams.playback_ports=1; + cmlparams.capture_ports=1; for (node = params; node; node = jack_slist_next (node)) { @@ -1048,33 +1071,23 @@ driver_initialize (jack_client_t *client, JSList * params) cmlparams.port = param->value.ui; cmlparams.port_set=1; break; - case 'n': - cmlparams.node_id = param->value.ui; - cmlparams.node_id_set=1; - break; case 'p': cmlparams.period_size = param->value.ui; cmlparams.period_size_set = 1; break; - case 'b': - cmlparams.iso_buffers = param->value.ui; - cmlparams.iso_buffers_set = 1; - break; - case 'r': + case 'n': cmlparams.buffer_size = param->value.ui; cmlparams.buffer_size_set = 1; break; - case 's': - cmlparams.iso_prebuffers = param->value.ui; - cmlparams.iso_prebuffers_set = 1; + case 'r': + cmlparams.sample_rate = param->value.ui; + cmlparams.sample_rate_set = 1; break; case 'i': - cmlparams.iso_irq_interval = param->value.ui; - cmlparams.iso_irq_interval_set = 1; + cmlparams.capture_ports = param->value.ui; break; - case 'a': - cmlparams.sample_rate = param->value.ui; - cmlparams.sample_rate_set = 1; + case 'o': + cmlparams.playback_ports = param->value.ui; break; } } diff --git a/drivers/freebob/freebob_driver.h b/drivers/freebob/freebob_driver.h index c58c679..914e813 100644 --- a/drivers/freebob/freebob_driver.h +++ b/drivers/freebob/freebob_driver.h @@ -66,14 +66,6 @@ //#define DEBUG #endif -#define FREEBOB_USE_RT 1 -#define FREEBOB_RT_PRIORITY_PACKETIZER 60 -// midi priority should be higher than the audio priority in order to -// make sure events are not only delivered on period boundarys -// but I think it should be smaller than the packetizer thread in order not -// to lose any packets -#define FREEBOB_RT_PRIORITY_MIDI 59 - // debug print control flags #define DEBUG_LEVEL_BUFFERS (1<<0) #define DEBUG_LEVEL_HANDLERS (1<<1) @@ -118,11 +110,28 @@ #define debugPrintWithTimeStamp(Level, format, args...) #endif +// thread priority setup +#define FREEBOB_RT_PRIORITY_PACKETIZER_RELATIVE 5 + +#ifdef FREEBOB_DRIVER_WITH_MIDI + + #define ALSA_SEQ_BUFF_SIZE 1024 + #define MIDI_TRANSMIT_BUFFER_SIZE 1024 + #define MIDI_THREAD_SLEEP_TIME_USECS 100 + // midi priority should be higher than the audio priority in order to + // make sure events are not only delivered on period boundarys + // but I think it should be smaller than the packetizer thread in order not + // to lose any packets + #define FREEBOB_RT_PRIORITY_MIDI_RELATIVE 4 + +#endif + +typedef struct _freebob_driver freebob_driver_t; /* * Jack Driver command line parameters */ - + typedef struct _freebob_jack_settings freebob_jack_settings_t; struct _freebob_jack_settings { int period_size_set; @@ -131,21 +140,6 @@ struct _freebob_jack_settings { int sample_rate_set; int sample_rate; - int fifo_size_set; - jack_nframes_t fifo_size; - - int table_size_set; - jack_nframes_t table_size; - - int iso_buffers_set; - jack_nframes_t iso_buffers; - - int iso_prebuffers_set; - jack_nframes_t iso_prebuffers; - - int iso_irq_interval_set; - int iso_irq_interval; - int buffer_size_set; jack_nframes_t buffer_size; @@ -155,14 +149,14 @@ struct _freebob_jack_settings { int node_id_set; int node_id; + int playback_ports; + int capture_ports; + freebob_handle_t fb_handle; }; #ifdef FREEBOB_DRIVER_WITH_MIDI -#define ALSA_SEQ_BUFF_SIZE 1024 -#define MIDI_TRANSMIT_BUFFER_SIZE 1024 -#define MIDI_THREAD_SLEEP_TIME_USECS 100 typedef struct { int stream_nr; @@ -173,7 +167,8 @@ typedef struct { typedef struct _freebob_driver_midi_handle { freebob_device_t *dev; - + freebob_driver_t *driver; + snd_seq_t *seq_handle; pthread_t queue_thread; @@ -198,7 +193,6 @@ typedef struct _freebob_driver_midi_handle { * JACK driver structure */ -typedef struct _freebob_driver freebob_driver_t; struct _freebob_driver { @@ -231,6 +225,8 @@ struct _freebob_driver channel_t playback_nchannels; channel_t capture_nchannels; + freebob_device_info_t device_info; + freebob_options_t device_options; #ifdef FREEBOB_DRIVER_WITH_MIDI freebob_driver_midi_handle_t *midi_handle;