Sonic Piメモ

Sonic Pi(ソニックパイ)は、音楽生成、ライブコーディング(ステージ上でのプログラミングによるDJ等)、子供から大人までのプログラミング入門(体験から入門、活用まで)に最適なプログラミング言語です。下記にサンプルプログラムを多数公開していますので情報処理教育等に活用下さい。
タイトルの波形画像の作り方は

英ケンブリッジ大のSam Aaron氏の作であり、Radsberry Pi, MacOSX, Windows, Linuxに対応しているオープンソースソフトウェアです。(MITライセンス)


2018年1月23日頃 ver3.1 'Sauna'が公開されました。 macOS版に加え、新たにWindows版も公開されています。
3.0での新機能の多くは、ブログrbnrpiで詳しく解説されています。
追加されたchordは、7-11,7-13,halfdim,halfdiminished,m7b5,maj,minの7つ
エフェクトにeq,tremolo、コマンドに、with_swing、set,get、サンプルプログラムにCloud Beatなども追加されています。

以下のプログラムを実行すると、新しく追加されたサンプル音を聴くことができます。
a=[:perc_bell2, :perc_door, :perc_impact1, :perc_impact2, :perc_swoosh, :ambi_sauna, :bd_mehackit, :sn_generic, :loop_3d_printer, :loop_drone_g_97, :loop_electric, :loop_mehackit1, :loop_mehackit2, :loop_perc1, :loop_perc2, :loop_weirdo]
for i in 0...a.length
sample a[i]
sleep sample_duration(a[i])
end

また、バージョン毎のsynth、sample,chord,scaleの数は、それぞれ、
42 164 70 73 (Ver.3.1 最新版)
42 129 70 73 (Ver.3.01)
42 129 63 73 (Ver.2.11)
39 129 63 71 (Ver.2.10)
と増加してきています。(下記の1行を各バージョンのSonic Piで実行しました。)
puts synth_names.length,all_sample_names.length,chord_names.length,scale_names.length


2017年9月末、Sonic Piについての新しい Q&A等の掲示板がオープンしました。in_thread



Sonic Piは、日本発で世界的に活用されているRuby言語(まつもとゆきひろ氏作)と音響合成言語のSuperCollider とQt等を使って作られています。
プログラムで本格的に音を出し音楽とすることのできる環境の中では、容易さや音質の面で最も優れていると思われます。
音を出し耳で確認しながらプログラミングができるので、英国の特にケンブリッジでは子供のプログラミング入門用(文法はほぼRuby)として大いに用いられているようで、世界中に広まりつつあります。

Sonic Piの操作画面



概要

下記の最初の項目のPDFには、多くの情報を詰め込んでいます。
思いついたものを順不同に並べています。

Sonic Piメモ (PDF、約33頁) 使い方、リファレンス、注意点、サンプルなどいろいろ(自分用メモで加筆中、中身は順不同です.)
「春の海」(宮城道雄)の演奏例とプログラム、その作製法
MIDIファイルやMuseScoreの楽譜データをSonic Pi用に変換する方法 MIDI -> MuseScore -> MusicXML ->(Processingによる変換プログラム) -> Sonic Pi
テキストファイルによるSonic Piのリアルタイム制御 (Ver.3になって必要なくなりました.)
Sonic PiからProcessingへの、ProcessingからSonic Piへの、テキストファイルを介した連携 (Ver.3になって必要なくなりました.)
Processingで操作するSonic Piのテルミン (Ver.3になって必要なくなりました.)
オフィシャルサイトのプログラム例の日本語解説
DTMF音のプログラム例
Sonic Piで竹内関数音楽 (たらいまわし関数、Takeuchi,Tak function)(再帰呼び出し,recursive call)
5行のプログラムで1000000桁円周率π音楽
5行のプログラムで素数音楽
・ランダム般若心経 ( 上記のPDF SonicPi_memo.pdf 内に記載 )
AudacityのエコーをSonic Piで
小鳥のさえずり
1/fゆらぎ的なカラスの鳴き声
マキシマイザー的な使い方
n平均律音楽 (12以外の平均律で演奏する.微分音) 例「かえるのうた」「フレールジャック」
DNA ゲノム音楽 (MITメディアラボ所長伊藤穣一氏の遺伝子塩基配列を使用)
バブルソート音楽.データの可聴化 (Bubble Sort)
五度円(五度圏)上を廻るコード (Circle of Fifth)
Gapminderの平均余命データを可聴化 (社会問題の可聴化例)
ピタゴラスのコンマのずれを聞く 2017.4
リサージュ図形のいろいろ 2017.5
Sonic Piによる奏者の発音タイミングデータの活用 (Miles Davis "So What")
Sonic Piによるドビュッシーのシリンクスの演奏。5人の巨匠の比較。 Debussy,Syrinx
ランダムな音程が元の旋律に変化、音のモーフィング (Random to Melody、Morphing; Hey Jude)
最も簡単なライブコーディング体験法 (The Simplest Live Coding Experience)
LibreOfficeのImpress(MS-OfficのPowerPointに相当)のサウンドをSonic Piから直接鳴らす
音感テスト(音程) Check of pitch perception NEW 2017.7
等速で変化するポルタメント (Portamento changing with constant speed)
パーリンノイズ音楽 (Perlin Noise Music) NEW 2017.8
ニュートン法による方程式の解の音楽 (Equation Solving Music, Newton Method)
波形アートの作成法(このページのタイトル画像、Sonic Piは使いません) wav2vec,Inkscape (Making of Sound Wave Art)
将棋の棋譜を音楽化(Shogi Music) 藤井聡太、羽生善治、Ponanzaなど New 2018.4
2つの交差したポルタメント(Two Intersected Portamentos) New 2018.4
囲碁の棋譜を音楽化(Go Music) Google Alpha Go、李世石、柯潔ら New 2018.4
コードをアルペジオで鳴らす例 PPM(Peter Paul & Mary) の The Cruel War (悲惨な戦争) New 2018.4
タブ譜をSonic Piで鳴らす方法の例 Eagles - Hotel California intro., New 2018.4



2016.11.5 オープンソースカンファレンス(OSC Tokyo/Fall)で「授業で使ってみた音関連OSS」というタイトルで「Sonic Pi」を中心にセミナー講演をしました。資料


紹介

mehackit (Creative high school technology courses in the Nordics.) が、Processingの操作パネルで操作し、Sonic Piを鳴らすシンセサイザーをオープンソースで公開しています。
Processingの画面をマウスで操作するだけで、いろいろなビートを操作することができ、大変興味深いものです。

下図、左側がProcessingのプログラムを実行すると現れる操作画面。     右側がSonic Piのプログラム


手順
プログラミング言語のProcessingがインストールしてあることが前提です。
Githubの mehackit/technomachine: Processing + Sonic Pi Techno Machine https://github.com/mehackit/technomachineからプログラムを入手します。
右側にある[Clone or download]ボタンから "technomachine-master.zip" をダウンロードし、zipファイルを解答した中にあるフォルダ[Sonic_Pi_Techno_Machine]をProcessingのスケッチ用フォルダに入れ、ファイル"Sonic Pi Techno Machine.rb"をSonic Piで開き、両者を実行(どちらが先でも可のようです)すると、上記の図のようにProcessingのSonic Pi_Techno Machineウィンドウで、Sonic Piを操作できるようになります。

なお、実行前に、Processing側では、ライブラリーのcontrolP5とoscP5をインストールしておくことが必要です。
 メニューの[スケッチ]→[ライブラリーをインポート]→[ライブラリを追加] という操作でライブラリーのインストールできます。
Sonic Piは、Ver.2.11.1が必要です。
Processing3.3 macOSで動作確認済. Windowsでも問題ないと思われます。

Processingのプログラムは450行程度であり、その中身も多数のボタン操作の記述がほとんどなので、これを元に改造することも容易でしょう.



「春の海」のSonic Piによる演奏例


宮城道雄の
「春の海」(MuseScoreファイルのHarunoumi_v2c.mscz)(著作権は消滅)を五線譜ソフトMuseScoreを使ってパート毎に(琴は右手と左手も)別々のMusicXMLファイルにエクスポートし、さらにSonic Pi用に変換(自作のProcessing言語による下記のプログラムで)してみました。
一部、トレモロや、アルペジオを省略している部分があります。
# 琴の右手と左手の分別は、左手の音を伸ばす必要があり、右手のデータとできない部分のみを左手としています。
# Harunoumi_v2c.msczでは、スピートの指定部分に何らかの音符か休符がないと、XML作成時にスピード指定が消えてしまう(変換プログラムが対応していない)ので、尺八、琴(右、左)には、音符や休符の長さなどを変更している部分があります。

(Sonic Pi ForumでRobin Newmanさんに教わった) CueとSyncを使った実行方法によって全曲を連続して演奏することができます。
下記の4つのSonic Piのプログラムを別々のBufferに入れ、最初に[パート3]を入れたBufferでRunして下さい。(音は出ずにsyncだけが登録されます) 次に[パート2b]、その次に[パート2a]のBufferをRunして下さい。同様にsyncだけが登録されて音は出ません。最後に[パート1]を実行すると、連続して全曲が演奏されます。
再度連続演奏をする場合には、[パート3]のRunからの手順を繰り返す必要があります。

Sonic Pi用プログラム (拡張子はRubyと同じ.rb)
春の海(Harunoumi_1.rb) パート1
春の海(Harunoumi_2a.rb) パート2a
春の海(Harunoumi_2b.rb) パート2b
春の海(Harunoumi_3.rb) パート3

上記を連続して演奏した MP3ファイル
Harunoumi_SonicPi.mp3 (CC-BY)

#(なお、これで完成というわけではなく、このデータを元にプログラミングによって、自在に音を加工してゆくことの方に意味があります。)
上記のパート2a以降をSonic Pi上で単独に演奏したい場合には、各プログラム中に3箇所あるsyncの行の行頭に#を入れてコメント化して下さい。cueの行はそのままで問題ありません。

参考ファイル
MuseScoreで出力した3つのMusic-XMLファイル(これをProcessingプログラムでSonic Piに変換しました。)
MusicXMLファイル(尺八 Shakuhachi)
MusicXMLファイル(琴 右手 Koto Right)
MusicXMLファイル(琴 左手 Koto Left)

・元の 春の海(Haru no Umi, The Sea in Spring/The Sea of Spring) (harunoumi_v2b.mid) MIDIファイル


Processing による MusicXML to Sonic Pi 変換プログラム

上記の春の海の変換に仕様した、MuseScoreで出力したMusicXMLファイルを読み込み、Sonic Piのコードを出力する
Processing言語のプログラムを公開します。
Processingは、Java系の言語であり、データの可視化、アート作品の生成などで幅広く用いられていますが、ここではグラフィックス機能は一切使っていません。

MusicXMLtoSonicPi_01.pde , ( Licence CC-BY )

Sonic Piは、主にEDM(Electric Dance Music)やノイズ系の音楽のDJで用いられていますが、既存の音楽を演奏するには、play文を一から作らなければなりません。教育用に用いる場合も、音楽データを利用できると、活用の幅が広がります。

このプログラムは、とりあえず動作するだけの汚いスパゲティープログラムで、既に自分でも修正は困難を極めます。
入力ファイル名(??.xml)は、プログラム中に書き込んで下さい。
Sonic Piのプログラムは、Processingの標準出力に表示されますので、コピペして下さい。
出力される data??.txt 等のファイルは、不要です。
MusicXMLファイルを作成する前の入力データとする、MuseScoreのスコア譜は、パート譜に分割して1パートだけにして下さい。さらにMuseScore内のパート1-4 を使用している場合は1のみとして下さい。
# MuseScore上で、あるパートだけの音符や休符の選択(右クリックから[選択]→[詳細]→[同一の声部]) やパート1とパート2の交換(メニューの[編集]→[声部]) ができます。
装飾音符にはある程度対応していて、1/16拍とします。(多数の装飾音符が並ぶと次の音符の長さが負になります。)
コードやタイには対応します。タイの付いたコードにはあまり対応していません。
ダブルシャープ/フラットには対応していませんので、MuseScoreでダブル#bなしの移調を2回繰り返して元に戻すことによって削除して下さい。

MIDIファイルがあれば、MuseScoreで読み込んで、さらにMusicXMLに書き出してSonic Piに変換することができますので、Sonic Piを容易に活用するツールとなります。


使用した
Sonic Pi (MIT Licence)
MuseScore (GPL Licence)
Processing (GPL Licence)
は、いずれもオープンソースであり無償で公開されています。



変換操作の仕組みについて
MuseScoreで春の海は、下記のように入力されています。

これを、MuseScore上でMusicXML形式にエクスポートしたファイルの、尺八パートの冒頭と最初の2音付近は、下記のようになっています。 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE score-partwise PUBLIC "-//Recordare//DTD MusicXML 3.0 Partwise//EN" "http://www.musicxml.org/dtds/partwise.dtd"> <score-partwise> <identification> <rights>&lt;font size=&quot;8&quot;/&gt;春の海</rights> <encoding> <software>MuseScore 2.0.3</software> === === === === <note default-x="94.20" default-y="-10.00"> <pitch> <step>D</step> <octave>5</octave> </pitch> <duration>12</duration> <voice>1</voice> <type>eighth</type> <stem>down</stem> </note> </measure> <measure number="3" width="162.40"> <note default-x="12.00" default-y="-5.00"> <pitch> <step>E</step> <octave>5</octave> </pitch> <duration>48</duration> <voice>1</voice> <type>half</type> <stem>down</stem> </note> === === これらの中から、音符の音程を表している <step>D</step> や、音符の長さ <duration>12</duration> などを取り出してSonic Pi用に変換した Sonic Pi のコードの一部が下記です。(拡張子.rbのファイル) (ここで、a,bは2次元配列です。) a[0]=[:r,:r,:r,:r,:D5,:E5, ... ] # 音程 b[0]=[4.0,2.0,1.0,0.5,0.5,2.0, ... ] # 長さ c=[60, ... ] # テンポ use_synth :dpulse # シンセ音源に dpulseを用いる for i in 0...a.length # a配列のi要素の数だけ繰り返す use_bpm c[i] # テンポを指定する for j in 0...a[i].length # a[i]のjの要素の数だけ繰り返す play a[i][j], sustain: b[i][j]*0.6, amp: 0.3 # 配列a[i]のj番目の要素を音程として音源を鳴らす。 sleep b[i][j] # 配列b[i]のj番目の要素の数値を拍として間を置く. end end
---
上記の変換プログラムを英国のRobin Newmanさんが自身のブログ(Raspberry Pi関連,Sonic Pi関連で有名)で詳細に(このページよりもずっと詳細に丁寧に)解説してくれました。
また、このプログラムを活用し、MIDIデータから変換し、Sonic Piで演奏した23分もの大曲など数曲を公開されています。

Converting MusicXML or midi files to work with Sonic Pi rbnrpi ブログ
Fugue in F by Sidney Newman played by Sonic Pi(23分) Youtube




テキストファイルによる、Sonic Piのリアルタイムコントロール

適当な場所にMIDIノート番号の数字を一つだけ入れたテキストファイルを作成し SonicPi_Text_MidiNo.txt という名前で保存します。
同様に、音量とするamp値の数字を一つだけ入れたテキストファイルを作成し SonicPi_Text_Amp.txt という名前で保存します。
同様に、sleep値とする数字を一つだけ入れたテキストファイルを作成し SonicPi_Text_Sleep.txt という名前で保存します。
loop do
  a=File.read("/Users/???/SonicPi_Text_MidiNo.txt").to_f # 保存したファイルのフルパス名を与えます.
  b=File.read("/Users/???/SonicPi_Text_Amp.txt").to_f
  c=File.read("/Users/???/SonicPi_Text_Sleep.txt").to_f
  play a,amp: b
  sleep c
end
例
ファイル SonicPi_Text_MidiNo.txt の中身の例は、 60。  60.5も可能
ファイル SonicPi_Text_Amp.txt の中身の例は、 1.0
ファイル SonicPi_Text_Sleep.txt の中身の例は 0.5
Sonic PiのプログラムをRunした後、テキストエディタ等でファイルの中身を書き換えて、"その都度保存"すると、Sonic Piの動作をリアルタイムに制御できます。

参考 rANGEL (PDF)


Sonic PiとProcessing間によるテキストファイルを介したリアルタイムコントロール 例

上記のSonic Piの制御に用いたテキストファイルを、Processingでの画面上のマウスクリックの座標等から算出し、テキストファイルに書き出すことにより作成します。
逆に、Sonic Pi側で音程をテキストファイルに出力し、Processingで読み込むことにより、グラフィックスを作成することができます。

Sonic Pi --> Processing の例

Sonic Piで同時に鳴るランダムな2つの音の音程と音量をx,y,rとして3つのファイル(場所はProcessingプログラムのフォルダ中)に書き出す。 Processingで、ファイルから値を読み込んで、x、yを中心とし、rを半径とした円をランダムな色で描く。 リアルタイムではあるが、書き出す側と読み込む側の同期はしていない。 Sonic Pi側のプログラム use_debug false use_random_seed 0 # 乱数の種の番号。デフォルトは0 loop do x=rrand(48,96) # MIDIノート番号48〜96 (C3〜C6)の音を実数の乱数で生成。x座標とする y=rrand(48,96) # 同上。y座標とする。 r=rrand(0.1,5) # 0.1〜5.0の実数の乱数。音量とする。 File.write("Processingプログラムへのパス/SonicPi_to_Processing/SPtest1.txt",x) # xの値をProcessingのプログラムフォルダ内のファイルに書き出す。 File.write("Processingプログラムへのパス/SonicPi_to_Processing/SPtest2.txt",y) # yの値を 同上 File.write("Processingプログラムへのパス/SonicPi_to_Processing/SPtest3.txt",r) # rの値を 同上 play [x,y],amp:r # x,yを同時に、音量rで鳴らす。 sleep 0.25 # 0.25拍置く(デフォルト速度では0.25秒) end Processing側のプログラム // Sonic Piの2つの音とその強さの値をProcessingのdataディレクトリにファイル出力し、読み込んでグラフィック表示する。 // Sonic Pi側の書き込み中にProcessing側で読み込むと値がないファイルとなってエラーするため、読み込んだ配列の長さが0かどうかを調べている。 void setup() { size(600, 600); # 画面サイズ background(0); # 背景色を黒に strokeWeight(5); # 線の太さを5ピクセルに colorMode(HSB); # 色モデルをHSBに frameRate(5); # 画面の更新速度を5回/秒に } void draw() { float x=0,y=0,r=0; fill(0,2); # 塗り色を黒、透明度を2に(0が完全透明,255が不透明) rect(-5,-5,width+10,height+10); # 画面全体を薄い半透明の黒の四角形で塗りつぶす String[] s1 = loadStrings("SPtest1.txt"); # SonicPiで書き込んでいる値をファイルから読み込む,x String[] s2 = loadStrings("SPtest2.txt"); # 同上,y String[] s3 = loadStrings("SPtest3.txt"); # 同上,r if(s1.length>0) x=(float(s1[0])-48+1)*width/48.; # 画面サイズに合わせてx座標を作成する。ファイルが空の場合は配列の長さがゼロとなっているので、座標を生成しない。 if(s2.length>0) y=(float(s2[0])-48+1)*height/48.; # 同上 y if(s3.length>0) r=(float(s3[0]))*20.0; # 同上、半径r fill(random(255),255,255); # 塗り色の色相をランダムに設定。彩度と明度は最大。 stroke(random(255),255,255); # 同上、線の色 ellipse(x, y, r, r); # 円を描く // println(x+" "+y+" "+r); }

Processing --> Sonic Pi の例

Processing側で、マウスで画面をクリックした場所に円を描く。円の座標を2つの音程とし、円の半径はクリックしていた時間から生成し、それを音量とする。これら3つの値を3つのファイルに書き出す。 Sonic Pi側で3つのファイルを読み込み、2つの音を少しずらして鳴らし、読み込んだ音量で鳴らす。鳴らす間隔は1/4拍に固定。 リアルタイムではあるが、2つのプログラムは、同期していない。 Processing側 // Processing_to_SonicPi PrintWriter fx,fy,fr; float x,y,r; float xmin=48,xmax=96; float msec; void setup(){ size(600,600); background(255); stroke(255,0,0); strokeWeight(1); } void draw(){ fill(255,255,255,5); // 塗り色を白色の透明度5に設定 rect(-5,-5,width+10,height+10); // 半透明の白色の四角形を画面全体に描く } void mousePressed(){ msec=millis(); // マウスボタンがクリックされた時間を記憶する。 } void mouseReleased(){ // マウスボタンが離された時に実行される noFill(); x=mouseX*(xmax-xmin)/width+xmin; // マウスのx座標から音程を生成する. y=mouseY*(xmax-xmin)/height+xmin; // マウスのy座標から音程を生成する. r=map(millis()-msec , 0 , 1000, 0 , 5); // マウスボタンが押されていた時間から音量を生成する. if(r>5) r=5; // 音量の最大値を5とする strokeWeight(r*2); // 線の太さを音量から生成する ellipse(mouseX,mouseY,r*30,r*30); // マウスの座標に音量を直径として円を描く println(x+" "+y+" "+r); fx=createWriter("SPtest1.txt"); // Sonic Piに渡す値を保存するファイルを作成する.x用 fy=createWriter("SPtest2.txt"); // 同上、y用 fr=createWriter("SPtest3.txt"); // 同上、r用 fx.println(x); // xの値をファイルに出力する fy.println(y); // yの値を同上 fr.println(r); // rの値を同上 fx.flush(); // バッファからファイルに書き込む fy.flush(); fr.flush(); fx.close(); // ファイルを閉じる fy.close(); fr.close(); } Sonic Pi側 # Processing_to_SonicPi use_synth :dsaw # 音源の指定 loop do # 無限ループ x=File.open("Processingプログラムへのパス/Processing_to_SonicPi/SPtest1.txt").read.split(" ") # Processingのプログラムフォルダからxの値を読み込む y=File.open("Processingプログラムへのパス/Processing_to_SonicPi/SPtest2.txt").read.split(" ") r=File.open("Processingプログラムへのパス/Processing_to_SonicPi/SPtest3.txt").read.split(" ") play x[0].to_f, amp: r[0].to_f # x座標に元ずく音を音量rで鳴らす sleep 0.05 # 0.05拍置く play y[0].to_f, amp: r[0].to_f # y座標に元ずく音を音量rで鳴らす sleep 0.2 # 0.2拍置く end # .read.split(" ") は、データをスペースで区切って配列の要素にする機能ですが、行末コードによるエラーがこれにによって解消したので、そのまま使用しています。

上記の原理で作ったProcessingでのマウスの動きによって動作するSonic Piのテルミン(Thermin)は、Sonic Piメモ(PDF)内に記載しています。

KinectやLeapMotionによってより手の動きを取得して本物に近い操作としたり、Aruduino等で他のハードウェアと組み合わせて音を出すような仕組みにすることも容易にできるでしょう。





Sonic Pi 本家で、下記のコードの音を聞くことができます。(Topページの下部で)

Sonic Pi Examples (Officialページのサンプルプログラム) の日本語コメントによる解説

Haunted Bells

loop do # 無限ループを開始 sample :perc_bell, rate: (rrand 0.125, 1.5) # サンプル音源の:per_bellを0.125〜1.5のランダムな速度で再生 sleep rrand(0, 2) # 間隔をランダムに0〜2拍あける. end # 無限ループはここまで

Pentatonic Bleeps

with_fx :reverb, mix: 0.2 do # 全体にエフェクトのリバーブを0.2だけかける. loop do # 無限ループ開始 play scale(:Eb2, :major_pentatonic, num_octaves: 3).choose, release: 0.1, amp: rand # E♭のメジャー・ペンタトニックスケールのオクターブ2から3オクターブ分の音から1音をランダムに選び、余韻0.1拍、強さ1未満で、デフォルトの:beep音(サイン波)を鳴らす。 sleep 0.1 # 0.1拍の間をあける. end # 無限ループここまで end # エフェクトここまで

Tron Bikes

loop do # 無限ループ開始 with_synth :dsaw do # :dsaw 鋸型波形を使う with_fx(:slicer, phase: [0.25,0.125].choose) do # スライサを使い、間隔を0.25拍または0.125拍とする. with_fx(:reverb, room: 0.5, mix: 0.3) do # リバーブを使い、部屋サイズを0.5、混合度合いを0.3とする. start_note = chord([:b1, :b2, :e1, :e2, :b3, :e3].choose, :minor).choose # 開始音を、マイナーコード6種から選んだ一つのコード、からさらに選んだ1音とする. final_note = chord([:b1, :b2, :e1, :e2, :b3, :e3].choose, :minor).choose # 終了音 同上 p = play start_note, release: 8, note_slide: 4, cutoff: 30, cutoff_slide: 4, detune: rrand(0, 0.2), pan: rrand(-1, 0), pan_slide: rrand(4, 8) # 開始音を余韻8拍、前の音からの音程の移動に4拍、ローパスフィルタのカットオフ高さを30(ノート番号)、前の音のカットオフ値からの移動に4拍、音程0.2未満ずらした音を混ぜる、パンは左〜中央、パンの移動に4〜8拍かける. control p, note: final_note, cutoff: rrand(80, 120), pan: rrand(0, 1) # 終了音に対して設定に従い連続的に移動する。カットオフ値は80〜120、パンは、中央から右 end end end sleep 8 # 8拍の間を置く end # 無限ループ終わり

Wob Rhythm

with_fx :reverb do # リバーブをかける in_thread do # 他と並行動作させる. loop do # 無限ループ開始 r = [0.5, 1.0/3, 3.0/5].choose # 音程となる再生速度を3種からランダムに選ぶ 8.times do # 8回繰り返す sample :ambi_choir, rate: r, pan: rrand(-1, 1) # サンプリング音源の:ambi_choirを速度rで、左右のパンはランダムにして再生する。 sleep 0.5 # 0.5拍の間を置く end end end end # メインプログラム with_fx :wobble, phase: 2 do |w| # wobbleの間隔を2拍とし、2拍目のドラム音にモジュレーションをかける. # |w|は使われていないがsleepの後にcotrol w, phase: rrand(0.5, 4) 等により変化を増やせる. with_fx :echo, mix: 0.6 do # エコーを混合度合0.6で適用し、ドラムが減衰しながら3回鳴っているようする. loop do # 無限ループ開始 sample :drum_heavy_kick # サンプル音源のdrum_heavy_kickを鳴らす. sample :bass_hit_c, rate: 0.8, amp: 0.4 # 同時に bass_hit_cを、再生速度0.8、強さ0.4で鳴らす. sleep 1 # 1拍置く end # 無限ループはここまで end # エコーはここまで end # wobbleはここまで

Ocean Waves

with_fx :reverb, mix: 0.5 do # リバーブを混同度合い0.5で適用する loop do # 無限ループ開始 s = synth [:bnoise, :cnoise, :gnoise].choose, amp: rrand(0.5, 1.5), attack: rrand(0, 4), sustain: rrand(0, 2), release: rrand(1, 3), cutoff_slide: rrand(0, 3), cutoff: rrand(60, 80), pan: rrand(-1, 1), pan_slide: 1, amp: rrand(0.5, 1) # 3種のノイズ音源から一つ選び、強さを0.5〜1.5、音の立ち上がり時間を0〜4拍、音の持続時間を0〜2拍、余韻時間を1〜3拍、ローパスフィルタのカットオフ音程の変化時間を0〜3拍、カットオフ音程を60〜80、パンを-1〜1、パンの変化に要する時間を1拍、強さを0.5〜1とする。 control s, pan: rrand(-1, 1), cutoff: rrand(60, 115) # 上記設定から音源をパン-1〜1、カットオフ音程60〜115に変化させる. sleep rrand(2, 3) # 2〜3拍置く. end end

IDM Breakbeat

define :play_bb do |n| # 関数play_bb を定義する.nの値が与えられて呼び出される. sample :drum_heavy_kick # サンプリング音源のdrum_heavy_kickを再生する. sample :ambi_drone, rate: [0.25, 0.5, 0.125, 1].choose, amp: 0.25 if rand < 0.125 # randが0.125以下の場合(1/8の確率で)この行を実行する. # ambi_droneを再生速度4種のいずれかで、強さ0.25で再生する. sample :ambi_lunar_land, rate: [0.5, 0.125, 1, -1, -0.5].choose, amp: 0.25 if rand < 0.125 # 同上 ambi_lunar_landを1/8の確率で再生する. sample :loop_amen, attack: 0, release: 0.05, start: 1 - (1.0 / n), rate: [1,1,1,1,1,1,-1].choose # loop_amenを立ち上がり時間0、余韻時間0.05拍、音源の開始位置1 - (1.0 / n)、再生速度は、7種から選ばれる.1/7の確率で、-1となり、逆再生(スクラッチ音)となる. sleep sample_duration(:loop_amen) / n # サンプル音源loop_amenの長さの半分の時間置く. end loop {play_bb([1,2,4,8,16].choose)} # 無限ループの中で、定義された関数をnの値を5種の中から選んで実行する. # 無限ループは、loop{ } とも書ける. # 関数の引数は、( )で囲っても良い.

Acid Walk

in_thread do # 並列実行するプログラム. use_synth :fm # fm 音源を使う sleep 2 # 2拍置く loop do # 無限ループ開始 28.times do # 28回繰り返す sample :drum_bass_hard, amp: 0.8 # サンプリング音源のdrum_bass_hardを強さ0.8で再生する. sleep 0.25 # 0.25拍置く. play :e2, release: 0.2 # 2オクターブ目のEの音を減衰0.2拍で鳴らす. sample :elec_cymbal, rate: 12, amp: 0.6 # サンプリング音源のelec_cymbalを再生速度12倍、強さ0.6で再生する. sleep 0.25 # 0.25拍置く. end # ここまでを28回繰り返す sleep 4 # 4拍置く. end end # メインプログラム use_synth :tb303 # 音源をth303にする with_fx :reverb do |rev| # リバーブを設定する. loop do # 無限ループ開始 control rev, mix: rrand(0, 0.3) # リバーブのmix値を0〜0.3とする with_fx :slicer, phase: 0.125 do # 1/8拍間隔で音をスライスする sample :ambi_lunar_land, sustain: 0, release: 8, amp: 2 end control rev, mix: rrand(0, 0.6) # リバーブのmix値を0〜0.6に変更する. r = rrand(0.05, 0.3) # 余韻長さとするrを0.05〜0.3とする. 64.times do # 64回繰り返す play chord(:e3, :minor).choose, release: r, cutoff: rrand(50, 90), amp: 0.5 # Eのオクターブ3のマイナーコードから1音を任意に選び、余韻長さr、ローパスフィルタのカットオフ音程50〜90、強さ0.5で鳴らす sleep 0.125 end control rev, mix: rrand(0, 0.6) # リバーブのmix値を0〜0.6に変更する. r = rrand(0.1, 0.2) with_synth :prophet do 32.times do sleep 0.125 play chord(:a3, :m7).choose, release: r, cutoff: rrand(40, 130), amp: 0.7 end end control rev, mix: rrand(0, 0.6) # リバーブのmix値を0〜0.6に変更する. r = rrand(0.05, 0.3) 32.times do play chord(:e3, :minor).choose, release: r, cutoff: rrand(110, 130), amp: 0.4 sleep 0.125 end control rev, mix: rrand(0, 0.6) # リバーブのmix値を0〜0.6に変更する. with_fx :echo, phase: 0.25, decay: 8 do # エコーを位相0.25、減衰を8拍とする. 16.times do # 16回繰り返す play chord([:e2, :e3, :e4].choose, :m7).choose, release: 0.05, cutoff: rrand(50, 129), amp: 0.5 sleep 0.125 end # 16回のループはここまで end # 無限ループはここまで end # リバーブはここまで end # tb303音源はここまで

以上、Sonic Piの公式ページのサンプルプログラムの解説




試しに作ってみた小プログラム集

Sonic Piでプッシュフォンのダイアル音を鳴らす. DTMF tone

# DTMF sound (Dual-Tone Multi-Frequency) dial="0123456789ABCD*#" # 鳴らしたいプッシュボタンを文字列で与える hi=[1209,1336,1477,1633] # 高音側の周波数 lo=[697,770,852,941] # 低音側の周波数 pushButton=[["1","2","3","A"], # プッシュボタンの並び ["4","5","6","B"], ["7","8","9","C"], ["*","0","#","D"]] define :dtmfPlay do |d| # d に鳴らしたいボタンの文字が入り、音を鳴らす関数 for i in 0...4 # lo for j in 0...4 # hi if(d == pushButton[i][j]) # 鳴らしたいボタンに一致する並びを調べる play hz_to_midi(lo[i]),attack: 0.05 ,release: 0.3 # 低音側の音を鳴らす、アタックは弱め、余韻は短め play hz_to_midi(hi[j]),attack: 0.05 ,release: 0.3 # 高音側の音を鳴らす(2音は同時に鳴る) end end end end for i in 0...dial.length puts dial[i] dtmfPlay dial[i] # dialの配列から1文字取り出して、音を鳴らす関数を呼ぶ sleep 0.5 # 間隔を与える end


Sonic Piで竹内関数音楽(たらいまわし関数,Tarai,Tak function)

関数(メソッド)を巧みに再帰呼び出ししている関数です。
いろいろな言語で試みられていますが、Sonic Piで記述するのが最も容易だと思われます。

use_bpm 130
define :tarai do |x,y,z|
  a=[:D4,:E4,:F4,:G4,:A4,:B4,:C5,:D5,:E5,:F5,:G5,:A5,:B5]
  2.times do
    puts x,y,z
    play_pattern_timed [a[x+1],a[x+1]+12,a[y+1],a[y+1]+12,a[z+1],a[z+1]+12,a[y+1],a[y+1]+12],0.25
  end
  n=n+1
  if(x<=y)
    return y
  else
    return tarai( tarai(x-1,y,z), tarai(y-1,z,x), tarai(z-1,x,y))
  end
end

tarai 10,5,0


最後のreturn文の()は省けないようです。
関数の定義と呼び出しは、
define :tarai do |x,y,z|
tarai 10,5,0
を
define tarai(x,y,z)
tarai(10,5,0)
と書いても問題ないようです。

参考
Wikipediaの竹内関数
Tarai Function Music aike氏
竹内関数で音楽生成 aike氏
ハッカーの遺言状──竹内郁雄の徒然苔 第18回:問題児も悪くない


再帰呼び出しを使った簡単なプログラム例
最小公倍数(例では12と18の)を求める.
# ( )を使わない表記では、
define :gcd do |a,b|
  return a if b == 0
  gcd b, a % b
end
puts gcd 12,18

# ( )を使う表記では、
def gcd(a, b)
  return a if b == 0
  gcd(b, a % b)
end
puts gcd(12,18)



5行のプログラムで、1000000桁や10000000桁の円周率音楽, Pi Music


いろいろな数字を用いた音楽が作られていますが、その中でも円周率は古くから多くの人によって音楽とされているようです。 Sonic Piでは、Rubyのファイル読み込み機能を使って数字や文字をファイルから簡単に読み込むことができます。 複数行のファイルの場合は、行単位に配列の要素として読み込むことができます。ここでは、円周率を全て1行に並べているテキストファイルを一つの文字列として読み込んで利用しています。
読み込んだ文字列から、一文字づつを取り出して、整数に変換してから値を2倍して、中央のド(MIDIノート番号60)に加えて音程として使用しています。

円周率100万桁が改行なしに入力されている"pi1000000.txt"は、
https://www.angio.net/pi/digits.html から入手できます。
プログラムは、下記の5行と非常に簡単に記述できます。
pi=File.open("ファイル pi1000000.txt へのパス").read  # ファイルの置き場所は任意. デスクトップ等でも可.
for i in 0...pi.length
  play pi.slice(i, 1).to_i*2+60
  sleep 0.125
end
この設定では、演奏の完了には約37時間かかります。

二桁ずつ取り出すなどの改良も容易です。
for i in (0...pi.length).step(2)
  play pi.slice(i, 2).to_i+40
  sleep 0.125
end
なお、3.14の2文字目のピリオドは無視しています。
scaleやchordで音を与えるなどの工夫も容易にできます。

さらに、10000000桁(1000万桁)にしたい場合には、ここから Pi_10000000.txt が入手できます。


5行のプログラムで、素数音楽, Prime Numbers Music

素数の列(2から15,485,863までの100万個)をファイルから読み込み、前後の数値の差をC4に加えて鳴らします。

ファイルの準備
primes1.txt を http://primes.utm.edu/lists/small/millions/primes1.zip から入手して展開して下さい。
macOSのターミナル、Windows10のコマンドプロンプト(bash付), Linux または UNIXのターミナルで下記のコマンドにより、ファイル中の不要な行とスペース、改行コードを削除し、p1.txtファイルを生成します。
sed -e '1,2d' primes1.txt| tr -d '\n'| tr -d '\r'| sed -e 's/ */ /g'> p1.txt
p1.txtは8.2MBになります。

Sonic Piのプログラムは、
prime=File.open("ファイル p1.txt へのパス").read.split(" ")
for i in 0...prime.length-1
  play 60+prime[i+1].to_i-prime[i].to_i
  sleep 0.125
end


AudacityのエコーをSonic Piで

Sonic PiのfxのechoとAudacityのエコーは異なる仕組みで実現されています。Audacityのエコーは、[ディレイ時間]と[減衰ファクター]で設定でき、わかりやすいものでしたので、Sonic Piで同じようなエコーを生じるプログラムを作成してみました。 ディレイ時間によって、残響にも山彦風にもでき、減衰ファクターを1より大きくして発散させることも可能で、変わった音を作成することもできます。 ディレイ時間毎に、元の音に減衰ファクターをかけた音を足し合わせています。ディレイ時間毎に減衰ファクターの掛け合わせられる回数が増えてゆきます。 Audacityのソースリストをの確認したわけではありませんので、異なる場合もあります。
下記の例では、内蔵サンプリング音源のamen loopにエコーをかけていますが、他のファイルにしたい場合には、file=の後ろにファイルをドロップすればフルパスが入力されます。

参考:amenの起源は、The Winstons(1969)の
「Amen Brother」(Youtube)
file= :loop_amen_full			# 音を与える
sampleTime = sample_duration(file)		# 音の長さを調べる
delayTime = 0.2			# ディレイ時間
decayFactorIni = 0.4			# 減衰ファクター
decayFactor = decayFactorIni
sample file
(sampleTime/delayTime).times do
  sleep delayTime
  sample file, amp: decayFactor
  decayFactor = decayFactor * decayFactorIni
end


小鳥のさえずりをSonic Piで

多重起動により、小鳥の群れとすることができます。
2017.7.31 間違いを修正しました。
use_random_seed Time.new.usec				# 乱数の系列をミリ秒によって変える
loop do
  f1=hz_to_midi(rrand(4000, 5000))			# さえずりの高音側周波数の範囲をHzで与えmidi番号に
  f2=hz_to_midi(rrand(1000, 3000))			# さえずりの低音側周波数の範囲をHzで与えmidi番号に
  s= play f1, attack:0.02, sustain:0.2, release:0,
    note_slide:0.1, pan_slide: 0.1, amp:rrand(0.1,2), amp_slide: 0.1	# 高音側の音を鳴らす
  sleep 0.05					# 非常に短く伸ばす
  control s, note: f2, pan:rrand(-1,1), amp:rrand(0.1,2)			# 低音側の音を鳴らす
  sleep 0.05					# 非常に短く伸ばす
  control s, note: f1, pan:rrand(-1,1), amp:rrand(0.1,2)			# 高音側の音を鳴らす
  sleep rrand(0.1,1)					# さえずりの時間間隔は少し長めに
end
ずっと聞いていると、あまり気持ちよくはありません。音量や間隔や周波数に 1/fゆらぎ を取り入れると心地よくなると思われます。(次節)


1/fゆらぎ的カラス

周波数、左右のパン、音量、時間間隔を独立して1/fゆらぎ的(間欠カオス)に変化させたカラスの鳴き声(:misc_crow)です。
周波数はわずかしか動かしていません。
音量と時間間隔には同じ乱数値を使い、時間間隔が短い時には音量が小さ目になるようにしています。

1/f fluctuation, Intermittent Chaos method
use_random_seed Time.new.usec # 現在のミリ秒値で乱数系列を選択
define :x1f do |x|
  if x<0.5
    x=x+2*x*x
  else
    x=x-2*(1-x)*(1-x)
  end
  if x<0.01     # 両端付近の処理.この部分は適当です。
    x=rrand(0.01,0.1)
  elsif x>0.99
    x=rrand(0.9,0.99)
  end
  return x
end
x1=rand;x2=rand;x3=rand # 初期値
loop do
  x1=x1f x1 # 関数 x1fに引数x1を与え、戻り値x1を得る. x1=x1f(x1)と書いてもよい.
  x2=x1f x2
  x3=x1f x3
  # 再生速度の変化0.9〜1.1、左右のパン-1〜1、音量0.5〜1.5、時間間隔0〜2
  sample :misc_crow,rate:0.9+x1/5,pan:x2*2-1,amp:x3+0.5
  sleep x3*2
end



サンプル音をHypercompresするMAXIMIZERをSonic Piで

Loudness War(音圧競争)という、音楽の販売のためだけに音を大きくする競争が今でも(特に日本では)続けられており批判もされています。Audacityでもコンプレッサーやリミッターやマキシマイザーを使うとこのような効果を得ることができますが、Sonic Piでも容易に超圧縮をすることができました。
ampの値を非常に大きするだけで波形がクリップされて"矩形"となることなく振幅が拡大されるため、音割れが殆どない状態で音量を大きくすることができます。
例: ラベルのボレロでは、最初のフルートから巨大な音量とし、後半でフルオーケストラになっても同様の音量とすることができました。

sample "Bolero.wav", amp:100

sample "Bolero.wav", amp:1000
1000でも視聴可能でした.


12以外の平均律で演奏する。n平均律、n Equal Temperament, 微分音 Microtonal music

平均律は、通常12等分(2の12乗根をかけてゆく)が用いられますが、15平均律,31平均律,100平均律などの n平均律が微分音とも呼ばれ、民族音楽や、現代音楽等で用いられているようです。
下記のプログラムでは、通常の演奏データを、nEqualTemperamentの値を他の整数値に変えるだけで平均律の分割数を変更した演奏とすることができます。live_loopを使っているので、一度Runした後、StopせずにnEqualTemperament値を変えて再度Runすると、輪唱の音程が順次変更されてゆきます。
中央のド(C4,60)を基準にして、12平均律の場合のC1からC9の間の音程を生成します。(24とした場合には、中央のドの音程はそのままで、各鍵盤の間にもう一つづつ鍵盤を増やしたことに相当します.)
11平均律や13平均律を聞いていると音感が悪くなるかもしれません。小さすぎる値にすると音が足りなくなる場合があります。差を聞き取れませんが10000平均律でも動作はします。

# n Equal Temperament Music
nEqualTemperament=12    # 12平均律の場合。 この数値を6,10,13,31,100 等、自由に変更して下さい。
A4=440  # Tuning チューニングを変更したい場合
C5=A4*2.0**(3.0/12.0)
C0=C5/(2.0**5)
nET=[]
centerC=nEqualTemperament*4
for i in 0..nEqualTemperament*9
  nET[i]=hz_to_midi(C0*2.0**(i/nEqualTemperament.to_f))
end
# 以上が音程の生成。以下は演奏。
use_synth :tri # 音色 :triを:pianoに変更すれば 微分音ピアノ になります。
use_bpm 160 # 速度
a=[]
b=[]
# かえるのうた Kaeruno uta
a[0]=[:C4,:D4,:E4,:F4,:E4,:D4,:C4] # ドレミファミレド
b[0]=[1,1,1,1,1,1,2]
a[1]=[:E4,:F4,:G4,:A4,:G4,:F4,:E4] # ミファソラソファミ
b[1]=[1,1,1,1,1,1,2]
a[2]=[:C4,:C4,:C4,:C4] # ドドドド
b[2]=[2,2,2,2]
a[3]=[:C4,:C4,:D4,:D4,:E4,:E4,:F4,:F4,:E4,:D4,:C4] # ドドレレミミファファミレド
b[3]=[0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,1,1,2]
# 3部の輪唱で演奏する。
live_loop :lop1 do
  for i in 0...a.length
    for j in 0...a[i].length
      play nET[a[i][j]-(60-centerC)],sustain:b[i][j]*0.9,pan:-1
      sleep b[i][j]
    end
  end
end
sleep 8 # 8拍後に第2パートをスタートする
live_loop :lop2 do
  for i2 in 0...a.length
    for j2 in 0...a[i2].length
      play nET[a[i2][j2]-(60-centerC)],sustain:b[i2][j2]*0.9,pan:0
      sleep b[i2][j2]
    end
  end
end
sleep 8 # さらに8拍後に第3パートをスタートする
live_loop :lop3 do
  for i3 in 0...a.length
    for j3 in 0...a[i3].length
      play nET[a[i3][j3]-(60-centerC)],sustain:b[i3][j3]*0.9,pan:1
      sleep b[i3][j3]
    end
  end
end


曲を「かえるのうた」から、「フレールジャック」に変更する場合には、上記のaとbの配列[0]から[3]の8行を、下記2行に置き換えてください。
# Frere Jacques
a[0]=[:C4,:D4,:E4,:C4,:C4,:D4,:E4,:C4,:E4,:F4,:G4,:E4,:F4,:G4,:G4,:A4,:G4,:F4,:E4,:C4,:G4,:A4,:G4,:F4,:E4,:C4,:C4,:G3,:C4,:C4,:G3,:C4]
b[0]=[1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,2.0,1.0,1.0,2.0,0.5,0.5,0.5,0.5,1.0,1.0,0.5,0.5,0.5,0.5,1.0,1.0,1.0,1.0,2.0,1.0,1.0,2.0]



DNA Genome Music, DNA遺伝子音楽


NHKで放映中の「スーパープレゼンテーション」のキャスターである伊藤穰一氏(MITメディアラボ所長)が、
TED 「How to read the genome and build a human being ゲノムを解読し ヒトを生み出す」リッカルド・サバティーニ
の回で、自らのゲノムを(日本人の公開例が少ないこともあり)公開していると語っていたのでデータを入手し、Sonic Piで音にしてみました。

伊藤穰一氏の遺伝子データの公開ページ
ファイルは、https://my.pgp-hms.org/user_file/download/1789
ファイル中に、塩基のA,G,T,C以外にI,T,-の文字があったので、IをE、TをF、-をBに置き換えて音程にしています。
genome_Joichi_Ito_Full_20160218143309.txt は、大きすぎたので、先頭の1000行を使用。(全576326行のファイルの後ろ側を削除してgenome_Joichi_Ito_Full_20160218143309_1-1000.txtとして使用)
ファイルの最終行に空行を入れないこと.(演奏後にエラーとなります.)

ファイル内の一部の様子(TAB区切りデータの4カラム目が塩基配列です.#で始まる行を読み飛ばして、行の後ろからTABの位置を探しています。)
# rsid chromosome position genotype
rs3094315 1 752566 AA
rs12562034 1 768448 AG


Sonic Piのプログラム
path="各使用環境でのファイルへのpath /genome_Joichi_Ito_Full_20160218143309_1-1000.txt"
d = []
open(path){|f| d = f.readlines}
for i in 0...d.length
  if d[i].index("#")
  else
    puts d[i][d[i].index("\t",-6)+1...d[i].length-1]
    dd=d[i][d[i].index("\t",-6)+1...d[i].length-1]
    for j in 0...dd.length
      ddd=dd[j]
      ddd="D" if dd[j]=="I"
      ddd="E" if dd[j]=="T"
      ddd="B" if dd[j]=="-"
      play ddd
      sleep 0.5   # 音の間隔
    end
  end
end
なお、御本人からTwitterにて,いいねとリツイートをいただいていますので公認と考えれれます。


修正版
最初に作成した上記では、ファイルを全部読み込んでから操作を行っていたので全遺伝子のデータを一度に読み込むことができませんでした。
下記では、1行づつ読み込んでいるので、元のファイル genome_Joichi_Ito_Full_20160218143309.txt をそのまま読み込むことができます。
また、改行コードを.chompで除き、.split("\t")でTAB区切りデータを分割し4要素目の[3]を取り出すようにしました。
塩基配列の記載文字数は、1文字と2文字が混在しています。(もし3文字以上があった場合も動作します.)
if文による分岐の記述方法については、検討の余地があります。

path="ファイルへのパス genome_Joichi_Ito_Full_20160218143309.txt"
File.open(path) do |file|
  file.each_line do |dataLine|
    if !dataLine.index("#")
      d=dataLine.chomp.split("\t")[3]
      for i in 0...d.length
        dd=d[i]
        dd="D" if d[i]=="I"
        dd="E" if d[i]=="T"
        dd="B" if d[i]=="-"
        play dd
        sleep 0.1
      end
    end
  end
end
========================================
DNA遺伝子音楽を宇宙的サウンドにした例 Genome cosmic sounds

上記のプログラムで使用した単音をコードとして使い、先頭音を変えながら上昇(メジャーコード :M )、下降(マイナーコード :m )させています。
コードをより複雑なものに変更するだけでイメージを大きく変えることができます。(:major7, :minor7, :sus4, '7sus4', :dim7等)
ファイルの読み込み方法は修正前のものです。

path="各使用環境でのファイルへのpath /genome_Joichi_Ito_Full_20160218143309_1-1000.txt"
use_debug false
d = []
open(path){|f| d = f.readlines}
with_fx :panslicer do
  for i in 0...d.length
    if d[i].index("#")
    else
      puts d[i][d[i].index("\t",-6)+1...d[i].length-1]
      dd=d[i][d[i].index("\t",-6)+1...d[i].length-1]
      for j in 0...dd.length
        ddd=dd[j]
        ddd="D" if dd[j]=="I"
        ddd="E" if dd[j]=="T"
        ddd="B" if dd[j]=="-"
        ddd=ddd+"3"
        puts ddd
        for k1 in 0..9
          play chord(ddd,:M,num_octaves:3,invert:k1),amp:rrand(0.5,2),attack:0.1
          sleep 0.25
        end
        for k2 in 9.downto(0)
          play chord(ddd,:m,num_octaves:3,invert:k2),amp:rrand(0.5,2),attack:0.1
          sleep 0.25
        end
      end
    end
  end
end



バブルソート音楽、可聴化, Buble Sort Music, Sonification

データを目で見えるようにする手法の"可視化"に対して、音で聴いて耳で判断できるようにすることを"可聴化(
Sonification)"といいます。Sonic Piは可聴化に対しても優れたツールとなります。
ここでは、最も簡単な例としてバブルソートの過程を音として鳴らしてみました。1オクターブの音階を使い、最も悪い並びである逆並びからスタートさせています。
# のコメント行を活かせば、ランダムな音程からスタートできますが、ソートがずっと早く終わります。
nの値を増やすことで、音の数を変えることができます。
音階指定の:majorを他の音階とすることもできます。:minor, :hirajoshi(琴の平調子) 等
nを増やして音数が足りなくなった場合には、scaleのスタート値の60(中央のド)を小さくして、num_octaves:の値を大きくして下さい。
他のソートアルゴリズムと音で比較してみるのも興味深いでしょう。

# Sonification, Buble Sort Music 
n=8  # 音の数
a=[]
for i in 0...n
  a[n-i-1]=scale(60,:major,num_octaves:3)[i]
end
# n*2.times do  # Randomization
#  i=rrand_i(0,n-1)
#  j=rrand_i(0,n-1)
#  a[i],a[j]=a[j],a[i]
# end
for i in 0...n-1
  for k in 0...n
    play a[k]
    sleep 0.1
  end
  puts "-----------"
  sleep 1
  for j in 0...(n-1-i)
    if a[j]>a[j+1] then
      a[j],a[j+1]=a[j+1],a[j]
    end
  end
end
#(n-1).downto(0) do |k|  # 逆順に鳴らす場合下のforの代わりに
for k in 0...n
  play a[k]
  sleep 0.2
end



五度円(五度圏)上を廻るコード

完全五度の関係にある調を順に並べて行くと12の調からなる円になります。隣り合ったコード同士は相性が良く3つ並んだ3コードで曲が作られたりしています。
以下のプログラムでは、Cから始め、左側、現在と同じ、右側、を乱数の-1,0,1で決めてランダムに移動します。移動量は12で割った余りをつかっていますので1オクターブ内を移動します。音はコードで2音ずつ鳴らしています。

# Random walk around on the Circle of Fifth
use_debug false
use_random_seed Time.new.usec
use_synth :pluck
i=0
loop do
  2.times do
    play_pattern_timed (chord 48 + i%12, :major),0.01
    puts i/7, note_info(48 + i%12)
    sleep 0.5
  end
  i=i+(rrand_i(0,2)-1)*7
end

時々、+9または-3して対応するマイナーコード(:minor)(円の内側)にするなども容易にできる改良です。



Gapminderの平均余命データを可聴化

Gapminderは、
NHK スーパープレゼンテーションの初回放送 ハンス・ロスリング(Hans Rosling)「増え続ける世界人口」2012年4月2日 でも紹介され、注目を集めているデータの可視化で社会問題を理解し解決しようというサイトです。参考(本サイト内)
トップページとなっているグラフは、各国の平均余命を縦軸に、個人の収入を横軸に取り、1800年から現在までの変化を点の動きで見ることができ、点の大きさを国の人口、色で地域を表し、5次元データを一つの画面上にわかりやすく可視化した画期的なものです。

データは全て公開されていますので、この中から、日本と英国の平均余命を音にして可聴化を試みてみました。
下記のプログラムでは、日本を左側の英国を右側のスピーカーから、余命を音程に、年度順に、発音のタイミングをずらしてピアノ音で鳴らしています。音程は整数化していないので微分音となっています。(to_fをto_iとすれば平均律の音程になります。)
コメント化しているplay文を使えば、両者の差を音程として鳴らすことができます。
前半は音程が低いので、ノートPCのスピーカーでは聞き辛いと思われます。
音色を変えるだけでも印象が大きく異なります。よりわかりやすく印象的なものとするのは工夫次第です。
国名をCSVファイル内にあるものに変更すれば、他の国々とすることができます。
Perocessingのグラフィックスと連携して、グラフとしての可視化と同時に可聴化することも試してみたいものです。


プログラム
#日本と英国の余命データの可聴化
# Sonification of Japan vs UK Life Expectancy Sounds
use_synth :piano
require 'csv'
path="path to  /indicator life_expectancy_at_birth.csv"
d=CSV.read(path, headers: false)
for i in 0...d.length
  C1=i if d[i][0]=="Japan"
  C2=i if d[i][0]=="United Kingdom" # "United States"
end
for j in 1...d[C1].length
  puts d[0][j]
  #play 72+(d[C1][j].to_f-d[C2][j].to_f)*1.5,amp:3 # play difference
  play d[C1][j].to_f,amp:3,pan:-1 # play JP from left
  sleep 0.1
  play d[C2][j].to_f,amp:3,pan:1 # play UK from right
  sleep 0.1
end

使用したデータファイルは、 "indicator life_expectancy_at_birth.csv" です。
Ruby言語のCSVに関する機能を使用して読み込んでいます。
path= の後ろは、データファイルの置き場所に応じて変更して下さい。

このデータのありかと作成方法
Gapminderの旧版(フラッシュ版)は、XY軸にそれぞれ元データを表示するボタンがありましたが、新版には見当たりませんでした。
データの一覧ページから" Life expectancy (years) "を探します。
Excelファイルとして "indicator life_expectancy_at_birth.xlsx" をダウンロードし、カンマ区切りのCSV形式で保存します。
Excelファイルへの直リンクは、http://spreadsheets.google.com/pub?key=phAwcNAVuyj2tPLxKvvnNPA&output=xls
作成されたCSVファイルの後半の263行から1001行までは、カンマのみのデータでない行なので、テキストエディタ等でこれらの行を削除して保存します。
念のため行末コードをUNIXのLFとして保存したのが、上記ファイルです。

同様に、他の膨大な社会問題についてのデータも同様に入手できますので、可聴化してみるのは興味深いことでしょう。


ピタゴラスのコンマのずれを聞く

ピタゴラスが美しい響きの得られる音程の比率について考察したときに、弦の長さを2/3にした時の響きが美しかったので、この操作を繰り返して得た音階がピタゴラス音階と言われています。五度円は、この2/3倍の音程を時計方向に順に並べたものです。 弦を2/3とすると、音程は1.5倍となりますが、繰り返してゆくと上のオクターブに移動してしまいます。このときには、音程を1/2してオクターブを下げて元のオクターブの中に収まるようにします。これを繰り返して行くと、五度円となり、一周すると元に戻ります。しかし、開始した音程とは完全には一致しません。このずれをピタゴラスのコンマ(Pythagorean Comma)と言っています。
以下のプログラムでは、一周する間の各音を順に鳴らし、最後に元の音と一周後の音のずれを同時に鳴らして、唸りとして聞こえるようにしています。
開始音をC4以外に変更した場合も同様となります。

a=midi_to_hz(:C4) # 開始音
play hz_to_midi(a);sleep 1
b=a
12.times do
  b=b*1.5
  b=b/2.0 if b>a*2
  play hz_to_midi(b);sleep 1
end
puts "Pythagorean comma=",(hz_to_midi(b)-hz_to_midi(a))*100
play [hz_to_midi(a),hz_to_midi(b)],sustain:4  # ピタゴラスのコンマによる唸り



リサージュ図形のいろいろ

Sonic Piでは、左右の音の位相のズレをXY軸としてグラフ表示をしてくれます。
グラフの表示は、[Prefs]ボタンから[ビジュアル]→[Lissajous]をチェック.
左右にpanを振って適当な整数比となる周波数を与えると図形を観察することができます。
release時間(デフォルト設定のまま)によって図形がうまく重なって移行してくれました。

プログラムは、
a=[[600,600],[600,550],[600,500],[600,400],[600,300],[600,200]]
for i in 0...a.length
  play hz_to_midi(a[i][0]),amp:3,sustain:2,pan:-1
  play hz_to_midi(a[i][1]),amp:3,sustain:2,pan:1
  sleep 2
end
配列中の周波数[ , ]の左右を入れ替えると、グラフのXY軸が交換します。panの値の入れ替え(1と-1)でも同様です。

このプログラムの解説とver.2.12の機能を使い大幅に拡張したプログラムの解説したYoutubeビデオを英国のRobin Newmanさんが公開しています。
改良版のコードも公開されています。



Sonic Piによる奏者の発音タイミングデータの活用(Miles Davis "So What")

Miles DavisのSo Whatの冒頭のトランペットソロの部分の演奏を利用しています。

作成方法の概略
1) AudacityまたはSoinc Visualiserのスペクトル表示機能を利用して発音の開始時間をラベルとしてマーク(目視)し、ラベルファイルとして出力します。(テキストファイルが得られます)
下図は、Audacityで読み込んだMilesのソロの出だしのD5,A4,D4の部分にラベルを付けたところ.(マウスでクリックしてcommand+B, Winではcontrol+B)
ここでは、基音よりも2倍音の成分の方が大きく見えており、これは聴感上と一致すると思われますので、基音でなく2倍音の開始位置を選んでラベルを付けています。
3倍音以上も、スケールを変えて目視確認はしましたが、基音または2倍音よりも大きくなることはありませんでした。

2) Excel等で各時間の差をとって横並びにしてカンマで区切り、音符の長さとする。このとき要素の先頭と最後だけは後で調整します。
これが下記の配列bとなります。

3) MIDIデータWebから入手しをMuseScoreで読み込み、演奏に合わせて楽譜を修正します。(このとき、音の長さ、休符は使用しないので考慮するは必要ありません)
MuseScoreで作成されたMilesのソロの先頭部分の例。上記のスペクトルに対応

4) MuseScoreでMusicXML形式に出力し、本サイト内で公開しているProcessingによる変換プログラムでSonic Piの音符に変換します。
5) 出力された音符のデータから休符":r,"を全て削除してから、先頭にのみ加えると下記の配列aが得られます。

6) これらの作業は、一回で音程データと時間データが一致することはありませんでした。演奏させてみて、ずれた部分を探しての修正を繰り返すことになります。
作業1)では、楽譜には記述されない、小さな音を拾うか捨てるか迷うことがありました。この部分は、演奏の解析にも活用できるでしょう。同じ音程の音でも、整数次倍音が優勢な音と奇数次倍音が優勢な音なども観察できます。(トランペットは構造上、奇数次倍音が優勢な楽器と言われています。)


この作業では、音の強さは考慮していません。
#でコメント化してある2行は、別途作成したマイルスの元演奏のソロ開始の少し前から切り出したWAVファイルを同時に再生するためのものです。
この目的のために、配列bの先頭を 5.31秒 と長くしていますので、適宜0.31等に書き換えて下さい。
スペクトルの表示色の設定により音として見える大きさが異なり、また、色の変化から目視で発音のタイミングを得ているので、ある程度の誤差はありますが、元演奏にほぼピッタリと合ったタイミングでSonic Piが演奏してくれます。
スペクトル表示の設定を操作すると、赤く見える部分の大きさが変わります。スペクトル表示前に、コンプレッサ(マキシマイザー)を強くかけて音量を揃えておくのも一つの方法と考えられます。
楽器をpianoにすると、フェイクの様子がより鮮明になります。
完全なソロ演奏の場合は、作業が比較的に容易です。DebussyのSyrinxもデータは作成済みで公開予定(演奏者は、Moyse, Gazzelloni, Galway, Phaud etc.)
OpenSMILEの利用や、Processing等の言語でFFTで音を自動取得するプログラムの作成も検討しましたが、誤差が大きく自動化が難しかったためあきらめました。


use_bpm 60
#f=" Path to the file   So_What_solo.wav"
a=[]
b=[]
a[0]=[:r,:D5,:A4,:D4,:D4,:A4,:G4,:A4,:D4,:D4,:D4,:F4,:A4,:G4,:A4,:D4,:D4,:F4,:A4,:G4,:A4,:B4,:C5,:B4,:C5,:B4,:A4,:F4,:A4,:G4,:A4,:D4,:D4,:D5,:D5,:D5,:D5,:D5,:F5,:D5,:A4,:G4,:F4,:F4,:E4,:F4,:G4,:A4,:Df5,:D5,:E5,:G5,:E5,:D5,:C5,:A4,:G4,:D4,:D4,:Af3,:Ef4,:Df4,:F4,:Af4,:Fs4,:Bf4,:C5,:Df5,:Ef5,:C5,:Bf4,:Bf4,:Fs4,:Af4,:Fs4,:F4,:Af4,:F4,:Ef4,:Ef4,:Bf3,:Df4,:Ef4,:F4,:Fs4,:Af4,:Bf4,:Df5,:D5,:Af5,:D5,:Df5,:C5,:Bf4,:Af4,:G4,:A4,:Df5,:D5,:A4,:A4,:D5,:A4,:D4,:F4,:A4,:D5,:D5,:D5,:F5,:E5,:D5,:A4,:A4,:G5,:E5,:C5,:E5,:G5,:E5,:C5,:C5,:G4,:E4,:C5,:E5,:C5,:E5,:G5,:E5,:C5,:A4,:F4,:Af4,:A4,:D5,:A4,:G4,:F4,:F4,:D4,:F4,:A4,:Df5,:D5,:A4,:G4,:G4,:F4,:A4,:G4,:A4,:D4,:D4,:F4,:A4,:G4,:A4,:C5,:B4,:C5,:B4,:A4,:A4,:Af5,:F5,:Df5,:Bf4,:Af4,:Fs4,:F4,:Ef4,:Ef4,:Df4,:F4,:Ef4,:Fs4,:F4,:Af4,:Fs4,:Bf4,:Af4,:C5,:Bf4,:Df5,:Ef5,:C5,:Af4,:D5,:E5,:F5,:G5,:E5,:C5,:A4,:C5,:E5,:G5,:E5,:C5,:D5,:C5,:B4,:A4,:A4,:D4,:F4,:A4,:G4,:A4,:Df5,:D5,:E5,:C5,:A4,:D4,:F4,:Af4,:A4,:D4,:D4]
b[0]=[5.31,0.804,0.273,2.015,0.295,0.227,0.644,0.223,0.244,1.738,0.122,0.295,0.257,0.358,0.463,0.379,0.063,0.278,0.244,0.404,0.484,0.046,0.665,0.168,0.349,0.303,0.589,0.265,0.185,0.248,0.206,0.278,0.942,0.349,0.273,0.198,2.137,0.564,0.762,0.316,0.324,0.391,0.403,2.989,0.219,0.231,0.135,0.286,0.265,0.326,0.326,0.24,0.614,0.24,0.208,0.185,0.406,0.303,2.865,0.328,0.371,0.109,0.273,0.228,0.209,0.219,0.21,0.202,0.395,0.29,1.035,0.376,0.074,0.909,0.442,0.29,0.252,0.37,0.299,1.935,0.248,0.181,0.24,0.206,0.219,0.21,0.244,0.189,0.429,0.459,0.328,0.177,0.341,0.265,0.177,0.244,0.202,0.252,0.24,0.391,2.259,0.303,0.21,0.265,0.589,2.524,0.387,1.94,0.442,0.888,0.328,0.261,0.341,2.163,0.74,2.676,0.21,0.366,0.438,0.745,0.337,1.59,0.728,2.352,0.417,0.759,0.204,0.244,0.179,0.334,0.566,0.82,0.297,0.258,0.751,0.316,0.285,0.297,0.492,1.611,0.171,0.251,0.238,0.074,0.294,0.411,0.334,2.905,0.169,0.257,0.319,0.461,0.294,0.158,0.241,0.201,0.272,0.619,0.269,0.179,0.247,0.161,0.362,1.803,1.154,0.238,1.544,0.244,0.359,0.411,0.464,0.303,0.628,1.977,0.189,0.269,0.199,0.222,0.223,0.65,0.179,0.136,0.13,0.878,0.436,0.217,0.384,2.19,0.254,0.189,0.272,1.046,1.825,0.73,0.21,0.195,0.167,0.377,0.977,0.418,0.306,0.439,0.167,0.408,2.051,0.176,0.238,0.204,0.213,0.198,0.275,0.217,0.823,0.696,0.49,0.107,0.294,0.186,0.387,0.513,3]
#sample f, amp:3
use_synth :pretty_bell
in_thread do
  for i in 0...a.length
    for j in 0...a[i].length
      play a[i][j], amp:3
      sleep b[i][j]
    end
  end
end
So What(マイルスのソロ部分のみ)
前半2分は、Sonic Piのシンセ:pretty_bellに原曲を重ねて、後半2分は同じ部分を:pianoのみで.



Sonic Piによるドビュッシーのシランクスの演奏。5人の巨匠の比較。Debussy, Syrinx

マルセル・モイーズ Marcel Moyse 0:02- (2m26s)
セヴェリーノ・ガッゼローニ Severino Gazzelloni 2:32- (3m27s)
ジャンピエール・ランパル Jean-Pierre Rampal 6:05- (1m54s)
ジェームズ・ゴールウェイ James Galway 8:04- (2m17s)
エマニュエル・パユ Emmanuel Pahud 10:26- (3m23s).


コードとデータの作製法は、上記のSo Whatのプログラムとほぼ同様ですが、トリルの回数が演奏者によって大きく異なっているので、これにより音の総数も違ってきています。
音のタイミングの取得には、Sonic Visualiserを使用しました。(Audacityのスペクトルは使用せず) 目視によって音の出だしのタイミングをマークして数値として得ていますので、ある程度の誤差を含んでいます。
Youtubeのビデオ中で使用した音は、下記プログラムのampとreleaseとpanを音の長さによって少しだけ変化させるようにしています。
楽器をピアノ(use_synth :piano) とすると、余韻が減るため、一音一音の間隔がより際立って聴こえます。
play a[i][j]+1 というようにして半音上げ等の移調が簡単にできます。(半音上げると尺八で吹きやすくなり、+5程度で鼻笛で吹けるようになりますが、かなりの難曲です。)
使用ソフトウェアは、Sonic Pi, Sonic Visualiser, Audacity(音の切り貼り), MuseScore(楽譜からMusicXMLファイルの作成), ProcessingプログラムでMusciXMLをSonic Piの音符に変換、以上はOpen Source Software
ビデオ化には iMovie (Apple)を使用.

use_bpm 60
a=[]
b=[]
# Marcel Moyse
a[0]=[:r,:Bf5,:A5,:B5,:Af5,:G5,:A5,:Gf5,:F5,:E5,:Df5,:Bf5,:C6,:B5,:Bf5,:Bf5,:A5,:B5,:Af5,:G5,:A5,:Gf5,:F5,:E5,:Df5,:Bf4,:Gf4,:G4,:B4,:Gf4,:G4,:C5,:Gf4,:G4,:Df5,:F5,:E5,:Df5,:Bf4,:Gf4,:G4,:B4,:Af4,:B4,:Df5,:E5,:Af5,:Af5,:B5,:Df6,:Ef6,:Bf5,:Bf4,:A4,:B4,:Af4,:G4,:A4,:Gf4,:F4,:E4,:Df4,:Bf4,:A4,:B4,:Af4,:G4,:A4,:Gf4,:Af4,:Bf4,:Df5,:Ef5,:Gf5,:F5,:Ef5,:Df5,:Bf4,:Af4,:Df4,:Ef4,:Gf4,:Af4,:Bf4,:Df5,:Ef5,:Gf5,:F5,:Ef5,:Df5,:Bf4,:Df5,:Ef5,:Gf5,:A5,:Af5,:G5,:Gf5,:Ef5,:D5,:Df5,:C5,:A4,:Af4,:G4,:Gf4,:Ef4,:Gf4,:F4,:E4,:Ef4,:F4,:E4,:Ef4,:Gf4,:F4,:E4,:Ef4,:Gf4,:F4,:E4,:Ef4,:F4,:E4,:Ef4,:D4,:F4,:E4,:Df4,:C4,:Df4,:Gf4,:A4,:D4,:Gf4,:F4,:D4,:Df4,:Df5,:D4,:F4,:E4,:Df4,:C4,:Df4,:Gf4,:A4,:D4,:Gf4,:F4,:D4,:Df4,:Ef5,:Df5,:B4,:Bf4,:Af4,:Ef4,:Gf4,:Af4,:Bf4,:Df5,:Ef5,:Df5,:Ef5,:F5,:Ef5,:Df5,:B4,:Bf4,:B4,:Df5,:D5,:Df5,:B4,:Bf4,:B4,:D5,:E5,:D5,:B4,:Bf4,:A4,:Af4,:Gf4,:D4,:Gf4,:Af4,:A4,:Bf4,:Ef5,:Df5,:Ef5,:Df5,:Ef5,:Df5,:Ef5,:Df5,:Bf4,:Gf5,:F5,:Gf5,:F5,:Gf5,:F5,:Gf5,:F5,:Gf5,:Bf4,:F5,:Gf5,:Af5,:Bf5,:Bf5,:A5,:B5,:Af5,:G5,:A5,:Gf5,:F5,:E5,:Df5,:Bf5,:Df6,:E6,:D6,:Df6,:Bf5,:A5,:B5,:Af5,:G5,:A5,:Gf5,:F5,:E5,:Df5,:Bf4,:A4,:B4,:Af4,:G4,:A4,:Gf4,:F4,:E4,:Df4,:Bf4,:A4,:B4,:Af4,:G4,:A4,:Gf4,:F4,:E4,:Df4,:Df4,:Gf4,:F4,:E4,:Df4,:A4,:G4,:Df4,:B4,:A4,:G4,:F4,:Ef4,:Ef4,:Df4]
b[0]=[1,1.409,0.109,0.102,0.882,0.114,0.098,0.656,0.338,0.307,0.287,1.393,0.202,0.149,4.689,1.046,0.104,0.083,0.752,0.116,0.08,0.633,0.352,0.237,0.21,1.398,0.21,0.155,2.306,0.433,0.27,0.247,0.201,0.189,0.163,0.06,0.524,0.439,1.052,0.183,0.149,2.21,0.422,0.264,0.216,0.112,0.672,0.166,4.153,1.816,4.538,3.286,1.163,0.109,0.128,0.746,0.125,0.088,0.652,0.409,0.279,0.202,1.18,0.109,0.078,0.594,0.101,0.098,0.566,0.295,0.218,0.19,0.256,0.068,0.502,0.315,0.21,2.503,0.596,0.324,0.284,0.181,0.179,0.148,0.105,0.19,0.052,0.373,0.26,0.202,2.13,0.383,0.164,0.132,0.794,0.109,0.056,0.14,0.658,0.158,0.141,0.087,0.868,0.234,0.172,0.192,0.411,0.058,0.526,0.496,1.543,0.649,0.493,0.29,0.097,0.262,0.278,0.232,0.056,0.463,0.431,0.395,0.095,0.91,1.149,0.571,0.102,0.437,0.326,0.559,0.604,0.742,1.008,0.38,0.064,0.508,0.697,1.809,2.03,0.242,0.108,0.367,0.297,0.541,0.647,0.785,0.949,0.298,0.062,0.394,0.398,1.132,1.966,0.344,0.133,0.124,1.821,0.326,0.195,0.159,0.142,0.115,0.492,0.096,0.081,0.089,0.476,0.275,0.174,1.645,0.339,0.233,0.214,0.17,0.172,0.271,0.189,0.128,0.168,0.087,0.096,0.101,0.096,0.088,0.079,0.127,0.07,0.064,0.095,0.972,0.298,0.08,0.061,0.073,0.062,0.079,0.056,0.095,0.618,0.258,0.088,0.098,0.066,0.074,0.071,0.057,0.067,0.065,0.588,0.081,0.085,0.076,4.246,1.527,0.099,0.081,0.647,0.101,0.093,0.676,0.366,0.222,0.375,1.473,0.285,0.076,0.408,0.222,1.723,0.083,0.103,0.593,0.113,0.086,0.663,0.494,0.385,0.516,0.415,0.219,0.122,0.122,0.115,0.105,0.606,0.344,0.307,0.246,0.419,0.2,0.139,0.128,0.104,0.115,0.601,0.399,0.382,1.91,0.399,0.082,0.582,0.736,3.161,0.662,0.767,3.286,4.132,0.81,0.874,0.866,0.987,0.282,4.946]
use_synth :pretty_bell
in_thread do
  for i in 0...a.length
    for j in 0...a[i].length
      play a[i][j], amp:2.5, release:b[i][j]+0.3
      sleep b[i][j]
    end
  end
end

奏者を変更するには、上記のプログラム中の配列a,bを下記と入れ替えて下さい。
# Marcel Moyse
a[0]=[:r,:Bf5,:A5,:B5,:Af5,:G5,:A5,:Gf5,:F5,:E5,:Df5,:Bf5,:C6,:B5,:Bf5,:Bf5,:A5,:B5,:Af5,:G5,:A5,:Gf5,:F5,:E5,:Df5,:Bf4,:Gf4,:G4,:B4,:Gf4,:G4,:C5,:Gf4,:G4,:Df5,:F5,:E5,:Df5,:Bf4,:Gf4,:G4,:B4,:Af4,:B4,:Df5,:E5,:Af5,:Af5,:B5,:Df6,:Ef6,:Bf5,:Bf4,:A4,:B4,:Af4,:G4,:A4,:Gf4,:F4,:E4,:Df4,:Bf4,:A4,:B4,:Af4,:G4,:A4,:Gf4,:Af4,:Bf4,:Df5,:Ef5,:Gf5,:F5,:Ef5,:Df5,:Bf4,:Af4,:Df4,:Ef4,:Gf4,:Af4,:Bf4,:Df5,:Ef5,:Gf5,:F5,:Ef5,:Df5,:Bf4,:Df5,:Ef5,:Gf5,:A5,:Af5,:G5,:Gf5,:Ef5,:D5,:Df5,:C5,:A4,:Af4,:G4,:Gf4,:Ef4,:Gf4,:F4,:E4,:Ef4,:F4,:E4,:Ef4,:Gf4,:F4,:E4,:Ef4,:Gf4,:F4,:E4,:Ef4,:F4,:E4,:Ef4,:D4,:F4,:E4,:Df4,:C4,:Df4,:Gf4,:A4,:D4,:Gf4,:F4,:D4,:Df4,:Df5,:D4,:F4,:E4,:Df4,:C4,:Df4,:Gf4,:A4,:D4,:Gf4,:F4,:D4,:Df4,:Ef5,:Df5,:B4,:Bf4,:Af4,:Ef4,:Gf4,:Af4,:Bf4,:Df5,:Ef5,:Df5,:Ef5,:F5,:Ef5,:Df5,:B4,:Bf4,:B4,:Df5,:D5,:Df5,:B4,:Bf4,:B4,:D5,:E5,:D5,:B4,:Bf4,:A4,:Af4,:Gf4,:D4,:Gf4,:Af4,:A4,:Bf4,:Ef5,:Df5,:Ef5,:Df5,:Ef5,:Df5,:Ef5,:Df5,:Bf4,:Gf5,:F5,:Gf5,:F5,:Gf5,:F5,:Gf5,:F5,:Gf5,:Bf4,:F5,:Gf5,:Af5,:Bf5,:Bf5,:A5,:B5,:Af5,:G5,:A5,:Gf5,:F5,:E5,:Df5,:Bf5,:Df6,:E6,:D6,:Df6,:Bf5,:A5,:B5,:Af5,:G5,:A5,:Gf5,:F5,:E5,:Df5,:Bf4,:A4,:B4,:Af4,:G4,:A4,:Gf4,:F4,:E4,:Df4,:Bf4,:A4,:B4,:Af4,:G4,:A4,:Gf4,:F4,:E4,:Df4,:Df4,:Gf4,:F4,:E4,:Df4,:A4,:G4,:Df4,:B4,:A4,:G4,:F4,:Ef4,:Ef4,:Df4]
b[0]=[1,1.409,0.109,0.102,0.882,0.114,0.098,0.656,0.338,0.307,0.287,1.393,0.202,0.149,4.689,1.046,0.104,0.083,0.752,0.116,0.08,0.633,0.352,0.237,0.21,1.398,0.21,0.155,2.306,0.433,0.27,0.247,0.201,0.189,0.163,0.06,0.524,0.439,1.052,0.183,0.149,2.21,0.422,0.264,0.216,0.112,0.672,0.166,4.153,1.816,4.538,3.286,1.163,0.109,0.128,0.746,0.125,0.088,0.652,0.409,0.279,0.202,1.18,0.109,0.078,0.594,0.101,0.098,0.566,0.295,0.218,0.19,0.256,0.068,0.502,0.315,0.21,2.503,0.596,0.324,0.284,0.181,0.179,0.148,0.105,0.19,0.052,0.373,0.26,0.202,2.13,0.383,0.164,0.132,0.794,0.109,0.056,0.14,0.658,0.158,0.141,0.087,0.868,0.234,0.172,0.192,0.411,0.058,0.526,0.496,1.543,0.649,0.493,0.29,0.097,0.262,0.278,0.232,0.056,0.463,0.431,0.395,0.095,0.91,1.149,0.571,0.102,0.437,0.326,0.559,0.604,0.742,1.008,0.38,0.064,0.508,0.697,1.809,2.03,0.242,0.108,0.367,0.297,0.541,0.647,0.785,0.949,0.298,0.062,0.394,0.398,1.132,1.966,0.344,0.133,0.124,1.821,0.326,0.195,0.159,0.142,0.115,0.492,0.096,0.081,0.089,0.476,0.275,0.174,1.645,0.339,0.233,0.214,0.17,0.172,0.271,0.189,0.128,0.168,0.087,0.096,0.101,0.096,0.088,0.079,0.127,0.07,0.064,0.095,0.972,0.298,0.08,0.061,0.073,0.062,0.079,0.056,0.095,0.618,0.258,0.088,0.098,0.066,0.074,0.071,0.057,0.067,0.065,0.588,0.081,0.085,0.076,4.246,1.527,0.099,0.081,0.647,0.101,0.093,0.676,0.366,0.222,0.375,1.473,0.285,0.076,0.408,0.222,1.723,0.083,0.103,0.593,0.113,0.086,0.663,0.494,0.385,0.516,0.415,0.219,0.122,0.122,0.115,0.105,0.606,0.344,0.307,0.246,0.419,0.2,0.139,0.128,0.104,0.115,0.601,0.399,0.382,1.91,0.399,0.082,0.582,0.736,3.161,0.662,0.767,3.286,4.132,0.81,0.874,0.866,0.987,0.282,4.946]

# Severino Gazzelloni
a[0]=[:r,:Bf5,:A5,:B5,:Af5,:G5,:A5,:Gf5,:F5,:E5,:Df5,:Bf5,:C6,:B5,:Bf5,:Bf5,:A5,:B5,:Af5,:G5,:A5,:Gf5,:F5,:E5,:Df5,:Bf4,:Gf4,:G4,:B4,:Gf4,:G4,:C5,:Gf4,:G4,:Df5,:F5,:E5,:Df5,:Bf4,:Gf4,:G4,:B4,:Af4,:B4,:Df5,:E5,:Af5,:Af5,:B5,:Df6,:Ef6,:Bf5,:Bf4,:A4,:B4,:Af4,:G4,:A4,:Gf4,:F4,:E4,:Df4,:Bf4,:A4,:B4,:Af4,:G4,:A4,:Gf4,:Af4,:Bf4,:Df5,:Ef5,:Gf5,:F5,:Ef5,:Df5,:Bf4,:Af4,:Df4,:Ef4,:Gf4,:Af4,:Bf4,:Df5,:Ef5,:Gf5,:F5,:Ef5,:Df5,:Bf4,:Df5,:Ef5,:Gf5,:A5,:Af5,:G5,:Gf5,:Ef5,:D5,:Df5,:C5,:A4,:Af4,:G4,:Gf4,:Ef4,:Gf4,:F4,:E4,:Ef4,:F4,:E4,:Ef4,:Gf4,:F4,:E4,:Ef4,:Gf4,:F4,:E4,:Ef4,:F4,:E4,:Ef4,:D4,:F4,:E4,:Df4,:C4,:Df4,:Gf4,:A4,:D4,:Gf4,:F4,:D4,:Df4,:Df5,:D4,:F4,:E4,:Df4,:C4,:Df4,:Gf4,:A4,:D4,:Gf4,:F4,:D4,:Df4,:Ef5,:Df5,:B4,:Bf4,:Af4,:Ef4,:Gf4,:Af4,:Bf4,:Df5,:Ef5,:Df5,:Ef5,:F5,:Ef5,:Df5,:B4,:Bf4,:B4,:Df5,:D5,:Df5,:B4,:Bf4,:B4,:D5,:E5,:D5,:B4,:Bf4,:A4,:Af4,:Gf4,:D4,:Gf4,:Af4,:A4,:Bf4,:Ef5,:Df5,:Ef5,:Df5,:Ef5,:Df5,:Ef5,:Df5,:Ef5,:Df5,:Ef5,:Df5,:Ef5,:Df5,:Ef5,:Df5,:Bf4,:Gf5,:F5,:Gf5,:F5,:Gf5,:F5,:Gf5,:F5,:Gf5,:F5,:Gf5,:F5,:Gf5,:F5,:Gf5,:F5,:Gf5,:F5,:Bf4,:F5,:Gf5,:Af5,:Bf5,:Bf5,:A5,:B5,:Af5,:G5,:A5,:Gf5,:F5,:E5,:Df5,:Bf5,:Df6,:E6,:D6,:Df6,:Bf5,:A5,:B5,:Af5,:G5,:A5,:Gf5,:F5,:E5,:Df5,:Bf4,:A4,:B4,:Af4,:G4,:A4,:Gf4,:F4,:E4,:Df4,:Bf4,:A4,:B4,:Af4,:G4,:A4,:Gf4,:F4,:E4,:Df4,:Df4,:Gf4,:F4,:E4,:Df4,:A4,:G4,:Df4,:B4,:A4,:G4,:F4,:Ef4,:Ef4,:Df4]
b[0]=[1,2.634,0.167,0.189,1.994,0.211,0.167,0.669,0.589,0.4,0.306,2.125,0.386,0.215,5.006,2.121,0.149,0.164,1.841,0.16,0.149,0.659,0.426,0.295,0.204,1.437,0.266,0.178,1.976,0.255,0.193,0.196,0.135,0.164,0.171,0.113,0.462,0.182,1.184,0.275,0.242,2.527,0.367,0.28,0.173,0.16,1.504,0.393,4.391,1.957,3.156,5.761,2.045,0.16,0.142,1.721,0.127,0.196,0.557,0.448,0.44,1.11,1.557,0.196,0.153,1.499,0.226,0.229,0.644,0.378,0.287,0.131,0.335,0.055,0.542,0.324,0.218,2.547,1.055,0.462,0.269,0.211,0.2,0.211,0.156,0.236,0.073,0.531,0.251,0.284,2.638,0.335,0.16,0.138,1.321,0.135,0.171,0.131,1.099,0.167,0.131,0.084,1.31,0.251,0.258,0.233,0.544,0.047,0.569,0.626,2.86,0.731,0.64,0.524,0.071,0.52,0.471,0.362,0.085,0.457,0.74,0.453,0.095,0.524,0.875,0.402,0.095,0.491,0.58,0.653,0.66,0.788,2.097,0.573,0.093,0.728,0.631,2.394,2.92,0.48,0.138,0.653,0.477,0.646,0.604,0.708,1.084,0.564,0.155,0.478,0.349,1.503,2.285,0.282,0.155,0.173,2.363,0.444,0.366,0.278,0.271,0.176,1.133,0.333,0.171,0.136,0.502,0.446,0.313,2.625,0.533,0.346,0.226,0.173,0.204,0.218,0.173,0.085,0.1,0.116,0.122,0.335,0.14,0.182,0.109,0.173,0.12,0.118,0.151,1.946,0.189,0.302,0.073,0.076,0.089,0.047,0.067,0.06,0.058,0.069,0.08,0.055,0.069,0.042,0.082,0.082,1.028,0.126,0.267,0.096,0.062,0.089,0.049,0.095,0.085,0.064,0.095,0.08,0.073,0.069,0.082,0.056,0.096,0.044,0.156,1.403,0.32,0.195,0.233,6.409,3.063,0.18,0.124,1.937,0.124,0.178,0.598,0.491,0.62,1.161,2.172,0.238,0.102,0.606,0.6,3.091,0.207,0.153,1.346,0.162,0.133,0.508,0.484,0.546,1.926,1.01,0.271,0.198,0.196,0.169,0.147,0.469,0.444,0.558,1.963,0.777,0.182,0.151,0.189,0.115,0.135,0.566,0.557,0.906,3.629,0.946,0.236,0.995,1.044,2.703,1.181,1.483,3.866,5.723,1.168,0.951,1.384,2.832,0.819,7.308]

#Jean-Pierre Rampal
a[0]=[:r,:Bf5,:A5,:B5,:Af5,:G5,:A5,:Gf5,:F5,:E5,:Df5,:Bf5,:C6,:B5,:Bf5,:Bf5,:A5,:B5,:Af5,:G5,:A5,:Gf5,:F5,:E5,:Df5,:Bf4,:Gf4,:G4,:B4,:Gf4,:G4,:C5,:Gf4,:G4,:Df5,:F5,:E5,:Df5,:Bf4,:Gf4,:G4,:B4,:Af4,:B4,:Df5,:E5,:Af5,:Af5,:B5,:Df6,:Ef6,:Bf5,:Bf4,:A4,:B4,:Af4,:G4,:A4,:Gf4,:F4,:E4,:Df4,:Bf4,:A4,:B4,:Af4,:G4,:A4,:Gf4,:Af4,:Bf4,:Df5,:Ef5,:Gf5,:F5,:Ef5,:Df5,:Bf4,:Af4,:Df4,:Ef4,:Gf4,:Af4,:Bf4,:Df5,:Ef5,:Gf5,:F5,:Ef5,:Df5,:Bf4,:Df5,:Ef5,:Gf5,:A5,:Af5,:G5,:Gf5,:Ef5,:D5,:Df5,:C5,:A4,:Af4,:G4,:Gf4,:Ef4,:Gf4,:F4,:E4,:Ef4,:F4,:E4,:Ef4,:Gf4,:F4,:E4,:Ef4,:Gf4,:F4,:E4,:Ef4,:F4,:E4,:Ef4,:D4,:F4,:E4,:Df4,:C4,:Df4,:Gf4,:A4,:D4,:Gf4,:F4,:D4,:Df4,:Df5,:D4,:F4,:E4,:Df4,:C4,:Df4,:Gf4,:A4,:D4,:Gf4,:F4,:D4,:Df4,:Ef5,:Df5,:B4,:Bf4,:Af4,:Ef4,:Gf4,:Af4,:Bf4,:Df5,:Ef5,:Df5,:Ef5,:F5,:Ef5,:Df5,:B4,:Bf4,:B4,:Df5,:D5,:Df5,:B4,:Bf4,:B4,:D5,:E5,:D5,:Cs5,:B4,:Bf4,:A4,:Af4,:Gf4,:D4,:Gf4,:Af4,:A4,:Bf4,:Ef5,:Df5,:Ef5,:Df5,:Ef5,:Df5,:Df5,:Bf4,:Gf5,:F5,:Gf5,:F5,:F5,:Bf4,:F5,:Gf5,:Af5,:Bf5,:Bf5,:A5,:B5,:Af5,:G5,:A5,:Gf5,:F5,:E5,:Df5,:Bf5,:Df6,:E6,:D6,:Df6,:Bf5,:A5,:B5,:Af5,:G5,:A5,:Gf5,:F5,:E5,:Df5,:Bf4,:A4,:B4,:Af4,:G4,:A4,:Gf4,:F4,:E4,:Df4,:Bf4,:A4,:B4,:Af4,:G4,:A4,:Gf4,:F4,:E4,:Df4,:Df4,:Gf4,:F4,:E4,:Df4,:A4,:G4,:Df4,:B4,:A4,:G4,:F4,:Ef4,:Ef4,:Df4]
b[0]=[1,1.409,0.106,0.102,0.704,0.078,0.091,0.453,0.337,0.286,0.206,1.517,0.203,0.197,4.995,1.21,0.107,0.093,0.569,0.046,0.102,0.366,0.238,0.248,0.228,1.167,0.216,0.164,1.303,0.206,0.125,0.132,0.08,0.109,0.091,0.091,0.267,0.202,1.176,0.199,0.154,1.162,0.186,0.139,0.077,0.078,1.094,0.229,2.191,1.281,2.624,4.332,1.206,0.126,0.086,0.641,0.103,0.093,0.396,0.367,0.184,0.189,0.659,0.113,0.055,0.267,0.084,0.075,0.234,0.164,0.168,0.122,0.115,0.042,0.282,0.149,0.173,1.29,0.289,0.184,0.215,0.125,0.106,0.104,0.094,0.09,0.057,0.244,0.061,0.123,0.863,0.205,0.106,0.106,0.53,0.073,0.071,0.116,0.235,0.084,0.042,0.115,0.399,0.104,0.055,0.058,0.245,0.052,0.27,0.19,1.38,0.489,0.216,0.189,0.045,0.299,0.181,0.208,0.045,0.332,0.327,0.215,0.087,0.338,0.267,0.158,0.071,0.142,0.183,0.364,0.228,0.251,0.65,0.237,0.051,0.266,0.177,1.387,2.544,0.187,0.094,0.145,0.173,0.342,0.226,0.194,0.319,0.155,0.08,0.193,0.173,0.64,0.955,0.147,0.11,0.103,1.576,0.273,0.109,0.122,0.119,0.086,0.197,0.102,0.039,0.109,0.289,0.268,0.372,1.181,0.245,0.102,0.128,0.118,0.118,0.068,0.119,0.058,0.087,0.015,0.044,0.126,0.131,0.068,0.057,0.058,0.1,0.071,0.048,0.048,0.614,0.112,0.086,0.044,0.078,0.06,0.075,0.084,0.254,0.093,0.046,0.094,0.103,0.077,0.203,0.049,0.046,0.052,1.357,0.993,0.096,0.089,0.315,0.065,0.093,0.345,0.263,0.199,0.373,0.787,0.163,0.049,0.319,0.179,1.338,0.109,0.075,0.491,0.089,0.125,0.47,0.472,0.647,1.337,0.21,0.131,0.118,0.125,0.144,0.1,0.428,0.428,0.451,0.805,0.125,0.152,0.109,0.109,0.125,0.107,0.432,0.457,0.673,2.575,0.325,0.081,0.421,0.393,2.241,0.625,0.58,4.407,4.529,0.572,0.441,0.672,1.399,0.283,7.843]

# James Galway
a[0]=[:r,:Bf5,:A5,:B5,:Af5,:G5,:A5,:Gf5,:F5,:E5,:Df5,:Bf5,:C6,:B5,:Bf5,:Bf5,:A5,:B5,:Af5,:G5,:A5,:Gf5,:F5,:E5,:Df5,:Bf4,:Gf4,:G4,:B4,:Gf4,:G4,:C5,:Gf4,:G4,:Df5,:F5,:E5,:Df5,:Bf4,:Gf4,:G4,:B4,:Af4,:B4,:Df5,:E5,:Af5,:Af5,:B5,:Df6,:Ef6,:Bf5,:Bf4,:A4,:B4,:Af4,:G4,:A4,:Gf4,:F4,:E4,:Df4,:Bf4,:A4,:B4,:Af4,:G4,:A4,:Gf4,:Af4,:Bf4,:Df5,:Ef5,:Gf5,:F5,:Ef5,:Df5,:Bf4,:Af4,:Df4,:Ef4,:Gf4,:Af4,:Bf4,:Df5,:Ef5,:Gf5,:F5,:Ef5,:Df5,:Bf4,:Df5,:Ef5,:Gf5,:A5,:Af5,:G5,:Gf5,:Ef5,:D5,:Df5,:C5,:A4,:Af4,:G4,:Gf4,:Ef4,:Gf4,:F4,:E4,:Ef4,:F4,:E4,:Ef4,:Gf4,:F4,:E4,:Ef4,:Gf4,:F4,:E4,:Ef4,:F4,:E4,:Ef4,:D4,:F4,:E4,:Df4,:C4,:Df4,:Gf4,:A4,:D4,:Gf4,:F4,:D4,:Df4,:Df5,:D4,:F4,:E4,:Df4,:C4,:Df4,:Gf4,:A4,:D4,:Gf4,:F4,:D4,:Df4,:Ef5,:Df5,:B4,:Bf4,:Af4,:Ef4,:Gf4,:Af4,:Bf4,:Df5,:Ef5,:Df5,:Ef5,:F5,:Ef5,:Df5,:B4,:Bf4,:B4,:Df5,:D5,:Df5,:B4,:Bf4,:B4,:D5,:E5,:D5,:B4,:Bf4,:A4,:Af4,:Gf4,:D4,:Gf4,:Af4,:A4,:Bf4,:Ef5,:Df5,:Ef5,:Df5,:Ef5,:Df5,:Ef5,:Df5,:Ef5,:Df5,:Ef5,:Df5,:Ef5,:Df5,:Ef5,:Df5,:Ef5,:Df5,:Ef5,:Df5,:Ef5,:Df5,:Ef5,:Df5,:Bf4,:Gf5,:F5,:Gf5,:F5,:Gf5,:F5,:Gf5,:F5,:Gf5,:F5,:Gf5,:F5,:Gf5,:F5,:Gf5,:F5,:Gf5,:F5,:Gf5,:F5,:Gf5,:F5,:Gf5,:F5,:Gf5,:F5,:Bf4,:F5,:Gf5,:Af5,:Bf5,:Bf5,:A5,:B5,:Af5,:G5,:A5,:Gf5,:F5,:E5,:Df5,:Bf5,:Df6,:E6,:D6,:Df6,:Bf5,:A5,:B5,:Af5,:G5,:A5,:Gf5,:F5,:E5,:Df5,:Bf4,:A4,:B4,:Af4,:G4,:A4,:Gf4,:F4,:E4,:Df4,:Bf4,:A4,:B4,:Af4,:G4,:A4,:Gf4,:F4,:E4,:Df4,:Df4,:Gf4,:F4,:E4,:Df4,:A4,:G4,:Df4,:B4,:A4,:G4,:F4,:Ef4,:Ef4,:Df4]
b[0]=[1,2.337,0.143,0.096,0.789,0.134,0.098,0.6,0.261,0.201,0.19,1.994,0.372,0.281,3.761,1.203,0.123,0.065,0.272,0.102,0.093,0.325,0.19,0.16,0.171,1.203,0.417,0.181,0.836,0.091,0.091,0.145,0.083,0.102,0.367,0.094,0.223,0.198,1.065,0.517,0.23,2.416,0.366,0.138,0.094,0.098,0.923,0.19,2.922,1.673,2.157,4.033,1.092,0.091,0.102,0.232,0.127,0.109,0.555,0.19,0.181,0.189,0.6,0.094,0.089,0.194,0.091,0.085,0.377,0.143,0.134,0.141,0.47,0.083,0.33,0.183,0.225,1.829,0.412,0.412,0.187,0.112,0.114,0.1,0.098,0.414,0.053,0.359,0.145,0.234,1.622,0.379,0.185,0.181,0.595,0.105,0.067,0.127,0.312,0.087,0.145,0.141,0.452,0.149,0.105,0.127,0.321,0.094,0.281,0.274,2.188,0.657,0.457,0.468,0.074,0.39,0.192,0.183,0.04,0.194,0.18,0.176,0.054,0.176,0.196,0.23,0.053,0.221,0.294,0.55,0.386,0.941,1.277,0.463,0.085,0.328,0.321,1.769,2.159,0.526,0.058,0.178,0.283,0.55,0.332,0.557,0.37,0.189,0.051,0.223,0.243,1.339,2.139,0.653,0.23,0.178,2.099,0.317,0.096,0.094,0.074,0.105,0.889,0.134,0.094,0.094,0.423,0.229,0.207,1.696,0.243,0.123,0.141,0.1,0.071,0.089,0.078,0.129,0.087,0.102,0.138,0.143,0.141,0.132,0.098,0.141,0.094,0.096,0.131,1.893,0.196,0.141,0.087,0.077,0.069,0.073,0.076,0.059,0.105,0.058,0.082,0.069,0.076,0.076,0.064,0.066,0.075,0.055,0.074,0.063,0.067,0.06,0.055,0.09,1.364,0.212,0.092,0.093,0.076,0.063,0.073,0.071,0.071,0.067,0.081,0.061,0.08,0.063,0.088,0.087,0.073,0.068,0.076,0.063,0.078,0.066,0.077,0.067,0.086,0.092,0.065,1.498,0.109,0.093,0.136,4.922,1.065,0.1,0.09,0.24,0.089,0.09,0.373,0.229,0.14,0.143,1.53,0.603,0.093,0.744,0.417,1.341,0.096,0.096,0.278,0.094,0.093,0.465,0.323,0.415,0.746,0.455,0.102,0.137,0.129,0.102,0.096,0.37,0.232,0.187,0.561,0.278,0.184,0.098,0.13,0.142,0.096,0.553,0.607,1.021,1.564,0.418,0.055,0.229,0.239,1.848,0.678,0.448,3.482,3.158,0.464,0.514,0.643,2.39,0.536,8.221]

# Emmanuel Pahud
a[0]=[:r,:Bf5,:A5,:B5,:Af5,:G5,:A5,:Gf5,:F5,:E5,:Df5,:Bf5,:C6,:B5,:Bf5,:Bf5,:A5,:B5,:Af5,:G5,:A5,:Gf5,:F5,:E5,:Df5,:Bf4,:Gf4,:G4,:B4,:Gf4,:G4,:C5,:Gf4,:G4,:Df5,:F5,:E5,:Df5,:Bf4,:Gf4,:G4,:B4,:Af4,:B4,:Df5,:E5,:Af5,:Af5,:B5,:Df6,:Ef6,:Bf5,:Bf4,:A4,:B4,:Af4,:G4,:A4,:Gf4,:F4,:E4,:Df4,:Bf4,:A4,:B4,:Af4,:G4,:A4,:Gf4,:Af4,:Bf4,:Df5,:Ef5,:Gf5,:F5,:Ef5,:Df5,:Bf4,:Af4,:Df4,:Ef4,:Gf4,:Af4,:Bf4,:Df5,:Ef5,:Gf5,:F5,:Ef5,:Df5,:Bf4,:Df5,:Ef5,:Gf5,:A5,:Af5,:G5,:Gf5,:Ef5,:D5,:Df5,:C5,:A4,:Af4,:G4,:Gf4,:Ef4,:Gf4,:F4,:E4,:Ef4,:F4,:E4,:Ef4,:Gf4,:F4,:E4,:Ef4,:Gf4,:F4,:E4,:Ef4,:F4,:E4,:Ef4,:D4,:F4,:E4,:Df4,:C4,:Df4,:Gf4,:A4,:D4,:Gf4,:F4,:D4,:Df4,:Df5,:D4,:F4,:E4,:Df4,:C4,:Df4,:Gf4,:A4,:D4,:Gf4,:F4,:D4,:Df4,:Ef5,:Df5,:B4,:Bf4,:Af4,:Ef4,:Gf4,:Af4,:Bf4,:Df5,:Ef5,:Df5,:Ef5,:F5,:Ef5,:Df5,:B4,:Bf4,:B4,:Df5,:D5,:Df5,:B4,:Bf4,:B4,:D5,:E5,:D5,:B4,:Bf4,:A4,:Af4,:Gf4,:D4,:Gf4,:Af4,:A4,:Bf4,:Ef5,:Df5,:Ef5,:Df5,:Ef5,:Df5,:Ef5,:Df5,:Ef5,:Df5,:Ef5,:Df5,:Bf4,:Gf5,:F5,:Gf5,:F5,:Gf5,:F5,:Gf5,:F5,:Gf5,:F5,:Gf5,:F5,:Gf5,:F5,:Gf5,:F5,:Bf4,:F5,:Gf5,:Af5,:Bf5,:Bf5,:A5,:B5,:Af5,:G5,:A5,:Gf5,:F5,:E5,:Df5,:Bf5,:Df6,:E6,:D6,:Df6,:Bf5,:A5,:B5,:Af5,:G5,:A5,:Gf5,:F5,:E5,:Df5,:Bf4,:A4,:B4,:Af4,:G4,:A4,:Gf4,:F4,:E4,:Df4,:Bf4,:A4,:B4,:Af4,:G4,:A4,:Gf4,:F4,:E4,:Df4,:Df4,:Gf4,:F4,:E4,:Df4,:A4,:G4,:Df4,:B4,:A4,:G4,:F4,:Ef4,:Ef4,:Df4]
b[0]=[1,1.583,0.131,0.091,1.437,0.12,0.123,0.651,0.376,0.273,0.516,2.777,0.286,0.18,7.218,1.664,0.136,0.132,1.032,0.091,0.129,0.562,0.328,0.28,0.562,1.712,0.228,0.193,2.572,0.261,0.147,0.274,0.136,0.09,0.422,0.088,0.276,0.37,2.02,0.263,0.137,3.161,0.374,0.218,0.139,0.097,0.869,0.251,3.524,3.245,3.449,6.107,1.401,0.111,0.094,1.027,0.119,0.096,0.459,0.282,0.282,0.51,0.975,0.109,0.124,0.792,0.094,0.098,0.463,0.235,0.229,0.233,0.371,0.089,0.327,0.192,0.227,2.459,0.692,0.422,0.278,0.284,0.184,0.141,0.092,0.133,0.053,0.131,0.094,0.147,1.951,0.424,0.178,0.147,1.014,0.096,0.087,0.097,0.652,0.095,0.088,0.049,1.106,0.103,0.096,0.131,0.694,0.096,0.324,0.424,2.833,0.831,1.026,0.646,0.093,0.451,0.291,0.414,0.051,0.321,0.419,0.587,0.069,0.948,1.855,0.859,0.098,0.371,0.453,0.616,0.6,0.976,1.629,1.018,0.088,0.241,0.376,2.963,3.953,1.061,0.098,0.604,0.359,0.659,0.471,0.88,2.286,0.869,0.092,0.327,0.3,3.049,2.918,0.373,0.139,0.135,1.937,0.392,0.227,0.096,0.1,0.096,0.776,0.135,0.098,0.057,0.514,0.319,0.284,1.894,0.331,0.224,0.296,0.12,0.153,0.224,0.139,0.143,0.229,0.184,0.096,0.229,0.094,0.098,0.129,0.094,0.057,0.082,0.098,1.304,0.184,0.276,0.063,0.078,0.055,0.084,0.055,0.084,0.045,0.043,0.057,0.278,0.929,0.092,0.324,0.104,0.096,0.08,0.051,0.049,0.071,0.063,0.073,0.059,0.059,0.053,0.065,0.057,0.145,1.114,0.324,0.09,0.098,7.888,1.616,0.057,0.092,1.537,0.09,0.094,0.694,0.408,0.382,0.882,1.814,0.455,0.055,0.745,0.416,1.902,0.135,0.1,1.065,0.133,0.102,0.655,0.512,0.835,3.933,0.478,0.229,0.186,0.235,0.178,0.147,0.598,0.416,0.608,1.024,0.504,0.235,0.235,0.229,0.186,0.188,0.741,0.51,0.978,3.222,0.584,0.086,0.524,0.363,3.673,0.927,0.694,6.353,4.145,1.114,0.792,1.298,2.124,0.435,13.131]
オープンソースソフトウェアだけで、このようなデータが作成できますので、音楽や演奏の解析等へのSonic Piのさらなる活用が期待されます。

Sonic Piを離れますが、
X軸を時間、Y軸を音程として5人の奏者を色分けしてプロットすると下記のようになります。まず、全長、最高音の部分、トリルの部分などの位置関係から眺めると興味深いものです。

X:Time , Y:Pitch , Black(Moyse), Red(Gazzelloni), Green(Rampal), Blue(Galway), Magenta(Pahud)

全演奏時間で正規化すると、ある程度類似点が見えてきますが、間の取り方は様々です。

X:Normalised Time , Y:Pitch , Black(Moyse), Red(Gazzelloni), Green(Rampal), Blue(Galway), Magenta(Pahud)

さらに、拡大してフレーズごとに比較するなど試してみると興味深いと思われます。



ランダムな音程が旋律に変化 (Morphing from random to melodies)


ランダムな音程が、だんだんと元の旋律に近づいて行きます。(音のモーフィングとも言えます。)

1) 元となる旋律の音程だけをランダムな音程に置き換えて、ランダムな音程で演奏します。

2) 一音ずつ再度乱数を作り、前回と今回のランダムな音程を比べて、元の旋律に近づいた方を採用して演奏します。(同じ音程だけずれていた場合は上下のずれが反転する場合もあります.)

ずれの絶対値和がゼロ(=元の旋律)になるまで、2)に戻って繰り返します。

CGの
コンピュータ画伯 (情報処理学会誌2017.6)のアイデアを音に適用しました。

下記の例では、Hey Judeの最初の4小節を使っており、ランダムから12回かかって元の旋律になります。
乱数の種の番号(use_random_seed)、乱数の上下限(low,high)の値を変えると様子が変わります。
最後の1音が、なかなか修正されない場合があります。

# Random to Melody by Sonic Pi
use_random_seed 0
use_debug false
use_bpm 180
use_synth :piano
low=:C4.to_i
high=:C6.to_i
# Hey Jude 2 vars
a=[:C5,:A4,:A4,:C5,:D5,:G4,:G4,:A4,:Bf4,:F5,:F5,:E5,:C5,:D5,:C5,:Bf4,:A4]
b=[1.0,2.5,0.5,0.5,0.5,3.0,0.5,0.5,1.0,1.5,0.5,0.5,0.5,0.5,0.25,0.25,2.0]
da=[]
s=0
for i in 0...a.length
  da[i]=(rrand_i(low,high)-a[i].to_i)
  # da[i]=-12  # 一オクターブ下から始まるメロディーに
  # da[i]=-a[i].to_i+60  # 全ての音が :C4 から始まるメロディーに
  play a[i]+da[i], amp:3,sustain:2,release:2
  sleep b[i]
  s+=da[i].abs
end
puts "Object func=#{s}"
while s>0
  sleep 2
  s=0
  for i in 0...a.length
    r=a[i]+rrand_i(-da[i].abs, da[i].abs);
    if ( (a[i]-r).abs <= da[i].abs ) then
      da[i]=(a[i]-r).abs;
    end
    play a[i]+da[i], amp:3,sustain:2,release:2
    sleep b[i]
    s+=da[i];
  end
  puts "Object func=#{s}"
end


コメント行の下記どちらかを生かすと最初のメロディーを指定できます。
# da[i]=-12 # 一オクターブ下から始まるメロディーに
# da[i]=-a[i].to_i+60 # 全ての音が :C4 から始まるメロディーに
2回目からランダムとなるため、あまり面白みがありません。
ランダムの度合いを小さめにする(乱数での音程の変化量を0〜2に制限する)と、よりモーフィング的に聞こえることでしょう。

音程と同様に、時間も変化させると、さらに興味深いと思われます。




最も簡単なライブコーディング体験 (The Simplest Live Coding Experience)


最も簡単なライブコーディングの例

play 60.00, sustain: 30
Runしてから音程を書き換えて、
play 61.00, sustain: 30
再度Run。さらに音程を書き換えて
play 61.20, sustain: 30
再々度Run。これを繰り返します。

上記のようにプログラムを "Run" して音が鳴っている間(30拍伸ばしている)に、60.00 を 60.10 等に書き換えて再度 "Run" します。
続けて、60.20、62.21 等に、70.00、71.05、50.00、51.00 等、次々と書き換えて "Run" し続けると奇妙な音が生成できます。
持続時間は30秒としているので、しばらくすると新たにRunした音が残ってゆきます。
マキシマイザー的な使い方のように、この操作をいくら繰り返して音を重ねても振り切れて音が割れることはないので安心です。

もう一行加えて、音源を左右に振るパン(pan)をランダム(rrand)値として加え

use_random_seed Time.new.usec
play 60.00, sustain: 30, pan: rrand(-1,1)

とすると、ステレオ環境での聴き映えが増します。
リサージュ図形も表示しておくと、変化するので視覚的にも美しく、最初のライブコーディング体験に適当でしょう。
1行目で乱数の系列をRunした時点でのミリ秒(usec)の値でその都度決めています。これがないと、左右のpan値は一定になってしまいます。





LibreOfficeのImpressのサウンドを鳴らす


LibreOfficeのImpressには、MS-OfficeのPowerPointと同様にスライド内で鳴らす音が多数用意されています。
音は、アプリケーション内にWAVファイルとして格納されているので、これを直接Sonic Piで指定して鳴らすことができます。

macOS版のLibreOffice 4.3では、下記のパス内にWAVファイルがあります。
バージョンによってパスは異なるようなので確認が必要です。
下記の例では、パス内にある音ファイルをabc順に再生し続けます。(最後のファイルの後はaに戻ります.)

path="/Applications/LibreOffice.app/Contents/share/gallery/sounds/"
i=0
loop do
  sample path,i
  sleep sample_duration path,i
  i=i+1
end

ファイル名を取得してから配列に入れて利用してみた例は、
s=["apert.wav","apert2.wav","applause.wav","beam.wav","beam2.wav","cow.wav","curve.wav","drama.wav","explos.wav","falling.wav","glasses.wav","gong.wav","horse.wav","kling.wav","kongas.wav","laser.wav","left.wav","nature1.wav","nature2.wav","ok.wav","pluck.wav","roll.wav","romans.wav","soft.wav","space.wav","space2.wav","space3.wav","sparcle.wav","strom.wav","theetone.wav","top.wav","train.wav","untie.wav","ups.wav","wallewal.wav"]
path="/Applications/LibreOffice.app/Contents/share/gallery/sounds/"
for i in 0...s.length
  sample path+s[i]
  sleep sample_duration path+s[i]
  sleep 0.1
end


LibreOfficeのライセンスはGPLですので、音だけを利用してもライセンス上の問題はないと思われます。

Windows10ではWAVファイルが、
C:\Program Files\LibreOffice 5\share\gallery\sounds\
にありましたが、Sonic Piからパスを指定しても鳴りませんでした。(十分な確認はしていません.)
WAVファイルをユーザー領域にコピーして使用すれば鳴ると思われます。



音感テスト(音程について) Check of Pitch Perception. Acoustic Training.

5つの音を鳴らします。
1音だけわずかにずれていますので、何番目がずれているか当ててください。
上にずれている場合と下にずれている場合があります。
5つ鳴った後で、ログに答えが表示されます。

use_debug false
use_random_seed Time.new.usec
n=5 # 鳴らす音の数
d=0.2*(rrand_i(0,1)*2-1) # 音をずらす量
r=rrand_i(0,n-1)
b=rrand_i(60,72) # 音程の範囲
a=[]
for i in 0...n
  da=0
  da=d if i==r
  a[i]=b
  play a[i]+da,release:0.5
  sleep 0.5
end
puts "Ans.= #{r+1}"

乱数を3回使っています。
1.音をずらす方向を音程を上げる方向にするか、下げる方向にするかを指定するために、0か1の乱数を2倍して1を引いて-1か1として利用しています。
2.音を5回鳴らす内の何回目の音程を変えるか。
3.元となる音程をC4〜C5の間から選択。
乱数の系列をプログラムの実行時のミリ秒の値で決めていますので、同じ乱数にはなりません。



等速で変化するポルタメント(Portamento changing with constant speed)

音程が変化する速度を一定としたポルタメントです。
2つの音程の差が大きければ、それに比例して音程の変化時間が長くなります。
音色によっては、音が途切れてしまいますが、:prophetでは、(ビンテージ)スポーツカーのエンジン音がギアシフトで変わるような音になります。
音色を:zawaにするとザワザワがつながり、その速度をbpmによって変えることができます。:mod_tri等もお勧め。

音を伸ばす長さsustain、音程の移動に要する拍数note_slideは、正の値でなければいけないので絶対値dn.absをとっています。
2つの音が同じ音程となってしまった場合には、新たに音程を作り直すようにしています。while内

use_bpm 240
use_synth :prophet
use_random_seed Time.new.usec
n1=rrand_i(48,72)
n2=n1
loop do
  while n1==n2
    n2=rrand_i(48,72)
  end
  dn=n2-n1
  puts n1,n2,dn
  s=play n1, sustain: dn.abs, note_slide: dn.abs, attack:0, release:0
  control s,note:n2
  sleep dn.abs
  n1=n2
end

play文をループの前に置き、control行だけをループ内に入れて、ループ内で note_slide:の値を変化させることができれば、音色によらず連続音とできますが、実現できていません。



パーリンノイズ音楽(Perlin Noise Music)

パーリンノイズ関数とは、コンピュータ・グラフィックスで活用されている、リアルなゆらぎを持っていて、雲や煙など、いろいろな表現に活用されている乱数を発生させる関数です。小さな変化が続き、時々ある程度大きな変化が起きます。
開発者のKen Perlinさんは、この業績によって(映画の)アカデミー技術賞を受賞しています。

下記では単音を鳴らしているだけですが、1D, 2D, 3Dそれぞれで活用されている関数ですので、複数の音と音色、音の長さとしてみるのも興味のあるところです。
プログラミング言語のProcessingでは、noise()という関数名で実装されており、CGに活用されています。

Ken Perlin本人によるプログラムは、ここ
LianさんによりRubyに移植されたプログラムは、ここ
このRubyのプログラムを、そのままSonic Piで利用することができました。

プログラムでは、ピアノの音色で、半音単位の音程にしています。
play 60+a.to_i, sustain:1
# <<<<< の行の値をいじると、乱数値が変わり、音が変わります。


ここから

def fastfloor(x)
  (x > 0 ? x : x-1).to_i
end

def noise(x, y, z)
  # find unit cube that contains point
  x_ = fastfloor(x) & 255
  y_ = fastfloor(y) & 255
  z_ = fastfloor(z) & 255
  
  # find relative x,y,z of point in cube
  x -= fastfloor(x)
  y -= fastfloor(y)
  z -= fastfloor(z)
  
  # compute fade curves for each of x,y,z
  u, v, w = fade(x), fade(y), fade(z)
  
  # hash coordinates of the 8 cube corners
  a = PT[x_] + y_
  aa = PT[a] + z_
  ab = PT[a+1] + z_
  b = PT[x_+1] + y_
  ba = PT[b] + z_
  bb = PT[b+1] + z_
  
  # and add blended results from 8 corners of cube
  lerp(w, lerp(v, lerp(u, grad(PT[aa  ], x  , y  , z  ), grad(PT[ba  ], x-1, y  , z  )),
               lerp(u, grad(PT[ab  ], x  , y-1, z  ), grad(PT[bb  ], x-1, y-1, z  ))),
       lerp(v, lerp(u, grad(PT[aa+1], x  , y  , z-1), grad(PT[ba+1], x-1, y  , z-1)),
            lerp(u, grad(PT[ab+1], x  , y-1, z-1), grad(PT[bb+1], x-1, y-1, z-1)))
       );
end

def fade(t); t * t * t * (t * (t * 6 - 15) + 10); end
def lerp(t,a,b); a + t * (b - a); end
def grad(_hash, x, y, z)
  h = _hash & 15
  u = h<8 ? x : y
  v = h<4 ? y : ((h==12 || h==14) ? x : y)
  ((h & 1) == 0  ? u : -u) + ((h & 2) == 0 ? v : -v)
end

PT_PERM =[ 151,160,137,91,90,15,
           131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23,
           190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,
           88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166,
           77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244,
           102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196,
           135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123,
           5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42,
           223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9,
           129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228,
           251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107,
           49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254,
           138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180    ]
PT = []; (0...256).each { |i| PT[256+i] = PT_PERM[i]; PT[i] = PT_PERM[i] }

# 以上がPerlin Noise関数の定義部分で、いじらずにそのまま用います。
# 以下が演奏部分で、関数にパラメータを与えてから乱数値を得て、playしています。

use_random_seed Time.new.usec  # <<<<<
use_synth :piano
x=rand # <<<<<
inc=0.015 * 3  # <<<<<
loop do
  a=(noise x+inc, x, 0.0 )* 20 # <<<<<
  
  a=-60 if a<-60
  puts a
  play 60+a.to_i, sustain:1
  sleep 0.1
  x=x+inc
end

上記プログラムで、
use_random_seed 0
とし、
inc=0.015 * 3 黒線
inc=0.015 * 5 赤破線
とした場合の乱数値をそれぞれプロットすると、下記のグラフのようになります。




ニュートン法による方程式の解の音楽 (Equation Solving Music, Newton Method)

強力な方程式の解法であるニュートン法を用い、1変数の3次関数を数値微分を使って解き、初期値から収束までの変数値を音として鳴らしています。
初期値によっては、変数値が振動してしまい、収束しにくい関数を例として使用しています。
f(x)=x^3 - 3*x^2 +x +3


xの初期値を-1から1の間でランダムに与え、ループ毎に変数値をx*5+60とした音を鳴らし、収束時にはシンバルを、ループが100以上で収束しない場合にはブザーを鳴らし、その後は新たな初期値から計算を繰り返します。
迅速に2次収束する場合、振動してしまう場合などを音で聞き分けることができます。

use_debug false
define :fun do |x|
  return x**3 -3*x**2 +x +3  # Equation
end

loop do
  x=rrand(-1,1)   # initial value
  lop=0
  f=fun x
  while f.abs>0.00001  # Convergence criterion
    lop=lop+1
    x1=x*1.001
    f1=fun x1
    df=(f-f1)/(x-x1)
    x=x-f/df
    f=fun x
    play 60+x*5 if 60+x*5 >0
    puts "Loop= #{lop}, x= #{x}, ObjectFunc= #{f}"
    sleep 0.25
    sample :drum_cymbal_closed
    sleep 0.25
    if lop>100 then
      puts "##### Diverged ##########"
      synth :square,note: :C3,sustain:2
      sleep 3
      break
    end
  end
  if f.abs<=0.00001
    sample :drum_cymbal_hard,amp:3
    puts "----- Converged ----------"
    puts "Loop= #{lop}, x= #{x}, ObjectFunc= #{f}"
    sleep 1
  end
end

2変数以上の問題を、Newton-Raphson法で解き、複数の音を鳴らしてみるというのも興味深いと思われます。



波形アートの作成法 (Making of Sound Wave Art)

サウンド・アート、Sound Art, Soundwave Art, Waveform Art

Sonic Piは使いませんが、本家のタイトル "Sonic Pi, The Live Coding Music Synth for Everyone" の読み上げ音声をアートにして見ました。
概要
I) 何らかの音を用意。必要に応じてAudacityで編集。ここではmacOSのsayコマンドを利用
II) pythonプログラムのwav2vecを使ってwavファイルをSVGファイルに変換する。Python言語についての知識は必要ありません。
III) SVGファイルをInkscapeで読み込んで編集/加工する。

詳細
1) 読み上げは、(これだけはプロプライエタリーですが)macOSのsayコマンドで、読み上げのwavファイルを作成。(声を日本語用にすれば日本語の読み上げもでき、多数の言語に対応)
Sonic Piでの録音、他の音源でもなんでも可。

macOSのターミナルでは、
say Sonic Pi - The Live coding Music Synth for Everyone -o SonicPi.wave
注:wavファイルの拡張子は.waveとする必要があるようです。
声を変えたい場合には、[システム環境設定]→[音声入力と読み上げ]→[テキスト読み上げ]→[システムの声]を変更します。

2) macOSには初めからpythonが入っているので、インストールの必要はありません。Windowsでは別途インストールが必要で、その後、パスの設定等をすれば、コマンドプロンプトで同様に使用できると思われます。(以下はmacOSの場合の例です。)
GitHubのCristoperさんのwav2vecからPython言語のwav2vecプログラムを入手します。(他にpipコマンド等の環境を構築していれば直接実行できるプログラムを入手することもできます。)
ページ内の緑色ボタン[Clone or download]→[Download ZIP]からダウンロードします。
展開すると、[wav2vec-master]というフォルダができます。
フォルダを適当な場所に移動するか、または、そのままダウンロードフォルダに置いたままでも使用できます。
(pythonに対して、実行されるwav2vecプログラムの位置と、入力されるwavファイルの位置を正しく指定することによって、実行後にsvgファイルが得られます。) ターミナルで、キーボードからcdとその後ろに半角スペースを入力してから、フォルダをターミナル画面にドロップし(自動的にフォルダのフルパスが入力されて)、returnキーを押すと、ターミナルのカレントディレクトリが、wav2vec-masterに移動します。
MP3等の音源を使う場合には、Audacity等でWAVに変換しておく必要があります。

音のファイルSonicPi.waveもこのフォルダ内に移動してから、

python wav2vec.py --downtoss 10 SonicPi.wave > SonicPi.svg

とすると、ベクトルグラフィックスのSVG形式のファイルが生成されます。(他のフォルダに生成されるかもしれません)
ここで、パラメータの --downtoss 10 は、サンプリング点を1/10に減らすという指定です。
指定しない場合、通常のCD等の音源のサンプリング周波数44.1kHzの場合、図にした時に1秒間で44100個のノードが生成するため、点の数を減らさないと図の編集が困難になる場合があります。

10分程度の音楽等でも。downtossを1000程度にすれば1MB程度のSVGファイルに変換でき、利用可能です。

3) SonicPi.svgをInkscapeで読み込みます。(Illustrator等でも可)

3-1) 波形を横に伸ばして適当なサイズにします。(先にwav2vecで出力サイズを指定しておくことも可)

3-2) この図は、一つのオブジェクトとなっているので、メニューの[パス]→[オブジェクトをパスへ]によって、パスに変換します。(なぜか、この操作で自動的に線が細く表示されるようになることがありました。)元がステレオ音の場合は、左右チャンネルの波形がグループ化されているので、先に[グループ解除]します。
3-3) 必要に応じて[ノードツール]を選んで(下図)、不要部分を消します。(この場合末尾の無音部分を消去)1/10に減らしているとはいえ、膨大な数のノードが見えます。

3-4) ストロークにグラデーションをかけます。(注意:塗り色(フィル)のグラデーションではありません。)
3-4-1) 波形を選択してから、[フィル/ストローク]を開き、[ストロークの塗り]から[線形グラデーション]のマークをクリックします。
3-4-2) 次に、画面左下にある[グラデーションツール]を選択すると、波形上に左右方向にグラデーション設定の赤線が現れます。
3-4-3) 赤線の左端の四角形をクリックして、パレットで適当な色を与えます。
3-4-4) 赤線の適当な場所で、線の真上をダブルクリックすると、ダイヤマークが現れるので、パレットで色を与えるとグラデーションの中間点の色とできます。この点はドラッグして左右に移動できます。これを繰り返して複数色のグラデーションを作成します。線の両端を移動して斜め方向や、縦方向のグラデーションとすることもできます。放射状のグラデーションにもできます。

3-4-5) [オブジェクトの変形に従ってグラデーションも変形]のボタンを押しておきます。図の3番目のボタンです。これを押していないと、波形を移動してもグラデーション設定が移動しないので、グラデーションが変わってしまいます。

4) Copy&Pasteまたは複製で3〜4つにします。
5) [フィルター]→[散乱]→[葉っぱ]等で飾ります。(葉っぱの大きさは線の太さに依存します.)
・わずかに[ぼかし]て少し拡大し、下側に影として置く。
・[フィルター]→[リッジ]等で飾る。
・透明度を変える。
など、いろいろ試して重ねる順番なども検討します。
・背景に四角形置いて背景色を与える、写真等を置く、写真を波形でマスクする等も効果的です。
・パスの両端が開いているので、それを繋げて、塗り色を与えるのも効果的でしょう。塗り色の代わりにパターンを使うこともできます。
・[パスの簡略化]は、4回程度ならば波形が原型をとどめていました。
・ノードを表示して全てを選択して[選択ノードの種類を対称に]とすると曲線化して下記のようになり、これも活用できそうです。(今回は利用せず.)


6) 文字を入力します。
完成ファイルの例は、Inkscape SVG file (このファイルは、ブラウザでは表示されない場合があります。完成波形は枠外に置いてあります。右クリックで保存してからInkscape等で開いてください。)

作成した図は、ベクトルグラフィックスですので、拡大による劣化はなく、カラー印刷してポスター化することもできます。
Sonic Piでの録音、自分の声や歌、楽器演奏など何でも音を波形のアート風にできます。プレゼントにも適しています。
音の加工とグラフィックを融合したワークショップなどにも適当でしょう。
2017年10月現在、Googleでのwav2vecのヒット数は 23件であり、日本語はゼロでしたので、しばらくは希少性もあるでしょう。

さらにSonic Piから離れますが、
他の数値データ、グラフ等をSVG化してInkscapeで読み込みグラフィックス化するということも、Processing言語で描画後、SVGファイルとして出力することにより、容易にできます。
ellipseやrectは楕円や長方形のオブジェクトとなり、strokeとfillが別々に生成されます。beginShape(),endShape()で生成した折れ線等は一つのパスとして生成されます。Inkscape上でグループ解除すれば加工が容易にできます。SVGファイルの生成は、beginRecordを使うか、またはcreateGraphicsを使うなどでできます。


参考
このような波形アートの作成サービスをしているサイトもあります。
Voice Art Galley (何年か前にここを見つけ、オープンソースだけを使って、さらに容易な手順で実現したかったのがきっかけ.)
Waveform Artist - MP3 to Waveform Poster
SOUNDVIZ
BespokenArt

さらに手の込んだアート作品は、
SoundWaves ART




将棋の棋譜の音楽化 (Shogi Music)

音楽プログラミング言語Sonic Piによって将棋の棋譜ファイル(CSA標準形式)を読み込み、音楽にしました。

Youtubeに掲載したビデオでは、現在旬と思われる4つの棋譜を連続して演奏しています。
1.藤井聡太(四段) vs 佐藤天彦(名人)
2.藤井聡太(五段) vs 羽生善治(竜王)
3.藤井聡太(六段) vs 杉本昌隆(七段) 師弟対決
4.PONANZA vs 佐藤天彦(名人) コンピュータ側の勝利

棋譜は盤面の形で、画面右下のログ内にテキストで表示されます。ログの表示領域のサイズを調整すると、静止した画面上で駒の動きを観察できます。

OpenShot Video Editorで作成

棋譜には、CSA標準ファイル形式<.A>を用いました。(半角英数だけで表示できて簡便なのを利点と考えて採用)
CSA棋譜ファイルは
将棋DB2等から入手できます。
将棋DB2では、棋譜表示画面の左下の [棋譜の書き出し]->[CSA形式] で表示しで、コピーし、保存したファイルがそのまま読み込み用に使用できます。
棋譜ファイルのサンプルは、Sample_Shogi_kifu.txt (中央の歩だけが動いて投了)

・駒の動きのX座標の値を音程として、移動の前後を連続変化させた音として鳴らしています。同時に重ねてY座標についても鳴らしていますので、このままではXとYの区別はつきませんが、少しずらして鳴らすなどでは聴感上あまり効果がありませんでしたのでそのままにしています。
・駒の種類によって音色を変えています。
・成駒には、ディストーションをかけています。
・相手の駒を取った場合と、駒台からの打駒の場合は、別の音も鳴らしています。
・先手を左側から、後手を右側のスピーカーから鳴らしています。
座標の変化を聞き分けるのは容易でなく、また序盤戦の棋譜は似ているため、どれもかなり類似しています。(Ponanzaは少し異なります.)
音の鳴らし方、音色等はまだまだ考慮不足です。
当初は、音を聞いただけで盤面が想定可能となるような可聴化も念頭にありました。
同様の手順で、囲碁やチェスの棋譜も容易に音として活用できます。

ソースコードは、まだバグが残っていると思われますが、
==========
# SonicPiによる将棋の棋譜ファイルの演奏
# Shogi game record music by Sonic Pi,  2018.4.1 Hiroshi Tachibana

# 棋譜データを読み込み、駒の動きを音にします。
# Sonic Piのログ表示領域を適当なサイズにしておくと、棋譜をテキストとして、盤面が静止した状態で観察しながら音を聞くことができます。
# 棋譜には、"CSA標準ファイル形式"を用います。(半角英数だけで表示できて簡便なのを利点と考えて採用)
# http://www.computer-shogi.org/protocol/record_v22.html

# 将棋盤は、右上が一1、左下が九9
# 一手の前後の動きのXY座標をそれぞれ、座標変化をポルタメントで変化させた2つの音として同時に鳴らし、先手の音を左側(pan:-1)、後手の音を右側(pan:1)としています。
# 駒の種類によってsynthの音色を変えています。成駒にはディストーションをかけました。
# 相手の駒を取った場合と駒台から打った場合には、特に別の音も鳴らしています。

# CSA規格中、盤面座標の数字は移動前と移動後の4桁連続のみ場合しか扱っていません。
# 対局データの開始は、先頭文字が%でなくなった時にしています。
# 最終行の判定は、先頭文字の+-が、%になった時にしており、途中に%行があるとそこで停止してしまいます。

# 棋譜ファイルの形式は CSA標準で、将棋DB2 https://shogidb2.com/ 等から入手できる。
#   棋譜表示画面の左下の [棋譜の書き出し]->[CSA形式] で表示し、コピーして保存する.
path="藤井聡太 四段 vs. 佐藤天彦 名人 第11回朝日杯将棋オープン戦本戦.csa"
#path="藤井聡太 五段 vs. 羽生善治 竜王 第11回朝日杯将棋オープン戦準決勝.csa"
#path="藤井聡太 六段 vs. 杉本昌隆 七段 第68期王将戦一次予選.csa"
#path="Ponanza_佐藤名人.txt"

use_bpm 80       # 速度の設定
use_debug false

# 9×9の2次元配列の作成。
ban=Array.new(9,"   ")
ban.length.times{|i|
  ban[i]=Array.new(9,"   ")
}

#XY=[:C4,:D4,:E4,:G4,:A4,:C5,:D5,:E5,:G5] # XY座標の音程
XY=[:E3,:G3,:C4,:E4,:G4,:C5,:E5,:G5,:C6] # XY座標の音程
komaS=["FU","TO","KY","NY","KE","NK","GI","NG","KI","KA","UM","HI","RY","OU"]
# 駒の種類による音色、成り駒には、distortionをかける
komaSound=[:beep,:beep,        # 歩 FU,NF
           :blade,:blade,      # 香車 KY,NY
           :chipbass,:chipbass,# 桂馬 KE,NK
           :tri,:tri,          # 銀 GI,NG
           :square,            # 金 KI
           :mod_tri,:mod_tri,  # 角 KA,UM
           :mod_saw,:mod_saw,  # 飛車 HI,RY
           :zawa]              # 王 OU

d=[]
open(path){|f| d = f.readlines}
i=0
while(d[i].slice(0,1) != "+")  # 駒の初期配置を読み込む。+で先手の手が始まる前までのPで始まる9行。
  if d[i].slice(0,1)=="P" then # 行の先頭がP
    k=d[i].slice(1,1).to_i-1
    ban[8][k]=d[i].slice(2,3)
    ban[7][k]=d[i].slice(5,3)
    ban[6][k]=d[i].slice(8,3)
    ban[5][k]=d[i].slice(11,3)
    ban[4][k]=d[i].slice(14,3)
    ban[3][k]=d[i].slice(17,3)
    ban[2][k]=d[i].slice(20,3)
    ban[1][k]=d[i].slice(23,3)
    ban[0][k]=d[i].slice(26,3)
    #   駒の初期配置の表示
    # puts k+1,ban[8][k], ban[7][k] ,ban[6][k] ,ban[5][k] ,ban[4][k] ,ban[3][k] ,ban[2][k] ,ban[1][k] ,ban[0][k]
  end
  i=i+1
end
puts
# 駒のない位置は、スペースとする
for ii in 0..8
  for jj in 0..8
    ban[ii][jj]="   " if ban[ii][jj]==" * "
  end
end

# 駒の全体配置を表示する
puts 0  # 手数
for ii in 0..8
  puts ban[8][ii],ban[7][ii] ,ban[6][ii] ,ban[5][ii] ,ban[4][ii] ,ban[3][ii] ,ban[2][ii] ,ban[1][ii] ,ban[0][ii]
end

#ファイル中の位置jを先手の初手の位置に移動する。
j=i+1

while(d[j].slice(0,1) != "%")
  # puts j-i,d[j]  # 手数、棋譜での表記
  sente=true if d[j].slice(0,1)=="+"  # +で始まる行が先手の手
  sente=false if d[j].slice(0,1)=="-" # -で始まる行が後手の手
  
  pos1=d[j].slice(1,2) # 移動前の位置
  pos2=d[j].slice(3,2) # 移動後の位置
  koma=d[j].slice(5,2) # 移動後の駒(成っている場合もある)
  
  # 駒の音色
  km=99
  for k in 0...komaS.length
    if ban[pos1.slice(0,1).to_i-1][pos1.slice(1,1).to_i-1].slice(1,2) == komaS[k] then
      km=k
      # puts "===",ban[pos1.slice(0,1).to_i-1][pos1.slice(1,1).to_i-1].slice(1,2),komaS[k],km,k
    end
  end
  
  sleep 0.5
  
  panVal=-1 if sente  # 先手の音を左側から出すためのpan
  panVal=1 if !sente  # 後手の音を右側から出すためのpan
  
  use_synth komaSound[km]
  # 成り駒の場合は、distortionをかける
  # 駒台からの打駒の場合
  if(pos1.slice(0,1).to_i-1==-1) then
    play :C7,amp:2
    play :C3,amp:3
    sleep 0.2
    # 通常の駒の移動の場合
  else
    # 成駒の場合
    if(km==1 || km==3 || km==5 || km==7 || km==10 || km==12) then
      with_fx :distortion,distort:0.9 do
        x=play XY[pos1.slice(0,1).to_i-1],pan:panVal,note_slide:0.75,sustain:1 # 移動前のX座標の音
        y=play XY[pos1.slice(1,1).to_i-1],pan:panVal,note_slide:0.75,sustain:1 # 移動前のY座標の音
        sleep 0.25
        control x,note:XY[pos2.slice(0,1).to_i-1],pan:panVal # 移動後のX座標の音
        control y,note:XY[pos2.slice(1,1).to_i-1],pan:panVal # 移動後のY座標の音
        sleep 0.25
      end
    else
      # 成っていない駒の場合
      x=play XY[pos1.slice(0,1).to_i-1],pan:panVal,note_slide:0.75,sustain:1 # 移動前のX座標の音
      y=play XY[pos1.slice(1,1).to_i-1],pan:panVal,note_slide:0.75,sustain:1 # 移動前のY座標の音
      sleep 0.25
      control x,note:XY[pos2.slice(0,1).to_i-1],pan:panVal # 移動後のX座標の音
      control y,note:XY[pos2.slice(1,1).to_i-1],pan:panVal # 移動後のY座標の音
      sleep 0.25
    end
  end
  
  # 相手の駒を取った場合(移動後の場所が最初から空でなかった場合)高音とドラムを鳴らす
  if ban[pos2.slice(0,1).to_i-1][pos2.slice(1,1).to_i-1] !="   " then
    use_synth :dpulse
    (play 84,pan:panVal; sample :drum_snare_hard,pan:panVal) if sente
    (play 96,pan:panVal; sample :drum_cymbal_hard,pan:panVal) if !sente
    # sleep 0.2
  end
  # 打駒の場合
  if pos1=="00" then
    ban[pos2.slice(0,1).to_i-1][pos2.slice(1,1).to_i-1]="+"+koma if sente # 打駒の場合、先手では先頭に+をつけて駒を移動後の場所に
    ban[pos2.slice(0,1).to_i-1][pos2.slice(1,1).to_i-1]="-"+koma if !sente# 打駒の場合、後手では先頭に-をつけて駒を移動後の場所に
  else
    ban[pos2.slice(0,1).to_i-1][pos2.slice(1,1).to_i-1]="+"+koma if sente # 打駒でない場合、駒を移動後の場所に
    ban[pos2.slice(0,1).to_i-1][pos2.slice(1,1).to_i-1]="-"+koma if !sente # 打駒でない場合、駒を移動後の場所に
  end
  
  ban[pos1.slice(0,1).to_i-1][pos1.slice(1,1).to_i-1]="   " if pos1!="00" # 打駒でない場合には、移動元の場所は空にする。
  
  # 駒の全体配置を再表示する
  puts j-i,d[j]  # 手数、棋譜での表記
  for k in 0..8
    puts ban[8][k],ban[7][k] ,ban[6][k] ,ban[5][k] ,ban[4][k] ,ban[3][k] ,ban[2][k] ,ban[1][k] ,ban[0][k]
    #puts ban[0][k],ban[1][k] ,ban[2][k] ,ban[3][k] ,ban[4][k] ,ban[5][k] ,ban[6][k] ,ban[7][k] ,ban[8][k]
  end
  j=j+1
end



2つの交差したポルタメント (Two Intersected Portamentos)

2つの音がそれぞれ別々の音色で、別々の音程に連続変化します。
将棋の駒の移動時にX,Y座標をずらしたポルタメントで鳴らしXとYが区別できるようにするために作成しましたが、採用しませんでした。
下記のプログラムは、図のように変化の開始点をずらして、音程を変化させています。
縦軸は、MIDIノート番号、横軸は拍


わかりやすいように拍毎にハイハットシンバルを鳴らしています。
in_thread do
  6.times do
    sample :drum_cymbal_closed
    sleep 1
  end
end
use_synth :beep
x = play 60, sustain: 5, note_slide:3
use_synth :saw
y = play 72, sustain: 5, note_slide:1
sleep 1
control x, note:72
sleep 1
control y, note:60
sleep 3





囲碁の棋譜の音楽化 (Go Game Music)

囲碁の棋譜ファイル(SFG形式)を読み込み、音楽にしました。
使用した棋譜は、
Google Alpha Go vs リ・セドル(李世石,Lee Sedol) 2016年3月15日の3連戦の最終局
Google Alpha Go vs 柯潔(Ke Jie) 2017年5月27日の3連戦の最終局

先手黒番Bを左側から、後手白番Wを右側スピーカーから出力しています。
X座標をpianoで鳴らし、直後にY座標をpluckの音色で鳴らしています。
BGM には、Sonic Piのトップページにあるサンプルプログラムの Ocean Waves を使わせてもらいました。
碁石の情報の全てを音にしているので、音を解析して棋譜に戻すことも原理的には可能であり、棋譜の可聴化とも言えます。

画面右下に表示されるログファイルの表示サイズを調整することにより、静止した状態で棋譜表示を眺めることができます。

OpenShot Video Editorで作成

棋譜は、碁遊庵の棋譜ダウンロードから入手しました。
ハンデや、手順のパスは扱っていません.
直接棋譜に書かれていない、囲われた石を取り除く等の処理はしていません.
( による棋譜の階層構造は判定していません。
手が;で始まるように書かれていて、さらに行頭にある手の場合も;で始まっていないと正常に読み込みません。
従って、行頭が;で始まっていないSGFデータ(例:人間の知識を必要としなくて最強のAlphaZeroの棋譜 DeepMind社のNature論文のSupplementary informationとして公開されている) などは、行頭の手が読み込まれません。(改行コードを全て削除して全データを1行にするなどで対応可)

使用する音は、音階scaleで指定しています。ここでは、琴の「六段の調」などで使われている平調子(hirajoshi)を採用しているので、"和"の雰囲気になっています。
Sonic Piで用意されているScaleを変更することにより、雲井調子(kumoi)、岩戸調子(iwato)他、世界中のいろいろな音階に変えることが容易にできます。

黒がB、白がW、碁盤の左上がaaで、右下がssです。
ログ領域のテキスト表示は、黒を0、白をC、盤上の9点をoで、その他を. で表しています。

ソースリスト
==========
path="/各PCでのパス/李世石-AlphaGo-20160315.sgf" # 棋譜ファイルをpath=の後ろにドロップすれば、入力されます。
#path="/各PCでのパス/AlphaGo-柯潔-20170527.sgf"

use_bpm 160   #  速度
use_debug false
scaleName=:hirajoshi #与えるスケール (平調子)   :kumoi :iwato :egyptian :bartok など変更可

# 19×19の2次元配列の作成。 SGFファイルでは、1-19は、a-sと表される.左上が原点
ban=Array.new(19," ")
ban.length.times{|i|
  ban[i]=Array.new(19," ")
}
for i in 0...19
  for j in 0...19
    ban[i][j]="."
    ban[i][j]="o" if (i==3 || i==9 || i==15) && (j==3 || j==9 || j==15) # 盤上の9箇所の黒点の位置
  end
end

te=0 # 手数表示用変数

# 初期盤面の表示
puts te
for i in 0...19
  ban1L=""
  for j in 0...19
    ban1L=ban1L+ban[i][j]+" "
  end
  puts ban1L
end

# BGM の Ocean Waves( copied from https://sonic-pi.net/ )
in_thread do
  with_fx :reverb, mix: 0.5 do
    100.times do
      s = synth [:bnoise, :cnoise, :gnoise].choose, amp: rrand(0.1, 0.3), attack: rrand(0, 4), sustain: rrand(0, 2), release: rrand(1, 3), cutoff_slide: rrand(0, 3), cutoff: rrand(60, 80), pan: rrand(-1, 1), pan_slide: 1
      control s, pan: rrand(-1, 1), cutoff: rrand(60, 115)
      sleep rrand(2, 3)
    end
  end
end

f=File.open(path).read   # pathで指定された外部棋譜ファイルを開く
for i in 0...f.length
  # データの文字の順番が、;、BまたはW、[、2文字開けて]となった場合に手とみなします。
  if f.slice(i, 1)==";" && (f.slice(i+1, 1)=="B" || f.slice(i+1, 1)=="W") && f.slice(i+2, 1)=="[" && f.slice(i+5, 1)=="]" then
    x=f.slice(i+3, 1).ord-97 # ASCII文字を数値に aは97
    y=f.slice(i+4, 1).ord-97 # ASCII文字を数値に
    # 先手Blackの場合の盤面文字の設定と音 pan:-1
    if f.slice(i+1, 1)=="B" then
      ban[y][x]="C"
      use_synth :piano  # 音色の指定B
      # scaleNameで指定されたの音階に従って鳴らす.(音階によって1オクターブ内の音数の多少(3-12)があるため、開始音を上下する必要あり)
      play scale(:C3, scaleName, num_octaves: 7)[x],pan: -1,sustain:1 # C3で始まる7オクターブのscaleの中からx番目の音を取り出して鳴らす.
      sleep 0.2  # X座標の音を鳴らした後、Y座標を鳴らすまでの遅れ時間
      use_synth :pluck  # 音色の指定B
      play scale(:C3, scaleName, num_octaves: 7)[y],pan: -1,sustain:1
      sleep 0.8  # 上記の遅れ時間と合わせて1.0拍になるようにしています。
    end
    # 後手Whiteの場合の盤面文字の設定と音 pan:1
    if f.slice(i+1, 1)=="W" then
      ban[y][x]="0"
      use_synth :piano  # 音色の指定W
      play scale(:C3, scaleName, num_octaves: 7)[x],pan: 1,sustain:1
      sleep 0.2  # X座標の音を鳴らした後、Y座標を鳴らすまでの遅れ時間
      use_synth :pluck  # 音色の指定W
      play scale(:C3, scaleName, num_octaves: 7)[y],pan: 1,sustain:1
      sleep 0.8  # 上記の遅れ時間と合わせて1.0拍になるようにしています。
    end
    
    # 盤面の描画
    te=te+1
    puts te,f.slice(i+1, 1)+f.slice(i+3, 2)
    for i in 0...19
      ban1L=""
      for j in 0...19
        ban1L=ban1L+ban[i][j]+" "
      end
      puts ban1L
    end
  else
    sleep 0.001 # データを読み飛ばす場合
  end
end
==========
プログラムは、Processingと連携させて盤面をグラフィックスで描画(手順を3Dで見えるようにする等)したり、Processing側で、演奏パラメータの変更や手数の指定などをリアルタイムで行えるようにすると、より興味深いものとなると思われます。
さらにAlpha Goと連携して、手の評価値と音を関連づけるなども考えられます。




コードをアルペジオで鳴らす例


Peter, Paul and Mary(PPM)のThe Cruel War (悲惨な戦争)のイントロのコードを与えて、アルペジオで鳴らしています.
コード名を変数として、音程、コードの種類の順番で与えるため、比較的見やすくできます。
アルペジオのパターンは、基音を0として、コード内のどの順番の音を鳴らすかを0,1,2,3等で与えます。
この曲自体は、パブリックドメインです。

use_synth :pluck
arpeggio=(ring 0,1,2,1,3,2,1,2)
# Intro
c=[:G3,:M,:G3,:M,:E3,:m,:E3,:m,:A3,:m,:A3,:m,:B3,:m,:B3,'7',
   :C4,:M,:C4,:M,:A3,:m,:A3,:m,:D4,:M,:C4,:M,:G3,:M] #,:G3,:M]
with_fx :reverb, room:0.9 do
  for i in 0...c.length/2
    8.times do
      play chord(c[i*2],c[i*2+1],num_octaves:2)[arpeggio.tick]
      sleep 0.25
    end
  end
  play :G3
end




タブ譜をSonic Piで鳴らす方法の例


TAB(タブ)譜は、ギター等の弦の番号とフレットを押さえるポジションがわかりやすく表現されているため広く使われています。このタブ譜の見た目の並びを、なるべくそのままSonic Piで鳴らせるようにした配列を作成してみました。タブ譜からの入力が多少楽にできます。
一つの配列の中に、各弦のポジション、音符の長さ、という順番で入力します。弾かない弦はxとして、仮に999を代入していますが値に意味はありません。(この方法では、見やすいように空白や-.等の記号にはできませんでした.)

例としてイーグルスの「ホテル・カリフォルニア」のイントロの前半を入力してみました。

# TAB to #SonicPi, Eagles Hotel California intro.
tuning=[:E3,:A3,:D4,:G4,:B4,:E5]
x=999
a=[
  # Bm
  [7,9,9,7,7,7],8,
  [x,x,9,x,x,x],16,
  [x,x,x,7,x,x],16,
  [x,x,9,x,x,x],16,
  [x,x,x,x,7,x],16,
  [x,x,9,x,x,x],16,
  [x,x,x,7,x,x],16,
  [x,x,x,x,x,7],4,
  [x,x,x,7,x,x],8,
  [x,x,x,9,7,x],8,
  # F#7
  [x,x,8,x,x,x],8,
  [x,x,x,9,x,x],16,
  [x,x,x,x,7,x],16,
  [x,9,x,x,x,x],16,
  [x,x,x,x,x,9],16,
  [x,x,x,9,x,x],16,
  [x,x,x,x,7,x],16,
  [x,x,8,x,x,x],2,
  # Asus2
  [x,x,7,x,x,x],8,
  [x,x,x,9,x,x],16,
  [x,x,x,x,10,x],16,
  [x,x,x,x,10,x],16,
  [x,x,x,x,x,7],8,
  [x,x,x,x,10,x],16,
  [x,x,7,x,x,x],8,
  [x,x,x,9,x,x],16,
  [x,x,x,x,10,x],16,
  [x,7,x,x,x,x],8,
  [x,x,x,9,x,x],16,
  [x,x,x,x,7,x],16,
  # E9
  [x,11,x,x,x,x],8,
  [x,x,x,x,x,7],16,
  [x,x,x,7,x,x],16,
  [x,x,x,x,x,7],16,
  [x,x,x,x,7,x],16,
  [x,x,x,7,x,x],16,
  [x,x,12,x,x,x],16,
  [x,x,x,x,x,7],2,
  # G
  [x,10,x,x,x,x],8,
  [x,x,9,x,x,x],16,
  [x,x,x,7,x,x],16,
  [x,x,9,x,x,x],16,
  [x,x,x,x,8,x],16,
  [x,x,9,x,x,x],16,
  [x,x,x,7,x,x],16,
  [x,x,x,x,x,7],8,
  [x,10,x,x,x,x],16,
  [x,x,x,x,8,x],16,
  [x,x,x,7,x,x],16,
  [x,x,x,9,x,x],16,
  [x,x,x,x,7,x],16,
  [x,x,x,9,x,x],16,
  # D
  [x,x,7,x,x,x],8,
  [x,x,x,x,x,10],16,
  [x,x,x,x,7,x],16,
  [x,x,x,7,x,x],16,
  [x,x,x,x,x,10],16,
  [x,x,7,x,x,x],16,
  [x,x,x,x,7,x],16,
  [x,9,x,x,x,x],8,
  [x,x,x,x,x,10],16,
  [x,x,x,x,7,x],16,
  [10,9,x,x,x,x],8,
  [x,x,7,x,x,x],16,
  [x,x,x,x,7,x],16,
  # Em7
  [x,7,x,x,x,x],16,
  [x,x,x,x,8,x],16,
  [x,x,9,x,x,x],16,
  [x,x,x,7,x,x],16,
  [x,x,9,x,x,x],16,
  [x,x,x,x,8,x],16,
  [x,x,9,x,x,x],16,
  [x,x,x,x,8,x],16,
  [x,x,x,x,x,7],8,
  [x,x,9,x,x,x],16,
  [x,x,x,7,x,x],16,
  [7,x,x,x,x,x],16,
  [x,x,9,x,x,x],16,
  [x,x,9,x,x,x],16,
  [x,x,x,x,7,x],16,
  # F#7
  [x,9,x,x,x,x],8,
  [x,x,8,x,x,x],16,
  [x,x,x,9,x,x],16,
  [x,x,x,9,x,x],16,
  [x,x,x,x,7,x],16,
  [x,x,8,x,x,x],16,
  [x,x,x,9,x,x],16,
  [x,x,x,x,x,9],2
]

use_bpm 74
use_synth :pluck
with_fx :reverb,room:0.9 do
  for i in 0...a.length/2
    for j in 0...6
      play tuning[j]+a[i*2][j] if a[i*2][j] !=x
    end
    sleep 4.0/a[i*2+1]
  end
end


















Hiroshi Tachibana

戻る