scanner-darkly / multipass

app development for monome eurorack modules and other platforms
GNU General Public License v2.0
29 stars 9 forks source link

Microtonal pitches with Just Friends i2c #9

Closed shankararunachalam closed 4 years ago

shankararunachalam commented 4 years ago

@scanner-darkly, please treat this more like a question, I guess. I am using TT as the i2c leader by setting set_as_i2c_leader() and setting set_jf_mode(1) to get JF synth mode. I map voice 0 to this by map_voice(0, VOICE_JF, 0, 1). Then, I am trying to use note_on_v to pass a microtonal pitch. As I look through the flow, I see that ultimately the JF i2c uses JF.VOX command. I haven't fully understood how you are passing the values to the command but doesn't VOX only react to relative semitone intervals of C3? (or other some preset tuning). In that case, the microtonal pitch wouldn't really work with JF i2c, correct?

I can still give up i2c and just pass pitch directly to the v/a Time CV of JF, keeping JF just in sound/cycle. So, this isn't really a problem for me. I just wanted to understand if there is a way to make microtonal i2c interaction with JF. Thanks!

scanner-darkly commented 4 years ago

judging by the documentation (https://www.whimsicalraps.com/pages/just-type) the i2c teletype op takes same values as CV op (as it lists using N and V notation). unless there is some internal quantization, you should be able to pass same values you would to set_cv to note_v and get same results (multipass will simply pass values from note_v to the i2c modules, while note will convert semitones to values using precalculated equal temperament table provided by libavr32)

i'm curious about the results myself as i want to support microtonal scales in orca's heart - are you finding the pitch is off?

shankararunachalam commented 4 years ago

Thanks for the quick response! The part that is confusing for me in the doc is: "JF.VOX chan pitch velocity" and then it defines pitch as "pitch: set the pitch relative to C3 (eg. N 3 for Eb3, or V 1 for C4)". The same thing in Just Type studies documentation has this: "pitch: assign a pitch, relative to C3 (eg N3 moves three semitones up from C3 to Eb3, V1 yields C4)". These two combined is what makes me think it is still honoring predefined semitones/octaves. Perhaps the transpose mechanism would allow for the notes to be customized, but it doesn't look like free-form cv. Am I reading this right?

Also, my code is not at a place where I can trust it to spit out the pitches I want. So, I can't trust what I am hearing just yet :).

shankararunachalam commented 4 years ago

Also, I should mention that I don't yet fully understand the VOX op. It looks like N is semitone count up from root and V is octave count up from root. The multipass code does a pitch >> 8 to set the to set N/V and a pitch & 0xff to get the 'offset'? I am not sure how these map. Apologies if I am missing something basic. Trying to figure this out as well as my code logic has got me in knots a bit :)

scanner-darkly commented 4 years ago

the reason multipass does it this way is because pitch value is unsigned 16 bit value, and i2c operates with 8 bit packages, so it's basically split into 2 packages, 8 MSB and 8 LSB.

re: documentation - the way i read it was - when using it J.VOX op on teletype you do the same thing as you do when you want to set a CV output to a note value. you can just assign any value in the range 0..16383 (which will get translated into 0..+10V output range) to a CV output: CV 12345. but this wouldn't be convenient if you use a CV output to drive 1V/Oct as you'd have to remember which values correspond to which pitches. so you get 2 helpers: N and V.

V simply means converting its parameter, a numeric volts value, to a corresponding value for CV op. so if you want to set your CV output to 3V you can simply do CV V 3 - this is exactly the same as doing CV 4915. it's just a shortcut that makes it take less space and more readable. as a matter of fact, V can be used anywhere - i often use V 10 as a shortcut for 16383.

same for N - it simply converts its parameter from semitones to the actual value CV or J.VOX expect (*see note below)

to summarize:

0..16383 values passed to CV and likely JF.VOX will get mapped to 0..10V range which in eurorack is mapped to 10 octave range. so, ignoring rounding errors, 1638 covers one octave range, and one ET semitone should be 16383 / 120.

this is not something you really need to care about unless you plan to use ET table yourself - but it's good to remember that DACs offer 12 bit precision, not 16, which might matter for microtonal scales i guess.

shankararunachalam commented 4 years ago

@scanner-darkly, brilliant. Couldn't have asked for a better explanation! That fully clears the confusion I had (and, of course, makes me a happy man, since I can use i2c 👍).

I had figured out the 12 bit resolution and the significance of using 0..4091 and the <<2 earlier. What you explained here rounds out the gaps I had in my understanding. Thanks a bunch, mate! Will close out this issue.

scanner-darkly commented 4 years ago

great! just remember there might still be some internal quantization applied in JF itself, although i doubt it.