A little rust for the scale intervals

A little rust for the scale intervals

·

0 min read

Photo by Geert Pieters on Unsplash

The last time we stopped with our scale alphabet. In our case we picked the C Major alphabet. but in the end actually this is the mechanism we will use for the minor Tuning as well.

Intervals, Frequencies and other chromatic magic

So what is the main difference between major and minor scales? Well it's 'very easy' that's why we made up 3 normal minor scale variations ... that's how easy it is.

In general we have 12 frequencies, those frequencies are the basis of most scales - that I know of.

So what is a frequency in our case? it's a vibration that we can hear, at least that's the ones we care about, actually it doesn't matter if we move our starting point frequency outside of the hearing spectrum or not ... the same interval rules apply, we just can't hear them. So to me it would be more abstract art or science and not creative musical art. But ... again debatable.

So we have a band/range of frequencies who all have a defined relative distance to each other. As an example I will remain in the previous major scale of C and take C3 as our root/key/home note

As you may already wonder what is C3 ? well the thing is in western music (maybe in the others as well) we have absolute values as starting points and the lowest defined starting point for the C major key is C0 with a frequency of 16.35 Hz.

Since our normal hearing range starts at ~ 20Hz ;D lets just say it's not the best example.

A great site to get a feel for frequencies.

We take C3 with a pitch of ~ 130.81 Hz

Our notes/frequencies will be:

C3 - 130.81 Hz 
D3 - 146.83 Hz 
E3 - 164.81 Hz 
F3 - 174.61 Hz 
G3 - 195.99 Hz 
A3 - 220 Hz 
B3 - 246.94 Hz 
C4 - 261.62 Hz

If we look at the calculated distances

C3 to D3 - 16.02 Hz
D3 to E3 - 17.98 Hz
E3 to F3 - 9.8 Hz
F3 to G3 - 21.38 Hz
G3 to A3 - 24.01 Hz
A3 to B3 - 26.94 Hz
B3 to C4 - 14.68 Hz

To me three things jump out:

  1. E3 to F3 and B3 to C4 are defined halfsteps
  2. The size of distance between the notes frequency wise increases steadily.
  3. A is a natural number.

The reason why this happens ... tbh ;D I would need to read up on it but at least I got a mathematical explanation

Our alphabet starts at A that's also why it has a natural number - I guess. We have a magic number that is the twelfth root of 2. This is the pythagorean tempered tuning.

the two is because every octave actually doubles the frequency and every octave is built on 12 semitones.

A2 = 110 Hz.
A3 = 220 Hz.

there are 12 intervals / steps in our system so the twelfth root of 2 multiplied with itself 12 times will return be 2 and every step between is our tempered sound interval ratio.

Read more:

The key point is the formular how we get the distance:

fn = f0 * (a)^n

so our fn is C3 our f0 is A2. a is our magic number ~ 1.059463094359

fn = A2 * (1.059463094359)^n

C is 1 fullstep and 1 halfstep away from A so 3 halfsteps (remember B to C is a halfstep) so f has 3 halfsteps from A2 to C3.

f3 = A2  * (1.059463094359)^3

In numbers:

C3 = 130.81 ~= 110 * (1.059463094359)^3

This was a little side track because I think it helps to actually get some idea and tools to see how it works.

Back to our minor scale(s)

The key difference between minor and major scale are the positions of the half tone steps.

so if the C major scale is

C D E F G A B C
 2 2 1 2 2 2 1

with our halfsteps between E to F and B to C. So this looks all pretty easy esp in the C Major scale where the scale halfsteps fall in line with tonal halfsteps.

The C natural minor scale.

Why natural? Because it's actually the 'normal' minor scale.

our halfsteps move from

  • 3-4 and 7-8 to
  • 2-3 and 5-6

And now to the fun of having these tempered scales

C D Eb F G Ab Bb C 
 2 1  2 2 1  2  2

As you can see now you know why I complain about the notation, There always have to be the whole alphabet and since 2 halftone steps are defined in the chromatic scale we now have to counter calculate where we put our halfsteps and wholesteps.

So to lower the distances between the notes D and E to a halfstep we need to move E closer to D by one halfstep. This means we add the 'halfstep' down marker 'b' to it. We now have 'E-flat' aka 'Eb'. That's actually the 12 intervals for so we can move our 'notes' within these 12 intervals and these notes are always there. A scale is just a grouping of notes that sound 'good/interesting' to us. Nothing less, nothing more. There are some underlying mathematical principles we can use if we construct them in a certain way, but lets not get ahead of ourselves.

One might point out it gives kinda unique fingerprints to scales at least in a classical sense.

So this would be the natural minor, but in music we have a kind of tonal groupings of notes which are as follows

I iii Vi - tonic 
ii IV - prepare tension
V Vii - tension

So the idea is that we want to build 'tension' and than 'release' that tension by going to a tonic note. Which will be extra interesting with key changes and also we can now construct in a common way which note / correlating chord can be played before our current one and usually sounds 'good/correct' to our ear.

This is a whole chapter on it's own I just bring it up because as you can see

Vii is a tension note at least in the major scale the halfstep of the Vii resolves by 'going home' to the next I this is a very common pattern.

If we look at the natural minor we see, to create our 'less happy' sound we moved our halftone steps to other positions.

Still musicians want to have this little signature move where tension and release to the new 'home/key/root' .... which brings us to the next minor scale ....

the harmonic minor scale

What is a harmony? A harmony is the combination of more than 1 note played together to create a harmony. Really quite literal that's it more than 1 note. In our western chord system, which are just harmonies usually we have the groups of 3 rule so a harmony usually have at least 3 note ringing together. besides power chords - the 5 cord - C5, D5 who have the I and the V ringing together. Also it does not matter how many I and V you play it's just defined as only those two notes.

I will not focus on chords at the moment we're still in intervals and scales but hopefully we will get there.

So in our harmonies we want our tension and release cycle to get that extra 'kick/feel'. This is why we just add a 3rd halfstep from:

  • 7 - 8 (Vii - I)

So our harmonic C minor scale looks as follows

C D Eb F G Ab B C 
 2 1  2 2 1  3 1

As you can see by restoring our Vii to I tension and release concept we now got a 3 halfstep interval in our scale. Which sound interesting and weird (if you get the chance try it out on your instrument)

Also the question 'why 3' could pop up. Remember the twelve semitones/halfstep/intervals/frequencies? if you add all the intervals together it has to result in 12 again. That's how our system is built.

So this gives us our tension and going home concept back which allows us to pronounce/accent our key way better/more distinctive.

But .... the chord construction is now out of place (I actually like it - but that's taste)

And we got a solution for that .....

The melodic minor scale

So the melodic minor scale is the correction to remove the 3 interval gap from the harmonic minor to make it feel more 'natural' again

We move our Ab to be an A again to even the distance to a maximum of two semitones at once. Which is now almost the C-Major again besides the 1 moved semitone in the beginning between ii and iii instead of iii and IV

major
C D E F G A B C
 2 2 1 2 2 2 1 

minor:
C D Eb F G A B C
 2 1  2 2 2 2 1

TL;DR

  • There are 3 minor scales
  • There is a tension an release concept in music
  • Notes are grouped by their purpose
  • The intervals move based on our intention of sound
  • The significant minor interval is the ii to iii since it exist in all our minor scales

And now to our ridiculous primitive rust code ;D in comparison of the other information I gave ... .

#[derive(Debug)]
enum ScaleError {
    InvalidKey,
    InvalidScale,
}

enum ScaleTypes {
    Major,
    NaturalMinor,
    HarmonicMinor,
    MelodicMinor,
}

fn get_intervals(scale_type: ScaleTypes) -> Result<[usize; 7], ScaleError> {
    match scale_type {
        ScaleTypes::Major => Ok([2,2,1,2,2,2,1]),
        ScaleTypes::NaturalMinor => Ok([2,1,2,2,1,2,2]),
        ScaleTypes::HarmonicMinor => Ok([2,1,2,2,1,3,1]),
        ScaleTypes::MelodicMinor => Ok([2,1,2,2,2,2,1]),
        _ => Err(ScaleError::InvalidScale)
    }
}

#[cfg(test)]
mod tests {
   use crate::{ScaleTypes, ScaleError, get_intervals};

   #[test]
    fn get_major_intervals() {
        let intervals: [usize; 7] = get_intervals(ScaleTypes::Major).unwrap();

        assert_eq!(intervals, [2,2,1,2,2,2,1])
    }

    #[test]
    fn get_natural_minor_intervals() {
        let intervals: [usize; 7] = get_intervals(ScaleTypes::NaturalMinor).unwrap();

        assert_eq!(intervals, [2,1,2,2,1,2,2])
    }

    #[test]
    fn get_melodic_minor_intervals() {
        let intervals: [usize; 7] = get_intervals(ScaleTypes::MelodicMinor).unwrap();

        assert_eq!(intervals, [2,1,2,2,2,2,1])
    }

    #[test]
    fn get_harmonic_minor_intervals() {
        let intervals: [usize; 7] = get_intervals(ScaleTypes::HarmonicMinor).unwrap();

        assert_eq!(intervals, [2,1,2,2,1,3,1])
    }
}

so we added a new error type that actually is not possible unless we don't implement the scale, so it only can be an implementation mistake. That's why we won't unit-test it, but still cover it since accidents happen.

#[derive(Debug)]
enum ScaleError {
    InvalidKey,
    InvalidScale,
}

we added a new enum that represents our scale types

enum ScaleTypes {
    Major,
    NaturalMinor,
    HarmonicMinor,
    MelodicMinor,
}

and we have our match function to give use all the intervals we want

fn get_intervals(scale_type: ScaleTypes) -> Result<[usize; 7], ScaleError> {
    match scale_type {
        ScaleTypes::Major => Ok([2,2,1,2,2,2,1]),
        ScaleTypes::NaturalMinor => Ok([2,1,2,2,1,2,2]),
        ScaleTypes::HarmonicMinor => Ok([2,1,2,2,1,3,1]),
        ScaleTypes::MelodicMinor => Ok([2,1,2,2,2,2,1]),
        _ => Err(ScaleError::InvalidScale)
    }
}

In theory I could also use an option here, but I see a missing scale not as optional but as an error.

Also another debatable thing would be, that I don't use a global immutable structure but returning a result of a function. The idea to me is that I don't need all intervals in the global space atm. Maybe later on it makes sense by just mapping them in a multidimensional array moving the address pointers.

Lets see when we get there it should remain immutable also functions and tables are isomorphic.

As always thanks for reading. I hope the music theory parts are not to boring :)

Feedback is always welcome :) For example I didn't explain that we use the harmonic only going UP C3 - C4 but going down there is no tension and release so we tend to play the natural one ;D .... or in other words ... musicians are weird and want to play something interesting to the ear ... so we make things complex based on the situation and mood ;D ....