コンピュータミュージック 2017 - 明治大学先端メディアサイエンス学科
OSC通信 – ProcessingでSonic Piをコントロール
今回は、最終コンサートの発表のヒントとして、Sonic PiとProcessingを連携する方法をとりあげます。
Sonic Piは内部にSuperCollierのサーバーを持っていて、Sonic Piでプログラムした演奏の情報を元に音響合成しています。この両者はOSC (Open Sound Control) というプロトコルで通信しています。Sonic Piのver 3.0以降からは、このOSCを外部から受けとることができるようになりました。これによって、OSCを出力するプログラムを作成することで、外部のプログラムからSonic Piを演奏することが可能です。
今回は、OSCを送出するプログラムをProcessingで作成して、簡単なOSC通信を実現します。
スライド資料
サンプルプログラム
連携の基本
Sonic Pi
live_loop :trigger do use_real_time a, b, c = sync "/osc/trigger/synth" synth :pluck, note: a, pan: b, sustain: c end
Processing
import oscP5.*; import netP5.*; OscP5 oscP5; NetAddress location; void setup() { size(480, 320); frameRate(60); oscP5 = new OscP5(this, 12000); location = new NetAddress("127.0.0.1", 4559); } void draw() { background(0); if (mousePressed) { ellipse(mouseX, mouseY, 40, 40); } } void mouseReleased() { float note = map(mouseX, 0, width, 20, 120); float pan = map(mouseY, 0, height, -1, 1); float sustain = 1.0; OscMessage msg = new OscMessage("/trigger/synth"); msg.add(note); msg.add(pan); msg.add(sustain); oscP5.send(msg, location); println(msg); }
演奏の工夫
Sonic Pi
live_loop :trigger do with_fx :flanger do use_real_time a, b, c = sync "/osc/trigger/synth" synth :dsaw, note: a, pan: -0.7, sustain: b, cutoff: c, amp: 0.2 synth :dsaw, note: a-9, pan: 0.7, sustain: b, cutoff: c, amp: 0.2 synth :dsaw, note: a-12, pan: 0.0, sustain: b, cutoff: c, amp: 0.2 end end
Processing
import oscP5.*; import netP5.*; OscP5 oscP5; NetAddress location; void setup() { size(480, 320); frameRate(60); oscP5 = new OscP5(this, 12000); location = new NetAddress("127.0.0.1", 4559); } void draw() { background(0); fill(255); if (mousePressed) { ellipse(mouseX, mouseY, 40, 40); } } void mousePressed() { float note = map(mouseX, 0, width, 20, 120); float cutoff = map(mouseY, 0, height, 150, 1); float sustain = 1.0; OscMessage msg = new OscMessage("/trigger/synth"); msg.add(note); msg.add(sustain); msg.add(cutoff); oscP5.send(msg, location); println(msg); }
自律的に演奏する
Sonic Pi
live_loop :trigger do with_fx :flanger do use_real_time a, b, c = sync "/osc/trigger/synth" synth :dsaw, note: a, pan: -0.7, sustain: b, cutoff: c, amp: 0.2 synth :dsaw, note: a-9, pan: 0.7, sustain: b, cutoff: c, amp: 0.2 synth :dsaw, note: a-12, pan: 0.0, sustain: b, cutoff: c, amp: 0.2 end end
Processing
import oscP5.*; import netP5.*; OscP5 oscP5; NetAddress location; float x = 0, y = 0; void setup() { size(1280, 720); frameRate(60); oscP5 = new OscP5(this, 12000); location = new NetAddress("127.0.0.1", 4559); } void draw() { background(0); fill(255); if (frameCount % 15 == 0) { float note = random(20, 120); float cutoff = random(10, 120); float sustain = 0.25; x = map(cutoff, 10, 120, 0, width); y = map(note, 20, 120, height, 0); OscMessage msg = new OscMessage("/trigger/synth"); msg.add(note); msg.add(sustain); msg.add(cutoff); oscP5.send(msg, location); println(msg); } fill(31, 127, 255); ellipse(x, y, 60, 60); }