Performed by Cole Ingraham on November 30, 2013 at the FaceArt Institute of Music in Shanghai, China.

Line Walk from Cole Ingraham on Vimeo.

]]>The piano is both an extremely versatile instrument and a prisoner of its design. A masterful performer can create a multitude of colors and textures with it but, without significant modification, it is confined to a specific tuning. Between Realities is an exploration of this limitation, not as a negative, but as a way of traversing the space where two dissimilar tuning systems meet. It is a meditation on the concept of intonation.

Performed at Center for New Music (C4NM) in San Francisco, CA.

]]>For the pitches, Stockhausen built a scale in which the interval between successive steps consists of the frequency proportion of the twenty fifth root of 5 —in other words, the interval of 5:1 (two octaves plus a just major third) is divided into 25 equal parts. This differs from the traditional tempered tuning system, in which an octave consists of twelve segments, the interval between two adjacent steps being therefore defined by the ratio twelfth root of 2. The intervallic unit is a “large semitone”, about 10% larger than the semitone of the equal-tempered twelve-tone system. Beginning at 100 Hz, this scale reaches to ca. 17,200 Hz, with a total of 81 equally spaced pitches. Because of the chosen basic interval, no octave duplications can occur (Stockhausen 1964, 37). The highest pitch, 17,200 Hz, is near the upper limit of human hearing, and occurs only in a single tone mixture, as the uppermost of its five pitches (Toop 2005, 6).

**The Simple Solution**

This does not quite lend itself to the same Scale approach as last time since, as the description clearly states, there are no octave repetitions. In this case it makes the most sense to just create the scale as an array or frequencies. Here’s some example code where we randomly walk around the Studie II scale:

(

Pbind(

\freq, Pwalk( // random walk around our scale

// make our non-octave scale

Array.geom( // since we are dealing with frequency, we use geom rather than series

81, // 81 steps

100, // starting from 100Hz

5.pow(1/25) // the growth rate (step size) is the 25th root of 5

),

Pwrand([-2, -1, 0, 1, 2], [0.05, 0.1, 0.15, 1, 0.1].normalizeSum, inf), // random stepping

Pseq([1, -1], inf), // reverse direction at boundaries

40 // start in the middle of the scale

),

\dur, 0.125 // each note is a 1/16th

).play

)

Most of the Pattern code here is straight from the Pwalk help file so I won’t talk about that too much. The main thing here is how we make the scale. In reading the description, we can see that Stockhausen started at 100Hz, and each of the 81 steps is higher by the 25th root of 5. SuperCollider’s Array.geom method is perfect for quickly giving us this:

`Array.geom(81,100,5.pow(1/25))`

That should be pretty straightforward. Here we say that we want 81 steps and that we will start from 100 (Hz). This much is exactly like Array.series if you are familiar with that. The only difference is that series adds the growth amount each step, whereas geom multiplies the last step by the growth amount to get the next step. Since we are working with frequency and not midi notes, we must multiply. 5.pow(1/25) is how we calculate the 25th root of 5.

**A Slightly Better Solution**

Now, this approach is fine and all but suffers from the same limitation I talked about in the last post: namely that you can’t use it like a true scale and pass in degrees. As I said before, it doesn’t totally make sense to think about this as a traditional scale since it has no octave equivalent notes, but it would be rather nice to be able to pass in indexes to it. This would allow us to get the “tone mixtures” that Stockhausen uses by “degree” rather than frequency. Here’s an example of just walking up the scale:

(

Pbind(

\root, 7 + (100.cpsmidi - 100.cpsmidi.round), // adjust the root to be 100Hz (g + 35 cents)

\octave, 3, // set the octave to the correct g (3)

\scale, (Array.geom(81,100,5.pow(1/25)).cpsmidi - 100.cpsmidi), // adjusted scale in midi numbers

\degree, Pseq((0..80),inf), // walk up the scale

\dur, 0.125 // each note is a 1/16th

).play

)

There are a few new things going on here due to how Patterns handle scale degrees. `\root`

specifies what pitch class (midi number between 0 and 11) will be used for \degree 0. Our scale starts from 100Hz with is midi number 43.349957715001 or G3 + 35 cents. Therefore we set the root to 7 (G) and add the cents to it with `(100.cpsmidi - 100.cpsmidi.round)`

just to be as exact as possible. Next we set `\octave`

to 3 to make the root G3 (5 is the default). At this point, using a degree of 0 will give us 100Hz.

How we use this with `\scale`

is slightly different as well. Rather than using a combination of Scale and Tuning like last time, we will just give the pattern our array that we talked about earlier. However, the array from before was in Hz and scales need to be in relative midi numbers. This is easily handled with `(Array.geom(81,100,5.pow(1/25)).cpsmidi - 100.cpsmidi)`

. We simple convert our array to midi and subtract our root note from it. IMPORTANT: this must be done with both the array and root in midi scale, not frequency.

**Final Thoughts**

I don’t do much with with non-octave or equal division of the *anything* scales myself so this may not be the cleanest approach. I really just wanted to try my hand at it. I know that Tuning has a way of handling “stretched” tunings like this somehow but I haven’t quite figured it out at the moment. With this approach you should be able to pretty easily drop in your own scale array and get crackin’ pretty quickly, keeping in mind that it’s your responsibility to know if and when your scale recycles. Hope this helps in some way.

SuperCollider has a built in mechanism for working with scales and tunings conveniently called Scale and Tuning respectively. These are particularly useful with Patterns as you can supply and change the scale and tuning you are using independent of the scale degree. Without this schema, you are stuck dealing directly with the exact pitches which, while straight forward and sometimes useful, can be limiting in certain situations.

Working with Scale and Tuning is pretty simple and well documented but there are a few quirks and redundant things to using it the way I need. My goal is to go straight from an array of ratios to something I can directly plug into a Pattern. For this, I made a simple function that handles all the subtitles:

// a function to convert an array or ratios to a Scale

(

~makeScale = {|ratios| // supply an array of ratios

Scale( // make a Scale

(0..ratios.size-1), // list the steps in the scale from 0 to the number of ratios

ratios.size, // how many steps we have in our scale

Tuning( // make a Tuning

(

ratios.ratiomidi // first we convert out ratios to midi

% 12 // then we mod 12 to put everything

).sort // lastly we sort it from low to high

)

);

};

);

```
```// three JI scales, each with different root

a = ~makeScale.value([1,9/8,6/5,4/3,3/2,8/5,7/4]); // our initial scale

b = ~makeScale.value((5/4)*[1,9/8,6/5,4/3,3/2,8/5,7/4]); // same scale transposed a 5/4

c = ~makeScale.value((3/2)*[1,9/8,6/5,4/3,3/2,8/5,7/4]); // same scale transposed a 3/2

`// test it out`

(

Pbind(

\root, 0, // the pitch class of the scale's root

\octave, 5, // the octave of the root with a scale degree of 0

\scale, Pstep([a,b,c],2,inf), // play each scale/tuning every 2 seconds

\degree, Pseq((0..a.size),inf), // walk up the scale

\dur, 0.125 // each note is a 1/16th

).play

)

Here’s what’s going on and why.

Scale first asks for an array of scale degrees based on the total number of degrees. For something like a major scale in 12TET this would be [0,2,4,5,7,9,11]. Since I want to deal with arbitrary scales sizes and the step sizes will be handled by the Tuning later, I just use (0..ratios.size-1) to make an array from 0 to one less than the number of ratios I supplied. If I give it 5 ratios, this gives [0,1,2,3,4].

Next Scale asks for the number of steps per octave. Since we want each ratio to be its own step, we just use ratios.size here. This effectively maps each ratio in the Tuning to each scale degree. At this point, Scale is just a wrapper around the Tuning, which is the real point of interest.

My way of dealing with the Tuning here is slightly more complicated than it absolutely needs to be, but I chose this approach because it offers the most flexibility.

All you really need is `Tuning(ratios.ratiomidi)`

, which would make a Tuning by taking our ratio array and converting it into the “midi number” version. This would be more than enough ** if** we always ensure that our ratios are between 1/1 and 2/1. However, I decided I wanted to be able to be lazy and do things like transpose my ratios like so: (5/4) * [1,9/8,6/5,4/3,3/2,8/5,7/4]. This needed a little more stuff going on under the hood.

With ratios.ratiomidi, we get the the “midi number” array. Then we % 12 to force everything between 0 and 12. Finally we sort the result. This means that even if we supply ratios that are beyond one octave, this will automatically correct them and put put them in the right order for a scale.

Hopefully this is somewhat helpful. Once we have our Scale, we can do all the cool Patterny things exactly the same way as with any other standard scale. I also like to think of Scale in this case as also being usable as a chord. For instance, if you supply a three note tuning representing a chord, you could have your pattern play degrees [0,1,2] which would be the chord. Then if you change the Scale to be a different chord, the notes will change even if the degrees do not. Since the function we made will adjust octaves of out of range ratios, this can automatically handle inversions for us and thus give smooth voice leading basically for free (if that’s something you want). It’s fun to play around with at any rate.

]]>[0, 4, 7] + 4 = [4, 8, 11]

or

[C, E, G] up a M3 = [E, G#, B]

(since I’m a programmer, I’m writing all of these as arrays, deal with it =P)

This is very intuitive and even someone who knows little or nothing about music could probably understand it (just go up by N keys from each note on the piano and you are done). When working with Just Intonation however, we are working with multiplication rather than addition. While the math involved is actually not terribly more difficult, the resulting numbers often appear really complicated:

[0, 4, 7] + 4 = [4, 8, 11]

as ratios would look like

[1:1, 5:4, 3:2] * 5:4 = [5:4, 25:16, 15:8]

or as partials

[4, 5, 6] * 5:4 = [20, 25, 30]

“Ack, those numbers are really big! How complex!!” is a common response to seeing this. You could imagine that if we were transposing by more “complex” ratios (those involving larger numbers and/or more distance between numerator and denominator) we would quickly end up with an unwieldily mess. No one wants to deal with 3, 4, or 5 digit numbers: this is music, not calculus (…hah)!

Beyond the ugly large numbers, I have one other major issue with the above approach (which I will call here **absolute pitch JI**: it completely looses its identity. Yes, seeing [5:4, 25:16, 15:8] means I can get out my calculator and figure out what frequencies I’ll get quite precisely, but I have no idea what is going on when I look at it. [1:1, 5:4] and [5:4, 25:16] are both the same interval but that’s difficult to see at first glance (and even more difficult when larger numbers are involved).

Stepping back to my first example, something like [0, 4, 7] is very familiar to anyone who’s studied 20th century music: it’s a pitch class set. What is a pitch class set at it’s core? It’s the *relative* intervals between pitches from some arbitrary reference point. Before I labeled [0, 4, 7] as [C, E, G] but [E, G#, B] is the exact same pitch class set, and when analyzing music with pitch class sets you would identify them as the same thing.

Applying the same approach to JI, what is the resulting chord from [1:1, 5:4, 3:2] * 5:4?

…

[1:1, 5:4, 3:2] * 5:4

Why would we change it? That just makes it less readable. In fact, now it’s perfectly clear both what the chord is AND that we are transposing it by 5:4. I’ll call this **relative** JI.

“But now I don’t know EXACTLY what notes I need!”

You’re doing it wrong! It doesn’t matter. An [0, 4, 7] is an [0, 4, 7] no matter where you start it from so why should it be any different with ratios?

“But… math!!”

Yes yes, I know. Eventually you’ll need to multiply everything out to get your frequencies for your fancy notes. You’ll also need to multiply all your ratios by your fundamental frequency for that anyway (since JI is always relative to a reference pitch in the first place).

**The Anatomy of a Pitch**

There is no reason to bounce everything down to frequencies until you are going to play them really. Before that, we might as well keep things in a format that’s more friendly for working with it. Taking an approach from programming, rather than thinking of pitches as **a number**, let’s think about if as a data structure:

// a single pitch

{

fundamental: 440,

ratio: 5/4,

transposition: 3/2

}

fundamental * ratio * transposition = frequency

Which equals 15:8 or 825Hz, but we can actually see how we got there. Often we don’t even want to include the fundamental with the actual pitch since it is more of a global thing (you’ll *usually* only have 1 fundamental for a piece or section). So really we are looking at:

{

ratio: 5/4,

transposition: 3/2

}

most of the time.

Here “ratio” is the identity (or Odentity/Udentity if you would rather use Partch’s terminology) of the pitch. What is “transposition” exactly? Just a series of ratios to multiply the ratio by to get to where you want to be. We can just as easily have this:

{

ratio: 5/4,

transposition: 3/2, 2/1, 6/5

}

which is 5:4 up a perfect fifth, then up an octave, then up a minor third: FAR more useful than seeing 225:32 by itself. Since multiplication is commutative, the order of the transpositions doesn’t matter. Just multiply everything together and you get your result!

**Use Case: Pitch Lattice**

A common way or working in JI is to use an n-limit lattice (just google “pitch lattice”). These usually look like a 2, 3, 4+ diminutional grid of number vomit when written out because people typically write the resulting ratio for each location. At its core however, a lattice isn’t *all* the possible ratios, it’s a set of transpositions. A typical 5-limit lattice in its simplest form is this:

….5/4

4/3 1/1 3/2

….8/5

What happens when you move one space in any direction? The lattice moves with you! That means that all you need to do is keep track of where you move. So in this example if I move right, right, up I would get:

{

ratio:

transposition: 3/2, 3/2, 5/4

}

“But derp, 3/2 * 3/2 is 9/8 man! Learn to math!!”

I don’t care what it is, I care how I got there. Remember, all a lattice *really* is is a grid of transpositions, not absolute notes. Much more useful than seeing 45/16, which, while it makes us look like we math pretty hard, doesn’t tell us anything.

**Final Thoughts**

Hopefully you will find this approach to be somewhat useful. As I mentioned many times, this is about valuing clarity over all else. It should also make working with ratios less daunting as I’m rather sick of hearing the complaint that “just intonation gets too complex/difficult/meh!” when you try to transpose, modulate, or even just stack ratios on top of ratios. It’s conceptually no different from equal temperament, only you end up multiplying rather than adding.

If math is a sticking point, why are you working with tunings?!?! (joking)

Seriously though, if you are working with things like this, it’s probably a good idea to use a computer to handle the math. This is 2014 after all! Even if you know nothing about programming in general, learn how to use a basic python interpreter or something like that so that you can write out:

440 * (3/2) * (3/2) * (5/4)

and it spits out 1237.5, rather than grabbing your calculator or abacus and slogging through all of it yourself (although you *should* be able to, it’s just way faster and less accident prone).