You provide motivation to finally expose time information to Lua DSP scripts.
Nice! That’s exactly what I need, thanks a lot.
Plugins have a local latency-compensated time.
Ok, I see. That’s probably why my BBT changes detected with that method were always a bit off.
It works, and by is shown in Window > Log.
Ah yes, that’s good to know.
Please let me know if that works for you and if you have further suggestions before we finalize this API with the 7.5 release.
Looks good to me. But would it be possible to have actual BBT and the length of the current cycle in ticks as well? Having that kind of information readily available would make things a little easier for my purposes, although that information can be computed relatively easily from the data that’s already there, I guess.
But would it be possible to have actual BBT and the length of the current cycle in ticks as well?
Scratch that. Ticks won’t actually be all that useful in this context. If you want to do sample-accurate playback then something like a sample count since the last quarter beat might be more useful. In any case, it should be possible to get all these numbers from what’s already there.
From an API POV the sample-position of the last beat would be more consistent. Then you can get sample count since the last quarter note by subtraction : time["sampleTime"] - time["beatPosition"]
BTW, what’s up with all the foo["bar"] indexing in the sample Lua code, is that a stylistic thing, or personal preference? I’m sure you know that in a Lua table, you can always just write the equivalent foo.bar instead (of course, this only works if the symbol is a proper Lua identifier). I also find it more convenient and readable to write something like
One more thing, though: The sampleTime from the time_info table is local latency-compensated time, right? So I can just pass that to Temporal.TempoMap:bbt_at() to get accurate and up-to-date BBT information?
The reason I still need the BBT info from the tempo map is that I need to be able to properly deal with more esoteric time signatures such as 11/8 or 13/16 that don’t evenly divide into quarters. Now one could derive that data from what time_info provides, but that would be cumbersome – Ardour already knows how to compute those values, so I’d rather use those. I can still put time_info to good use to detect meter changes and base pulses, so that I only need to invoke the BBT calculation when a new beat is due.
It’s based on code copied from C/C++. Also, when I add Lua bindings and write a quick example script I still have a C mindset.
Yes it is.
I think I also was too quick last night, exposing “sample-position of the last beat”. The value is not useful if there are tempo-ramps, or if the tempo-changed since the last beat.
I’m also not a big fan of using camelCase here (in C++ we only use it for classes and enums), so far I’ve just based it off VST 3 Interfaces: ProcessContext Struct Reference (and steinberg apparently likes camels).
I am thinking of changing it to underscores. e.g. “sample_time”, which is more consistent. Even more Lua-like would be nested tables: time.sample.start, time.sig.numerator etc. except there is the problem that end is reserved keyword we we cannot use time.sample.end, but time.sample_time_end work.
I think I also was too quick last night, exposing “sample-position of the last beat”. The value is not useful if there are tempo-ramps, or if the tempo-changed since the last beat.
I agree that it’s better to remove it again. It’s of limited use anyway, and this kind of information can be determined through the tempo map if needed.
And what about musicTimeEnd? That one is actually much more useful, since it lets you detect imminent beat increments, in order to schedule MIDI notes at the right sample time. For that to work, it should always equal the next cycle’s musicTime. Is that always true, regardless of any tempo changes?
I’m also not a big fan of using camelCase here
I’m firmly with you on that one. Lowercase + underscores FTW!
I’m tempted to remove time["bar"], which is somewhat ill defined (and assumes 4/4). Are you using that?
Not really. I’m using beat and ts_denominator to detect beats, so that I don’t have to access the tempo map in each cycle, and then sample to get proper BBT information from the tempo map. I think that for sample-accurate triggering I’ll also need beat_end and sample_end, and maybe tempo and tempo_end, but that’s about it.
This is looking good. I have a basic arpeggiator working now, which already does the job fairly well. I still need to figure out sample-accurate triggering, though, where things are likely to get complicated. I’ll look into that tomorrow.
This does the job reasonably well for me, also works great for playing drums.
The sample-accurate triggering wasn’t trivial, but not rocket science either. So the time_info API, as it stands, seems to work reasonably well for this kind of thing.
Please let me know if you spot any bugs or other mishaps. I wasn’t sure how to categorize this kind of MIDI effect, so an effect it is for now, which also makes it easy to find.
I’ll eventually upload this example, along with some other Ardour Lua scripts I’ve done for the students, to GitHub. But for the time being feel free to add this to the Ardour source, as you see fit.
Perhaps, when the transport is stopped MIDI messages can be passed though as-is?
make uncomment to pass through input notes transport dependent (Session:transport_rolling()).
Also transport start/stop should perhaps send all-note-off messages.
Perhaps, when the transport is stopped MIDI messages can be passed though as-is?
Also transport start/stop should perhaps send all-note-off messages.
Good ideas, will do.
Yeah, it’s a little thing, but I also found it to be stupidly fun, especially when I hook it up to the avldrums. Hope the students will like it, too. (I’m doing a DAW course this semester, mostly about Ardour. It’s a lot of fun, especially after I rediscovered its Lua interface. You’ve done a great job with this, it’s come a long way since I last dabbled around with it.)
I’d still like to do an alternative version of the plugin with better auto-generated velocities, using Barlow indispensabilities. I already have that as Lua code, so it will be easy to port over.
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: