コンピュータミュージック 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);
}
