狠狠撸

狠狠撸Share a Scribd company logo
Interactive Music II
ProcessingとSuperColliderの連携1
東京藝術大学芸術情報センター (AMC)
2014年1月8日
田所 淳
今日の内容
? いよいよ、Processingと、SuperColliderの連携に挑戦!!
今日の内容
? ProcessingとSuperColliderの連携をするには、Processingにラ
イブラリ(Library)を追加する
!

? OSCのためのライブラリ
? oscP5を使用
!

? SuperColliderとの連携に特化したライブラリ
? SuperCollider Client for Processing
oscP5
? まずは、oscP5をインストールする
? メニューから、Sketch > Import Library > Add Library を選択
oscP5
? Library Manager のウィンドウが表示される
? 検索欄に「oscP5」と入力
? 表示された、oscP5の横の「Install」ボタンを押す
oscP5
? 早速、OSCを使用して、ProcessingからSuperColliderにメッセー
ジを送ってみる
!

? SuperCollider側: OSCメッセージのDumpを設定
!

s.dumpOSC;
!
!

? 次に、メッセージを送出するProcessingのテストプログラムを
作成する
oscP5
? Processing側: OSCメッセージ送出プログラム
//OSCのライブラリ読み込み
import oscP5.*;
import netP5.*;

!

//OSC送受信のオブジェクト
OscP5 oscP5;
//送出先のネットアドレス
NetAddress remote;

!

void setup() {
//画面基本設定
size(400,400);
frameRate(60);
//OSC送受信のオブジェクトを生成
oscP5 = new OscP5(this, 12000);
//ネットアドレスを設定
remote = new NetAddress("127.0.0.1", 57110);
}
oscP5
? Processing側: OSCメッセージ送出プログラム
void draw() {
background(0);
}

!

//マウスクリックに反応
void mouseReleased() {
//OSCメッセージを生成
OscMessage msg = new OscMessage("/test");
//引数を追加
msg.add(123);
msg.add("Hello");
//OSC送出
oscP5.send(msg, remote);
}
oscP5
? Processingを実行すると、SuperColliderのPost Windowに以
下のようなメッセージが出現するはず
!

[ "/test", 123, "Hello" ]
!
FAILURE IN SERVER: /test Command not found
!
!

? Processingで生成したOSCメッセージを受信している
? ただし、SuperCollider側はまだ何もしていないのでエラーを
表示
oscP5
? 次に、SuperColliderで楽器(Synth)を定義して、それを
Processingから演奏してみる
oscP5
? SuperCollider側: 「test_inst」を定義
SynthDef("test_inst",{
arg freq=440, length=1.0, amp=0.5;
var env, out;
env = Env.perc(0.01, length);
out = SinOsc.ar([freq,freq*1.001])
* EnvGen.kr(env, doneAction:2) * amp;
Out.ar(0, out);
}).store;
oscP5
? Processing側:
//OSCのライブラリ読み込み
import oscP5.*;
import netP5.*;

!

//OSC送受信のオブジェクト
OscP5 oscP5;
//送出先のネットアドレス
NetAddress remote;
//カウンター
int counter;

!

void setup() {
//画面基本設定
size(400,400);
frameRate(60);
//OSC送受信のオブジェクトを生成
oscP5 = new OscP5(this, 12000);
//ネットアドレスを設定
remote = new NetAddress("127.0.0.1", 57110);
}
oscP5
? Processing側:
void draw() {
background(0);
}

!

//マウスクリックに反応
void mouseReleased() {
//OSCメッセージを生成
OscMessage msg = new OscMessage("/s_new");
//SuperColliderのパラメータを設定
msg.add("test_inst"); //Synth名
msg.add(1000 + counter); //Synth ID
msg.add(1); //アクションNo.
msg.add(0); //ノードID
//OSC送出
oscP5.send(msg, remote);
counter++;
}
oscP5
? 画面をクリックすると、音が鳴る(はず)
oscP5
? マウスのクリックする高さ(Y座標)で、音程が変化するように改
造してみる!
oscP5
? Processing側: mouseReleased() 関数を変更
//マウスクリックに反応
void mouseReleased() {
//OSCメッセージを生成
OscMessage msg = new OscMessage("/s_new");
//SuperColliderのパラメータを設定
msg.add("test_inst"); //Synth名
msg.add(1000 + counter); //Synth ID
msg.add(1); //アクションNo.
msg.add(0); //ノードID
//マウスのy座標で、音程を変更する
msg.add("freq");
msg.add(map(mouseY, height, 0, 20, 8000));
//OSC送出
oscP5.send(msg, remote);
counter++;
}
SuperCollider client for Processing
? SuperCollider client for Processing
? OSCp5よりも簡単に、SuperColliderとProcessingの連携が可
能となる
? こちらをより積極的に活用していきたい!
SuperCollider client for Processing
? インストール
? oscP5と同様に、Library Managerからインストール
SuperCollider client for Processing
? Processing側: こんなに簡単に!
import supercollider.*;
import oscP5.*;

!

Synth synth;

!

void setup () {
size(600, 400);
}

!

void draw() {
background(0);
}

!

//マウスクリックに反応
void mouseReleased() {
//新規に楽器を定義(まだ生成はされず)
synth = new Synth("test_inst");
//引数を設定
synth.set("amp", 0.5);
synth.set("freq", map(mouseY, height, 0, 20, 8000));
//楽器を生成
synth.create();
}
SuperCollider client for Processing
? Processing側にアニメーションをつけてみる
!

? 例えば…
? マウスをクリックすると、円が波紋のように拡がる
SuperCollider client for Processing
? Processing側:
import supercollider.*;
import oscP5.*;

!

Synth synth;
int NUM = 100;
float[] radius = new float[NUM];
PVector[] pos = new PVector[NUM];
int counter = 0;

!

void setup () {
size(800, 600);
frameRate(60);
noFill();
stroke(31, 127, 255);
strokeWeight(3);
for (int i = 0; i < NUM; i++) {
radius[i] = 0;
pos[i] = new PVector(width*2, width*2);
}
}
SuperCollider client for Processing
? Processing側:
void draw() {
background(0);
for (int i = 0; i < NUM; i++) {
ellipse(pos[i].x, pos[i].y, radius[i], radius[i]);
radius[i] += 1;
if(radius[i] > width*1.5){
radius[i] = 0;
pos[i].x = width*2;
pos[i].y = width*2;
}
}
}

!

void mouseReleased() {
synth = new Synth("test_inst");
synth.set("amp", 0.5);
synth.set("freq", map(mouseY, height, 0, 20, 8000));
synth.create();
int n = counter % NUM;
radius[n] = 0;
pos[n].x = mouseX;
pos[n].y = mouseY;
counter++;
}
SuperCollider client for Processing
? 完成!!
SuperCollider client for Processing
? 応用:
? 先週のアニメーションのサンプルを応用
? 壁にぶつかったとき、音が鳴る
たくさんの図形を同時に動かす
? Processing: 先週のサンプル
int NUM = 500; //配列の数
//位置のベクトルの配列
PVector[] location = new PVector[NUM];
//速度のベクトルの配列
PVector[] velocity = new PVector[NUM];
//塗りの色の配列
color[] col = new color[NUM];
//円の大きさ(直径)の配列
float[] diameter = new float[NUM];

!

void setup() {
size(640, 480); //640x480pixelの画面を生成
frameRate(60); //フレームレート
noStroke();
for (int i = 0; i < NUM; i++) { //配列の数だけ繰り返し
//位置のベクトルの初期設定
location[i] = new PVector(random(width), random(height));
//速度のベクトルの初期設定
velocity[i] = new PVector(random(-4, 4), random(-4, 4));
//色の初期設定
col[i] = color(random(255), random(255), random(255), 127);
//大きさの初期設定
diameter[i] = random(3, 40);
}
}
たくさんの図形を同時に動かす
? Processing: 先週のサンプル
void draw() {
background(15); //背景を描画
//配列の数だけ繰り返し
for (int i = 0; i < NUM; i++) {
fill(col[i]); //色を指定
//指定した位置に円を描画
ellipse(location[i].x, location[i].y, diameter[i], diameter[i]);
//位置のベクトルに速度のベクトルを加算、次の位置になる
location[i].add(velocity[i]);
//もし画面の左端、または右端に到達したら
if ((location[i].x > width) || (location[i].x < 0)) {
velocity[i].x *= -1; //X方向のスピードを反転
}
//もし画面の下端、または上端に到達したら
if ((location[i].y > height) || (location[i].y < 0)) {
velocity[i].y *= -1; //Y方向のスピードを反転
}
}
}
SuperCollider client for Processing
? このプログラムを改造する
!

? draw() 関数内
? if文で壁にあたった瞬間を検知している部分で、楽器を生成し、
演奏する
!

? プログラムを読み易くするため、新規に「playSynth()」 関数
を作成
? void playSynth(x座標、y座標)
たくさんの図形を同時に動かす
? Processing: draw()関数にplaySynth()を追加
void draw() {
background(15); //背景を描画
//配列の数だけ繰り返し
for (int i = 0; i < NUM; i++) {
fill(col[i]); //色を指定
//指定した位置に円を描画
ellipse(location[i].x, location[i].y, diameter[i], diameter[i]);
//位置のベクトルに速度のベクトルを加算、次の位置になる
location[i].add(velocity[i]);
//もし画面の左端、または右端に到達したら
if ((location[i].x > width) || (location[i].x < 0)) {
velocity[i].x *= -1; //X方向のスピードを反転
playSynth(location[i].x, location[i].y);
}
//もし画面の下端、または上端に到達したら
if ((location[i].y > height) || (location[i].y < 0)) {
velocity[i].y *= -1; //Y方向のスピードを反転
playSynth(location[i].x, location[i].y);
}
}
}
たくさんの図形を同時に動かす
? Processing: playSynth関数
void playSynth(float x, float y) {
//新規に楽器を定義(まだ生成はされず)
Synth synth = new Synth("test_inst");
//引数を設定
synth.set("amp", 0.5);
synth.set("freq", map(x, height, 0, 20, 8000));
//楽器を生成
synth.create();
}
SuperCollider client for Processing
? 完成!!
? 円のバウンドにあわせて、音が鳴るはず!

More Related Content

Interactive Music II ProcessingとSuperColliderの連携1