小数展開をMIDIで演奏 - その2 [音楽の周辺]
今日、他に同じネタをやってる人がないか探しているうちに作曲家の吉松隆氏のページに行き当たった。このページの12音技法のところに「円周率から無限旋律を作る」話がある。さすが専門家で音楽的に豊富な内容を簡潔に読ませてくれる。
今回の僕の興味はどっちかというと無理数による「無限旋律」よりも、有理数による「ミニマル」なフレーズのほうにあるけど、氏のページにはミニマルの例はなかった。そういうことは他にやられていないのか。
ところで氏のページは面白い。特にクラシック音楽探偵事務所はちょっと長いめのまとまった話題について作曲家としての視点から、かなりディープに語られている。月にひとつアップされるらしいので今後も楽しみにさせていただこうと思う。
BaseFormは最大36進数まで変換する(一桁を0...9a...zの36文字で表す)ので、それが音域の最大になる。七音階なら5オクターブを超えるので十分だろう。
Charactersは文字列を文字ひとつひとつの配列に変換する。あとはこれを音程に対応させればいい。対応のさせ方にはいろいろあるだろうけど、一番簡単だと思えるのは文字をそれぞれToCharacterCodeで整数にして、その数に対応する音程を並べる、というやり方だろう。
オプションのための場合分けや、休符を含めた場合の処理がちょっと煩わしいが、めんどくさいだけでそれほど難しくはない。
ということでいろいろ試してみる。こればかりは会社ではできない。榴岡の部屋のiMacにあるMathematicaがあるのでそれでやる。
簡単なところから1/7の十進展開。
1/5は十進展開すると0.2なので有限で切れてしまうけど、他の進数では循環小数になる場合がある。例えば8進数では0.14631463146314631463...となる。
このMathematicaのソースをここに置いておく。
ここで循環する部分だけをとりだしてそれが一致するものは同一と見なすことにする。つまり十進では 1/7
= 0.142857142857142...
1/70
= 0.0142857142857142...
であって、
この二つは数としては異なるが、循環する部分は同じなのでこれを同一視するということである。
そうすると2〜N進数で長さL以下の循環小数の数は最大
個あることになる(各桁に数字がすべて現れるとして)。これはもちろん有限だけどNがいくらでも大きな値をとることができるとすると無限個になる。それは無限に高い音を含むことになるので出現する最高音を決めると有限個になる。
NをMathematicaが可能な上限である36、Lを例えば20にしても式-2は1031を超える。
今回のやり方で生成できる種類はこの組み合わせがすべてできるとは限らないのでこれ以下ではあるが、それでも膨大な数が可能になる。
ここで一番気になるのは、完全にランダムな作り方、つまり長さL、それぞれの桁にN種類の文字が入る場合と作られる文字列は違うのかどうか、ということ。完全にランダムな場合と同じなら、乱数から作る方が簡単。
完全にランダムだと式2個あるわけで、有理数から作る場合は結局同じになってしまうんだろうか。そのへんまじめに計算しようとすると、整数論がちゃんと使えないといけないので僕の手に余ってしまう。はっきり言うが、僕は整数論は苦手。
だれか得意な人が計算してくれないだろうか。例えばある循環長さでは現れないパターンがあるとか、そういうのがあると面白いんだけど。
ところで氏のページは面白い。特にクラシック音楽探偵事務所はちょっと長いめのまとまった話題について作曲家としての視点から、かなりディープに語られている。月にひとつアップされるらしいので今後も楽しみにさせていただこうと思う。
4.2 fractionalNotesの実装
実装はMathematicaでやるのでそれほど難しくはない。与えられた数のN進小数展開した文字列を得るにはCharacters[ToString[BaseForm[N[num, leng],base]]]とすればnumをbase進数で表示した文字列が手に入る。桁数はleng桁になるがそれは残念ながら十進数での桁数になる。base進数でleng桁にしたければ
leng = lengb Log[10, base];などとする必要がある。ここでlengbはbase進数で必要な桁数。
BaseFormは最大36進数まで変換する(一桁を0...9a...zの36文字で表す)ので、それが音域の最大になる。七音階なら5オクターブを超えるので十分だろう。
Charactersは文字列を文字ひとつひとつの配列に変換する。あとはこれを音程に対応させればいい。対応のさせ方にはいろいろあるだろうけど、一番簡単だと思えるのは文字をそれぞれToCharacterCodeで整数にして、その数に対応する音程を並べる、というやり方だろう。
オプションのための場合分けや、休符を含めた場合の処理がちょっと煩わしいが、めんどくさいだけでそれほど難しくはない。
5 鳴らしてみる
以上のようなコマゴマとした実装を会社でやってた。まずいだろ。まあ、ちょこちょこっとでできたので普段メールを読んだりネットをうろうろしたりというような時間とあまり変わりない。いや、それでもまずいだろ。まあいい。ということでいろいろ試してみる。こればかりは会社ではできない。榴岡の部屋のiMacにあるMathematicaがあるのでそれでやる。
6 有理数の小数展開の音
まず、簡単な有理数を小数展開したときに途中で切れてしまわないで循環小数になる場合をみてみる。簡単なところから1/7の十進展開。
Sound[fractionalNotes[1/7, 25, digitBase -> 10, includeRest -> True, noteScale -> diatonicScale, showDigits -> True, startingNote -> "C"]]で生成されたMIDIがこれ。小数点以下は 1428571428571428571428571...とならぶので6/8拍子に聴こえる。 こんどはもうすこし長いコンパスになるようなものをやってみる。1/17の20進数展開。
Sound[fractionalNotes[1/17, 33, digitBase -> 20, includeRest -> True, noteScale -> diatonicScale, showDigits -> True, startingNote -> "A"]]MIDI。小数点以下は13abf5hcig984e2713abf5hcig984e271...なので16分音符の4/4拍子1小節分に聴こえる。
1/5は十進展開すると0.2なので有限で切れてしまうけど、他の進数では循環小数になる場合がある。例えば8進数では0.14631463146314631463...となる。
Sound[fractionalNotes[1/5, 20, digitBase -> 8, showDigits -> True, noteScale -> chromaticScale]]MIDI。スケールを半音階にしたけど、全音階風のサティみたいになった。
6.1 超越数の音
それではお約束の円周率。例えば9進法で小数点以下百桁は1241881240744278864517776173103582851654535346265230112632145028386403435416330308678132787158853681だそうで、ちょっと速いめにしてSound[fractionalNotes[Pi, 100, noteScale -> diatonicScale, digitBase -> 9, noteDuration -> 0.1, showDigits -> True]]とするとこんなふうな音。うーん、ランダムな感じ。あまり音楽的でない。
6.2 ミニマル風
もうちょっとミニマル風にしてみよう。ピアノで1/7の十進展開、ビブラフォンで1/11の13進法展開を重ねてみるとs1 = Sound[ fractionalNotes[1/7, 40, digitBase -> 10], {0, $noteDuration*40}]; s2 = Sound[ fractionalNotes[1/11, 40, digitBase -> 13, startingNote -> "C", soundInstrument -> "Vibraphone"], {0, $noteDuration*40}]; Sound[{s1,s2}]うわあ、いかにもありがちなそのまんまですがな。
このMathematicaのソースをここに置いておく。
7 有理数で何通りのパターンがあるのか
有理数のN進数表示は加算無限個あるが、循環小数の周期がいくらでも長いものがあって有限の時間で周期を聞き取ることができないものが含まれる。ある長さL以下の循環周期のものだけを考えてもやはり無限個ある。ここで循環する部分だけをとりだしてそれが一致するものは同一と見なすことにする。つまり十進では 1/7
1/70
| (2) |
NをMathematicaが可能な上限である36、Lを例えば20にしても式-2は1031を超える。
今回のやり方で生成できる種類はこの組み合わせがすべてできるとは限らないのでこれ以下ではあるが、それでも膨大な数が可能になる。
ここで一番気になるのは、完全にランダムな作り方、つまり長さL、それぞれの桁にN種類の文字が入る場合と作られる文字列は違うのかどうか、ということ。完全にランダムな場合と同じなら、乱数から作る方が簡単。
完全にランダムだと式2個あるわけで、有理数から作る場合は結局同じになってしまうんだろうか。そのへんまじめに計算しようとすると、整数論がちゃんと使えないといけないので僕の手に余ってしまう。はっきり言うが、僕は整数論は苦手。
だれか得意な人が計算してくれないだろうか。例えばある循環長さでは現れないパターンがあるとか、そういうのがあると面白いんだけど。
2010-07-28 22:19
nice!(0)
コメント(2)
トラックバック(0)
はじめまして。RealDigits 関数を使うと、もうちょっとだけすっきり書けて、進数の上限もなくなるかも、です。外してたらすみません。
by モリヤン (2010-07-30 13:00)
コメントありがとうございます。
RealDigits知りませんでした。これを使えばちょっとすっきり、どころか桁ごとに展開していたところはRealDigitsだけで済んで、ごちゃごちゃ書いたのは不要になりました。
新しい関数がどんどん増えて覚えきれません。というよりバージョン2.2あたりから覚えてるのはあまり増えていないような....
by decafish (2010-07-30 21:35)