音楽言語 MusicText プログラミングの覚え書

もくじ

  1. 概要
  2. 音符と文法について
    1. 音符
    2. 音を重ねる
    3. 強弱・スタッカート記号
    4. 音高を変化させる記号
  3. かっこ類の用法
    1. { }で繰り返し
    2. [ ]でランダムな取り出し
    3. @名前に代入
    4. かっこ類の処理順
  4. スケールの利用
    1. スケールの設定
    2. スケール名
    3. スケール音
    4. モード
  5. コードの利用
    1. コードネームの直接入力
    2. コードの設定と利用
    3. ディグリーネームによる和音の設定と利用
    4. ギター風ボイシングの利用
  6. マルチEDO(他平均律)について
    1. EDOの設定
    2. EDOの和音
    3. EDOのスケールとディグリーネーム
  7. 命令類まとめ

概要

  • テキストでシンプルに音楽を記述するための文法定義
  • そのテキストから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 ?
     

音符と文法について

音符と文法について:音符

オクターブ内の各音を数字で表し音符と考える。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平均律でいう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 ... }*20 2 4 ... 0 2 4 ... と同じ。
{ }rと数字で、その数字回かっこの中が全休符になる。 { 0 2 4 ... }r2r... r... と同じ。
この*rを連続して組み合わせて使うと、{ 0.0.0.0. }r4*12r4*12のように、バスドラムの4つ打ちが5小節めから12小節続き4小節休んでまた12小節...のようにフレーズのオンオフをコントロールできる。
さらに、{ }内の音符の内容が拍.ごとに書かれている時、*rを複数重ねて拍ごとにコントロールできる。例えば、
{0.0.0.0.}*2*r*r20.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の意味になり、047のいずれか一つだけを選ぶ。

  • [0 4 , 7] . この場合、カンマで区切られているのは0 47の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. :

  • tips
    [ 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 
    
    


  • tips
  • 中身のないかっこ () は直前の和音の内容をコピーする。
    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)。

  • tips
  • 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 から利用できる。 ch(0) に設定するか、他のチャンネルで直接鳴らすことができる。 I は三和音、右肩にシングルクォーテーション ' を一つつけて I' とすると四和音、2つつけて I'' とすると五和音、~になる。
    of で借用和音を表す。 V'ofV でVのV'、つまりIIのセブンスが鳴ることになる。連続して使えるので、 III'ofIIIofV などと書ける。
    mode( ) で構成される和音を Im IVm などとmを付けて利用することができる(というわけでmは「マイナー」という意味ではない)。 scale(0 2 4 5 7 9 11) mode(0 2 3 5 7 8 10) とすれば同主短調の和音を使えるということになる。
    その他、12以外のEDO時には意味がないが、 6 dim sus4 aug の記号をつけることができる。四和音時は Vsus4' などとする。
    分数コード表現は I/V などとし、分母は一オクターブ低く(_7 0 4 )なる。コードネーム同様に、 I/ のように分母を省略すると I/I の意味になり根音が一オクターブ低くなる。
    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 が最低音。

  • tips ストローク奏法
  • ギターをゆっくり掻き鳴らしたりピアノでそれを模したときのような、和音の各音を少しずつずらして発音する奏法を、記号 $ でシミュレートする。
    $( __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(x)
    • マイナス値可能。以降コロンまでの音符の発音位置をまとめてxティックずらす。
      // ドビュッシー『雪が踊っている』さわりで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....

    • staccato(x)
    • スタッカート記号 s を以降の音符にまとめてつける。xはスタッカートの個数。
    • duration(x)
    • 音符の発音時間をパーセントで設定する。x=100で最大レガート、x=50で半分のスタッカート。デフォルトは97。
    • scale(x, a b c d e f , o p q r s t)
    • スケールを設定。該当章を参照
    • mode(x, a b c d e f)
    • モードを設定。スケールの該当章を参照
    • bottom(x)
    • 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(x)
    • xにオクターブ内のいずれかの数字を入れると、音高記号の基準点が0から移動する。デフォルトx=0。 octavePosition(7) 7 9 11 0 2 4 6 .... とすると、通常時の _7 _9 _11 0 2 4 6 .... と同じ意味となる。和音の低音位置を調節するのに役に立つことがある。
    • transpose(x)
    • カラオケ機器のようにキーをx移動する。マイナス値可能。edo設定時も12で一オクターブ移動(MIDIノートに対する命令なので、edo時にオクターブ以外の値で移動しようとすると混乱した結果になるはず)
    • velocity(x)
    • ベロシティ値を設定。デフォルト100、最大127
    • randomVelocity(x)
    • ベロシティ値を発音時にランダムに変動させる範囲を設定。デフォルト0
    • randomTiming(x)
    • 発音タイミングをランダムに前後させるティック数の範囲を設定。デフォルト0。先頭のティック0の位置にある音符に対しては、マイナス値にはならないので効果は半分程度
    • intervalOfChord(x)
    • 和音の音程間隔を設定。デフォルト2
    • guitarLike(x)
    • ギター風ボイシングの音域設定。該当章を参照
    • delta(x)
    • key(x)
    • programChange(x)
    • MIDIの音色命令
    • pitchBendSensitivity(x)
    • デフォルト2
    • modeMessage(x)
    • MIDIチャンネルモードメッセージ
    test
    <0 8>

    このブログの人気の投稿

    DotMusic Language MIDI Converter README

    音楽用言語 開発メモ

    Googleドライブにアップデートした画像のリンク名を得る方法