Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Interactive Music II ProcessingとSuperColliderの連携1

  • Be the first to comment

Interactive Music II ProcessingとSuperColliderの連携1

  1. 1. Interactive Music II ProcessingとSuperColliderの連携1 東京藝術大学芸術情報センター (AMC) 2014年1月8日 田所 淳
  2. 2. 今日の内容 ‣ いよいよ、Processingと、SuperColliderの連携に挑戦!!
  3. 3. 今日の内容 ‣ ProcessingとSuperColliderの連携をするには、Processingにラ イブラリ(Library)を追加する ! ‣ OSCのためのライブラリ ‣ oscP5を使用 ! ‣ SuperColliderとの連携に特化したライブラリ ‣ SuperCollider Client for Processing
  4. 4. oscP5 ‣ まずは、oscP5をインストールする ‣ メニューから、Sketch > Import Library > Add Library を選択
  5. 5. oscP5 ‣ Library Manager のウィンドウが表示される ‣ 検索欄に「oscP5」と入力 ‣ 表示された、oscP5の横の「Install」ボタンを押す
  6. 6. oscP5 ‣ 早速、OSCを使用して、ProcessingからSuperColliderにメッセー ジを送ってみる ! ‣ SuperCollider側: OSCメッセージのDumpを設定 ! s.dumpOSC; ! ! ‣ 次に、メッセージを送出するProcessingのテストプログラムを 作成する
  7. 7. 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); }
  8. 8. 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); }
  9. 9. oscP5 ‣ Processingを実行すると、SuperColliderのPost Windowに以 下のようなメッセージが出現するはず ! [ "/test", 123, "Hello" ] ! FAILURE IN SERVER: /test Command not found ! ! ‣ Processingで生成したOSCメッセージを受信している ‣ ただし、SuperCollider側はまだ何もしていないのでエラーを 表示
  10. 10. oscP5 ‣ 次に、SuperColliderで楽器(Synth)を定義して、それを Processingから演奏してみる
  11. 11. 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;
  12. 12. 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); }
  13. 13. 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++; }
  14. 14. oscP5 ‣ 画面をクリックすると、音が鳴る(はず)
  15. 15. oscP5 ‣ マウスのクリックする高さ(Y座標)で、音程が変化するように改 造してみる!
  16. 16. 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++; }
  17. 17. SuperCollider client for Processing ‣ SuperCollider client for Processing ‣ OSCp5よりも簡単に、SuperColliderとProcessingの連携が可 能となる ‣ こちらをより積極的に活用していきたい!
  18. 18. SuperCollider client for Processing ‣ インストール ‣ oscP5と同様に、Library Managerからインストール
  19. 19. 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(); }
  20. 20. SuperCollider client for Processing ‣ Processing側にアニメーションをつけてみる ! ‣ 例えば… ‣ マウスをクリックすると、円が波紋のように拡がる
  21. 21. 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); } }
  22. 22. 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++; }
  23. 23. SuperCollider client for Processing ‣ 完成!!
  24. 24. SuperCollider client for Processing ‣ 応用: ‣ 先週のアニメーションのサンプルを応用 ‣ 壁にぶつかったとき、音が鳴る
  25. 25. たくさんの図形を同時に動かす ‣ 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); } }
  26. 26. たくさんの図形を同時に動かす ‣ 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方向のスピードを反転 } } }
  27. 27. SuperCollider client for Processing ‣ このプログラムを改造する ! ‣ draw() 関数内 ‣ if文で壁にあたった瞬間を検知している部分で、楽器を生成し、 演奏する ! ‣ プログラムを読み易くするため、新規に「playSynth()」 関数 を作成 ‣ void playSynth(x座標、y座標)
  28. 28. たくさんの図形を同時に動かす ‣ 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); } } }
  29. 29. たくさんの図形を同時に動かす ‣ 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(); }
  30. 30. SuperCollider client for Processing ‣ 完成!! ‣ 円のバウンドにあわせて、音が鳴るはず!

×