From 200565b81542d1b0fde1a657b807646733f2508c Mon Sep 17 00:00:00 2001 From: David Robillard Date: Fri, 9 Feb 2007 00:17:15 +0000 Subject: Applied patch from Steve Harris, changes to work with new LV2 ontology port classes. git-svn-id: http://svn.drobilla.net/lad/slv2@291 a436a847-0d15-0410-975c-d299462d15a1 --- hosts/lv2_jack_host.c | 114 +++++++++++++++++-------------------------- hosts/lv2_simple_jack_host.c | 17 +++---- slv2/port.h | 2 +- slv2/types.h | 34 ++++++------- src/port.c | 49 +++++++++++++------ utils/lv2_inspect.c | 35 +++++++++++++ 6 files changed, 136 insertions(+), 115 deletions(-) diff --git a/hosts/lv2_jack_host.c b/hosts/lv2_jack_host.c index 03d57d9..638c420 100644 --- a/hosts/lv2_jack_host.c +++ b/hosts/lv2_jack_host.c @@ -32,13 +32,11 @@ #endif // WITH_MIDI struct Port { - enum Direction { INPUT, OUTPUT} direction; - enum Type { UNKNOWN, FLOAT, MIDI } type; - - SLV2PortID id; - jack_port_t* jack_port; /**< For audio and MIDI ports, otherwise NULL */ - float control; /**< For control ports, otherwise 0.0f */ - LV2_MIDI* midi_buffer; /**< For midi ports, otherwise NULL */ + SLV2PortID id; + SLV2PortClass class; + jack_port_t* jack_port; /**< For audio and MIDI ports, otherwise NULL */ + float control; /**< For control ports, otherwise 0.0f */ + LV2_MIDI* midi_buffer; /**< For midi ports, otherwise NULL */ }; @@ -176,79 +174,53 @@ create_port(struct JackHost* host, struct Port* const port = &host->ports[port_index]; port->id = slv2_port_by_index(port_index); - port->type = UNKNOWN; + port->class = SLV2_UNKNOWN_PORT_CLASS; port->jack_port = NULL; port->control = 0.0f; port->midi_buffer = NULL; - + slv2_instance_connect_port(host->instance, port_index, NULL); char* type_str = slv2_port_get_data_type(host->plugin, port->id); - - if (!strcmp(type_str, SLV2_DATA_TYPE_FLOAT)) - port->type = FLOAT; - else if (!strcmp(type_str, SLV2_DATA_TYPE_MIDI)) - port->type = MIDI; - + /* Get the port symbol (label) for console printing */ char* symbol = slv2_port_get_symbol(host->plugin, port->id); - + /* Get the 'class' (not data type) of the port (control input, audio output, etc) */ - enum SLV2PortClass class = slv2_port_get_class(host->plugin, port->id); - - if (port->type == FLOAT) { - - /* Connect the port based on it's 'class' */ - switch (class) { - case SLV2_CONTROL_RATE_INPUT: - port->direction = INPUT; + port->class = slv2_port_get_class(host->plugin, port->id); + + /* Connect the port based on it's 'class' */ + switch (port->class) { + case SLV2_CONTROL_INPUT: port->control = slv2_port_get_default_value(host->plugin, port->id); slv2_instance_connect_port(host->instance, port_index, &port->control); printf("Set %s to %f\n", symbol, host->ports[port_index].control); break; - case SLV2_CONTROL_RATE_OUTPUT: - port->direction = OUTPUT; + case SLV2_CONTROL_OUTPUT: slv2_instance_connect_port(host->instance, port_index, &port->control); break; - case SLV2_AUDIO_RATE_INPUT: - port->direction = INPUT; + case SLV2_AUDIO_INPUT: port->jack_port = jack_port_register(host->jack_client, - symbol, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0); + symbol, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0); break; - case SLV2_AUDIO_RATE_OUTPUT: - port->direction = OUTPUT; + case SLV2_AUDIO_OUTPUT: port->jack_port = jack_port_register(host->jack_client, - symbol, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); + symbol, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); break; - default: - fprintf(stderr, "ERROR: Unknown port class\n"); - } - - } else if (port->type == MIDI) { - - if (class == SLV2_CONTROL_RATE_INPUT) { - port->direction = INPUT; + case SLV2_MIDI_INPUT: port->jack_port = jack_port_register(host->jack_client, - symbol, JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0); + symbol, JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0); port->midi_buffer = lv2midi_new(MIDI_BUFFER_SIZE); slv2_instance_connect_port(host->instance, port_index, port->midi_buffer); - } else if (class == SLV2_CONTROL_RATE_OUTPUT) { - port->direction = OUTPUT; + break; + case SLV2_MIDI_OUTPUT: port->jack_port = jack_port_register(host->jack_client, - symbol, JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput, 0); + symbol, JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput, 0); port->midi_buffer = lv2midi_new(MIDI_BUFFER_SIZE); slv2_instance_connect_port(host->instance, port_index, port->midi_buffer); - } else { - fprintf(stderr, "ERROR: Audio rate MIDI port?? Ignoring.\n"); - } - - } else { - - fprintf(stderr, "Unrecognized data type %s for port %s, ignored.\n", - type_str, symbol); - fprintf(stderr, " %s\n", - SLV2_DATA_TYPE_MIDI); - + break; + default: + fprintf(stderr, "ERROR: Unknown port class\n"); } free(symbol); @@ -267,31 +239,34 @@ jack_process_cb(jack_nframes_t nframes, void* data) if (!host->ports[p].jack_port) continue; - if (host->ports[p].type == FLOAT) { + if (host->ports[p].class == SLV2_AUDIO_INPUT + || host->ports[p].class == SLV2_AUDIO_OUTPUT) { slv2_instance_connect_port(host->instance, p, jack_port_get_buffer(host->ports[p].jack_port, nframes)); - } else if (host->ports[p].type == MIDI) { - + } else if (host->ports[p].class == SLV2_MIDI_INPUT) { void* jack_buffer = jack_port_get_buffer(host->ports[p].jack_port, nframes); LV2_MIDIState state; lv2midi_reset_state(&state, host->ports[p].midi_buffer, nframes); lv2midi_reset_buffer(state.midi); - - if (host->ports[p].direction == INPUT) { - jack_midi_event_t ev; - const jack_nframes_t event_count - = jack_midi_get_event_count(jack_buffer, nframes); + jack_midi_event_t ev; - for (jack_nframes_t e=0; e < event_count; ++e) { + const jack_nframes_t event_count + = jack_midi_get_event_count(jack_buffer, nframes); - jack_midi_event_get(&ev, jack_buffer, e, nframes); + for (jack_nframes_t e=0; e < event_count; ++e) { - state.midi = host->ports[p].midi_buffer; - lv2midi_put_event(&state, (double)ev.time, ev.size, ev.buffer); - } + jack_midi_event_get(&ev, jack_buffer, e, nframes); + + state.midi = host->ports[p].midi_buffer; + lv2midi_put_event(&state, (double)ev.time, ev.size, ev.buffer); } + } else if (host->ports[p].class == SLV2_MIDI_OUTPUT) { + + LV2_MIDIState state; + lv2midi_reset_state(&state, host->ports[p].midi_buffer, nframes); + lv2midi_reset_buffer(state.midi); } } @@ -303,8 +278,7 @@ jack_process_cb(jack_nframes_t nframes, void* data) /* Deliver output */ for (uint32_t p=0; p < host->num_ports; ++p) { if (host->ports[p].jack_port - && host->ports[p].type == MIDI - && host->ports[p].direction == OUTPUT) { + && host->ports[p].class == SLV2_MIDI_OUTPUT) { void* jack_buffer = jack_port_get_buffer(host->ports[p].jack_port, nframes); diff --git a/hosts/lv2_simple_jack_host.c b/hosts/lv2_simple_jack_host.c index ef386b7..5e1e0a9 100644 --- a/hosts/lv2_simple_jack_host.c +++ b/hosts/lv2_simple_jack_host.c @@ -155,12 +155,6 @@ create_port(struct JackHost* host, { SLV2PortID id = slv2_port_by_index(index); - /* Make sure this is a float port */ - char* type = slv2_port_get_data_type(host->plugin, id); - if (strcmp(type, SLV2_DATA_TYPE_FLOAT)) - die("Unrecognized data type, aborting."); - free(type); - /* Get the port symbol (label) for console printing */ char* symbol = slv2_port_get_symbol(host->plugin, id); @@ -169,27 +163,28 @@ create_port(struct JackHost* host, host->controls[index] = 0.0f; /* Get the 'class' of the port (control input, audio output, etc) */ - enum SLV2PortClass class = slv2_port_get_class(host->plugin, id); + SLV2PortClass class = slv2_port_get_class(host->plugin, id); /* Connect the port based on it's 'class' */ switch (class) { - case SLV2_CONTROL_RATE_INPUT: + case SLV2_CONTROL_INPUT: host->controls[index] = slv2_port_get_default_value(host->plugin, id); slv2_instance_connect_port(host->instance, index, &host->controls[index]); printf("Set %s to %f\n", symbol, host->controls[index]); break; - case SLV2_CONTROL_RATE_OUTPUT: + case SLV2_CONTROL_OUTPUT: slv2_instance_connect_port(host->instance, index, &host->controls[index]); break; - case SLV2_AUDIO_RATE_INPUT: + case SLV2_AUDIO_INPUT: host->jack_ports[index] = jack_port_register(host->jack_client, symbol, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0); break; - case SLV2_AUDIO_RATE_OUTPUT: + case SLV2_AUDIO_OUTPUT: host->jack_ports[index] = jack_port_register(host->jack_client, symbol, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); break; default: + // Simple examples don't have to be robust :) die("ERROR: Unknown port type, aborting messily!"); } diff --git a/slv2/port.h b/slv2/port.h index 8e5b006..7b1d98a 100644 --- a/slv2/port.h +++ b/slv2/port.h @@ -89,7 +89,7 @@ slv2_port_get_name(SLV2Plugin* plugin, /** Get the class (direction and rate) of a port. */ -enum SLV2PortClass +SLV2PortClass slv2_port_get_class(SLV2Plugin* plugin, SLV2PortID id); diff --git a/slv2/types.h b/slv2/types.h index 19f1f2b..7e366ba 100644 --- a/slv2/types.h +++ b/slv2/types.h @@ -48,30 +48,28 @@ slv2_value_free(SLV2Value); /** Port ID type, to allow passing either symbol or index * to port related functions. */ -struct _PortID { +typedef struct _PortID { bool is_index; /**< Otherwise, symbol */ uint32_t index; const char* symbol; -}; - -typedef struct _PortID SLV2PortID; +} SLV2PortID; -/** Class (direction and rate) of a port */ -enum SLV2PortClass { +/** Class (direction and type) of a port + * + * Note that ports may be of other classes not listed here, this is just + * to make the most common case simple. Use slv2_port_get_value(p, "rdf:type") + * if you need further class information. + */ +typedef enum _PortClass { SLV2_UNKNOWN_PORT_CLASS, - SLV2_CONTROL_RATE_INPUT, /**< One input value per block */ - SLV2_CONTROL_RATE_OUTPUT, /**< One output value per block */ - SLV2_AUDIO_RATE_INPUT, /**< One input value per frame */ - SLV2_AUDIO_RATE_OUTPUT /**< One output value per frame */ -}; - - -/** lv2:float, IEEE-754 32-bit floating point number */ -#define SLV2_DATA_TYPE_FLOAT "http://lv2plug.in/ontology#float" - -/** MIDI buffer, as defined by lv2-miditype.h */ -#define SLV2_DATA_TYPE_MIDI "http://ll-plugins.nongnu.org/lv2/ext/miditype" + SLV2_CONTROL_INPUT, /**< One input float per block */ + SLV2_CONTROL_OUTPUT, /**< One output float per block */ + SLV2_AUDIO_INPUT, /**< One input float per frame */ + SLV2_AUDIO_OUTPUT, /**< One output float per frame */ + SLV2_MIDI_INPUT, /**< MIDI input (LL extension) */ + SLV2_MIDI_OUTPUT /**< MIDI output (LL extension) */ +} SLV2PortClass; #ifdef __cplusplus diff --git a/src/port.c b/src/port.c index eb4ba48..f64dbbe 100644 --- a/src/port.c +++ b/src/port.c @@ -49,7 +49,7 @@ slv2_port_by_symbol(const char* symbol) } -enum SLV2PortClass +SLV2PortClass slv2_port_get_class(SLV2Plugin* p, SLV2PortID id) { @@ -57,20 +57,39 @@ slv2_port_get_class(SLV2Plugin* p, assert(class); assert(class->num_values > 0); assert(class->values); - - enum SLV2PortClass ret; - - if (!strcmp((char*)class->values[0], "http://lv2plug.in/ontology#ControlRateInputPort")) - ret = SLV2_CONTROL_RATE_INPUT; - else if (!strcmp((char*)class->values[0], "http://lv2plug.in/ontology#ControlRateOutputPort")) - ret = SLV2_CONTROL_RATE_OUTPUT; - else if (!strcmp((char*)class->values[0], "http://lv2plug.in/ontology#AudioRateInputPort")) - ret = SLV2_AUDIO_RATE_INPUT; - else if (!strcmp((char*)class->values[0], "http://lv2plug.in/ontology#AudioRateOutputPort")) - ret = SLV2_AUDIO_RATE_OUTPUT; - else { - fprintf(stderr, "Unknown port class: %s\n", class->values[0]); - ret = SLV2_UNKNOWN_PORT_CLASS; + + SLV2PortClass ret = SLV2_UNKNOWN_PORT_CLASS; + + int io = -1; // 0 = in, 1 = out + enum { UNKNOWN, AUDIO, CONTROL, MIDI } type = UNKNOWN; + + for (size_t i=0; i < class->num_values; ++i) { + if (!strcmp((char*)class->values[i], "http://lv2plug.in/ontology#InputPort")) + io = 0; + else if (!strcmp((char*)class->values[i], "http://lv2plug.in/ontology#OutputPort")) + io = 1; + else if (!strcmp((char*)class->values[i], "http://lv2plug.in/ontology#ControlPort")) + type = CONTROL; + else if (!strcmp((char*)class->values[i], "http://lv2plug.in/ontology#AudioPort")) + type = AUDIO; + else if (!strcmp((char*)class->values[i], "http://ll-plugins.nongnu.org/lv2/ext/MidiPort")) + type = MIDI; + } + + if (io == 0) { + if (type == AUDIO) + ret = SLV2_AUDIO_INPUT; + else if (type == CONTROL) + ret = SLV2_CONTROL_INPUT; + else if (type == MIDI) + ret = SLV2_MIDI_INPUT; + } else if (io == 1) { + if (type == AUDIO) + ret = SLV2_AUDIO_OUTPUT; + else if (type == CONTROL) + ret = SLV2_CONTROL_OUTPUT; + else if (type == MIDI) + ret = SLV2_MIDI_OUTPUT; } slv2_value_free(class); diff --git a/utils/lv2_inspect.c b/utils/lv2_inspect.c index c8ffd55..a7aaf1a 100644 --- a/utils/lv2_inspect.c +++ b/utils/lv2_inspect.c @@ -27,9 +27,37 @@ print_port(SLV2Plugin* p, uint32_t index) SLV2PortID id = slv2_port_by_index(index); char* str = NULL; + SLV2PortClass cl = SLV2_UNKNOWN_PORT_CLASS; printf("\n\tPort %d:\n", index); + cl = slv2_port_get_class(p, id); + printf("\t\tClass: "); + switch (cl) { + case SLV2_CONTROL_INPUT: + printf("Control input"); + break; + case SLV2_CONTROL_OUTPUT: + printf("Control output"); + break; + case SLV2_AUDIO_INPUT: + printf("Audio input"); + break; + case SLV2_AUDIO_OUTPUT: + printf("Audio output"); + break; + case SLV2_MIDI_INPUT: + printf("MIDI input"); + break; + case SLV2_MIDI_OUTPUT: + printf("MIDI output"); + break; + case SLV2_UNKNOWN_PORT_CLASS: + printf("Unknown"); + break; + } + + printf("\n"); str = slv2_port_get_symbol(p, id); printf("\t\tSymbol: %s\n", str); free(str); @@ -37,6 +65,13 @@ print_port(SLV2Plugin* p, uint32_t index) str = slv2_port_get_name(p, id); printf("\t\tName: %s\n", str); free(str); + + if (cl == SLV2_CONTROL_INPUT || + cl == SLV2_CONTROL_OUTPUT) { + printf("\t\tMinimum: %f\n", slv2_port_get_minimum_value(p, id)); + printf("\t\tMaximum: %f\n", slv2_port_get_maximum_value(p, id)); + printf("\t\tDefault: %f\n", slv2_port_get_default_value(p, id)); + } } -- cgit v1.2.1