夕食どきにご飯を炊いていると、テレビの音楽と、炊飯器の出すブーーーンという音が重なって、ものすごく気持ちの悪い不協和音が聞こえてきた。炊飯器からは、いったいどんな高さの音が出てるんだろう。絶対音感とかないので良くわからないが、こういう家電の出す音って、たぶん送電周波数50Hzの倍音になってるんじゃないだろうか。で、テレビから聞こえる音楽は、標準音のA4=440Hzに従ってるとすると、ピアノの鍵盤と炊飯器の音のずれ具合は、計算で出せるかもしれない。

音は、周波数が倍になると1オクターブ高くなり、周波数が半分になると1オクターブ低くなる。てことは、

  • A4-1オクターブなら、440Hzに2の-1乗(0.5)を掛ける
  • A4+0オクターブなら、440Hzに2の+0乗(1)を掛ける
  • A4+1オクターブなら、440Hzに2の+1乗(2)を掛ける

ということか。

ならば、さらに細かく、A4の半音上(つまり、A4+「12分の1オクターブ」)なら、440Hzに2の「12分の1乗」をかければよいはず。この「1」の部分を順番に変えていけば、ピアノの各鍵盤の周波数が計算できる。で、家電の出す50Hzの第n倍音(50Hz、100Hz、150Hz…)の周波数にいちばん近い鍵盤を探して、その周波数との差分を取れば、半音以内の周波数のズレが出るはず。

さらに、1半音は100セントだから、A4の1セント上なら、440Hzに2の「12分の0.01乗」をかければよいはずなので、これで家電の倍音が鍵盤の音から何セントずれているかも分かるはず。たぶん。

この理屈があっているかわからないけど、とりあえず計算してみよう。

最初は表計算ソフトで試行錯誤を始めたけど、だんだん面倒くさくなってきたので、Rubyでプログラムを書いてみた。こんな感じ。50Hzの第1倍音から第30倍音までの周波数を求めて、それをA4の-40半音から+40半音まで順番に探索して一番近い鍵盤を求めたうえで、さらにその前後の音を-50セントから+49まで順番に探索して、最終的にどの倍音がどの鍵盤から何セント高いか低いかを出している。ベタですね。もっと簡単な方法がありそうではある……

PowerTransmissionFreq = 50.0
A4Freq = 440.0
NoteNames = ["C","C#","D","D#","E","F","F#","G","G#","A","A#","B"]

def to_note_name(distance_from_A4)
  distance_from_C5 = distance_from_A4 - 3
  height = distance_from_C5 / 12 + 5
  offset = distance_from_C5 % 12
  NoteNames[offset] + height.to_s
end

(1..30).each do |overtone_factor|
  overtone_freq = PowerTransmissionFreq * overtone_factor

  prev_distance_from_A4 = 0
  prev_note_freq = 0.0
  prev_freq_delta = Float::MAX

  (-40..40).each do |distance_from_A4|
    note_freq = A4Freq * (2 ** (distance_from_A4 / 12.0))
    freq_delta = overtone_freq - note_freq
    if freq_delta.abs < prev_freq_delta.abs
      prev_distance_from_A4 = distance_from_A4
      prev_note_freq = note_freq
      prev_freq_delta = freq_delta
    else
      prev_cent = 0.0
      prev_cent_freq = 0.0
      prev_cent_freq_delta = Float::MAX
      (-50..49).each do |cent|
        cent_freq = A4Freq * (2 ** ((prev_distance_from_A4 + (cent.to_f / 100.0)) / 12.0))
        cent_freq_delta = overtone_freq - cent_freq
        if cent_freq_delta.abs < prev_cent_freq_delta.abs
          prev_cent = cent
          prev_cent_freq = cent_freq
          prev_cent_freq_delta = cent_freq_delta
        else
          break
        end
      end
      note_name = to_note_name(prev_distance_from_A4)
      printf "第%2d倍音(%8.3fHz) = A4%+3d半音(%8.3fHz)%+7.3fHz = %-3s%+3dcent(%8.3fHz)\n",
        overtone_factor, overtone_freq, prev_distance_from_A4, prev_note_freq, prev_freq_delta, note_name, prev_cent, prev_cent_freq
      break
    end
  end
end

で、これを動かしてみると、こうなった。まあなんとなくそれっぽい。

$ docker run -it --rm -v $PWD:/w -w /w ruby ruby harmony.rb
第 1倍音(  50.000Hz) = A4-38半音(  48.999Hz) +1.001Hz = G1 +35cent(  50.000Hz)
第 2倍音( 100.000Hz) = A4-26半音(  97.999Hz) +2.001Hz = G2 +35cent( 100.000Hz)
第 3倍音( 150.000Hz) = A4-19半音( 146.832Hz) +3.168Hz = D3 +37cent( 150.004Hz)
第 4倍音( 200.000Hz) = A4-14半音( 195.998Hz) +4.002Hz = G3 +35cent( 200.000Hz)
第 5倍音( 250.000Hz) = A4-10半音( 246.942Hz) +3.058Hz = B3 +21cent( 249.955Hz)
第 6倍音( 300.000Hz) = A4 -7半音( 293.665Hz) +6.335Hz = D4 +37cent( 300.009Hz)
第 7倍音( 350.000Hz) = A4 -4半音( 349.228Hz) +0.772Hz = F4  +4cent( 350.036Hz)
第 8倍音( 400.000Hz) = A4 -2半音( 391.995Hz) +8.005Hz = G4 +35cent( 400.001Hz)
第 9倍音( 450.000Hz) = A4 +0半音( 440.000Hz)+10.000Hz = A4 +39cent( 450.024Hz)
第10倍音( 500.000Hz) = A4 +2半音( 493.883Hz) +6.117Hz = B4 +21cent( 499.911Hz)
第11倍音( 550.000Hz) = A4 +4半音( 554.365Hz) -4.365Hz = C#5-14cent( 549.900Hz)
第12倍音( 600.000Hz) = A4 +5半音( 587.330Hz)+12.670Hz = D5 +37cent( 600.017Hz)
第13倍音( 650.000Hz) = A4 +7半音( 659.255Hz) -9.255Hz = E5 -24cent( 650.179Hz)
第14倍音( 700.000Hz) = A4 +8半音( 698.456Hz) +1.544Hz = F5  +4cent( 700.072Hz)
第15倍音( 750.000Hz) = A4 +9半音( 739.989Hz)+10.011Hz = F#5+23cent( 749.885Hz)
第16倍音( 800.000Hz) = A4+10半音( 783.991Hz)+16.009Hz = G5 +35cent( 800.002Hz)
第17倍音( 850.000Hz) = A4+11半音( 830.609Hz)+19.391Hz = G#5+40cent( 850.024Hz)
第18倍音( 900.000Hz) = A4+12半音( 880.000Hz)+20.000Hz = A5 +39cent( 900.049Hz)
第19倍音( 950.000Hz) = A4+13半音( 932.328Hz)+17.672Hz = A#5+33cent( 950.270Hz)
第20倍音(1000.000Hz) = A4+14半音( 987.767Hz)+12.233Hz = B5 +21cent( 999.821Hz)
第21倍音(1050.000Hz) = A4+15半音(1046.502Hz) +3.498Hz = C6  +6cent(1050.135Hz)
第22倍音(1100.000Hz) = A4+16半音(1108.731Hz) -8.731Hz = C#6-14cent(1099.801Hz)
第23倍音(1150.000Hz) = A4+17半音(1174.659Hz)-24.659Hz = D6 -37cent(1149.821Hz)
第24倍音(1200.000Hz) = A4+17半音(1174.659Hz)+25.341Hz = D6 +37cent(1200.034Hz)
第25倍音(1250.000Hz) = A4+18半音(1244.508Hz) +5.492Hz = D#6 +8cent(1250.272Hz)
第26倍音(1300.000Hz) = A4+19半音(1318.510Hz)-18.510Hz = E6 -24cent(1300.358Hz)
第27倍音(1350.000Hz) = A4+19半音(1318.510Hz)+31.490Hz = E6 +41cent(1350.109Hz)
第28倍音(1400.000Hz) = A4+20半音(1396.913Hz) +3.087Hz = F6  +4cent(1400.144Hz)
第29倍音(1450.000Hz) = A4+21半音(1479.978Hz)-29.978Hz = F#6-35cent(1450.358Hz)
第30倍音(1500.000Hz) = A4+21半音(1479.978Hz)+20.022Hz = F#6+23cent(1499.771Hz)

ちなみに、送電周波数が60Hzの場合はこうなるらしい。

$ docker run -it --rm -v $PWD:/w -w /w ruby ruby harmony.rb
第 1倍音(  60.000Hz) = A4-35半音(  58.270Hz) +1.730Hz = A#1+49cent(  59.943Hz)
第 2倍音( 120.000Hz) = A4-23半音( 116.541Hz) +3.459Hz = A#2+49cent( 119.887Hz)
第 3倍音( 180.000Hz) = A4-15半音( 184.997Hz) -4.997Hz = F#3-47cent( 180.042Hz)
第 4倍音( 240.000Hz) = A4-11半音( 233.082Hz) +6.918Hz = A#3+49cent( 239.773Hz)
第 5倍音( 300.000Hz) = A4 -7半音( 293.665Hz) +6.335Hz = D4 +37cent( 300.009Hz)
第 6倍音( 360.000Hz) = A4 -3半音( 369.994Hz) -9.994Hz = F#4-47cent( 360.085Hz)
第 7倍音( 420.000Hz) = A4 -1半音( 415.305Hz) +4.695Hz = G#4+19cent( 419.888Hz)
第 8倍音( 480.000Hz) = A4 +1半音( 466.164Hz)+13.836Hz = A#4+49cent( 479.546Hz)
第 9倍音( 540.000Hz) = A4 +4半音( 554.365Hz)-14.365Hz = C#5-45cent( 540.141Hz)
第10倍音( 600.000Hz) = A4 +5半音( 587.330Hz)+12.670Hz = D5 +37cent( 600.017Hz)
第11倍音( 660.000Hz) = A4 +7半音( 659.255Hz) +0.745Hz = E5  +2cent( 660.017Hz)
第12倍音( 720.000Hz) = A4 +9半音( 739.989Hz)-19.989Hz = F#5-47cent( 720.170Hz)
第13倍音( 780.000Hz) = A4+10半音( 783.991Hz) -3.991Hz = G5  -9cent( 779.926Hz)
第14倍音( 840.000Hz) = A4+11半音( 830.609Hz) +9.391Hz = G#5+19cent( 839.775Hz)
第15倍音( 900.000Hz) = A4+12半音( 880.000Hz)+20.000Hz = A5 +39cent( 900.049Hz)
第16倍音( 960.000Hz) = A4+13半音( 932.328Hz)+27.672Hz = A#5+49cent( 959.093Hz)
第17倍音(1020.000Hz) = A4+15半音(1046.502Hz)-26.502Hz = C6 -44cent(1020.240Hz)
第18倍音(1080.000Hz) = A4+16半音(1108.731Hz)-28.731Hz = C#6-45cent(1080.283Hz)
第19倍音(1140.000Hz) = A4+16半音(1108.731Hz)+31.269Hz = C#6+48cent(1139.901Hz)
第20倍音(1200.000Hz) = A4+17半音(1174.659Hz)+25.341Hz = D6 +37cent(1200.034Hz)
第21倍音(1260.000Hz) = A4+18半音(1244.508Hz)+15.492Hz = D#6+21cent(1259.696Hz)
第22倍音(1320.000Hz) = A4+19半音(1318.510Hz) +1.490Hz = E6  +2cent(1320.034Hz)
第23倍音(1380.000Hz) = A4+20半音(1396.913Hz)-16.913Hz = F6 -21cent(1380.071Hz)
第24倍音(1440.000Hz) = A4+21半音(1479.978Hz)-39.978Hz = F#6-47cent(1440.339Hz)
第25倍音(1500.000Hz) = A4+21半音(1479.978Hz)+20.022Hz = F#6+23cent(1499.771Hz)
第26倍音(1560.000Hz) = A4+22半音(1567.982Hz) -7.982Hz = G6  -9cent(1559.852Hz)
第27倍音(1620.000Hz) = A4+23半音(1661.219Hz)-41.219Hz = G#6-43cent(1620.466Hz)
第28倍音(1680.000Hz) = A4+23半音(1661.219Hz)+18.781Hz = G#6+19cent(1679.551Hz)
第29倍音(1740.000Hz) = A4+24半音(1760.000Hz)-20.000Hz = A6 -20cent(1739.785Hz)
第30倍音(1800.000Hz) = A4+24半音(1760.000Hz)+40.000Hz = A6 +39cent(1800.098Hz)

今度ご飯を炊くとき、実際なんの音が出ているのか確認してみよう。

※バージョン情報

  • ruby 3.3.0