Skip to content

Instantly share code, notes, and snippets.

@shantiphula
Created August 24, 2020 01:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save shantiphula/341299147ffdec3af55106e24d7d8d94 to your computer and use it in GitHub Desktop.
Save shantiphula/341299147ffdec3af55106e24d7d8d94 to your computer and use it in GitHub Desktop.
「調和純正律で遊ぼう!」倍音成分同士のハモり・うなり解析
#!/usr/bin/env ruby
# 与えられた音群の、周波数成分(基音及び倍音成分)同士の、ハモり数とうなりを解析する。
def analyze_tremolos(hz_array_of_tones)
# 第何倍音成分まで考慮するか。
harmonics_max = 5
# ハモりの一致は±何Hz許容するか。(本来はセントで考えたほうがいいが)
match_fuzz_hz_max = 1.0
# うなりの秒当たり回数( beats per second )はどの範囲を人間が認識できるとするか。
major_bps_range = (0.5..20.0)
# すべての周波数成分を取り出す。
all_hz = hz_array_of_tones.map { |hz|
fuzz = 0 # (-0.5 + rand).round(2)
(1..harmonics_max).map { |n|
(hz + fuzz) * n
}
}.flatten
# 周波数成分同士の組み合わせにつき、うなり回数とハモり回数の解析をする。
analysises = all_hz.combination(2).map do |hz1, hz2|
hz_diff = (hz1 - hz2).abs
# 1秒間のうなり回数
beat_per_sec = hz_diff.round(1)
{ hz: [hz1, hz2].sort, bps: beat_per_sec }.merge(
(hz_diff < match_fuzz_hz_max) ? { matched: true } : {}
)
end.flatten
major_tremolos = analysises.find_all { |it|
major_bps_range.cover?(it[:bps])
}.sort_by { |it|
[it[:bps], it[:hz]]
}
matched_harmonics = analysises.find_all { |it|
it[:matched]
}.map { |it|
it[:hz]
}.sort
# puts [hz_array_of_tones.join(" : "), matched_harmonics.count, major_tremolos.size].join("\t")
# return
pp({ hz_array_of_tones => {
"一致倍音数(±1Hz)" => matched_harmonics.count,
"うなり(0.5〜20 beats/sec)" => major_tremolos,
} })
end
puts "# 純正律(小さい整数比の例)"
analyze_tremolos [264, 330, 396]
analyze_tremolos [352, 440, 528]
analyze_tremolos [396, 495, 297 * 2]
analyze_tremolos [330, 396, 495]
analyze_tremolos [440, 528, 330 * 2]
puts "# 純正律(大きな整数比の例)"
analyze_tremolos [297, 352, 440]
analyze_tremolos [495, 594, 704]
# analyze_tremolos [1650.000, 1980.000, 2346.667]
puts "# 平均律の五和音"
analyze_tremolos [261.63, 329.63, 392.00]
analyze_tremolos [349.23, 440.00, 523.26]
analyze_tremolos [392.00, 493.88, 587.32]
analyze_tremolos [329.63, 392.00, 493.88]
analyze_tremolos [440.00, 523.26, 659.26]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment