7

I have recently been searching for a formula to determine the octave a note is in, given the number of that key on the piano. For example, given the key #77 (C7# for reference), how could I mathematically determine its octave number?

So far, I have tried dividing by 12 and 13, rounding to the nearest whole, since there are 12-13 notes in an octave (counting black and white keys), depending if you include the repeat of the first note or not.

Any ideas? Thank you!

7
  • Intriguing! There are 12 pitches in an octave; like hours in a day, "a.m." last up to but not including noon. Jul 8 at 13:09
  • Thank you all for your help! I have applied the final answer of FLOOR((x+8)/12) to a computer program I was making that converts computer-code files to music. For anyone interested, I will post a link to it in a few hours. Jul 8 at 14:14
  • And here is the link to the project: github.com/flancast90/Harpsichord. For anyone interested, I would love some feedback. You do not need to be a programmer to use it, the base of the actual program is music theory concepts I have learned, expressed mathematically. Jul 8 at 22:27
  • @Finn_Lancaster 1. note that math.floor((note_loc+8)/12) is the same as (note_loc + 8) // 12 or even int((note_loc + 8) / 12); 2. even if the range of a piano keyboard is pretty standard, it's better to consider the 128-range of MIDI with a (possibly customizable) constant used as offset in order to get the correct pitch; 3. some time ago I developed a virtual keyboard in PyQt5, in case you're interested in studying its code: gist.github.com/MaurizioB/43a053575f17eae371a9d7394e66a46e Jul 9 at 0:41
  • Awesome! Glad to see there are some fellow programmers/musicians here! Jul 9 at 0:52
6

Given a key number x, the octave can be calculated by FLOOR([x+8]/12).


As pointed out by @user80003, this formula cannot distinguish between enharmonically equivalent pitches. It will give wrong answers for B#s and Cbs. Given key #76, the above formula gives 7 as the octave, which is correct for C7, but incorrect for B#6.

This can only be accommodated when the pitch is known and made enharmonically equivalent. Using pitch class (PC) notation (C=0; C#/Db=1; D=2; ...; B=11), for example, eliminates the problem.

KeyNum = (12 * Octave) + (PC - 8)

Thus

Octave = FLOOR[ (KeyNum + 8 - PC)/12 ]

Since B# and C are equivalent in pitch-class terms (0) — as are B and Cb (11) — the octave is calculated unambiguously, but with the loss of the letter-name designation.

1
  • Thanks, @Aaron, this adds the corrections myself and others were suggesting to @guidot’s answer. I would upvote except for my too-low reputation, and I would like to wait for any new developments on @user80003’s answer before accepting as answer. EDIT: Just upvoted Jul 8 at 13:47
3

Note that there is no definitive answer as stated, since for example key #76 is used for both C7 and B♯6 and key #75 is used for both C♭7 and B6, meaning that the actual octave number may depend on the tonality.

4
  • Interesting, @user80003, I did not even think of that. Because of the FLOOR function, I believe that the octave number returned would be correct, but nonetheless #76 and #77 would return slightly different decimal answers before being floored, I think. Jul 8 at 13:45
  • 3
    This answer seems to point out the complications of special cases without an attempt to address the basic question.
    – guidot
    Jul 8 at 13:51
  • @guidot It addresses the basic question by pointing out that it's unanswerable as given. There's no way to distinguish between enharmonically equivalent pitches with different octave designations. Piano keys are 1-based, so given the formula FLOOR([x+8]/12), for key #76 the return value will be 7, which is correct for C7, but incorrect for B#6.
    – Aaron
    Jul 8 at 13:56
  • 2
    Should be a comment, but idk if new users have the rep to do that.
    – qwr
    Jul 8 at 22:33
1

You have to consider the offset caused by the non-existing keys of the first octave on the piano as well. Otherwise divsion by 12 should work.

So if you keyboard starts with a, then (key_number + 9)//12 should do the trick. Note, that octave numbering is a minefield of its own (whether to start with 0 or 1).

It of course depends also on the number you assign to the first key (key_number). The given 9 works for those starting with 0, to be replaced by 8 when you start with one.

5
  • 2
    Shouldn't it be key_number+8? The lowest octave transitions from 0 to 1 on C, which is the fourth key, so you want 4+8 = 12 // 12 = 1, no? (Note that this assumes you're numbering the first key 1, as opposed to 0, but 1 is in line with OP's example key.
    – Athanasius
    Jul 8 at 13:31
  • For the sake of simplicity, assuming that C1 was the beginning of the first octave, disregarding A0, etc, how then would the formula change. Would just division by 12 work? Jul 8 at 13:31
  • @Finn_Lancaster - in case it's unclear, note that "//" in this answer indicates integer division, where you truncate the answer by ignoring any decimal and taking the integer (as in a mathematical floor function).
    – Athanasius
    Jul 8 at 13:33
  • Answered my question just before I asked! Yep, sounds just like floor - returning the nearest integer less than or equal to the given number. Jul 8 at 13:35
  • 1
    @Anthanasius: your comment with adding 8 instead of 9 seems to be correct. Just verified with note 40 (Middle C), which means 48/12=4. With 9, the floor function returns the same, and should have no difference because of the low number of octaves on the piano, but as soon as the number of octaves was too high, the slightly more decimal would mean an incorrect answer. Jul 8 at 13:40
1

A standard grand piano keyboard goes from 39 notes below Middle C to 48 notes above Middle C. So, if you number the keys from 1 to 88 (as opposed to 0 to 87), then Middle C = #40.

Assuming you define octaves as going from C to B (ignoring the tricky numbering of B♯ and C♭), then the octave number of key n is (n - 40) // 12 + M, where // is Python's floor division operator and M is the octave number assigned to Middle C.

If M=4 (as in scientific pitch notation), then (n + 8) // 12 is an equivalent formulation.

Not the answer you're looking for? Browse other questions tagged or ask your own question.