works perfectly for me with crow + m4l. what version of ableton are you on?
- haven’t updated to 11.1 yet but will do so this week
hmm, have been reports of crashes with m4l devices and ableton 11 but not heared of troubles with the crow pack…
I’m trying to query the JF voices to see which one is free.
According to the Just Type help page, I should be able to do something like the following to see if, when the strum() function is called by the clock, the channel (in this case 1) is free or not. Whatever I do, it keeps repeating that it’s true in the rate of the clock. Maybe I’m not getting something- how does this work?
function strum()
while true do
clock.sync(1/2)
-- check if voice 1 is free
channel = 1
if crow.ii.jf.get('trigger', channel) == True then
print("true!")
else
print("false!")
end
note = math.random(#notes[1])
crow.ii.jf.pitch(math.random(6),(notes[noteSet][note]/12-1)+tune)
crow.ii.jf.trigger(math.random(6),1)
end
end
crow.ii.jf.event = function( e, value )
if e.name == 'trigger' then
-- handle trigger response
-- e.arg: first argument, ie channel
-- e.device: index of device
print(e.arg)
end
end
The problem (or at least one of) is that crow.ii.jf.get(...)
doesn’t return anything! It triggers an asynchronous event that is received in the crow.ii.jf.event()
handler (which you have correctly configured). Where you are printing print(e.arg)
in that handler, try adding the value so you can see what it’s actually reporting: print(e.arg, value)
.
Secondly, I think that in lua truthy is true
, not True
though I could be wrong and it has an upper-case alias (regardless, changing that won’t fix this case).
I think that when you get
the 'trigger'
, it will return 1
or 0
(rather than true
and false
) though I’d confirm that by looking at the print in the event
handler.
Curious why you’re trying to inspect the voice allocator (though it’s cool that you can! i didn’t conceive of that as a use-case when getting trigger
states). I always assumed people would use the in-built play_note
allocator, or make their own custom allocator and use play_voice
instead.
Thank you, it seems your assumptions are right, on true being lowercase and trigger not returning true/false…
though value
always returns 1 for me, even if I make sure it is playing or not by commenting out the triggering of the voice. Any idea why? This is my code:
function strum()
while true do
clock.sync(1/8)
-- check if voice 1 is free
channel = 1
crow.ii.jf.get('trigger', channel)
note = math.random(#notes[1])
crow.ii.jf.pitch(math.random(6),(notes[noteSet][note]/12-1)+tune)
--crow.ii.jf.trigger(math.random(6),1)
end
end
crow.ii.jf.event = function( e, value )
if e.name == 'trigger' then
-- handle trigger response
-- e.arg: first argument, ie channel
-- e.device: index of device
print(e.arg, value)
end
end
As for why I’m trying to inspect the voice allocator- after making my Tidbit script I had this (still vague) idea of doing a slow version. Vague idea incoming:
It would have slow moving notes that would never suddenly change pitch while they are playing (so no triggering notes that are playing, hence the need for this). It would however have gradual/glissandi-like pitch changes during its AR envelope (is this possible at all?). It would be called HIKE and would look like six mountains on Norns display, and some animation would indicate the pitch and the AR envelope form. Of course this would be influenced by twiddling TIME. Anyway the idea is not complete yet, but I have a hunch this could be interesting.
EDIT: simpler said- this would allow you to play notes only when there is one voice free- making the TIME knob also responsible for the rate new notes are let in- and making sure there are not sudden pitch changes while envelopes are going.
sounds really interesting!
i think the issue is the way get 'trigger'
is implemented might mean it’s always 1 when in synthesis mode. the reason being, trigger
returns whether the channel is in motion – i don’t think this variable tracks whether the volume has hit zero, so when the oscillator goes silent it is still oscillating (just being muted), like in an analogue oscillator.
for your idea of the frequency of notes being played being relatively to the TIME knob, you could just poll the value of time with crow.ii.jf.get 'time'
(receiving the value in the jf.event
handler), and control a norns clock
which triggers the notes. i’d use jf.play_voice
and build a simple round-robin allocator – it’s just a wrapping counter from 1 to 6.
regarding the gliss idea, there is no in-built support for this (JF is already at the limit of processing power in synthesis mode). the way i’d suggest to try it is with something like the fnl
function i made for a maps stream (ep3.lua · GitHub) – it lets you continuously sweep values over i2c with a given framerate. you’ll probably need to experiment with the speed, and interleaving the oscillators to find something stable though (as the technique can easily saturate the i2c bus).
Thank you so much! This is great and it’s wonderful to hear a bit about how things are implemented! A lot to unpack and to experiment with here… I’ll try some stuff out Thanks!
I’ve been using a crow script running Just Friends as a synthesizer. After I change to a different script in Crow, something unrelated to JF, JF continues to run in the same mode. I’m not sure how to get it back to it’s normal operation. Is there an ii.jf___ command to quit?
ii.jf.mode(0) should switch it. 1 is synth mode, 0 is standard
is it only some JF’s that behave this way when working with crow or do you always have to send JF this command to get it back to normal?
in my own experience, jf will reset to non-synth mode after power cycling. if you’re not rebooting, it will continue running in synth mode until you tell it not to.
if it’s an option/useful, i sometimes add some code to switch modes when one of the inputs receives a gate
Not crow-related, but other modules will also affect the mode of JF. In particular I find that Ansible will put JF into synth mode on startup, if it was set to send output to JF before it was powered down. That can be a knotty problem if you don’t have a grid with you when you turn the case on the next time.
Unexpected mode changes for JF over i2c are a bit problematic in my experience and have often lead to me frantically trying a bunch of different things on crow, Ansible, teletype to try and get JF back to normal. I’m not sure what the answer is, but I wonder if at least every device that can switch JF to mode 1 never does so unless explicitly told to by the user. So, for Ansible, it should start up in mode 0 even if it shut down in mode 1, and for teletype it shouldn’t switch to mode 1 even if a JF.NOTE command is sent (iirc this will quietly switch JF to mode 1).
I also kind of wish there was a way on JF itself to reset back to mode 0 by wiggling the switch a bunch of times or something. Although I guess that wouldn’t prevent it being switched back again by Ansible.
this is not happening for me. i routinely use jf.note
commands in my scripts, and as long you don’t put the mode switch (jf.mode 1
) in your init script, jf will not respond to note commands and will function as normal.
Interesting… I wonder if it might be Ansible for me that’s doing this. Will do more testing!
Hi everyone,
I’m not sure about it and I didn’t found an answer so I wanted to ask. Is it possible to use ii.jf.retune
with the Synthesis mode ? So, it could be possible to tune each voice with ratios instead of volts ? Thank you !
retune
won’t get you what you want, but you can use the regular ii.jf.play_note
(or play_voice
), and generate the pitch argument with the justvolts
function. It’d look something like:
ii.jf.play_note( justvolts(3/2), 3)
you could wrap this in a helper function if you want it feel different, eg:
jf_play_ratio( 3, 2 )
Oh I see, fantastic ! Thanks a lot. I was too focused on the Just Type reference on github and missed the globals on the crow script reference.