zen tracker



Work In Progress.
Here is the start of a tracker interface for max. It's gone through a few iterations already. The bulk of this project is currently a JS/v8 GUI object, which writes to a multi-channel buffer. I chose the buffer as data-storage because (unless i am mistaken) its indices can be looked-up sample accurately by a phasor, and in turn can trigger a gen~ object. At the moment it only supports one pattern, but it can be as long as you want, and has no hard limits to the number of channels. There will be further abstraction and facilities to store/retrieve patterns, sequences of patterns.
The columns can be any type from the following: Note, 2Hex, 4Hex, FFXXYY, and trigger.
nnn | note | ... === ^^^ notes
hh | 2hex | ..
hhhh | 4hex | ....
b | bang/trigger ( 1 or .) | .
ffxxyy | COMMAND+ARG | ......and a pattern markup in js like this: ( each track needs to have a param-type, a param-name, and a group index. )
var pattern_markup = {
length: 64,
descriptors: {
track: {
0: ['nnn', 'Note 0', 0],
1: ['hh', 'Volume 0', 0],
2: ['hh', 'Duration 0', 0],
3: ['hhhh', 'Offset 0', 0],
4: ['nnn', 'Note 1', 1],
5: ['hh', 'Volume 1', 1],
6: ['hh', 'Duration 1', 1],
7: ['hhhh', 'Offset 1', 1],
...
16: ['b', 'Trigger', 4],
17: ['hh', 'Volume', 4],
18: ['hh', 'LDelay', 4],
19: ['hh', 'RDelay', 4],
20: ['ffxxyy', 'Effect 1', 4],
21: ['ffxxyy', 'Effect 2', 5]
}
},
data: [], // filled at runtime
lexical_track: "" // this is compiled automatically from the descriptors
};The Tracker Interface
keyboard shortcuts, at the time of writing, constricted by existing Max kb shortcuts:
- spacebar : enter/exit edit mode
- arrow keys : navigate cursor
- ctrl + arrows : faster navigation
- ctrl + x : cuts
- ctrl + c : copy
- ctrl + v : paste
- shift + arrows : set the selection rectangle
- shift + i : interpolate selection
- shift + plus/minus : (not numkeys) transposes
- alt + up/down : shifts content of selection
- ctrl + pg up/down : cycle pattern -/+ 16 rowsSo, What can you do with it?
It will write data to a multi-channel buffer, and you can read from that buffer at desired time-intervals. I'm still adding some UI/UX for swing (i'm partial to shuffle techno). For the inquisitive the JS module has routines for writing to matrices and Ableton midi tracks (in realtime).
What's the purpose then?
I come from old school trackers, 4 channels then st3, impulse tracker, buzz, sunvox. Of the list of trackers I've used, I think impulse tracker came closest to a direct link between thought and pattern data, and reproducible happy accidents. Everything could be done via keyboard. I would like to achieve some kind of platform where i can drive soft-synths or samples or send midi / CC changes.
The current maxpat that might be interesting to look at in the repo is :
step6_tracker_editor.maxpat
Goals?
Yes, serious goals. This thing has been on my mind for maybe 25 years. I'm keeping the tracker part open source, because - if you think about it - it's just a glorified excel-type interface. Agnostic to the final use-case. Personally I want to make hardware that runs this patch and a variety of max/msp synths/samplers which can be surgically controlled via the tracker interface. I've wanted this stuff way before hardware trackers emerged.
Feedback + warnings welcome :) i've only been using max for 6 months and am slowly going through youtube and the GO book. I've also implemented some routines that write data to Ableton Live tracks, which is also pretty cool as reinventing the wheel is not necessarily my goal.
amazing work for 6 months of max usage! stoked to see this project progress
Thanks for the support Francisco!
Not knowing 100% what i'm doing is definitely slowing things down. Various YouTubers demystified some max/msp things to the stage where i've implemented triggering in various time-resolutions, and hitting a wall with midi output into Live (timing slop, and note dropping). Polyphony is solved.
implemented so far:
scheduler rate event triggering (both strictly scheduler rate, and signal timed bangs...)
signal rate triggering into `mc.midiplayer`, no banging. (codebox reads buffers and outputs multichannel streams of busy-notenum-velocity into `mc.midiplayer`).
I don't think I can live with the timing slop or note dropping, and i don't know if it's midi... or the scheduler, or Live. The only real way to see if i can get tight timing out of this is to stay entirely in the signal domain. That means implementing some kind of gen based synth, which i've avoided but am prepared to do at this point.
Next up is a small padsynth and a sampler, and Envelope UI for both. kb controlled like impulse tracker , something like this where the dotted line is the sustain point, and you can add / remove / move envelope points and sustain points. (maybe time and velocity scale factors too)

I dunno, didn't realize it would get complicated :)