# stepsPerOctave | pitchesPerOctave

Hi guys,

I’m trying to figure out some of the theory behind the SuperCollider pitch model in order to update my sampler to play in other-than-western tuning-systems.

At the moment I’m quite confused by the concept of steps-per-octave and, particularly, I’m not able to understand what’s the difference between it and pitches-per-octave.

Let’s say I want to model an equiheptatonic scale, so, proceeding step by step and from the general to the particular,

1. I create an ET7 tuning first:
``````t = Tuning.et(7);
``````
1. then I use it as the tuning for my scale:
``````a = Scale.new([0,1,2,3,4,5,6], 7, tuning:t);
``````

Now, evaluating `a.pitchesPerOctave` I get 7 (which is ok to me, the tuning the scale is based on, contains, indeed, seven pitches) but, evaluating `a.stepsPerOctave`, I get 12.0 I have read in some tutorials and help files (link, link) that, within Event Patterns, when dealing with equal temperaments other than ET12, the use of the key \stepsPerOctaves is recommended (precisely to specify, at least I think, values for steps per octave other than 12 in case it is needed).

I thought my scale fell right into this case, however, I find that evaluating the `stepsPerOctave` method on the scale does not return 7 as I would have expected but 12. Why? What am I missing?

It appears that 12 is hardcoded and cannot be overridden.

In Tuning:

``````	stepsPerOctave {
^octaveRatio.log2 * 12.0
}
``````

So, if octaveRatio == 2, the normal case, stepsPerOctave will always be 12.

BUT… look at the tuning values in your case:

``````t = Tuning.et(7);

-> Tuning([ 0.0, 1.7142857142857, 3.4285714285714, 5.1428571428571, 6.8571428571429, 8.5714285714286, 10.285714285714 ], 2.0, "ET7")

t.at(1).asFraction  // [12, 7]

t.at(2).asFraction  // [24 == 12*2, 7]
``````

So each tuning value is `i * (12/7)`, scaling your 7 degrees equally across a “unit” of 12.

Then:

``````a = Scale((0..6), 7, t);

// what's the ratio from A=440
// up to scale degree 1 in ET7?
a.degreeToFreq(1, 440, 0) / 440  // -> 1.1040895136734

// what's 7th root of 2?
2**(1/7)  // -> 1.1040895136738
``````

So it’s producing the right answer – 1 step in ET7 should indeed be the 7th root of 2 – leading to the conclusion that stepsPerOctave is an internal implementation detail that you don’t need to bother with.

hjh

1 Like

Don’t feel compelled to use the Tuning/Scale classes if, like me, you don’t find them intuitive.

3 Likes

it can be improved

1 Like