*** unclechu has quit IRC | 00:52 | |
*** gabrbedd has quit IRC | 02:54 | |
*** gabrbedd has joined #lv2 | 02:58 | |
*** falktx has joined #lv2 | 03:22 | |
*** falktx` has quit IRC | 03:26 | |
*** oofus_lt has joined #lv2 | 07:19 | |
*** unclechu has joined #lv2 | 08:17 | |
*** ricardocrudo has joined #lv2 | 09:19 | |
*** falktx|work has joined #lv2 | 09:19 | |
*** arguy has quit IRC | 10:50 | |
*** rncbc has joined #lv2 | 14:19 | |
*** oofus_lt has quit IRC | 14:27 | |
*** ssj71 has joined #lv2 | 15:18 | |
*** son0p_ has quit IRC | 15:25 | |
*** son0p_ has joined #lv2 | 15:27 | |
*** oofus has joined #lv2 | 16:36 | |
*** jcelerier has joined #lv2 | 16:52 | |
jcelerier | hello :) | 16:52 |
---|---|---|
jcelerier | I'd like to make my sequencer LV2-compatible, is there a quick tutorial somewhere ? | 16:53 |
jcelerier | I've looked into lilv library | 16:53 |
jcelerier | but I don't really know where to starT... | 16:53 |
*** ricardocrudo has quit IRC | 16:55 | |
*** falktx|work has quit IRC | 16:55 | |
*** unclechu has quit IRC | 17:04 | |
*** unclechu has joined #lv2 | 17:16 | |
ColaEuphoria | jcelerier, could you describe your sequencer and what it does, specifically? | 17:17 |
jcelerier | ColaEuphoria: www.i-score.org | 17:17 |
jcelerier | it works like a tree and allows to use elements of programming in the score (conditions, loops, etc.) | 17:17 |
jcelerier | and allows to react to external events (network requests, etc..) | 17:18 |
jcelerier | the idea is to go a bit further than ableton in terms of interactivity | 17:19 |
jcelerier | currently I use Faust for audio effects | 17:19 |
ColaEuphoria | hmm | 17:23 |
ColaEuphoria | currently AFAIK, jcelerier, jalv is an example host for lv2 plugins | 17:23 |
ColaEuphoria | but IMO it isn't the smallest working example of an LV2 host | 17:24 |
jcelerier | I'm more looking for an explanation of the concepts behind LV2 to be fair | 17:24 |
jcelerier | e.g. what's the relationship between nodes, ports, plug-ins, plug-in classes, etc... | 17:24 |
jcelerier | how "everything fits together" basically | 17:24 |
ColaEuphoria | plug-in classes are nothing more than metadata, something that the host can use to put plugins into convenient locations for the user if it so desires | 17:25 |
ColaEuphoria | lv2 is essentially one big graph database | 17:26 |
jcelerier | not atree ? | 17:26 |
jcelerier | a tree * | 17:26 |
ColaEuphoria | in that sense, no | 17:27 |
ColaEuphoria | but lilv makes traversing the graph easier than, e.g., writing your own RDF query code | 17:27 |
ColaEuphoria | all the LilvNode stuff in lilv seems to be abstractions of the nodes in the lv2 graph database | 17:28 |
jcelerier | huh, it's using RDF behind the scenes ? | 17:30 |
jcelerier | wow | 17:30 |
jcelerier | okay, but I guess most of it is useful if I want to recreate UIs from the plug-ins | 17:31 |
ColaEuphoria | jcelerier, i made a super simple, non-general host for what it's worth http://pastebin.com/upB7ieBD | 17:32 |
jcelerier | for now just calling some process(float** in, float** out) would be fine for me :p | 17:32 |
jcelerier | also it seems to load plug-ins automagically, but does this work reliabely on every platform or is there a way to load things manually ? | 17:32 |
jcelerier | (for instance for weirder stuff such as emscripten, etc...) | 17:32 |
jcelerier | thanks, checking it | 17:33 |
jcelerier | lilv_new_uri(lworld, "https://sine.synth.love/"); > it can load stuff directly from the net ? Oo | 17:33 |
ColaEuphoria | noooo | 17:33 |
ColaEuphoria | the URI scheme is simply a universally unique identifier | 17:34 |
jcelerier | xD | 17:34 |
ColaEuphoria | it's just convention to make it a URI | 17:34 |
jcelerier | ... okay | 17:34 |
ColaEuphoria | it doesn't actually connect to anything | 17:34 |
ColaEuphoria | for example | 17:35 |
ColaEuphoria | well, just that LV2 doesn't really load plugins by filepath | 17:35 |
jcelerier | so, here, port 0 is an input constant, and port 1 is the data output. | 17:35 |
ColaEuphoria | it "queries" for turtle files in the standard LV2 paths on your system | 17:36 |
ColaEuphoria | in here, yes | 17:36 |
ColaEuphoria | it was a quick simple lv2 plugin i made | 17:36 |
jcelerier | and I guess that I can check for all the ports and see what they do | 17:36 |
jcelerier | in order to find the ones that I'm interested in. | 17:36 |
jcelerier | can ports vary dynamically ? | 17:36 |
jcelerier | or can I assume that they won't chang e? | 17:36 |
ColaEuphoria | keep in mind that what i'm doing with my "host" is extremely specific and won't work for much more than that specific plugin | 17:37 |
ColaEuphoria | ports can change if they make use of the Morph feature | 17:38 |
ColaEuphoria | I don't think it's worth implementing though, at least not when you're trying to just get basic LV2 functionality working | 17:38 |
ColaEuphoria | hosts should query the ports for each plugin it loads and not make assumptions about what ports do what | 17:38 |
jcelerier | okay | 17:38 |
jcelerier | and hopefully there will be a port that will allow some audio processing | 17:39 |
ColaEuphoria | yes | 17:39 |
ColaEuphoria | and that port | 17:39 |
ColaEuphoria | or ports | 17:39 |
ColaEuphoria | will be a lv2:AudioPort and an lv2:OutputPort | 17:40 |
jcelerier | nice, thanks | 17:40 |
jcelerier | I guess there are some macros / enum somewhere to allow finding themù | 17:40 |
ColaEuphoria | lilv has plenty of port-specific functions | 17:40 |
jcelerier | damn, that C++ API needs a good overhaul imho | 17:42 |
ColaEuphoria | what C++ API? | 17:43 |
jcelerier | lilvmm.hpp | 17:43 |
ColaEuphoria | ugh | 17:43 |
ColaEuphoria | honestly | 17:43 |
ColaEuphoria | C++ "wrapper" APIs tend to ubiquitously be garbage | 17:43 |
ColaEuphoria | it's also important to point | 17:48 |
ColaEuphoria | that lv2 discovery | 17:48 |
ColaEuphoria | simply queries your system for lv2 stuff | 17:48 |
ColaEuphoria | but DOESN'T immediately load the actual binaries | 17:48 |
jcelerier | nice | 17:48 |
ColaEuphoria | LilvNode *pluguri = lilv_new_uri(lworld, "https://sine.synth.love/"); | 17:49 |
ColaEuphoria | this queries the turtle files in your LV2 paths for a plugin who identifies itself as "https://sine.synth.love" | 17:49 |
ColaEuphoria | nothing more than a string | 17:49 |
ColaEuphoria | LilvInstance *synth = lilv_plugin_instantiate(plug, 44100, NULL); | 17:49 |
ColaEuphoria | i believe this actually loads the binary | 17:49 |
jcelerier | okay | 17:51 |
ColaEuphoria | i should probably fix this up and make it into some official "babby's first" host example | 17:51 |
ColaEuphoria | and note that an actual host must pay attention to the LV2 threading rules in http://lv2plug.in/ns/lv2core/ | 17:52 |
jcelerier | hmmm | 17:55 |
jcelerier | makes sense I guess | 17:55 |
jcelerier | > | 17:55 |
jcelerier | Plugin functions in any class MUST NOT manipulate any state which might affect other plugin or host code | 17:56 |
jcelerier | hehe | 17:56 |
jcelerier | that's a bit naive :p | 17:56 |
ColaEuphoria | you'd be surprised | 17:59 |
ColaEuphoria | how many people think it's a good idea to, for example, use `static` variables in functions | 18:00 |
ColaEuphoria | when writing a plugin | 18:00 |
jcelerier | yeah that's what I meant, it's like saying "Plugin authors MUST NOT write buggy plugins" | 18:00 |
ColaEuphoria | eh, it's just a formal way of saying it | 18:00 |
jcelerier | I think that the Bitwig Studio approach is cool for this : run each plug-in in its own process | 18:01 |
ColaEuphoria | you'd think that's cool | 18:01 |
ColaEuphoria | until you notice it's pretty tricky to get the inter-process communication to be efficient | 18:01 |
jcelerier | ah sure, but for the end-user it's so good to not loose data due to some_1998_vst.dll | 18:02 |
jcelerier | okay, this seems like it won't be such a terrible task after all. thanks a lot for your help :) | 18:08 |
ColaEuphoria | I'm also working on the "babby's first lv2 host" example now | 18:10 |
ColaEuphoria | going to try and formalize it | 18:10 |
jcelerier | that lv2_atom api smells a lot like max/msp's api | 18:21 |
ColaEuphoria | does it? i've never dealt with max/msp | 18:22 |
jcelerier | https://cycling74.com/sdk/MaxSDK-6.0.4/html/group__atom.html | 18:23 |
jcelerier | (do yourself a favor and keep not dealing with it ^^) | 18:24 |
ColaEuphoria | lol | 18:27 |
ColaEuphoria | alright i won't. i've had enough after VST | 18:27 |
ColaEuphoria | ;) | 18:27 |
drobilla | I suggest looking at the lilv API and/or simpler example hosts to get basic things working first | 18:33 |
drobilla | Diving down the rabbit hole of trying to understand absolutely everything from the specs first is not going to end well | 18:33 |
drobilla | lv2file is pretty small as well, but it's a bit messy | 18:35 |
ColaEuphoria | drobilla, at what point does lilv actually load a plugin binary? | 18:44 |
drobilla | instantiate | 19:00 |
jcelerier | @drobilla: are there examples somewhere on your website ? | 19:01 |
drobilla | This is not twitter :P | 19:02 |
drobilla | jcelerier: No, other than what's in lilv itself (utils) and Jalv | 19:02 |
drobilla | Jalv started much smaller/simpler than it is these days, it's probably outgrown its life as an "example" | 19:02 |
jcelerier | okay | 19:02 |
jcelerier | yeah, I was a bit discouraged when I saw 7-level-deep nested if-else | 19:03 |
jcelerier | :p | 19:03 |
jcelerier | I also tried to look at qtractor's source but it's intertwined with the gui and various ifdef for LV2_ATOM | 19:03 |
drobilla | One of the utils, say lv2info, has everything in there needed to get at a plugin | 19:03 |
drobilla | From there, instantiate, and the rest is kind of self-explanatory and/or direct usage of the LV2 plugin API itself | 19:04 |
jcelerier | okay | 19:04 |
jcelerier | https://github.com/jeremysalwen/lv2file/blob/master/lv2file.c#L333 if someone can help me, I don't really graps what's going on from here | 19:59 |
jcelerier | is it looking for the number of ports and their type to compare with the loaded file's channels and create more instances in case the plug-in is mono and the file stereo ? | 20:00 |
*** kwmiebach has quit IRC | 20:02 | |
jcelerier | also, is there a reason for Instance to not call lilv_instance_free in its dtor ? | 20:11 |
jcelerier | kinky API | 20:26 |
jcelerier | plug.me | 20:26 |
drobilla | Probably don't want to use the C++ API. | 20:29 |
ColaEuphoria | drobilla, http://drobilla.net/docs/lilv/#gad973d7894eb44e7dd62328e8d9e6a82a | 20:30 |
ColaEuphoria | "void(*" isn't a helpful definition for a function pointer... | 20:30 |
* drobilla shrugs | 20:31 | |
drobilla | Doxygen bug | 20:31 |
ColaEuphoria | it could also be overuse of typedef ;) | 20:32 |
drobilla | It could also not be. and isn't. | 20:32 |
ColaEuphoria | i just have no idea what type its parameters are | 20:33 |
ColaEuphoria | could it at least be possible to get past the doxygen weirdness by explicitly putting the type under the Parameters list? | 20:33 |
*** kwmiebach has joined #lv2 | 20:33 | |
drobilla | You can get past it like I and roughly everyone else does by just reading the header ;) | 20:33 |
ColaEuphoria | I could | 20:34 |
ColaEuphoria | But that's only because I'm already really invested in this | 20:34 |
ColaEuphoria | Maybe I could see if I could get around this and possibly put a merge request or something | 20:35 |
drobilla | Feel free to figure out why Doxygen barfs or file a ticket. | 20:35 |
drobilla | I seem to recall this working, so maybe something broke. I dunno. | 20:36 |
drobilla | Works here: http://lv2plug.in/doc/html/group__state.html | 20:37 |
ColaEuphoria | interesting | 20:37 |
drobilla | Er, no, it doesn't work there, just in the index at the top | 20:55 |
ColaEuphoria | I can't believe doxygen would do something this narrow-sighted | 20:59 |
ColaEuphoria | It's as if they never anticipated people to typedef a function pointer | 20:59 |
jcelerier | weird, I checked on some docs for one of my libs and typedefs are... well, correct | 21:02 |
jcelerier | it looks like a parsing bug | 21:02 |
drobilla | C++ tool from Qt people, I'm not terribly surprised :) | 21:06 |
jcelerier | my main processing function looks like this : http://paste.ofcode.org/kTc3pjS9WSNmFTHYmb98KM | 21:15 |
jcelerier | but I get a segfault in run :( | 21:15 |
jcelerier | have I forgotten something ? | 21:15 |
ColaEuphoria | do you even gdb? | 21:15 |
jcelerier | (input and output are both valid and of the correct size) | 21:15 |
ColaEuphoria | i don't think activate() is allowed to be called from the audio thread | 21:16 |
ColaEuphoria | even if that isn't why it's segfaulting | 21:16 |
ColaEuphoria | it isn't allowed | 21:16 |
jcelerier | well, all the pointers seem valid in gdb | 21:16 |
jcelerier | okay | 21:16 |
ColaEuphoria | same with deactivate() | 21:16 |
ColaEuphoria | http://lv2plug.in/ns/lv2core/ | 21:17 |
ColaEuphoria | see "Threading Rules" | 21:17 |
ColaEuphoria | you also shouldn't be calling activate() or deactivate() on every call to run() | 21:17 |
ColaEuphoria | it's very expensive to do that | 21:18 |
jcelerier | so LV2_Descriptor == LilvInstance ? | 21:18 |
ColaEuphoria | more like LV2_Handle | 21:18 |
jcelerier | damn, it even botched jackd | 21:18 |
* drobilla cringes at capitalized method name | 21:18 | |
jcelerier | drobilla: it gets worse :p | 21:19 |
drobilla | You are probably connecting to junk, but yes, not only can you not call activate in the audio thread, activate() and deactivate() must be called in pairs | 21:19 |
jcelerier | in pairs ? | 21:19 |
drobilla | i.e. you can't activate() run() activate() run(), it's a double activate() | 21:19 |
jcelerier | ah yes | 21:19 |
jcelerier | okay, I guess doing activate in the constructor and deactivate in the destructor would work ? | 21:20 |
drobilla | (and since activate() nukes plugin state you can't process a stream like that anyway) | 21:20 |
drobilla | You probably want activate and deactivate as their own methods, as they are in the LV2 API | 21:20 |
drobilla | cf, | 21:21 |
drobilla | lv2.h | 21:21 |
ColaEuphoria | he's using it through lilv | 21:21 |
drobilla | I'm aware. | 21:21 |
ColaEuphoria | oh | 21:21 |
ColaEuphoria | i see | 21:22 |
drobilla | The lilv_instance_* are trivial inline wrappers for the LV2 methods | 21:22 |
ColaEuphoria | when are de|activate() typically called anyway? | 21:22 |
drobilla | "Soon" before and after calling (a series of) run(), respectively. | 21:23 |
jcelerier | I ran this code : http://paste.ofcode.org/vEqXFaKEEmESQAg4G4E9sX and I still get a segfault in lilv_instance_run, not when dereferencing my buffers | 21:23 |
ColaEuphoria | they WILL be dereferenced by the plugin inside the plugin | 21:23 |
jcelerier | well yes, but I guess that if the pointer wasn't valid, it would have crashed in the for-loop at the beginning | 21:24 |
drobilla | Please actually show us enough code to see what is happening and/or a backtrace | 21:24 |
ColaEuphoria | it'll crash on lilv_instance_run() as the plugin will dereference its port connections | 21:24 |
ColaEuphoria | (if anything) | 21:25 |
drobilla | I assume you're just not connecting at least one port | 21:25 |
jcelerier | the back trace directly goes in lilv_instance_run and then in stereoecho::Dsp::compute_static(int, float *, float *, float *, float *, PluginLV2 *) | 21:25 |
jcelerier | and in_port.size() == out_port.size() == 2 | 21:26 |
jcelerier | okay well.. | 21:27 |
jcelerier | I tried with another plugin and it works | 21:27 |
ColaEuphoria | ahh the wonders of coding a host :) | 21:27 |
jcelerier | T_T | 21:28 |
ColaEuphoria | having a plugin ruin everything | 21:28 |
jcelerier | and all this for what ? running guitarix plug-ins while I already handle Faust x) | 21:29 |
ColaEuphoria | Does it handle midi? | 21:30 |
jcelerier | mh.... you can get midi note_on, note_off, and CC but there is no piano roll for now | 21:31 |
ColaEuphoria | I'm still looking for enough reasons to finish Delicate Synth and finally get it into a state where I'm comfortable sharing it | 21:31 |
jcelerier | (but originally it's not a DAW, it's a show control software) | 21:31 |
jcelerier | is there a built-in way to handle for instance stereo sounds with a mono plug-in, or should I just duplicate the instances, apply the same paramters, and hope that the plug-in doesn't call rand() too much ? | 21:41 |
drobilla | No, up to the host | 21:42 |
jcelerier | okay | 21:44 |
ColaEuphoria | you don't need to duplicate the instances for that... | 21:44 |
ColaEuphoria | just duplicate their write buffer | 21:44 |
drobilla | You do if the plugin has internal state, which is almost all of them | 21:45 |
drobilla | (You don't for the other way around) | 21:45 |
ColaEuphoria | oh | 21:46 |
ColaEuphoria | i read that backwards | 21:46 |
jcelerier | yeah, echo plug-ins would sound funny :p | 21:46 |
ColaEuphoria | i thought he wanted to apply a stereo effect to a mono source | 21:46 |
jcelerier | shit, I've got a conference in three days and I'm here procrastinating T_T | 21:47 |
jcelerier | damn, I understood my crash | 22:20 |
jcelerier | you actually have to connect *all the ports | 22:20 |
ColaEuphoria | yes | 22:21 |
ColaEuphoria | because the plugin WILL dereference all its data that it works with | 22:21 |
jcelerier | :] | 22:21 |
drobilla | <drobilla> I assume you're just not connecting at least one port | 22:21 |
jcelerier | I thought that you were referring to an audio port | 22:22 |
ColaEuphoria | <ColaEuphoria> it'll crash on lilv_instance_run() as the plugin will dereference its port connections | 22:22 |
ColaEuphoria | drobilla, should ports be connected before calling lilv_state_restore()? | 22:25 |
ColaEuphoria | i'm assuming yes | 22:26 |
drobilla | Doesn't matter | 22:26 |
drobilla | Ports are only accessible in the run() context | 22:26 |
drobilla | (In a better world, they'd be parameters and this pointless internal state wouldn't exist at all) | 22:26 |
jcelerier | is there some kind of "test-plugin" that could be used to check that everything works ? | 22:29 |
jcelerier | i.e. by using most or all of the features | 22:29 |
jcelerier | (or at least that nothing crashes) | 22:30 |
*** ssj71 has quit IRC | 22:31 | |
drobilla | I wrote a simpler sndfile example: http://pastebin.com/HBnq3J0z | 22:49 |
* drobilla is also clearly procrastinating | 22:49 | |
*** kwmiebach has quit IRC | 23:01 | |
jcelerier | nice, thanks ! | 23:02 |
jcelerier | well commented and everything :p | 23:02 |
jcelerier | you should put this on the website imho | 23:02 |
drobilla | It'll go in lilv | 23:14 |
drobilla | Though it's pretty dumb about I/O mapping so doesn't make the most useful thing in the world right now, whatever | 23:15 |
*** rncbc has quit IRC | 23:16 | |
*** kwmiebach has joined #lv2 | 23:18 | |
jcelerier | well, it looks like everything works more or less as I wish ! | 23:36 |
jcelerier | would any of you be interested in alpha-testing my software one day ? | 23:37 |
*** kwmiebach has quit IRC | 23:46 |
Generated by irclog2html.py 2.13.0 by Marius Gedminas - find it at mg.pov.lt!