lv2 midi input
Moderators: MattKingUSA, khz
- skei
- Established Member
- Posts: 339
- Joined: Sun May 18, 2014 4:24 pm
- Has thanked: 8 times
- Been thanked: 57 times
- Contact:
lv2 midi input
i'm currently adding lv2 support to my plugin framework.. but the documentation isn't the best i've seen, and i have a few problems.. i started with the midi gate example here: http://lv2plug.in/book/#_midi_gate, and modified it so that it just prints out the raw midi bytes when there's a midi event.. this works in qtractor and ardour, but not in carla.. which is a bit unfortunate, since carla is the only lv2-supporting host i use myself.. with carla, if i print out the supported extensions (the 'features' thing) during instantiation, i don't see any mention of anything resembling midi.. but then, qtractor tells me it only supports one feature ('http://lv2plug.in/ns/ext/urid#map'), but still it works.. hmm.. i'm getting confused..
so, concretely.. what do i do to receive midi from carla?
and also, is there a 'canonical' list of extensions i can expect all hosts to support?
- tor-helge
so, concretely.. what do i do to receive midi from carla?
and also, is there a 'canonical' list of extensions i can expect all hosts to support?
- tor-helge
- skei
- Established Member
- Posts: 339
- Joined: Sun May 18, 2014 4:24 pm
- Has thanked: 8 times
- Been thanked: 57 times
- Contact:
Re: lv2 midi input
i've been looking through a bunch of examples on github, and trying the event extension stuff, but still the same results..
there's obviously something i don't understand.. :-/ maybe i should put lv2 away for a while, and focus on vst3, and then (possibly) return to it a little later..
there's obviously something i don't understand.. :-/ maybe i should put lv2 away for a while, and focus on vst3, and then (possibly) return to it a little later..
-
- Established Member
- Posts: 33
- Joined: Sat Jun 27, 2015 6:29 pm
- Been thanked: 1 time
- Contact:
Re: lv2 midi input
Some hosts route/eat/drop standard output/error from plugins. Don't know whether carla is one of them. You can try to write to a file instead...this works in qtractor and ardour, but not in carla..
Or even better, use LV2's log extension (if carla supports it).
You just mention in your plugin metadata (the strange RDF turtle file) that your atom event port support MIDI, and the host will send the MIDI to that port.so, concretely.. what do i do to receive midi from carla?
No, that's why they are called extensions. It works like this: If a plugin needs an extension, it mentions that in its plugin metadata and if the host does not support that extension, it simply won't support that plugin, e.g. don't show it as a selection to the user.and also, is there a 'canonical' list of extensions i can expect all hosts to support?
Last edited by ventosus on Fri Jun 22, 2018 7:11 am, edited 1 time in total.
-
- Established Member
- Posts: 33
- Joined: Sat Jun 27, 2015 6:29 pm
- Been thanked: 1 time
- Contact:
Re: lv2 midi input
MIDI plugins (or more general event plugins) need that extension. So the plugin you've looked at lists it as required in its plugin metadata.qtractor tells me it only supports one feature ('http://lv2plug.in/ns/ext/urid#map')
Some hosts list all their supported extensions in the features list. Other hosts only list the required (by the plugin) extensions in the features list. The latter is most probably what you saw in qtractor (I'm pretty sure that it supports more extensions...)
- skei
- Established Member
- Posts: 339
- Joined: Sun May 18, 2014 4:24 pm
- Has thanked: 8 times
- Been thanked: 57 times
- Contact:
Re: lv2 midi input
i know.. (and yes, carla drops stdout, it seems).. in my framework, i have a bunch of "debug outputs", selectable with some #ifdefs, like stdout, logfile, socket, gui/window, etc.. when coding plugins, i usually push all debug output through a socket, and print it out in another terminal.. all other debug info is printed correctly, so this works quite well..ventosus wrote:Some hosts route/eat/drop standard output/error from plugins. Don't know whether carla is one of them. You can try to write to a file instead...
Or even better, use LV2's log extension (if carla supports it).
i thought i did.. i followed the examples rigorously, and double- and triple-checked everything.. but obviously there's something i missed, or whatever..ventosus wrote:You just mention in your plugin metadata (the strange RDF turtle file) that your atom event port support MIDI, and the host will send the MIDI to that port.
yeah, i have understood that now..ventosus wrote:If a plugin needs an extension, it mentions that in its plugin metadata and if the host does not support that extension, it simply won't support that plugin, e.g. don't show it as a selection to the user.
- skei
- Established Member
- Posts: 339
- Joined: Sun May 18, 2014 4:24 pm
- Has thanked: 8 times
- Been thanked: 57 times
- Contact:
Re: lv2 midi input
thanks!ventosus wrote:Here a MIDI-only plugin bundle with lots of examples:
https://github.com/x42/midifilter.lv2
- skei
- Established Member
- Posts: 339
- Joined: Sun May 18, 2014 4:24 pm
- Has thanked: 8 times
- Been thanked: 57 times
- Contact:
Re: lv2 midi input
ok..ventosus wrote:MIDI plugins (or more general event plugins) need that extension. So the plugin you've looked at lists it as required in its plugin metadata.qtractor tells me it only supports one feature ('http://lv2plug.in/ns/ext/urid#map')
Some hosts list all their supported extensions in the features list. Other hosts only list the required (by the plugin) extensions in the features list. The latter is most probably what you saw in qtractor (I'm pretty sure that it supports more extensions...)
- skei
- Established Member
- Posts: 339
- Joined: Sun May 18, 2014 4:24 pm
- Has thanked: 8 times
- Been thanked: 57 times
- Contact:
Re: lv2 midi input
yeah.. i see it now.. no idea why i overlooked that before..falkTX wrote:Carla captures the stdout/stderr so it can be shown on the GUI, it is useful to get some debug output out of plugins from users that do not start Carla from a terminal.
Disabling this is quite easy, it is right on the first page of Carla settings.
but since i have this socket thing up and running (i initially needed it to test and debug vst plugins in bitwig), it's not an issue, actually..
- skei
- Established Member
- Posts: 339
- Joined: Sun May 18, 2014 4:24 pm
- Has thanked: 8 times
- Been thanked: 57 times
- Contact:
Re: lv2 midi input
so, the problem i'm having is getting midi input from carla.. the code below works in qtractor and ardour (haven't tested much else).. in carla, the light/led lights up when i press a midi key, but my plugin doesn't seem to receive the midi events..
i tried to extract the minimal code needed to show what i do.. let's hope it still understandable
i separate plugins into two classes, the main plugin class which handles/manages the plugin/.so itself, and the descriptors, etc, and an instance class for each, well, instance.. the plugin class is a static class (object?), mainly to have automatic cleanup via the destructor when the .so is unloaded.. MLV2* prefixed variables are part of the plugin (or instance) class, on_instance_midiEvent() is a virtual function that individual plugins override if they want midi input.. and also, most of this is wrapped in #ifdef PLUGIN_RECEIVE MIDI .. #endif and similar constructs..
define midi input port:
instantiation:
connect the port:
and finally, at the start of the run() function:
does anybody see any obvious errors or missing things or other issues?
i also tried another way, using some AtomPort stuff (i think?), with the same results,
except that i felt it was more confusing - more terminology and stuff i don't fully grasp yet..
(but that also worked in qtractor and ardour, but not carla, so the problem might be somewhere else?)
i tried to extract the minimal code needed to show what i do.. let's hope it still understandable
i separate plugins into two classes, the main plugin class which handles/manages the plugin/.so itself, and the descriptors, etc, and an instance class for each, well, instance.. the plugin class is a static class (object?), mainly to have automatic cleanup via the destructor when the .so is unloaded.. MLV2* prefixed variables are part of the plugin (or instance) class, on_instance_midiEvent() is a virtual function that individual plugins override if they want midi input.. and also, most of this is wrapped in #ifdef PLUGIN_RECEIVE MIDI .. #endif and similar constructs..
define midi input port:
Code: Select all
lv2:port [
a ev:EventPort, lv2:InputPort;
lv2:index 6 ;
ev:supportsEvent <http://lv2plug.in/ns/ext/midi#MidiEvent> ;
lv2:symbol "midi" ;
lv2:name "MIDI Input" ;
] .
Code: Select all
LV2_URI_Map_Feature* map_feature;
const LV2_Feature* const* ft;
for (ft=features; *ft; ft++) {
if (!strcmp((*ft)->URI,"http://lv2plug.in/ns/ext/uri-map")) { // LV2_URI_MAP_URI
map_feature = (LV2_URI_Map_Feature*)(*ft)->data;
MLV2EventType = map_feature->uri_to_id(
map_feature->callback_data,
"http://lv2plug.in/ns/ext/event",
"http://lv2plug.in/ns/ext/midi#MidiEvent"
);
}
else if (!strcmp((*ft)->URI, "http://lv2plug.in/ns/ext/event")) {
MLV2EventFeature =(LV2_Event_Feature*)(*ft)->data;
}
}
Code: Select all
MLV2EventBuffer = (LV2_Event_Buffer*)data_location;
Code: Select all
LV2_Event_Iterator event_iterator;
lv2_event_begin(&event_iterator,MLV2EventBuffer);
while (lv2_event_is_valid(&event_iterator)) {
uint8_t* data;
LV2_Event* event = lv2_event_get(&event_iterator,&data);
if (event->type == 0) {
MLV2EventFeature->lv2_event_unref(MLV2EventFeature->callback_data, event);
}
else if (event->type == MLV2EventType) {
uint32_t offset = event->frames;
const uint8_t* msg = (uint8_t*)data;
on_instance_midiEvent(offset,msg[0],msg[1],msg[2]);
}
lv2_event_increment(&event_iterator);
}
i also tried another way, using some AtomPort stuff (i think?), with the same results,
except that i felt it was more confusing - more terminology and stuff i don't fully grasp yet..
(but that also worked in qtractor and ardour, but not carla, so the problem might be somewhere else?)
- skei
- Established Member
- Posts: 339
- Joined: Sun May 18, 2014 4:24 pm
- Has thanked: 8 times
- Been thanked: 57 times
- Contact:
Re: lv2 midi input
no, just one.. this is just a test plugin, and i have 2 audio inputs, 2 audio outputs, and 2 control inputs (parameters), plus this midi inputfalkTX wrote:do you have more than 1 midi input port?
i will try thatfalkTX wrote:try setting the lv2:designation lv2:control on the port.
ok.. i have to read up a little about these atoms, and look at urid-mapfalkTX wrote:you are using 2 deprecated things, which is not a good thing to start with.
atom can be confusing, but please use urid-map instead of uri-map.
the 2nd parameter on the uri-map function is confusing..
not yet.. i will publish the library/framework as soon as i can get the main plugin formats (ladspa, dssi, lv2, vst2, vst3, standalone) basically working (at least a minimal version, so i can build for example a simple gui-less synth in all formats)falkTX wrote:is the full code published somewhere?
..and decided on licensing and all that stuff :-/
i use the latest version from your kx studio repositories (help/about says "version 1.9.8 (2.0-beta6)"falkTX wrote:also, is your carla self-compiled? I would say, make sure you are using latest git, I am about to make a new bugfix release.
lots of stuff fixed lately
(in linux mint/cinnamon, in case that matters)..
always looking forward to new versions of your stuff..
(mega-thanks for all your linux-audio efforts!)
- skei
- Established Member
- Posts: 339
- Joined: Sun May 18, 2014 4:24 pm
- Has thanked: 8 times
- Been thanked: 57 times
- Contact:
Re: lv2 midi input
i looked at the example from here: http://lv2plug.in/book/#_midi_gate
and came up with something like the below.. i don't fully understand what everyting is doing yet, so i absolutely need to look at some docs
but, same result.. works in qtractor, didn't test in ardour, doesn't work in carla..
the little led/light on the plugin in the carla rack view lights up when i press a midi key.. does that mean carla is sending the midi to the plugin?
kode_debug.ttl:
and came up with something like the below.. i don't fully understand what everyting is doing yet, so i absolutely need to look at some docs
but, same result.. works in qtractor, didn't test in ardour, doesn't work in carla..
the little led/light on the plugin in the carla rack view lights up when i press a midi key.. does that mean carla is sending the midi to the plugin?
kode_debug.ttl:
Code: Select all
@prefix doap: <http://usefulinc.com/ns/doap#> .
@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix atom: <http://lv2plug.in/ns/ext/atom#> .
@prefix midi: <http://lv2plug.in/ns/ext/midi#> .
@prefix urid: <http://lv2plug.in/ns/ext/urid#> .
<urn:skei.audio/kode_debug>
a lv2:Plugin , lv2:InstrumentPlugin ;
doap:name "kode_debug" ;
lv2:optionalFeature lv2:hardRTCapable ;
lv2:requiredFeature urid:map ;
lv2:port [
...
...
] , [
a lv2:InputPort , atom:AtomPort ;
atom:bufferType atom:Sequence ;
atom:supports midi:MidiEvent ;
lv2:designation lv2:control ;
lv2:index 6 ;
lv2:symbol "midi_in" ;
lv2:name "Midi in"
] .
Code: Select all
#define KODE_PLUGIN_LV2_MAX_URIS 16
plugin instance class:
const LV2_Atom_Sequence* MLV2AtomSequence = KODE_NULL;
LV2_URID_Map* MLV2Map = KODE_NULL;
KODE_uint32 MMidiEventType = 0;
LV2_URID* MLV2URIS = KODE_NULL;
plugin class.
// for some reason, i thought it could be smart to prepare for multiple uri's..
LV2_URID MLV2URIS[KODE_PLUGIN_LV2_MAX_URIS] = {0};
instantiate()
LV2_URID_Map* map = NULL;
for (int i=0; features[i]; ++i) {
if (!strcmp(features[i]->URI, LV2_URID__map)) {
map = (LV2_URID_Map*)features[i]->data;
break;
}
}
if (!map) return KODE_NULL;
MLV2URIS[0] = map->map(map->handle, LV2_MIDI__MidiEvent);
...
instance->MLV2URIS = MLV2URIS;
connect()
MLV2AtomSequence = (const LV2_Atom_Sequence*)data_location;
run()
uint32_t offset = 0;
LV2_ATOM_SEQUENCE_FOREACH(MLV2AtomSequence, ev) {
if (ev->body.type == MLV2URIS[0]) {
const uint8_t* const msg = (const uint8_t*)(ev + 1);
offset = (uint32_t)ev->time.frames;
on_instance_midiEvent(offset,msg[0],msg[1],msg[2]);
}
}
- skei
- Established Member
- Posts: 339
- Joined: Sun May 18, 2014 4:24 pm
- Has thanked: 8 times
- Been thanked: 57 times
- Contact:
Re: lv2 midi input
no, i'm sending/playing notes..falkTX wrote:are you trying to send MIDI CCs by any chance?
those are disabled by default.
btw, when plugins have midi input, you can use the built-in keyboard widget to send some notes to the plugin.
test that too, to see if something gets received or not.
and, nothing happens if i click on the on-screen keyboard..
it looks like everything is ok on the carla side, but no reaction from my plugin..
so, i just tested with jalv (jalv.select?)..
the plugin loads and everything, but just like carla, nothing is printed out..
(and it looks ok in catia, with a red midi_in port)
maybe that indicates that it's the handling of events insinde my plugin that is the problem?
hmmm...
i just watched a video about the atom stuff, and read some docs, or specs?.. something are a little bit clearer (atom, uri/urid, at least the principles, the 'what' part).. but something are maybe a bit more confusing (the 'how') part)..
it wouldn't hurt if there were more 'how to get started with..' or 'introduction to..' tutorials..
- skei
- Established Member
- Posts: 339
- Joined: Sun May 18, 2014 4:24 pm
- Has thanked: 8 times
- Been thanked: 57 times
- Contact:
Re: lv2 midi input
i feel so stupid! my connect_port function was buggy!
after fixing this, i have midi input in carla too!!
sorry for taking up everybody's time with my stupidity!
after fixing this, i have midi input in carla too!!
sorry for taking up everybody's time with my stupidity!