音楽用言語 開発メモ
もくじ
概要
- 汎用テキストで音楽を記述するための文法を定義
- そのテキストからMIDIデータを生成するプログラム MusicText Processor をマイクロソフトのエディター Visual Studio Code の拡張機能として公開準備中
- 同作者のデスクトップアプリ「テクスチュアルMIDIシーケンサーT3」での文法を見直し、マルチEDO(他平均律)にも対応させた
- 名前候補の変遷
- MusicText これは既存でない。…ひょっとしてダサいから?
- MIDI Text (Music Interpreted by Dotted Integer Text)
- Miditext これは既存
- (Simple) Music Description Text (簡易)音楽記述文 Standard Music Description Language というのが既存
- Multi-EDO Music Language (MEML)
- Music Text: MUDIT ( Multi-EDO Music Dots Interpreted Text ) ? Mudit は何かしら既存
- MIDI Text : MIDIT ?
- "Dot-beat TTM Converter" (dot-beat notation によるテキストを TTM(Text-To-MIDI) 変換するプログラム)に決定 21/12/02
- "BeatDot Text-To-MIDI Converter" (BeatDot music notation で書かれたテキストをMIDIファイルに変換(Text-To-MIDI, TTM)するプログラム)に決定 22/06/10
- "BeatDots Text-To-MIDI Converter" (BeatDots music notation で書かれたテキストをMIDIファイルに変換(Text-To-MIDI, TTM)するプログラム)に決定。BeatDotでは何か名前被りがあったので。こういうの気にする必要あるん? 22/06/10
- "DotMusic Text MIDI Converter" (".Music"という音楽サイトはその昔あったらしいが、現時点のかぶりはなさそう。22/12/11)
- "DotMusic Language MIDI Converter" (Text --> Languageのほうが意味合いがはっきりする、か? 22/12/13)
- "DotMusic Language MIDI Converter"の作業開始 22/12/15
- "DotMusic Language MIDI Converter ver.1.0.0."の作業が落ち着いたので、公開準備 23/01/14
- このページ(BeatDot時代の文法による)はアーカイブとして残しておく
音符と文法について
音符と文法について:音符
オクターブ内各音の音高を数字で表す。12平均律で 0
1
2
3
4
5
6
7
8
9
10
11
の12音。ほかに例えば、7平均律なら 0
1
2
3
4
5
6
の7音、31平均律なら 0
から 30
までの31音を音符として使う。デフォルト時、中央ド(C4)が 0
の高さだが、マルチEDO(12平均律以外)時は12平均律でいうA=220Hzを基準の 0
音の高さとした。
休符restを r
、タイtieを t
または -
で表す(タイとは直前の音符を伸ばす音符)。
シャープ #
とフラット b
(小文字のb)を音符の直前につけると 1音(半音)上下する。
オクターブを上下させるにはキャレット ^
(上)とアンダーバー _
(下)を音符の直前につける。これら音高の記号は複数回重ねて使える。
文字はすべて半角文字を用いる。音符間に一つ以上のスペースが必須、ドット記号の前後のスペースは任意。改行は制限される場合がある。
これら音符の持続時間が、直後のドット(ピリオド .
)の数との関係で決められる。一つの .
が一拍分の時間を表す。
// 『きらきら星』メロディー
//「//」はコメントアウト記号
0. 0. 7. 7. 9. 9. 7.. 5. 5. 4. 4. 2. 2. 0..
7 7 5 5 .... 4 4 2 - .... 7 7 5 5 .... 4 4 2 - ....
0 0 7 7 9 9 7 - .... .... 5 5 4 4 2 2 0 - .... ....
拍より細かい音符も同様に
// 『グリーンスリーブス』のメロディー
tempo(50)
// テンポ命令「ドットが1分間に50個の速さ」・BPM=50と同じ
// 小節線「|」に解釈上の意味はありません
r 9.|^0 - ^2. ^4 - - ^5 ^4 -.|^2 - 11. 7 - - 9 11 -.|
^0 - 9. 9 - - #7 9 -.|11 - #7. 4 - 9.|
^0 - ^2. ^4 - - ^5 ^4 -.|^2 - 11. 7 - - 9 11 -.|
^0 - - 11 9 -. #7 - - #5 #7 -.|9 - 9. 9 - r.
音符と文法について:音を重ねる
複数の音符を丸かっこ ( )
で囲んで和音を示す。スラッシュ /
で同時に演奏するパートを重ねる。セミコロン ;
で複数のパートを閉じ、次の部分の演奏へ進む。
// エリック・サティ『ジムノペディ第一番』イントロ
tempo(80) velocity(80)
// velocity(80)は音の強さの指定
__7... / r. (_11 2 6).. ; __2... / r. (_9 1 6).. ;
// スラッシュの前後を入れ替えても同じ
r. (_11 2 6).. / __7... ; r. (_9 1 6).. / __2... ;
コロン :
は曲の先頭に返って音を重ねる。
// エリック・サティ『ジムノペディ第一番』続き
tempo(80)
// メロディー コロンで終わって…
velocity(85) r. ^6. ^9. ^7. ^6. ^1. 11. ^1. ^2. 9 ... 6 ... ... ... ... :
// 曲の先頭から伴奏を重ねる 「{ }*4」は波カッコの中を4回繰り返す かっこの項で後述
velocity(80) { r. (_11 2 6).. / __7... ; r. (_9 1 6).. / __2... ; }*4
音符と文法について:強弱・スタッカート記号
velocity( )
やrandomVelocity( )
といった丸カッコ付きの命令類は命令後の音符全体に適用されるが、個々の音符の直後にフォルテf
、ピアノp
、スタッカートs
、音程を動かす~
といった記号をつけられる。
//「ch(10)」はMIDIチャンネル10に入力する命令 チャンネル10はMIDIの慣習としてパーカッション音で使う(各音程の音色は音源によって異なります)
// transpose(-24)は以後の音符入力を2オクターブ下げる命令
tempo(100) ch(10) transpose(-24) { 6 6 }*4 .... ;
// このハイハットに強弱をつけて、シンプルなリズムと{ }で繰り返し
{{ 6f 6ppp }*4 .... }*9 : { _11. r. _11 _11. r. ; _11. r. _11 _11. 1. ; }*4 :
// ch(0)は音は出さないがコードを設定 後述
ch(0) r .... .... { C .... .... F .... G .... }*2 :
// ch(9)ベース 「c0」で設定したコードのルート音を取り出し 後述
// 「s」で裏拍の音をスタッカートして短くしている 「2~」は後述のピッチベンドで2の音程を下げている
ch(9) r.... ... 2~. { { c0 ^c0s. }*4 }*8
音符と文法について:音高を変化させる記号
ピッチベンドを使ってプログラム的にかけるビブラートをチルダ ~
を付けて表すが、見直しの予定。 ~0
低い音程から入る 0~
音程を下げていく 0~~
ビブラートをかけるかっこ類の用法
かっこ類の用法:かっこ{ }で繰り返し
{ }*
と数字で、かっこの中身をその数字回繰り返す。
{ 0 2 4 ... }*2
は0 2 4 ... 0 2 4 ...
と同じ。{ }r
と数字で、その数字回かっこの中が全休符になる。
{ 0 2 4 ... }r2
はr... r...
と同じ。この
*
とr
を連続して組み合わせて使うと、{ 0.0.0.0. }r4*12r4*12
のように、バスドラムの4つ打ちが5小節めから12小節続き4小節休んでまた12小節...のようにフレーズのオンオフをコントロールできる。さらに、
{ }
内の音符の内容が拍.
ごとに書かれている時、*
とr
を複数重ねて拍ごとにコントロールできる。例えば、{0.0.0.0.}*2*r*r2
は0.0.0.0. 0.0.0.0. 0.r.0.r. 0.r.0.r.
となる。*r*r
で拍ごとに休符にするかどうかを指定している。また、{0.0.0.0.}*2*r2
とすると、0.0.0.0. 0.0.0.0. 0.0.r.r. 0.0.r.r.
となる。カッコ内の拍を*
とr
の個数で割り、*
、r
ひとつあたりに相当する音符を生かしたり休符にすると指定している。拍ごとといっても文字面の処理なので、パートがあるときに拍のコントロールをするなら...例えば2段パートの下段だけ生かそうとする時などには、
{0.4.7.. / (_0 4 7)....;}rrrr****2
または{0.4.7.. / (_0 4 7)....;}r*2
などとして、(
r. r. r.. / (_0 4 7).... ; r. r. r.. / (_0 4 7).... ;
に変換される)、拍数でなくカッコの中の実際のドットの数と辻つまを合わせなければならない。次例参照。{{ }*2}*4
のように入れ子が可能。内側のかっこを先に処理する。{ }
に何も付けなければカッコは無視される。
r
でも*
でもどちらでもいいという場合、?
を使って{ }*?4
のように書くと、2分の1の確率で?
がr
か*
になる。
// 繰り返し機能でフレーズコントロール
tempo(105) transpose(-24)
// 裏拍パーカッション、4つ打ちバスドラム、ハンドクラップをパートでまとめて繰り返し
{ {ch(9) r _8 .}*4 / ch(10) {0.}*4 / ch(10) {r. __11.}*2 ; }*rr2 **r2 *2 *****rr*rrrr2 *r*2 *4 r****rr*rrrr2
// 少々煩雑な覚え書:裏拍のパーカッションにDAWで別のエフェクトをかけるために別チャンネルにした。
ところが「ch(9)」といった命令類はその直後の音符のタイミングで入力されるので、繰り返しで
その音符の拍を休符にしたときに、一緒に消えてしまう。するとこの場合、後続の音符が「ch(10)」の
それとして入力されてしまう場合が出てくる。なので、「ch(9)」は拍ごとに繰り返し書かれる必要が
あった。
かっこ類の用法:かっこ[ ]でランダムな取り出し
[ ]
はいろいろに動作する。例で見ると、[0,4,7]*4 ....
は、カンマ,
で区切った要素からランダムに4つ取り出す。0 7 4 4 ....
や4 0 0 4 ....
や4 7 4 7 ....
等に変換される。[0,4,7] .
お尻の数字を省略すると[ ]*1
の意味になり、0
4
7
のいずれか一つだけを選ぶ。[0 4 , 7] .
この場合、カンマで区切られているのは0 4
と7
の2つであり、結果は0 4 .
か7.
のいずれかとなる。[0 4. , 7] .
のように中にドット.
が含まれると要注意で、この結果は0 4 ..
か7.
となり、うっかり拍子をランダムに変えてしまう。[7]
中の要素が一つだけの時、「あるかないか」の意味になる。0 [7] .
のとき、結果は0 7 .
か0 .
になる。
// []でランダムなフレーズの利用
tempo(90) ch(10) transpose(-24)
{ {0 [0] .}*4 }*r*r16 : // バスドラム ランダムな8分
{ {8 8pp.}*4 }*16 : // ハイハット 一定
randomVelocity(30) // ベロシティにランダムな値の幅を与える
swing(0,30) // 16分音符の2,4つ目の位置を30ティック遅らせてハネさせる
// スネアドラムをコントロールして繰り返し、ランダムな16分フレーズを生成
{ {[2,r]*4.}*4 }r*4*4r2*r2*4
音符をランダムに選択する上記の
[ ]
[ ]*x
とは違って、以降の [ ]nt
[ ]dt
[ ]rt
は音符をランダムに入れ替える。[0 2. 4. 4 5. 7.]note
または[0 2. 4. 4 5. 7.]nt
このように、フレーズごとかっこに入れて
note
またはnt
を付けると、中のフレーズの音符noteをランダムに入れ替える。休符とタイは動かさない。結果は7 4 . 4 . 5 0 . 2 .
や2 4 . 4 . 7 0 . 5 .
や4 2 . 7 0 . 4 .
などのように、リズムと構成音を変えずにフレーズを変えることになる。試しに『グリーン・スリーブス』のメロディーをまるごと入れてみると、
tempo(50)
[ r 9.|^0 - ^2. ^4 - - ^5 ^4 -.|^2 - 11. 7 - - 9 11 -.|
^0 - 9. 9 - - #7 9 -.|11 - #7. 4 - 9.|
^0 - ^2. ^4 - - ^5 ^4 -.|^2 - 11. 7 - - 9 11 -.|
^0 - - 11 9 -. #7 - - #5 #7 -.|9 - 9. 9 - r. ]nt
r ^2 . ^4 t 11 . 11 t t ^2 #7 t . #7 t 9 . #7 t t 11 9 t . 11 t ^0 . ^0 t t 9 ^0 t . 7 t 9 . ^4 t #5 . 9 t ^0 . #7 t t ^5 7 t . ^4 t ^5 . 9 t t ^2 9 t . 11 t t 9 4 t . ^2 t t ^4 9 t . 9 t 11 . 9 t r .
のようになる。旋律が散漫になったが、旋法の持っている雰囲気やリズムの印象は失われないようだ。
[0 2. 4. 4 5. 7.]dot
または[0 2. 4. 4 5. 7.]dt
dot
またはdt
を付けると、中のフレーズのドットの位置をランダムに動かす。0 . 2 4 . 4 . 5 7 .
や0 2 .. 4 . 4 5 7 .
や0 2 4 . 4 .. 5 7 .
などのように、同じフレーズのリズムだけ変えることになる。『グリーン・スリーブス』のメロディーを入れてみると、こちらは
tempo(50)
[ r 9.|^0 - ^2. ^4 - - ^5 ^4 -.|^2 - 11. 7 - - 9 11 -.|
^0 - 9. 9 - - #7 9 -.|11 - #7. 4 - 9.|
^0 - ^2. ^4 - - ^5 ^4 -.|^2 - 11. 7 - - 9 11 -.|
^0 - - 11 9 -. #7 - - #5 #7 -.|9 - 9. 9 - r. ]dt
r . 9 ^0 t ^2 ^4 . t t .. ^5 . ^4 . t ^2 t 11 7 t t 9 . 11 . t ^0 t 9 9 t . t #7
9 t 11 t #7 4 t 9 ^0 t ^2 ^4 . t t ^5 . ^4 t ^2 . t 11 7 t t . 9 11 t ^0 t . t 11 9 t #7 t
t #5 #7 t 9 . t . 9 9 t r .
と千鳥足状態になってしまった。範囲を限定して使用すべきなのだろう。
[0 2. 4. 4 5. 7.]rt
rt
を付けると、音符のかたまり中の休符・タイの位置をランダムに動かす。ドットを越えては移動しない。なので上の文のフレーズに変化はないが、譜割りの細かいフレーズではそれなりの変化をする。tempo(50) [r 9.|^0 - ^2. ^4 - - ^5 ^4 -.|^2 - 11. 7 - - 9 11 -.|
^0 - 9. 9 - - #7 9 -.|11 - #7. 4 - 9.|
^0 - ^2. ^4 - - ^5 ^4 -.|^2 - 11. 7 - - 9 11 -.|
^0 - - 11 9 -. #7 - - #5 #7 -.|9 - 9. 9 - r.]rt :
// テンポガイド
ch(10) transpose(-36) r. {9 10 10. 9 10 10.}*8
9 r. t ^0 ^2. t ^4 ^5 t t ^4. ^2 t 11. t 7 t 9 t 11. ^0 t 9. t 9 t #7 9 t. 11 t #7. t 4 9. ^0 t ^2. ^4 ^5 t t ^4 t. ^2 11 t. t 7 9 t t 11. t ^0 t 11 9 t. #7 #5 t t #7 t. 9 9 t. t r 9. :
[ 0 [7].]*4
のような入れ子処理可能。{ }
と違って、[ ]
は何も付けなくても機能する。意味のない英小文字を付けて([ ]t
など)無視させることができる。
かっこ類の用法:@名前に代入
@アットマークと英数字・アンダーバーを使った任意の名前に、音符を={ }で囲んで代入し、その名前で使うことができる。// かえるのうた輪唱
transpose(12) velocity(95) randomVelocity(4) randomTiming(20)
r.... ....
// メロディー1・「@Flog_1」に代入
@Flog_1 ={ 0 2 4 5 4 2 0 r .... .... 4 5 7 9 7 5 4 r .... ....
0 r 0 r 0 r 0 r .... .... 0 0 2 2 4 4 5 5 .... 4s 2s 0 r .... } r.... ... (0 _4 _7)sp.:
// メロディー2・代入された部分を輪唱で繰り返し
transpose(-12) r .... .... .... .... @Flog_1 :
// 伴奏
transpose(-24) velocity(85) {0 r. 7 7. 0 r. 7 r.}***r2*8***r2
かっこ類の用法:かっこ類の処理順
@名前代入・繰り返し{ }・ランダム[ ]の順に処理されるが、@名前代入時に[ ]
を使うとそれを{ }
より先に処理する 。同じかっこでは内側のかっこが先に処理される。{ }
と[ ]
では、先に{ }
を処理してから[ ]
を処理するので、[ ]
での例にみられるように、例えば{[0,4,7]*4 .... }*2
はいったん[0,4,7]*4 .... [0,4,7]*4 ....
となり、同じフレーズの繰り返しではなくそれぞれ異なったフレーズがランダムに作られることになる。ランダム
[ ]
処理の結果をフレーズとして繰り返したい場合は、@名前代入を使う。
// @名前代入とランダム[ ]の動作
// バスドラムとハイハット
tempo(90) ch(10) transpose(-24) {0 r 0 r ....}*8r4*3 : { {8 8pp.}*4 }*16 :
// スネアドラム
randomVelocity(25) swing(0,60)
{ @pattern1 ={ r [2,r]*15 .... } }*4 // 1小節パターン×4
{ @pattern2 ={ r [2,r]*15 ....}*2 }*2 // 2小節パターン×2
@pattern4 ={ r [2,r]*15 .... }*4 // 4小節パターン×1 代入しないのと同じ
{ @pattern2 }*2 // 2小節パターン×2
スケールの使用
スケールの使用:スケールの指定
ある音律で使用できるすべての音のうち、音楽として使用するために構造的に選び出された音の並びを音階(スケール)といい、我々の音楽言語においてもこれらを指定しておけば、後述のローマ数字による和音を使ったり、音符をスケール音に限定して指定できるようになる。スケールは
scale(0 2 4 5 7 9 11)
のように指定する。0 2 4 5 7 9 11はデフォルトで設定されているスケールでハ長調 C Major のドレミファソラシドだが、同様にト長調 G Major なら主音7から始めてscale(7 9 11 0 2 4 6)
と設定する。このように主音+全音(2)+全音(2)+半音(1)+全音(2)+全音(2)+全音(2)(+半音(1))で長音階の各調を指定できるが、計算が面倒なので、最初に主音を指定してカンマを置き、0はじまりの音階構造を書けば各調を指定できるものとした。これを使えば、ト長調は
scale(7, 0 2 4 5 7 9 11)
と入力できる。またホ調自然短音階 E minor なら、主音が
4
でハ調の自然短音階 C minor が0 2 3 5 7 8 10
だからscale(4, 0 2 3 5 7 8 10)
と入力できる。スケールの使用:スケール名
音符の入力時に数字以外の階名・音名等を使いたい時、スケールの指定時に、使いたい名前をカンマ後に付け加えることができる。scale(0 2 4 5 7 9 11, c d e f g a b) c d e ...
はscale(0 2 4 5 7 9 11) 0 2 4 ...
、
scale(7, 0 2 4 5 7 9 11, do re mi fa so ra ti) do re mi ...
はscale(7 9 11 0 2 4 6) 7 9 11 ...
に変換される。スペースで区切られた各名前が、おのおの並びに応じたスケール音を代理する記号となる。我々の音楽言語が数字を使うことから、初見のとっつきにくさを少しでも軽減するために取り入れた仕様だが、さて必要だろうか?(文字のかぶりで発生する不具合のもとになりそう)
スケールの使用:スケール音
記号m
を使って、設定されたスケールから音を取り出すことができる。まず上述の代理のスケール名と機能的には同じだが、
m0
m1
~とするとm
についた0始まりの数字の順にスケール音を代理して、例えばscale(0 2 3 5 7 8 10)
の場合 m0
m1
m2
m3
m4
m5
m6
は0 2 3 5 7 8 10に変換される。また
m?
はスケールからどれでも1音、-m
--m
... +m
++m
...は直前の音から-
+
の数に応じて上下したスケール音、m-
m--
... m+
m++
...は直後の音から-
+
の数に応じて上下したスケール音、を取り出す。 スケール音から取るのではないが同じ記号を使うのものとして、
m
が直前と同音、mm
が直後と同音。また
m
、-m
等はその前にまったく音の入力がない場合m?
になる。スケールの使用:モード
スケールの中でメロディーに「ドレミソラ」しか使わないというような場合がある。そういったスケール内の「モード」をmode()
を使って設定し(デフォルトでペンタトニックmode(0 2 4 7 9)
に設定)、記号M
で上記のスケールm
と同様の使い方で取り出すことができる。また
M0 M1 M2
...としてもモード音を取り出すことができる。
// モード音でメロディーを作る
// スケール音から作られるディグリーネームによるコード(後述)でch(0)にコード進行を設定
tempo(105) scale(0 2 4 5 7 9 11) mode(0 2 4 7 9) ch(0)
VI'.... II'....V'.... I'....
VI'.... II'....V'....I'....
IV'.... IV'.... I'....I'....
IV'.... IV'.... I'....I'....
VI'.... II'....V'....I'....
V'ofVofV.... V'ofV....V'....I'.... I'.... :
// mode()から取るペンタトニックのメロディー A、B、サビ、サビ’、A、B
// 音形を残した上でランダム性を活かす狙い [ ]のランダムは代入時に決まるがMの処理は後
ch(1) velocity(95) randomVelocity(4) randomTiming(15)
@melo1 ={^[2,4,7,9] @pattern1={[M,r,r,t,-M,+M]*3} .. @pattern2={[M,r,r,t,-M,+M]*4}.. }*3*r1
@melo2 ={^[2,4,7,9] @pattern3={[M,r,r,t,-M,+M]*3} .. @pattern4={[M,r,r,t,-M,+M]*4}.. }*3*r1
{^[2,4,7,9,11] @pattern5={[M,r,r,t,-M,+M]*3} .. @pattern6={[M,r,r,t,-M,+M]*4}.. }*r3r1
{^[2,4,7,9,11] @pattern5 .. @pattern6.. }*2*r1r1
@melo1
@melo2 :
// 伴奏 コード進行より取得
velocity(85) { r (c1 c2 c3) r () ....;}*24 (c1 c2 c3)p.. :
{__c0s. r. __c2s. r.}*24 __c0..
メロディー生成の振り幅を記録するため連続の5テイクを録音コードの使用
コードの使用:コードネームの直接入力
コードネームを使って和音を入力することができる。CM7..
は( 0 4 7 11) ..
に変換される。使用できるコードネームは次の通り。ルートがCなら、
C
Cm
C7
Cm7
CM7
CmM7
C6
Cm6
Caug
Caug7
C-5
C7-5
Cm-5
Cm7-5
Cdim
Cdim7
Csus4
C7sus4
(#、bが付く場合はC#m7、Dbm7のように書く)。以上のコードネームに
( )
をつけてテンションコードを付けられる。add9はC(9)
、ナインスはCM7(9)
、さらにCM7(9,#11,b13)
のように書き足していける。テンションコードはオクターブ高く変換され、最後のものは( 0 4 7 11 ^2 ^6 ^8)..
になる。また、
D/G
のように分数コードを入力できる。分母はオクターブ低く(_7 2 6 9 )..
のように変換される。D/D
はルートがオクターブ低く(_2 6 9 )..
と変換される。テンションなどと組み合わせた書き順はD#(9)/D#
のようになる。分母がルートと同音の場合は、分母を省略できる。
Cm/C
を Cm/
と書いても良い。分数コードの仕様はまだ固まっていない(はじめからルートをオクターブ低くしておいてもいいのでは?)。
// コードネーム、テンションコード、分数コードを直接入力して響きの概略を聴く
// ボサノヴァ・ピアノ曲集『イパネマの娘』より一部改変
// 分数コードでルートを1オクターブ低く
tempo(130) velocity(84) randomVelocity(4) randomTiming(15)
r.... Eb6/.... Eb7(#9)/.... Bb7(13)/.... Bbm7/.... FbM7/.... ....
EbM7(9)/.... EbM7(9).... F7(13)/.... F7(13)....
Fm7/Bb.... Bbaug/E.... EbM7/.... Bb7(13)/....
EbM7(9)/.... Cm7/.... F7(13)/.... ....
Fm7/Bb.... Bbaug/Ab.... Gm7/.. C7(b9,#11)/.. Fm7(9)/.. Bb7(b9,#11)..
EM7/.... C#m7(9)/.... EmM7/.... Adim7/....
GM7/.... Em7(9)/.... Gm7/.... C7/....
FmM7/.... Fm7.... Abm6/.... Db7/....
Gm7/.... C7(b13)/.... Fm7/.... E/.. D7(#9)/.. :
// リムショット
ch(10) transpose(-24) velocity(60) randomVelocity(20) {1 1 1 1 1 1 1 1 .... }*40
()
は直前の和音の内容をコピーする。tempo(130) velocity(84) randomVelocity(4) randomTiming(20)
Eb6/Eb.- ()p.-.. Eb7(#9)/Eb.- ()p.-.. Bb7(13)/Bb.- ()p.-.. Bbm7/Bb.- ()p.- ().-. FbM7/Fb.... ....
ところでコードネームには強弱記号
f
p
を直接つけてかまわない(FbM7/Fbp
)。
chordNameAnalyse(Eb)
のようにキー(この場合Eフラット)を指定して書くと、コードネームのルート音がディグリー(ローマ数字による音階表記)の何にあたるか簡易な判別を行い、Visual Studio Code のターミナルにログを出力する。例えば//『枯葉』より
chordNameAnalyse(G)
Gm.... Cm7.... F7.... BbM7.... EbM7.... Am7-5.... D7.... Gm....:
とすると、Gのキーでディグリーネームが判別されターミナルに
Analysed G:
[I]Gm.... [IV]Cm7.... [bVII]F7.... [bIII]BbM7.... [bVI]EbM7.... [II]Am7-5.... [V]D7.... [I]Gm....:
と出力される。
コードの使用:コードの設定と利用
コード進行をch(0)
に入力することで、他チャンネルで記号c
C
を使って曲中の位置に応じたコード音を取り出すことができる。記号の使い方はスケールの
m
M
から類推されるものと大差なく、c0
c1
c2
~とすると和音の構成音をルート(根音)から順に取り出しc?
はコードからどれでも1音、-c
--c
... +c
++c
...は直前の音から-
+
の数に応じて上下したコード音、c-
c--
... c+
c++
...は直後の音から-
+
の数に応じて上下したコード音、を取り出す。
コード音から取るのではないが同じ記号を使うのものとして、
c
が直前と同音、cc
が直後と同音をとる。また、
c()
で設定された和音をそのままコピーする。単音で取り出すとき音高記号
_
^
はつかない。和音が休符のとき、
c
C
も休符となる。トライアド(三和音)のコードが指定されているとき、
c0
c1
c2
で指定できるが、c3
~を指定すると、はじめに戻ってルート音0から取る。コードC(0 4 7)が指定されているとき(c3 c4 c5)
は(0 4 7)となる。セブンス以降の音を取るのではない。記号大文字の
C
の場合、テンション(9th, 11th, 13th)から音を取る。テンションが入力されているときはそのテンションから、入力されていないときはナチュラルテンションからとる。例えばC7(b9,#11)でC0 C1 C2
を指定すると1 6 9が選ばれる。大文字
C
C6
C7
はコードネームとして解釈されるので注意。
// ch(0)コードの設定と利用
ch(0) r.... .... Eb6.... Eb7(#9)....Bb7(13)....Bbm7....FbM7.... ....
EbM7(9).... EbM7(9).... F7(13).... F7(13)....
Fm7/Bb....Bbaug/E....EbM7.... Bb7(13)....
EbM7(9)....Cm7....F7(13).... ....
Fm7/Bb....Bbaug/Ab....Gm7..C7(b9,#11)..Fm7(9)..Bb7(b9,#11)..
EM7....C#m7(9)....EmM7....Adim7....
GM7....Em7(9)....Gm7....C7....
FmM7....Fm7....Abm6....Db7....
Gm7....C7....Fm7....E..D7(#9).. r.... :
// ピアノ ランダムにコード音を散らしてバッキングに動きをつける
tempo(130) velocity(84) randomVelocity(4) randomTiming(15)
ch(1) {c()p..c()p.. }*r7r1*r1r1*r1r1*r7r1*r2*2*r16 :
transpose(12) { [c?,+c,-c,r,r,r,r,r,r]*4 .. [c?,+c,-c,r,r,r,r,r,r]*4.. ; }r*22r2*16 :
{pdl ....}*6r6*6r2*20 : {pdl .... ....}r3*3r3*1 : // pdlはサスティンペダルを表す音符
// ベース ルート音を取得
ch(9) transpose(-12) velocity(100) { _c0. - c. _c0. - [-,c]. }*40 :
// リムショット
ch(10) transpose(-24) velocity(70) randomVelocity(10)
{1 1ppp 1ppp 1 1ppp 1ppp 1 1ppp .... 1ppp 1ppp 1 1ppp 1ppp 1 1ppp 1ppp .... }*20
コードの使用:ディグリーネームによる和音の設定と利用
先に例をみたが、scale( )
で設定されているスケールの各音に1音飛ばしで2つスケール音を重ねた和音を、I II III IV V VI VII ~という名前(ディグリーネーム)で設定し、コードネーム同様に記号 c
や、次項の g
から利用できる。コードネームの場合、そのコード自体の構造を表すいわばリテラルな名前がつけられていたが、ここでのディグリー名による和音はスケール構造が前提となっている。どういうことかというと、ハ長調のIの和音、ハ短調のIの和音はそれぞれコードネームで書くと
C
、 Cm
だが、ここでのディグリーネームによる表現では両方とも I
と書く。 I
の音の構造がどうなるかはスケールの設定によるわけだ。 ch(0)
に設定するか、他のチャンネルで直接鳴らすことができる。デフォルトのscale(0 2 4 5 7 9 11)の場合 I
は三和音(0 4 7)、右肩にシングルクォーテーション '
を一つつけて I'
とすると四和音(0 4 7 11)、2つつけて I''
とすると五和音(0 4 7 11 2)、~になる。 of
で借用和音を表す。 V'ofV
でVのV'、つまりIIのセブンスが鳴ることになる。連続して使えるので、 II'ofVofV
などと書ける。 mode( )
で構成される和音を Im IVm
などとmを付けて利用することができる(というわけでmは「マイナー」という意味ではない)。 scale(0 2 4 5 7 9 11) mode(0 2 3 5 7 8 10)
とすれば同主短調の和音を使えるということになる。分数コード表現は
I/V
などとし、分母は一オクターブ低く(_7 0 4 )鳴る。コードネーム同様に、 I/
のように分母を省略すると I/I
の意味になり根音が一オクターブ低くなる。 I/_I
とするとさらにもう一オクターブ下げられる。 フラット・シャープの位置はコードネーム(
Dbm7/Ab
のような)と違って、 bIII/bV
のように前に付ける。慣習に合わせた仕様。ところで、コード本などでbIIIといった場合、平行短調のIII(メジャーコードか増三和音)を指す場合が多いが、ここでのbIIIは単に現調IIIの全体を半音下げた和音である。平行短調のIIIを指定するには、mode( )で平行短調を設定してIIImを使うことになるだろう。あるいは分母だけ半音下げてメジャーコードにはできる(
III/
(_4 7 11)を III/bIII
(_b4 7 11)にする)。このあたりどういう仕様が正解なのかまだよくわからない。その他、12-EDO時の便宜をはかり、
7
6
dim
sus4
aug
の記号をつけることができる。また、コードネームの場合と同様に( )を付けてテンションコードを書き込むことができる。書き順は、 IIaug(#9,b13)ofV/IV
などとなる。
intervalOfChord( )
という命令で、重ねる音のスケール音程間隔を設定する。デフォルトは2。
コードの使用:ギター風ボイシングの利用
ここでいうギター風ボイシングとは、4度間隔で張られた6本の弦に可動式のカポを挟んだとして、そこから4?フレットの距離なら自在に押弦できるとした場合に可能なコードのボイシングをプログラム的に求めて利用するもの。ルート音ではなくても低音をミュートしない。ギターというより何か別の素朴な撥弦楽器みを感じるのだが、便宜上ギター風ボイシングと呼んでいる。g()
で、設定したコードをギター風ボイシング(ここでいう)に加工したコードを利用できる。各弦を模した6個の音を、低い方から記号
g0 g1 g2 g3 g4 g5
で取り出せるが(ギターは高いほうから1弦、2弦~と数えるから逆になる)、ギター風ボイシング(ここでいう)ではいつもすべての弦を使うわけではないので、コードで使われていない弦の音を指定してしまうことがあり都合が悪い。なので、 g0 g1 g2
が低い方から3音、
g5 g4 g3
で高い方から3音を取る、という指定の仕方をする。同タイミングで同音を指定している場合は一方のみ発音する。
guitarLike(x)
という命令で、音域をコントロールする。数字 x が最低音を示す(仮想的カポを挟んだ仮想的フレットを押さえた音)。デフォルトは guitarLike(4)
で、これは実音__4
が最低音。 $
でシミュレートする。 $( __4 __11 _4 _8 _11 4)
や g()$$$
のように和音を表す記号類の前後につける。カッコの前につけると低いほうの音から発音し、カッコの後ろにつけると高い音から発音する。 $
の数はズラす効果をコントロールする。$ひとつあたり randomTiming( )
でランダムに求められるズレの幅の2倍の時間幅でズレる。本来のタイミング周辺に前後するので、tick位置が0で入力されている和音での効果は半減する(マイナスのタイミングでは発音できないので)。// Independence Free は良い音源
ch(0) {G .... Em ....}*2 C.... .... D .... .... :
velocity(84) randomVelocity(15) randomTiming(15) guitarLike(11) ch(1)
{g0 g3 g4 g5 g4 g3 .... / pdl....;}*8 :
r....r....r....r....$g()p.... $g()pp .... $$$$$$g()p .... ....
マルチEDO(他平均律)について
マルチEDOについて:EDOの設定
edo(x)
命令により x EDO(平均律)を設定する。が、すべての場合に正確な音程が出ているかどうかいまひとつ確信がもてない(どれも調子っぱずれに聞こえるので耳で判断するのが困難)。また、プログラム的には目指す高さの音にいちばん近い低い音からピッチベンドで音程を上げているのだが、音源によりピッチベンドの効きに差が出てしまう。
// 音源の問題 31平均律
velocity(84) randomVelocity(4) edo(31)
0 1 2 3 4 5 6 7 8 9 10 ..........
上の合成音源は問題ないようだが、下のサンプリング音源はピッチベンドの効きが悪く、残念ながら使い物にならなそうだ。
また通常0の高さはC=261.626…だが、計算の簡便のためすべてのEDOで0のときA=220hzの高さになるようにした。edo(12)を設定するといつもの12平均律と異なり、0はCでなくAの高さになる。
マルチEDOについて:EDOの和音
EDO設定時はピッチベンドを使用するが、MIDIの仕様上ピッチベンドは各チャンネルに一つであり、各音を個別に調整した和音を一つのチャンネルで出すことができない。なので原則的にチャンネル単音だが、 ( )
を用いて和音を入力すると、自動的に次のチャンネルを使用して各音ごとにピッチベンドを設定するようになっている。velocity(84) randomVelocity(4) edo(11) 0.4.7.(0 4 7)...
これから作られるデータを抜き出すと、
ch:1 tick:0 status:e value1:0 value2:64 チャンネル1 ピッチベンド(status:e)
ch:1 tick:0 status:9 value1:57 チャンネル1 発音(status:9)、value1:57は鍵盤の位置(A=220hz)
ch:1 tick:960 status:e value1:81 value2:75 2つめ
ch:1 tick:960 status:9 value1:61
ch:1 tick:1920 status:e value1:47 value2:84 3つめ
ch:1 tick:1920 status:9 value1:64
ch:1 tick:2880 status:e value1:0 value2:64 チャンネル1 和音の最低音
ch:1 tick:2880 status:9 value1:57
ch:2 tick:2880 status:e value1:81 value2:75 チャンネル2 和音の真ん中の音
ch:2 tick:2880 status:9 value1:61
ch:3 tick:2880 status:e value1:47 value2:84 チャンネル3 和音の最高音
ch:3 tick:2880 status:9 value1:64
のように和音の同時発音数に応じて次のチャンネルを使うことになるので、データが送られるDAWの側でも見込まれるチャンネルに音色を用意しておく必要がある。
パート
/
やコロン :
を使って音を重ねるときは、 ch( )
でチャンネルを変更して行う。マルチEDOについて:EDOのスケールとディグリーネーム
マルチEDO下でもスケール・モードを設定し、ディグリーネームコードを使用できる。// 15平均律で適当な8音スケールを設定しディグリーネーム和音を使う
velocity(84) randomVelocity(4) edo(15) scale(0 2 3 5 7 9 11 13)
ch(0) { @chord={[I II III IV]nt} .... .... .... .... }*4 : // 和音を適当に並べる
ch(1) { c() ....}*16 : // 三和音なので1から3チャンネルを使う
ch(4) { r __c0 r __c0 ....}*16 : // 低音
ch(5) transpose(12) // edo時でもtranspose(12)でオクターブ移動する(仕様)
@melo1={ r m? @pattarn1={ [-c,+c,r]*6 } .... }*4
@melo2={ r m? @pattarn2={ [-c,+c,r]*6 } .... }*4
@melo1 @melo2 :
良く言って地下ダンジョンBGM風? マルチEDOでは概して一本調子に不穏な感じになってしまい、ここからポップの原石を探そうとすると途方に暮れてしまう。12平均律音楽の歴史の奇跡的な厚みを感じざるを得ない。
命令類まとめ
英字と丸かっこで構成される命令類 xxxx(xx)
は音符ではないので、直接ドットを付けることはできず、音符とともに入力されなければならない。 tempo(100) 0. tempo(80) 0. tempo(60) 0.
のように、命令を入力できる最小の譜割りは拍単位である。- ch(x) 使用するMIDIチャンネルを設定する。xは1から16まで。デフォルト1。ch(0)はコード設定用に用意したもので、何を書いてもMIDIデータに出力されない。
- tempo(x) テンポ設定。デフォルト120。1から915まで入力可能
- edo(x) 使用する平均律を設定。該当章を参照
- swing(x) 8分音符のハネ。拍の1/2の位置にある音符(分解能960分の480の位置)の前後に移動するティック(=発音時間の最小単位)値(x)を設定。
- swing(x,y) xが8分音符のハネ、yが16分音符のハネ。拍の1/2の位置にある音符(480の位置)の前後移動値(x)、拍の1/4、3/4の位置にある音符(240,720の位置)の前後移動値(y)を設定。
- swing(x,y,z) 拍の1/4(x)、1/2(y)、3/4(z)の位置のある音符(240, 480, 720の位置)の前後移動値を設定。以上swing命令はデフォルト0、マイナス値可能。拍自体の位置を動かすときは次の
slide(x)
を使う。
// swing命令の入力
ch(10) tempo(120) {_5 _4 .}*4 r..
swing(80) {_5 _4 .}*4 r.. // 8分音符のハネ
tempo(80) swing(0) {_5 _4 _4 _4 .}*4 r..
swing(0, 80) {_5 _4 _4 _4 .}*4 r.. // 16分音符のハネ
swing(0,0) {_5 r _4 _4 .}*4 r..
swing(-160, -80) {_5 r _4 _4 .}*4 r.. // これは三連符と同じになる { _5 _4 _4 .}*4
swing(-80, 0, 80) {_5 _4 _4 _4 .}*4 r.. // 16分音符の前側は前方に、後ろ側は後方に
// ドビュッシー『雪が踊っている』さわりでslide 少しつっこみ気味
tempo(132) velocity(83) randomVelocity(5) randomTiming(10) staccato(1)
transpose(12) @pattern={4 5 7 9 4 5 7 9 ....} slide(230) { @pattern }*5 {4 5 7 9 2 4 5 7 ....}*2 :
transpose(-12) velocity(85) r.... {4 5 7 9 4 5 7 9 ....}*5 {^2 ^0 10 9 ^0 10 9 7....}*2 :
velocity(95) staccato(0) r.... .... 10.... ^0.... 10.... ^#0.... 2.... 2....
s
を以降の音符にまとめてつける。xはスタッカートの個数。
c?
が設定済みの和音から取得する音をその近辺に低く限定する。例えば bottom(_11)
とすると、c?は設定済み和音のうち、_11以上で一番低い音(テンション除く)を取得する。和音連結の際に音を揃える(その音を最低音にして転回形を作る)のに役立つことがある。// bottom(x)とcで和音をスムーズにつなぐ工夫
ch(0) { I.... IV.... V.... I.... r.... }*4 :
ch(1) velocity(90) bottom(_11) // c?の取得音を_11以上の最低音に限定
{ c0.c1.c2.c1. }*5 // 音がバラバラで不自然
{ c?.+c.+c.-c. }*5 // 音が揃い自然
{ c().... }*5 // おかしくはないが旋律的に飛躍
{ (c? +c +c).... }*5 // 滑らかで和声的
octavePosition(7) 7 9 11 0 2 4 6 ....
とすると、通常時の _7 _9 _11 0 2 4 6 ....
と同じ意味となる。和音の低音位置を調節するのに役に立つことがある。
<0 8>