Microtonality in Tidal

So I’ve recently started playing around with microtonality in tidal.

So far I have quite a simple way of adding in any EDO system with let edo a b = note (b*(12/a)) where a is the number of divisions being used and b is just the note pattern in edo-steps. This allows you to pattern both the tuning system and the notes against each other which can give some pretty weird and fun chord progressions.

I’m now trying to look into coding in just intonation systems, particularly Partch’s 43 just intonation system. However, I’m not really at all a coder and I’m really struggling to work out how to code in a base scale in the first place (I’m trying to use let … in if … then … else if … but keeping getting parse errors) and then even if I do achieve that I’m not sure how to make it permutable across octaves. Any ideas from folks with more coding experience?

1 Like

Hi buddy, I think you’re on the right track.I picked up this old sketch which I think still works

d1
  $ degrade
  $ fast 2
  $ note ("e4*4" |+ (irand 22 |* (12/22)))
    # s "supervibe"
    # sustain 4
    # gain 0.8

The scale function is awesome, I suggest you try something like

do
  let edo base note = note / base
  let myscale = toScale $ map (edo 22) [0,2,4,6,8,10,12,14,16,18,20]
  d1 $ note (scale myscale (irand 8)) # s "superpiano"

edit: fixed parentheses

3 Likes

Hi, thanks for the tips!

Just to clarify, for EDO (Equal Division of Octave) systems the previous definition works.

Thanks for pointing me towards scale though, since that’s exactly what I was looking for to get non-equally divided microtonal systems!

So now the following works for all EDO, pythagorean tuning and partch 43-note tuning (and I’ve added a shorthand so you don’t have to write out the full scale stuff every time).

let edo a b = note (b*(12/a))
    scale = getScale (scaleTable ++ [("pythagorean", [0.9,2.04,2.94,4.08,4.98,5.88,7.02,7.92,9.06,9.96,11.11,12]),
                                     ("partch", [0.215,0.532,0.845,1.117,1.506,1.650,1.824,2.039,2.312,2.669,2.941,3.156,3.474,3.863,4.175,4.351,4.708,4.980,5.195,5.513,5.825,6.175,6.487,6.805,7.020,7.292,7.649,7.825,8.137,8.526,8.849,9.059,9.331,9.688,9.961,10.176,10.350,10.494,10.883,11.155,11.468,11.785,12])
                                    ])
    pythagorean a = note (scale "pythagorean" a)
    partch a = note (scale "partch" a) 

Of course you can also use the same approach for any non-standard tuning system.

1 Like

I’ve been converting rational intervals to semitones like so:

just2semi j = 12 * (log j) / (log 2)
newscales = [
      ("justionian",     map just2semi [1,   9/8,   5/4,   4/3,   3/2,   5/3, 15/8]),
      ("justdorian",     map just2semi [1,   9/8,   6/5,   4/3,   3/2,   5/3, 16/9]),
      ("justphrygian",   map just2semi [1, 16/15,   6/5,   4/3,   3/2,   8/5, 16/9]),
      ("justlydian",     map just2semi [1,   9/8,   5/4, 45/32,   3/2,   5/3, 15/8]),
      ("justmixolydian", map just2semi [1,   9/8,   5/4,   4/3,   3/2,   5/3, 16/9]),
      ("justaeolian",    map just2semi [1,   9/8,   6/5,   4/3,   3/2,   8/5, 16/9]),
      ("justlocrian",    map just2semi [1, 16/15,   6/5,   4/3,   45/32, 8/5, 16/9])]
scale = getScale (scaleTable ++ newscales)
1 Like

that super interesting, but how do you use these new scales then?
Can you show an example?

thanks

Guillaume

Super cool indeed! Will these scales work with toScale and via SuperDirt MIDI?

@guiq @nilhartman my scales should work the same as @Membrane’s scales above. map just2semi [...] is plain haskell which changes a list of rational intervals to semitone intervals. so newscales in my post is just a list of paired (scale_name, list_of_semitone_intervals) which we are going to add to the scale table.

adding+using new scales looks a little weird if you are used to imperative programming. in haskell you can’t just mutate a global scale table and be done with it. they way you add new scales is 1) getting the current scale table, 2) concatenating your new scales to it to form the new scale table, and 3) replacing the scale function with a new scale function derived from your new scale table. that’s what this line does:

scale = getScale (scaleTable ++ newscales)

once you have the new scale function, you could do

my_pattern_of_semitone_intervals = scale "justphrygian" "0 1 2 3 4 5 6 7"

or you could skip the whole scale/getScale/scaleTable thing and use toScale:

my_pattern_of_semitone_intervals = toScale (map just2semi [1, 16/15, 6/5, 4/3, 3/2, 8/5, 16/9]) "0 1 2 3 4 5 6 7"

either way, now my_pattern_of_semitone_intervals is what it claims to be, just a pattern of numbers which represent the intervals you want in semitones. for example you transpose it an octave by adding 12: my_pattern_of_semitone_intervals + 12. you can send it to superdirt as the note param, which is relative to middle C:

p 1 $ sound "supervibe" <| note my_pattern_of_semitone_intervals # legato 1

or midinote which starts at midi 0:

p 1 $ sound "supervibe" <| midinote my_pattern_of_semitone_intervals # legato 1

skipping the intermediate step, you might do:

p 1 $ sound "supervibe" <| note (scale "justphrygian" "0 1 2 3 4 5 6 7") # legato 1

then you can build up more complicated stuff like:

p 1 $ sound "supervibe" <| note (scale "justphrygian" "<0 1>" + scale "<justphrygian justlydian>" "{0 2 4 6 7}%8" - "{0 12 24}%8")  # legato 3

hope that helps!

2 Likes

Thanks Victor ! Tidal successfully evaluate the code here.
Alas, it doesn’t seem to work when sending out MIDI to another synth / DAW (I suppose I still need scale / .tun files).
Too bad, I wish I could give this justphrygian scale (I just LOVE phrygian mode hehe) a try !

Hey everybody :slight_smile:

For those who knows aleksi perala and his work with colundi sequences, here is a link with frequencies he used : http://web.archive.org/web/20170323163903/http://www.ovuca.com/research.html

I achieve to reproduce these temperaments scales with list comprehension in haskell. It looks like this :

let colundi5 = [ xy/33 | x <- [1,2,4,8,16,32], y <- [33, 39.6, 46.2, 52.8, 59.4]]
colundi6 = [ x
y/33 | x <- [1,2,4,8,16,32], y <- [33, 38.5, 44, 49.5, 55, 60.5]]
colundi7 = [ x*y/33 | x <- [1,2,4,8,16,32], y <- [33, 37.71429, 42.42857, 47.14286, 51.85714, 56.57143, 61.285714]]

(then use toScale tu use it)

2 Likes

Colundi everyOne ! As you know @guiq , these scales are not the Colundi sequence though.

haha yes you’re right, I think he used these scales in the mental union releases :slight_smile:

1 Like

MIDI note numbers do not encode microtuning, only semitones. There are various hacks involving pitch bend or poly aftertouch, but none of them is standard and you’d need a synth patch designed to receive it.

hjh

1 Like

I knew it hehe, I guess I was just genuinely candid and erm, “hopeful” here :wink:

1 Like