Home

Awesome

プログラマーのための古典派音楽理論

BNF

<program> ::= <info> \n <bars> | <bars>
<info>    ::= <bpm> <number> | <tempo>
<bpm>     ::= "BPM" | "bpm"
<number>  ::= ["1"-"9"]["0"-"9"]* | "0"
<tempo>   ::= "Grave" | "Largo" | "Lento" | "Adagio" | 
              "Larghetto" | "Adagietto" | "Andante" | "Maestoso" |
              "Moderate" | "Allegletto" | "Animato" | "Allegro" |
              "Assai" | "Vivace" | "Presto" | "Prestissimo"
<bars>    ::= <line> | <line> \n <bar> \n <bar> \n <bar> \n <bar> \n <bars>
<line>    ::= "|" | "|:" | ":|"
<bar>     ::= <tone> | <tone> <tone> | <tone> <tone> <tone> <tone>
<tone>    ::= <number> | ["A"-"G"](|"-")["0"-"9"](|"#"|"b") | "R" | "T"

また、// を書くと、以降が行末までコメントとみなされます。

処理

楽曲情報

最初の行には楽曲のテンポを指定することができます(プログラムの実行には関係ありません)。 省略した場合、Moderate が指定されます。

toneレベル処理

ソースコードは小節線(||::|)によって区切られる4行のbarごとに解釈されます。小節線のうち |::| は括弧と同様の構造で1対1に対応しており、出現が同数でない場合はエラーとなります。
以下にbarの一例を示します。

R   A5  F5  E5
E5      C5
G4  A4  T   G4
C4

C4T などはtoneと呼び、音符の情報を示します。C4 などは音高を表し、これはMIDIのノートナンバーに準拠します。TR については後述します。
toneは1行に1つ又は2つ又は4つ書くことができ、1行のtoneが1つ又は2つの場合、T が補完されます。上記の例は以下と等価です。

R   A5  F5  E5
E5  T   C5  T
G4  A4  T   G4
C4  T   T   T

また、toneの記法のうち上記のような数字とアルファベット(と臨時記号 # b)を組み合わせて書くものについては、数字のみで書き表すことができます。この場合の対応はこのページの国際式に準じます。
上記のソースコードは以下のように書き換えることができます。

R   81  77  76
76      72
67  69  T   67
60

各行の音符については補完がなされたのち、1~4行目の左から1番目、2番目、3番目、4番目の音符の組からchordに解釈されます。解釈にあたり、各toneはC C#(Db) D D#(Eb) E F F#(Gb) G G#(Ab) A A#(Bb) B の音名に置き換えられます。置き換えの際、R は無視され、T は直前の音符と同じ音名とみなします(直前に音符が存在しない場合は無視されます)。

置き換えたのち、音符の組が以下の表に過不足なく対応するかどうかを調べ(音高の重複は許します)、chordへの解釈を行います。解釈できない場合はエラーとなります(1st、3rd、5th、7thについては気にしないで下さい、より難解にしようとした名残です)。

chord1st3rd5th7th
ICEG
IIDFA
II7DF#AC
II7 omit5DF#C
II7F#AC
IVFAC
VGBD
V7GBDF
V7 omit5GBF
V7BDF
VIACE

上記のソースコードをchordに解釈すると、以下のようになります。

I VI IV I

chordレベル処理

chordは先頭から順に読んでいき、小節線の直後の I を区切りとしてprogressionというまとまりごとに解釈を行います。ただし、その際に以下のように変換がなされます。

変換対象変換後
II7、II7 omit5、II7II
V7、V7 omit5、V7V

この変換ののち、同じchordが連続して並んでいるものが現れた場合は、2つ目以降を無視します。
例えば、ソースコードをchordに解釈した結果が以下のようになった場合、これは I IV II VI IV II V VI IV V 、… のprogression列として解釈されます。

 |  I   IV  II  V
 |  I   IV  II  II7
 |  V   VI  IV  V
 |  I   ...

progression列として解釈されたものは、命令として実行できるものから逐次的に実行されていきます。chord列の終端に達した場合は、そこで正常終了します。命令については後述します。

chordを読んでいく際に小節線として |::| が現れるとき、直前に実行した命令の値(後述)によって読む場所が変化することがあります。

以下のchord列の場合、直前の命令の値によって得られるprogression列が変わります。

...
 |  I   V   VI  IV
 |: V   I   II  V
 |  I   VI  IV  II
:|  II  V   I   IV
 |  I   ...

命令

基本的に1~3つの連続したprogressionが命令として解釈されます。解釈できないprogressionが現れた場合は実行時エラーになります。また、各命令には命令の値があり、|::| での分岐に用います。

以下に入力をそのまま出力する処理(cat)を行うchord列の例を示します。

 |  I   I   V   V
 |  I   I   II  V
 |  I   I   IV  IV
 |  I   I   II  V
 |  I   I   V   V
 |  I   V   VI  V
 |  I   V   I   V
 |  I   V   VI  V
 |  I   I   IV  IV
 |  I   V   VI  V
 |  I   IV  II  V
 |: I   V   VI  V
 |  I   I   II  V
 |  I   IV  I   V
 |  I   V   VI  V
 |  I   V   I   V
 |  I   V   VI  V
 |  I   I   IV  IV
 |  I   V   VI  V
 |  I   IV  II  V
:|  I   I   I   I
 |

禁則

さて、ここからは音楽理論の話です。

※ここで紹介する禁則などは実際の音楽理論のそれとは異なる部分もあります。予めご了承ください。

曲を綺麗に聴こえるものにするためには、どんなtoneやchordなどでも良いという訳ではなく、一定の法則に則ったものにする必要があります。
この言語では、以下に示す法則に反するものは音楽理論エラーとなり、検出された時点で実行不可となります。
ただし、オプションで-IgnoreTheoryExを指定した場合はエラーを無視して実行を行うことができます(エラーメッセージは表示されます)。

toneの禁則

この言語では、弦楽四重奏で演奏できる曲を基本としており、1つのbar内にある4行のtone列は、上から順にソプラノ・アルト・テノール・バスにあたります。これを声部といいます。

R   A5  F5  E5  <- ソプラノ
E5      C5      <- アルト
G4  A4  T   G4  <- テノール
C4              <- バス
                   ↑これを声部という

音域

ソプラノ・アルトはバイオリン、テノールはビオラ、バスはチェロで演奏されるため、それぞれの声部におけるtoneはそれぞれの楽器で弾くことのできる音域の中に収まっている必要があります。以下にそれぞれの音域を示します。

声部最低音最高音
ソプラノ、アルトG3(55)C7(96)
テノールC3(48)C6(84)
バスC2(36)C5(72)

声部と音高

それぞれの声部について、下の声部の音高が上の声部の音高以上となってはいけません
以下に良くない例を示します。

E4
G4  <- ソプラノより高い音高になっているのでエラー
C4
C4  <- テノールと同じ音高になっているのでエラー

連続五度、連続八度

各声部がバランスのいい綺麗なハーモニーを奏でるために気を付けなければならないのが、連続五度と連続八度です。
まず、五度・八度の関係について解説します。これは、2つの声部で鳴っている音の関係を表す言葉であり、低いほうの声部から数えて音高の差が半音7個分(、半音19個分、半音31個分…)の時に五度の関係、半音12個分(、半音24個分、36個分…)の時に八度の関係といいます。

C5  <- バスから見て半音12個分なので八度の関係
G4  <- バスから見て半音7個分なので五度の関係
E4  <- バスから見て半音4個分
C4  <- この例ではここが基準

この五度・八度の関係にある2つの声部は他の声部より音が強く感じられるため、なるべく連続して同じ声部群が五度・八度の関係になることは好ましくないと考えられます。そのため、同じ声部同士で3回以上連続で五度の関係に、または八度の関係になってはいけません(五度の関係から八度の関係になる等は連続していないとみなします)。ただし、T については判定をせず、次に音高が変化するまで連続の回数を持ち越します。
以下に良くない例を示します。

C5  G4  A4  D5  <- テノールと4回連続八度になっている(エラー)
G4  D4  C4  F4  <- 最初の2つがテノールと2回連続五度になっている
C4  G3  A3  D4  <- ソプラノと4回連続八度、アルトと2回連続五度になっている(エラー)
E3  B2  E3  A3

限定進行音

toneの構成するchordが一定の条件を満たすものにおいて、メロディの流れを美しいものにするために一部のtoneについては次に鳴らすべき音が定められています
以下にその条件と音を示します。

chord条件次の音
V、V7、V7 omit5、V7音名がB半音上のC
V7、V7 omit5、V7音名がF半音下のE
II7、II7 omit5、II7音名がF#(Gb)半音上のG
II7、II7 omit5、II7音名がC半音下のB

不自然な音程の移動

演奏するにあたって弾きづらい音程についてはなるべく避ける必要があり、音高が変化する際に半音10個分以上の移動を行ってはいけません(ただし、半音12個分の移動は例外的に大丈夫です)。

chordの禁則

chordが変化する際は、その流れが違和感なく綺麗に聴こえる必要があります。そのため、ほぼ全てのchordに進行先が決まっています
chordの進行先は以下の通りです。

chord進行先
I全て
II、II7、II7 omit5、II7V、V7、V7 omit5、V7
IVVI 以外
VI、V7、V7 omit5、V7、VI
V7、V7 omit5、V7I、VI
VII 以外

また、曲が終わる(プログラムが終了する)際は必ずchordが I である必要があります

おまけ

オプションで-MakeMidiを指定した場合はソースコードは実行せず、ソースコードに従ってmidiファイルを生成します。
この際、|::| で囲まれた部分は必ず2回づつ演奏されます。

サンプルコード

cat

Vivace
| //I       V
    C5      G4
    E4      D4
    G3      G3
    C3      B2
| //I       II  V
    C5  T   A4  B4
    E4  T   F4  D4
    G3  T   F3  G3
    C3  T   D3  D3
| //I       IV
    C5      T
    E4      F4
    G3      A3
    C3      T
| //I       II  V
    C5  T   A4  B4
    E4  T   F4  D4
    G3  T   F3  G3
    C3  T   D3  D3
| //I       V
    C5      G4
    E4      D4
    G3      G3
    C3      B2
| //I   V   VI  V
    C5  D5  E5  B4
    E4  G4  A4  G4
    G3  B3  C4  G3
    C3  D3  C3  D3
| //I   V   I   V
    C5  B4  C5  D5
    E4  D4  E4  G4
    G3
    C3  D3  C3  B2
| //I   V   VI  V
    C5  F5  E5  B4
    E4  G4  A4  G4
    G3  B3  C4  G3
    C3  D3  C3  D3
| //I       IV
    C5      T
    E4      F4
    G3      A3
    C3      T
| //I   V   VI  V
    C5  F5  E5  B4
    E4  G4  A4  G4
    G3  B3  C4  G3
    C3  D3  C3  D3
| //I   IV  II  V
    C5  A4  T   B4
    E4  F4  T   D4
    G3  C4  F3  G3
    C3  F3  D3  D3
|://I   V   VI  V
    C5  F5  E5  B4
    E4  G4  A4  G4
    G3  B3  C4  G3
    C3  D3  C3  D3
| //I       II  V
    C5  T   A4  B4
    E4  T   F4  D4
    G3  T   F3  G3
    C3  T   D3  D3
| //I   IV  I   V
    C5  A4  G4  B4
    E4  F4  E4  D4
    G3  C4  T   G3
    C3  F3  G3  D3
| //I   V   VI  V
    C5  D5  E5  B4
    E4  G4  A4  G4
    G3  B3  C4  G3
    C3  D3  C3  D3
| //I   V   I   V
    C5  B4  C5  D5
    E4  D4  E4  G4
    G3
    C3  D3  C3  B2
| //I   V   VI  V
    C5  F5  E5  B4
    E4  G4  A4  G4
    G3  B3  C4  G3
    C3  D3  C3  D3
| //I       IV
    C5      T
    E4      F4
    G3      A3
    C3      T
| //I   V   VI  V
    C5  F5  E5  B4
    E4  G4  A4  G4
    G3  B3  C4  G3
    C3  D3  C3  D3
| //I   IV  II  V
    C5  A4  T   B4
    E4  F4  T   D4
    G3  C4  F3  G3
    C3  F3  D3  D3
:|//I
    C5
    E4
    G3
    C3
|