This is very cool. Just curious: Can you record the arpeggios your script creates in a seperate midi track so one can mess around with them later?
Yes, you can.
Create a MIDI track without synth plugin, add the ARP, then connect the output of that track to a new MIDI track to record on.
If you want to play live into the arp, you do not even need a separate track. You can change the Disk I/O to “Post Fader”, or like in this example to “Custom” and place the Arpeggiator at the top:
I put this on GH now, so that I can better keep track of the changes and accept pull requests. MIDI notes are passed through if transport isn’t rolling, and an all-notes-off is sent on the output channel when it starts rolling. (I don’t think it’s necessary to do this when transport stops, as Ardour already sends out a bunch of these by itself.)
The GH repo is here, it also contains a bunch of other action scripts for doing twelve-tone stuff:
I also noticed something strange. If I launch loop playback (L) while holding some notes, Ardour automatically sends note offs for each of the notes. (This interferes with the arpeggiator because it will think that the user released those keys and thereby deletes the note pattern.)
This doesn’t happen if I just launch playback with the space bar. Is this behavior by design or should I report a bug?
I think this is intentional. There is a MIDI note-tracker that engages at every locate (loop start and each loop cycle). @paul do you recall the details where TFSM triggers this?
Once the dust has settled, I’d like to include it in Ardour’s script collection.
Once the dust has settled, I’d like to include it in Ardour’s script collection.
I think this is intentional. There is a MIDI note-tracker that engages at every locate (loop start and each loop cycle).
Ok, I see. Well, there’s not much I can do to work around this on the Lua side, since AFAICT there’s no way to distinguish these synthetic note events from real ones. Anyway, the effect is somewhat mitigated in latch mode (which I just implemented).
Just updated https://github.com/agraef/ardour-lua again, to fix a couple of minor issues, and add a toggle for the all-new and shiny latch mode.
I also added a variation barlow_arp.lua now which creates more detailed rhythmic accents in the note velocities using Clarence Barlow’s indispensability formula. (Try it with some more exotic time signatures like 11/8 or 17/16 to notice the difference.)
Robin, is there a way in the Lua API to off-load some computations to a background thread? Computing the Barlow meter tables is a fairly cpu-intensive process, so I’d really like to get rid of the cpu spikes that I get when the time signature changes mid-flight. If not, then I might be able to do with Lua’s built-in green threads a.k.a coroutines, but I try to avoid these if I can.
I also made some changes so that automation of the integer control values works properly (using math.floor to ensure no fractional values). This is especially nice with the division control which can now be automated to quickly change, e.g., from duplets to triplets and back. Sounds nice.
No, there is not. It would need something like the LV2 worker extension.
I think of Ardour Lua DSP as special case, not a general purpose plugin API.
Lua DSP plugins can access all of libardour and directly modify the Ardour session state. No other plugin API can do that. Lua is also handy to quickly prototype things, and in cases where Lua is just used as glue to call C/C++ (libardour) vectorized DSP routines it can match performance with dedicated C/C++ plugins.
But complex tasks will always bet better served by dedicated general purpose plugin frameworks.
I saw “Barlow Arpeggiator” in your git repo and wondered what it was. So far I only knew about Barlow lenses, today I learned about Clarence Barlow.
One option would be to simply pre-compute all meters in the session at instantiation time, or cache new meters, so they are only computed once.
Right, I didn’t think of that Is there an easy way to get at all the time sig markers? Are they included in Session:locations ()?
Lua DSP plugins can access all of libardour and directly modify the Ardour session state. No other plugin API can do that.
It’s amazing. I’m still learning the API from documentation that, quoting from the horses’s mouth, “is Work in Progress and far from complete.”. So I hope that you don’t mind if I keep bugging you with my silly questions.
Anyway, I can probably figure this out on my own. Stay tuned…
You want to iterate over all Temporal::Meters and that is not possible from Lua just yet. It is tricky to expose those since internally (C++) meters are stored as intrusive list.
Currently you can only query the Meter at a given point in time (TempoMap:meter_at).
In any case. Since a user can change time signatures, you cannot know all meters at instantiation time. Yet, The plugin could cache meters every time a new one is encountered during playback. So you only get an x-run the first time the plugin encounters a new time sig.
And realistically 99% of all music in any DAW is 4/4, and the rest 0.95% is 3/4 and 6/8.
Also, “everything is in 4 unless you count it like a nerd” – some music youtuber
Right. Coincidentally, the barlow_arp still has a bug that causes it to use the note value instead of the number of divisions, so at present the rhythms are all wrong anyway, unless you stick to 4/4.
Working on it, stay tuned.
Ok, I understand. I figured out a way to just iterate over all the quarter beats of a session, that should catch most meter changes at startup.
Yes, I understand that. I still want to do a quick scan beforehand, so that the cache is already well-populated from the get-go.
Not in my test pieces. And not if your name is C. Barlow. I’ve actually seen him do polyrhythms in Sibelius (or was it Finale?), not that easy. And yes, Clarence knows how to use a DAW, too! Even though he still used to do MIDI programming on a (simulated) Atari ST, because “it’s so much easier”, peeking and poking directly into the MIDI port memory locations. Who wants or needs a system library to do that?
I once tried to explain to him why we don’t do it this way any more, but he would have none of it. In some ways, he reminds me of Mel (“Real Programmers write in FORTRAN”). Which he did, writing composition programs at a mainframe computer in the 1970s, studying at the Cologne Conservatory while Stockhausen was there. I’ve actually seen the listings, pages and pages of it, all pre-Fortran77. He wanted me to port this stuff to modern Fortran, but I politely declined.
I fixed that bug, so Barlow should play the right rhythms now. I also implemented the caching feature that we discussed, so most of the cpu spikes are gone.
But of course you’re right, 4/4 is where it’s at, except in the avant-garde music circles at the conservatories. The simple_arp should do the job for most people.
I still have a crash bug in latch mode, though, which isn’t easy to reproduce. Working on it, stay tuned.
The crash bug in latch mode is fixed now. As a bonus, I also threw in a pulse filter for the barlow_arp. The filter lets you “thin out” a rhythm by raising the min strength value, or create an off-beat rhythm by lowering the max strength value, or do both. E,g., try with avldrum, division = 3 and set the min filter value to something like 0.2 for that triplet feel.
This is something that only works well (and is actually very easy to implement) with the Barlow method, because it assigns a unique pulse strength to each pulse in any meter. At least I don’t know any other method which does this and still sounds convincing, no matter what time signature you use. And yes, it sounds great in 4/4, too.
I should maybe write some documentation now. Or post a test session which demonstrates this stuff.
I would really appreciate a short video demo! That would be great! Thanks a lot!
@laex, I’m sorry, but the semester is still in full swing over here, so I’m just too busy with other things right now. Maybe @unfa could do a video about it? He’s a lot better doing these videos anyway.
FWIW, here’s a little “Hello-Arp” demonstration session using barlow_arp.lua along with Reasonable Synth and the AVLDrums. Also, the drumkit arpeggiator track has a little bit of automation which changes division between duplets and triplets for added effect.
Here’s the session archive on my Google drive:
The synths are on extra tracks so that I can easily bounce the output from the arpeggiators. Which I did, so that you can also play the session if you don’t have the current git version of Ardour (you need to change the bounce tracks from “In” to “Disk” to do that). I’m sure that you Ardour buffs can do a lot better, but that’s how I usually do this kind of thing. Robin sketched out a neat trick above with the custom disk i/o setup which I think lets you do everything on a single track, but I still have to try that out. I didn’t even know that this custom I/O setup existed until I read his post.
Updated the arp plugins once more, they will now pass through non-note-related MIDI data like control and program change, pitch bends, etc., even when the arpeggiator is playing.
I also added a new “Sync” toggle which synchronizes the arpeggio with bars and beats in the current meter, instead of just cycling through all the notes with abandon. This sounds much nicer IMHO, and also makes the arpeggiator much easier to play live, especially when used together with latch mode. If you’re a lousy piano player like me and fumble each chord change, this is a heaven-sent.
Here’s another little demo session with the latest version of the barlow_arp plugin, which demonstrates sync mode and the pulse filter (on the drum track). Uses Robin’s versions of the gmsynth and avldrums LV2 plugins. No bounced arpeggios this time, so you need a recent Ardour “nightly” build to make it work.
If you look at the repo, I’ve reorganized the source a bit to make it easier to find things, and also added a little bit of documentation about the arpeggiators to the README. It’s still rather terse, but hopefully people who have used an arpeggiator before will find that information useful.
I finally added the usual gate and swing controls now. (The latter is only in simple_arp, as barlow_arp has its own way of doing these things with the pulse filter.)
So I’d say that the essentials should be covered now. I think I’m finished with these, enjoy. (And please report any bugs that you find at https://github.com/agraef/ardour-lua, thanks.)