キノコの自省録

日々適当クリエイト

音符の長さの計算式

半分はおおまぬけな話。

以前のエントリで、音符の長さとテンポから、実時間長を計算する式を公開しました。

X分音符の時間長と音階周波数の計算メソッド - キノコの自省録

数式とプログラムで表現すると、こんな感じです。

【数式】 D=\frac{60}{T}\cdot\frac{4}{L} (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分音符の長さを算出しますと、

D=\frac{60}{140}\cdot\frac{4}{8}=\frac{60}{280}≒0.214秒

です。

以下、音符の長さにまつわる間抜けなお話。

符点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パーサに対して、符点やタイなどのチェックをしている時です。やたらと酷い音ズレが発生したため、シーケンサーのコードのせいなのか、パーサのコードのせいなのか、上記音符の時間長計算のせいなのかと色々調べた結果、あっと気づいてしまったわけです。