音符の長さの計算式
半分はおおまぬけな話。
以前のエントリで、音符の長さとテンポから、実時間長を計算する式を公開しました。
X分音符の時間長と音階周波数の計算メソッド - キノコの自省録
数式とプログラムで表現すると、こんな感じです。
【数式】 (T=テンポ, L=X分音符, 求める長さDは秒)
# python def get_duration(tempo = 120, note_len = 4): base_ms = 60.0 / tempo note_rate = 4.0 / note_len return base_ms * note_rate
// C/C++ double getDuration(double tempo, int note_len) { double base_ms = 60.0 / tempo; double note_rate = 4.0 / note_len; return base_ms * note_rate; }
この式は全く正しいので、問題なく使用できます(tempoに0を入力すると落ちますが)。
例えば、テンポT=140の8分音符の長さを算出しますと、
です。
以下、音符の長さにまつわる間抜けなお話。
符点4分音符は3分音符ではない
「2分音符と4分音符の間なんだから、3分音符と同じでしょ」と、ずっと勘違いしていました。同様に、符点8分音符は6分音符だと思っていたということです。
当たり前ですが、X分音符というのは、その長さが「全音符/X」という意味です。4分音符は1/4=0.25, 8分音符は1/8=0.125, 合わせると符点4分音符は0.375になります。一方、3分音符は1/3=0.333なので、微妙に短いということがわかります。ちなみに3分音符は2分音符の3連符と同じです。
符点4分音符をX分音符で表現できるか、というと、それは無理です。計算すると、8/3(≒2.67)分音符になります。
なんで気づいたかというと、作ったばかりのMMLパーサに対して、符点やタイなどのチェックをしている時です。やたらと酷い音ズレが発生したため、シーケンサーのコードのせいなのか、パーサのコードのせいなのか、上記音符の時間長計算のせいなのかと色々調べた結果、あっと気づいてしまったわけです。