since the endless possibilities of using crow to play/program Just Friends over i2c seems to be a likely first use for many who will be receiving their crows this week, I wanted to kickstart convo around best practices + how to get the most out of this pairing.
though I’ll share some of my approaches to get things started, they do not represent the best approaches. I want to learn from you all, as I’m still wrapping my head around things. so, this will hopefully serve beginners and experienced artists alike
destination: all the notes at the same time
while building the
^^jf_synth device for crow’s Max/Max for Live toolkit, I ran into a funny thing – Just Friends is a 6 voice polyphonic synth, but in
transient/sound it sometimes loses track of pitch data when it receives simultaneous messages over i2c. this happened with Teletype as well, but it becomes very obvious when you plug a MIDI keyboard into a Max patch and make 6-note chord shapes.
I found that if I spaced out the message delivery between crow and Just Friends by ~10 milliseconds, I got perceivable polyphony with no dropped notes or weird pitches.
working around this behavior seems to be as good a starting point as any for this thread, so here’s two ways I approached scripting to successfully get (close enough for jazz/ambient/garage rock) simultaneous notes playing out of Just Friends:
if you crack open the [crow] object’s help patcher, you’ll find an
i2c tab with this patch:
on the right, you’ll find a [zl.queue] collecting every note event from the [kslider] (keyboard keys) + [midiin] combo as a list. when [zl.queue] receives a bang message in it’s left inlet, it pushes the first message it received through its outlet to crow and removes it from the list – First In, First Out (FIFO).
this gives Just Friends a bit of breathing room between note messages, to parse them out and allocate accordingly.
I took a similar approach with norns, while updating less concepts. less concepts only sends 2 notes at a time, but often simultaneously.
init(), I establish a 10ms clock called
jf_note_spacer to replicate the [metro 10] object from Max:
jf_note_spacer = metro.init() jf_note_spacer.time = 0.01 jf_note_spacer.count = 1
I chose to have it fire only once, whenever it’s activated. I then set up a function for it to trigger:
jf_note_spacer.event = jf_spacer
I also made sure that this metro wouldn’t run at startup by initializing it in a
so what is
jf_spacer()? it’s just a single crow command to handle the second note:
and it all comes together in my note handling function:
if i == 1 then crow.ii.jf.play_note((BLAH-BLAH-NOTE-MATHS)/12,5) elseif i == 2 then jf_note_spacer:start() end
- if the note is for the first voice in the pair, that can be played straightaway
- if the note is for the second voice in the pair, start that 10ms timer
- at the end of the 10ms timer, crow will send JF the data for that second voice
but it all sounds like simultaneous events!!
- lol, can someone plz come up with a better way to manage polyphonic messaging to JF in norns?
- as folks start to dive into Just Friends + crow, I’d love to learn from your approaches! as you get coding, what do you find works best to juice the most out of this pair?
- ask questions! share answers! be excellent to each other.