I started reworking autotriggers in astrid again this weekend… I think this time they’re nicer, simpler: basically just an array of structs in shared memory.
The structs have an interval, a phase, and a payload field with a corresponding enum that indicates the type of the payload.
There’s a thread whose sole job is to aquire a lock on them once every ~1ms, copy the trigger table (and then release the lock) and then loop over the active triggers and do one of three things based on the type:
-
treat the payload field as an astrid command string and parse it / send the message, (like
p foo=barsends a play message with thefoo=barparams, etc) -
treat the payload field as an astrid msg struct and just send it right away, (maybe useful for automated messages? not using it at the moment)
-
treat the payload as a 4096 step wavetable and send the current value interpolated at the phase as an astrid update message on every tick (every ~1ms!)
So mode #3 acts as a continuous LFO basically – sending update messages at the ~1ms control rate, which are handled by the instrument’s update callback if it’s been implemented – while modes #1/2 are more like gate generators where edges make messages and those only get sent once per interval.
I’ve only tested them by hard-coding in an array of autotriggers so far. There’s still a lot to do so they can be updated via messages (added/removed/changed) and ultimately configured in the instrument scripts, but maybe I can do that tomorrow night…
The (as of right now, imaginary) python interface for this in astrid instruments will look something like:
LFOS=(
# send play messages at 0.4hz
(0.4, 'p foo=bar'),
# send control messages
# w/the value of a hann window
# with a period of 1.2hz
(1.2, dsp.win('hann')),
# send a trigger message at 0.1hz
(0.1, 't drum=hat'),
)
For more complicated sequencing there is already a trigger callback, where these can be scheduled arbitrarily, but I’m working on a simpler interface to set up patterns with generators defined as a tuple of intervals in hertz and some polymorphic payload…