Appreciate the detailed response - really clarifies how to get geode working!

1 Like

Just spent some time with my new Just Friends/Crow/Norns (awake). Wow. Just Friends seems so powerful to me, unexpectedly so:

6 Likes

Has anyone tried to do any alternate tunings (microtonal etc) stuff with crow+jf?

I, of course, completely understand the need to use MIDI, but it is also a slight shame. In modular, using purely CV, we are not as much burdened by musical history and choices made decades ago (which we of course have to deal with every time working with MIDI.)

So, to clarify what I’m refering to, the problem is MIDI pitch bend values (which you need to get non-traditional pitches) are not note specific which can become a problem when using polyphony.

Thanks!

Do you specifically mean with the ^^jf_synth device not receiving MIDI pitch bend? There is nothing in the crow<>JF I2C connection that prevents microtonal sequencing of JF via crow.

JF receives a command from crow which tells it what interval to play relative to C3 and how loud to play it (amplitude in volts):

ii.jf.play_note(<v/oct voltage>, <amplitude voltage>)

So for instance, to play one octave above C3 at a 5Vpp amplitude, you would send:

ii.jf.play_note(1,5)

Two octaves above, at 3.4Vpp amplitude:

ii.jf.play_note(2,3.4)

Since one semitone corresponds to 1/12th of a volt in the V/oct standard, to play a perfect fifth above C3, you would send the following, since a perfect 5th is 7 semitones.

ii.jf.play_note(7/12,5).

One cent is one hundredth of a semitone, so 1/1200 volts. So, to send the note that is 37 semitones below a major third, you could send a message like this - 4/12 corresponds to a major third, and then we subtract 37 semitones from that voltage.

ii.jf.play_note(4/12 - 37/1200,5)

To incorporate pitch bend into the ^^jf_synth M4L device, you would need to come up with a scaling system to map pitch bend values (0-127) to voltage. You would then add this voltage to the voltage determined by the MIDI note. This combined voltage would then be put into the Lua command which gets sent back to the command center device and then out to crow itself and then on to JF.

8 Likes

I’m about to try out this 10ms delay trick in @dan_derks original post here but I’m curious if anything ever came out of the talk about generalizing this approach. Also curious if this can be fixed deeper down like the iic layer? Thanks everyone for your work on this.

This will be fixed in the next Crow firmware release. I’ve got proper polyphony working already, but it needs more testing.

14 Likes

That’s great to hear! I’ll hold off and wait for that. Thank you for the update.

Very nice, just started exploring this patch last night. What setting did you have your mode switch in?

Has anyone played with the ii.jf.retune command at all? I’m getting odd behaviour.

For example, if I send

ii.jf.retune(2, 2, 1)
ii.jf.retune(6, 6, 1)

I would expect 2n and 6n to be the same as their default settings. But instead with the Intone knob at noon, they play the same pitch (Identity) but as I rotate clockwise they go DOWN (I would expect them to go up) with the same pitch and then quickly become inaudible. And if turn Intone counter they immediately turn off past noon and there’s no output at all.

If I send ii.jf.retune(0, 0, 0) everything resets to the defaults correctly. Any ideas?

I have a theory, just because I ran into some troubles with setting arguments in Geode. not at my JF at the moment, but what happens if you send:

ii.jf.retune(2, 2/1638, 1/1638)
ii.jf.retune(6, 6/1638, 1/1638)

?

I thought the same thing too after reading the above, but no dice. There is no response from JF at all when I send those commands from Druid or Max.

When i select ii-JF in the awake patch nothing is happening
did i erroneously assume that i could send info from awake to JF w/o patching normally?
i do not seem to be getting ii info sent from crow to JF

Im not sure if this is related to what @dan_derks was talking about but Im experiencing odd pitch behaviour when using JF as a complete voice and using crow to play jf from a cv and gate source.

The script is:

input[1].change = function(s)
ii.jf.play_note(input[2].volts,5)
end

function init()
ii.pullup(true)
ii.jf.mode(1)
input[1].mode(‘change’, 1, 0.1, ‘rising’)
end

All it doest is every time you send a trigger to input 1, it will sample the voltage at input 2 and send it to JF as a new note to play but it seems to me like it doesn’t always sample the correct cv. If i send in a simple sequence from a track of kria (ansible out to crow in) i feel like it may be sampling too soon? I had a thought to delay the trigger before sampling to fix the issue but im not sure how to do that as im a super noob to coding. Anyone have ideas?

Sounds like Kria’s gates are triggering the input.change before it’s CV output has settled. There’s no in-built delay function in crow at the moment, but I sketched up this solution to the problem (though it’s untested as I’m away from my case rn):

-- add this function to your script
-- (to be included in crow firmware in future)
function delay( time, action )
    local function devent()
        action() -- this line executes the delayed function
        metro.free(dmetro.id)
    end
    local dmetro = metro.init( devent, time, 1 )
end

-- delay the call that reads the input voltage by 3ms
-- the old line is 'wrapped' in a function
-- this stops it from being executed immediately
input[1].change = function(s)
    delay( 0.003, function() ii.jf.play_note(input[2].volts,5) end )
end

function init()
    ii.pullup(true)
    ii.jf.mode(1)
    input[1].mode('change', 1, 0.1, 'rising')
end
3 Likes

Amazing! Thanks for code additions.
I just had a go adding it and I’m getting an error in druid saying:

Metro.init : nothing available

Any ideas?

Cycle mode, and the time/intone knobs will have a big effect on what is going on. I generally have time around 10 o’clock and intone around 11 o’clock I think.

@cosmicsoundexplorer that needs to be lowercase metro. Did you see uppercase in some docs somewhere that we should fix?

@Galapagoose All I did was copy your code, paste it into mine and removed the

function init()
ii.pullup(true)
ii.jf.mode(1)
input[1].mode(‘change’, 1, 0.1, ‘rising’)
end

saved it and uploaded it to crow. it then starts running the script and then I get

Merto.init: nothing available

my code now looks like this:

input[1].change = function(s)
ii.jf.play_note(input[2].volts,5)
end

– add this function to your script
– (to be included in crow firmware in future)
function delay( time, action )
local function devent()
action() – this line executes the delayed function
metro.free(dmetro.id)
end
local dmetro = metro.init( devent, time, 1 )
end

– delay the call that reads the input voltage by 3ms
– the old line is ‘wrapped’ in a function
– this stops it from being executed immediately
input[1].change = function(s)
delay( 0.003, function() ii.jf.play_note(input[2].volts,5) end )
end

function init()
ii.pullup(true)
ii.jf.mode(1)
input[1].mode(‘change’, 1, 0.1, ‘rising’)
end

I’m still a super noob so i may have stuffed it up?

I had a look at metro.lua on github and the code has metro with an uppercase M throughout it. would that be the issue?

Also is there a simple way to have JF base frequency start lower as i like to tune my oscillators to C3 on kria’s 3rd octave setting to enable me to go up and down in octaves.

Cheers!

@dan_derks @Galapagoose

Just wanted to check in to see if you guys had had a chance to check out the tuning commands, still no dice on my end. Thanks!

so, with teletype: JF.TUNE 1 x 1 messages allow me to walk through the first x >= 6 harmonics. this is expected and traditional behavior.

but when using ii.jf.retune with crow in druid:

  • ii.jf.retune( 1,x,1 ) where x>=1 just shuts the channel off completely.
  • ii.jf.retune( 1,1,1 ) does not restore, which is unexpected.
  • ii.jf.retune( 0,0,0 ) restores as expected.
  • ii.jf.retune(1,3/1638.4,1) no change

I’m stumped, too. @Galapagoose, any ideas?

looks like all this might be getting addressed in coming update – hang tight!

1 Like