SSブログ

小数展開をMIDIで演奏 [音楽の周辺]

今日の思いつきをどの分類にすればいいのかよくわからないけど、元ネタはよくある円周率πを音階にすれば無限旋律ができる、と言う話。それをMathematicaを使って汎用的にかつスマートにMIDIにしたい、ということ。

1  Mathematicaのサウンド機能

今日会社でMathematicaで計算をしていてふと気がついた。SoundNoteという関数。これはバージョン6からの新しい関数で全然知らなかった。

昔からMathematicaでは有界で凸凹が大量にある関数を把握するためにその値の変化を音として聴く、という機能がある。

例えば
Play[Sin[2 Pi 440 t], {t, 0, 1}]
とすると「ラ」の音が1秒間続くSoundというオブジェクトが生成される。さらに例えば
Play[Sin[2 Pi 440 t Sin[Pi t]], {t, 0, 1}]
は音程が低い音から始まって変化する。このような例なら式を見れば挙動はわかるが、もっと複雑な関数の場合、プロットしても領域が塗りつぶれるだけだけど音として聴けばどういう周期を持っているか、どういう周波数成分があるか、などの情報が直感的に得られる。便利と言えば便利ではあるが実際に使える場面は非常に少ない。それでも例えば周波数変調を受けているような関数の場合では式を見るより聴いた方が早い、ということはある。

2  SoundNote

そしてバージョン6からはMIDIを使って音を鳴らす機能がSoundオブジェクトに付加されていた。それがSoundNoteである。

例えば
Sound[SoundNote[0]]
とすると、中央の「ド」の音がGeneral MIDIのデフォルト楽器(普通はピアノ)の音が1秒間続くSoundオブジェクトが生成される。SoundオブジェクトをPlayすると、Macの場合ではMathlinkでMathKernelに接続されたjavaアプリが立ち上がってそれがMIDI音源(そのハードウェアが持っていたら)を鳴らすようになっている。

生成されたSoundオブジェクトはExportを使ってMIDIフォーマットで出力できる。つまり
Sound[SoundNote[0]]
Export["soundFileName.mid", %];
とすれはカレントディレクトリにsoundFileName.midというMIDIファイルができる。

2.1  音程の指定

SoundNoteはいろいろな引数をとる。まず音程の指定。
SoundNote[pitch]
とすると、pitchで指定された音程が1秒間鳴る。pitchは整数での指定と文字列での指定ができる。整数では0が中央の「ド」で、そこからの半音の数で指定する。例えば7は5度上の「ソ」で、-3は短三度下の「ラ」である。

文字列では「ド」を"C"なとと表す。半音階は"C#"、あるは"CSharp"などと書く。オクターブはGMで使う数字指定を流用する。つまり"C4"は中央の「ド」、"C5"はその1オクターブ上の「ド」である。

pitch指定をリストにすると、その和音が鳴らされる。
Sound[SoundNote[{0, 4, 7}]]
Sound[SoundNote[{"C", "E", "G"}]]
はどちらもハ長調の3和音が鳴る。また音程の代わりにグローバルシンボルのNoneを指定すると休符になる。

2.2  音の長さ

二つ目の引数をとるとそれで音の長さを秒単位で指定する。
SoundNote[pitch, t]
SoundNote[pitch, {t0, t1}]
二つ目の形式はt0秒後からt1秒後までの音を表す。

2.3  音色指定

みっつ目の引数は音色を表す。これはGMの楽器指定を文字列でとる。例えば
SoundNote[0, 1, "Organ"]
とすると、GMのオルガンの音色が使われる。それが実際にオルガンの音に聴こえるかどうかはハードが持っているGM音源に依存する。また、指定した音色が音源によっては実装されていない場合もあってそのときは何も発音されない。

パーカッションはやはりGMの名前を直接指定する。パーカッションだけは音程と長さを無視してパーカッションの名前だけを指定することができる。
Sound[SoundNote["Snare"]]

2.4  オプション

オプションはひとつだけで、次のような音量指定するもの。
SoundNote["C", .2, SoundVolume -> 0.5]
1が最大音量らしい。

3  無限小数の音

これだけではただのおもちゃだけど、ちょっと面白いことを思いついた。
数字を音程に変換する。そのとき
  1. 与えられた数mN進の小数で表示する
  2. それぞれの桁の数字を音高に対応させる
  3. 音高は半音階と全音階(七音階)の二通り
とする。つまり
  • 有理数は繰り返しがあるミニマルな旋律
  • 無理数は繰り返しのない無限旋律
になる。与える数mを変えると違った旋律になる。しかし有理数はN進数表示したとき、Nによっては循環小数になったりすぐ切れて0が続いたりする。また無理数はN進数表示のどんなNでも循環のない無限小数になるので、いろんな可能性がある。
ということでそういうMIDI音列を出力するMathematica関数を書こう。

つまり例えば、1/7を小数展開すると
1

7
= 0.14285714285714285714....
(1)
となるが、この小数部分をとりだして、MIDIの音にする。この場合、図-1のような6音が繰り返されるフレーズになる。
0727notes.png
またこれを7進数で表示すると0.10000....なのでいっきにつまらない音列になってしまうということもある。

4  fractionalNotes

ということでSoundNoteを使って小数展開した数字を音列に変換する関数を書いてみよう。

4.1  fractionalNotesの外部仕様

このような関数を作る。
fractionalNotes[num_,leng_,opt___]
これは数numの長さlengの小数展開からそれぞれの数字に対応する音程のSoundNoteオブジェクトを出力する。それをSoundに渡せば音が鳴る。

例えば
Sound[fractionalNotes[1/13,20]]
とすると1/13を10進小数展開して小数点以下20桁を取り出してそれを音程に変換する。その変換はとりあえず
  • 七音階の場合は0が、「ド」、1が「レ」
  • 半音階の場合は0が「ド」、1が「ド#」
七音階の場合は7進展開、半音階の場合は12進展開するとちょうどオクターブに収まることになる。もっと大きなN進数のNをとるとオクターブを超えて旋律が作れる。七音階の場合は0に対応する音を「ド」以外にもできる(旋法が選べる)ようにしよう。半音階はそういう必要はないだろう。

第1引数が不動小数点数(機械精度)だった場合は小数展開ができない(精度が足りない)のでエラーにする。また、整数が渡されたらこれは精度はあるがトリビアル(どんなN進数でも小数点以下は0が並ぶ)なのでこれもエラーにするか。
従って受けられる数は
  • 1/7などの有理数
  • √2などの代数的無理数
  • πなどの超越数
ということになる。

また、音の長さはとりあえず全部一定にしよう。
N進数のNを変更するのはオプションにしよう。デフォルトは当然十進数。

また休符を含めるかどうかもオプションで選べるようにしよう。つまり、休符を含める場合は
  • 0が休符
  • 七音階の場合は1が、「ド」、2が「レ」
  • 半音階の場合は1が「ド」、2が「ド#」
としよう。
他にもオプションを作る。

まず、七音階の場合の最低音に対応する音を指定する。例えば「D」を指定するとドリアンになる(というか最低音が「レ」になるだけだけど)。このオプションは半音階では無視される。

また、
  • 音の長さ
  • 音色(MIDIの楽器指定)
  • 音量
  • 文字列表示
などができるようにしよう。最後の文字列表示は、音に対応させた数字の列を表示する。これは単なる親切。

こんなもんか。明日、実装してみて実際のMIDIファイルの例を作ってみよう。
nice!(0)  コメント(0)  トラックバック(0) 

nice! 0

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

トラックバック 0

献立7/27献立7/28 ブログトップ

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。