SuperColliderを使って(意識の高い)キックをWOMBのスピーカーで流す

先日開催されたSuperCollider Workshop at WOMB LOUNGEに参加してきました。
内容はかなり濃く、SuperColliderで出来ることを筆頭に外部アプリケーションとの連携や通信を使った講義もあり充実した内容になっていました。
音を鳴らすことから始まり、音の加工やシンセを作りループで再生、シーケンスを作ったりと駆け足ではありましたが出来ることを洗いながらお腹いっぱいな内容でした。
OSCを使ったProcessingやMax/MSPとの通信は初心者にとってはかなり踏み込んだ話しだったのではないかと感じています。
個人的にはインスタレーションやメディアアートと言った分野で非常に有効な手段であると考えているのでワクワクしながら講義をうけていました。

 

五日目最終日には受講者によるSuperColliderを使った発表がありもちろん私も参加しました。
皆さんそれぞれSuperColliderを使ったユニークな音や曲を発表し、幅の広い発表会だったと感じています。
そんな中、私は「どうやったら面白い発表が少しでも出来るだろうか?」 と考え、
せっかくなら普段鳴らすことのできないクラブのスピーカーでキックを鳴らそう!と思い立ったわけです。

 

なのでキックしか作りませんでした。


(
  SynthDef(\SinKick, {
    arg freq = 440, gate = 0.1, amp = 0.5, source, pan = 0.0;
    source = Pan2.ar(
      SinOsc.ar(EnvGen.kr(Env.adsr(0, 1, 0, 0, 1, -20), gate, freq, 0, 0.5, 2), 1, 1)
      * EnvGen.kr(Env.perc(0, 0.1, 1, 8));
    );
    Out.ar(0, source);
  }).store;

  SynthDef(\SawKick, {
    arg freq = 440, gate = 0.1, amp = 0.5, source, pan = 0.0;
    source = Pan2.ar(
      Saw.ar(EnvGen.kr(Env.adsr(0, 1, 0, 0, 1, -20), gate, freq, 0, 0.5, 2), 1, 1)
      * EnvGen.kr(Env.perc(0, 0.1, 1, 8));
    );
    Out.ar(0, source);
  }).store;

  SynthDef(\FSinKick, {
    arg freq = 440, gate = 0.1, amp = 0.5, source, pan = 0.0;
    source = Pan2.ar(
      FSinOsc.ar(EnvGen.kr(Env.adsr(0, 1, 0, 0, 1, -20), gate, freq, 0, 0.5, 2), 1, 1)
      * EnvGen.kr(Env.perc(0, 0.1, 1, 8));
    );
    Out.ar(0, source);
  }).store;

  SynthDef(\SquareKick, {
    arg freq = 440, gate = 0.1, amp = 0.5, source, pan = 0.0;
    source = Pan2.ar(
      Pulse.ar(EnvGen.kr(Env.adsr(0, 1, 0, 0, 1, -20), gate, freq, 0, 0.5, 2), 0.5, 1, 1)
      * EnvGen.kr(Env.perc(0, 0.1, 1, 8));
    );
    Out.ar(0, source);
  }).store;

//distortion

  SynthDef(\FSinKick_dist, {
    arg freq = 440, gate = 0.1, amp = 0.5, source, pan = 0.0;
    source = Pan2.ar(
      FSinOsc.ar(EnvGen.kr(Env.adsr(0, 1, 0, 0, 1, -20), gate, freq, 0, 0.5, 2), 1, 1).distort * Line.kr(2, 0, 0.9)
      * EnvGen.kr(Env.perc(0, 0.1, 1, 8));
    );
    Out.ar(0, source);
  }).store;

//+noise

  SynthDef(\FSinKick_noise, {
    arg freq = 440, gate = 0.1, amp = 0.5, source, pan = 0.0;
    source = Pan2.ar(
      FSinOsc.ar(EnvGen.kr(Env.adsr(0, 1, 0, 0, 1, -20), gate, freq, 0, 0.5, 2), 1, 1).distort * Line.kr(2, 0, 0.9)
      + LFNoise0.ar(freq * 6, 0.01, amp)
      * EnvGen.kr(Env.perc(0, 0.1, 1, 8));
    );
    Out.ar(0, source);
  }).store;

//+ saw

  SynthDef(\FSinKick_saw, {
    arg freq = 440, gate = 0.1, amp = 0.5, source, pan = 0.0;
    source = Pan2.ar(
      FSinOsc.ar(EnvGen.kr(Env.adsr(0, 1, 0, 0, 1, -20), gate, freq, 0, 0.5, 2), 1, 0.5).distort * Line.kr(2, 0, 0.9)
      + Saw.ar(freq * 2, 0.0025, 0.25)
      + LFNoise0.ar(freq * 6, 0.01, amp)
      * EnvGen.kr(Env.perc(0, 0.1, 1, 8));
    );
    Out.ar(0, source);
  }).store;

//+ square

  SynthDef(\FSinKick_square, {
    arg freq = 440, gate = 0.1, amp = 0.5, source, pan = 0.0;
    source = Pan2.ar(
      FSinOsc.ar(EnvGen.kr(Env.adsr(0, 1, 0, 0, 1, -20), gate, freq, 0, 0.5, 2), 1, 0.5).distort * Line.kr(2, 0, 0.9)
      + Pulse.ar(EnvGen.kr(Env.adsr(0, 1, 0, 0, 1, -20), gate, freq, 0, 0.5, 2), 0.5, 0.03, 0.5)
      + Saw.ar(freq * 2, 0.0025, 0.25)
      + LFNoise0.ar(freq * 6, 0.01, amp)
      * EnvGen.kr(Env.perc(0, 0.1, 1, 8));
    );
    Out.ar(0, source);
  }).store;

//+ high

  SynthDef(\FSinKick_high, {
    arg freq = 440, gate = 0.1, amp = 0.5, source, pan = 0.0;
    source = Pan2.ar(
      FSinOsc.ar(EnvGen.kr(Env.adsr(0, 1, 0, 0, 1, -20), gate, freq, 0, 0.5, 2), 1, 0.5).distort * Line.kr(2, 0, 0.9)
      + Pulse.ar(EnvGen.kr(Env.adsr(0, 1, 0, 0, 1, -20), gate, freq, 0, 0.5, 2), 0.5, 0.03, 0.1)
      + Saw.ar(freq * 2, 0.0025, 0.25)
      + LFNoise0.ar(freq * 8, 0.01, 0.05)
      * EnvGen.kr(Env.perc(0, 0.1, 1, 8));
    );
    Out.ar(0, source);
  }).store;

//+ high++

  SynthDef(\FSinKick_high_saw, {
    arg freq = 440, gate = 0.1, amp = 0.5, source, pan = 0.0;
    source = Pan2.ar(
      FSinOsc.ar(EnvGen.kr(Env.adsr(0, 1, 0, 0, 1, -20), gate, freq, 0, 0.5, 2), 1, 0.5).distort * Line.kr(2, 0, 0.9)
      + Saw.ar(EnvGen.kr(Env.adsr(0, 1, 0, 0, 1, -20), gate, freq, 0, 0.2, 2), 0.5, 0.05).distort * Line.kr(-2, 0, 0.5)
      + Pulse.ar(EnvGen.kr(Env.adsr(0, 1, 0, 0, 1, -20), gate, freq, 0, 0.5, 2), 0.5, 0.03, 0.1)
      + Saw.ar(freq * 2, 0.0025, 0.25)
      + LFNoise0.ar(freq * 8, 0.01, 0.05)
      * EnvGen.kr(Env.perc(0, 0.1, 1, 8));
    );
    Out.ar(0, source);
  }).store;

//+ release

  SynthDef(\FSinKick_release, {
    arg freq = 440, gate = 0.1, amp = 0.5, source, pan = 0.0;
    source = Pan2.ar(
      FSinOsc.ar(EnvGen.kr(Env.adsr(0, 1, 0, 0, 1, -20), gate, freq, 0, 0.5, 2), 1, 0.5).distort * Line.kr(2, 0, 0.9)
      + Saw.ar(EnvGen.kr(Env.adsr(0, 0.5, 0, 0, 1, -20), gate, freq, 0, 0.2, 2), 0.5, 0.005).distort * Line.kr(-2, 0, 0.5)
      + Pulse.ar(EnvGen.kr(Env.adsr(0, 1, 0, 0, 1, -20), gate, freq, 0, 0.5, 2), 0.5, 0.03, 0.1)
      + Saw.ar(freq * 2, 0.0025, 0.25)
      + LFNoise0.ar(freq * 8, 0.01, 0.05)
      * EnvGen.kr(Env.perc(0, 0.3, 1, 8));
    );
    Out.ar(0, source);
  }).store;

//+ noise

  SynthDef(\FSinKick_noise2, {
    arg freq = 440, gate = 0.1, amp = 0.5, source, pan = 0.0;
    source = Pan2.ar(
      FSinOsc.ar(EnvGen.kr(Env.adsr(0, 1, 0, 0, 1, -20), gate, freq, 0, 0.5, 2), 1, 0.5).distort * Line.kr(2, 0, 0.9)
      + Saw.ar(EnvGen.kr(Env.adsr(0, 0.5, 0, 0, 1, -20), gate, freq, 0, 0.2, 2), 0.5, 0.005).distort * Line.kr(-2, 0, 0.5)
      + Pulse.ar(EnvGen.kr(Env.adsr(0, 1, 0, 0, 1, -20), gate, freq, 0, 0.5, 2), 0.5, 0.03, 0.1)
      + LFNoise0.ar(EnvGen.kr(Env.perc(0, 20, 1, 100)), 1, 1)
      * EnvGen.kr(Env.perc(0, 0.1, 1, 12));
    );
    Out.ar(0, source);
  }).store;

//+ Kick!!!!!!

  SynthDef(\FSinKick_last, {
    arg freq = 440, gate = 0.1, amp = 0.5, source, pan = 0.0;
    source = Pan2.ar(
      FSinOsc.ar(EnvGen.kr(Env.adsr(0, 1, 0, 0, 1, -20), gate, freq, 0, 0.5, 2), 1, 0.1).distort * Line.kr(2, 0, 0.9)
      + FSinOsc.ar(EnvGen.kr(Env.adsr(0, 1, 0, 0, 1, -20), gate, freq / 2, 0, 0.5, 2), 1, 0.1).distort * Line.kr(2, 0, 0.9)
      + FSinOsc.ar(EnvGen.kr(Env.adsr(0, 1, 0, 0, 1, -20), gate, freq * 2, 0, 0.5, 2), 1, 0.05).distort * Line.kr(2, 0, 0.9)
      + Saw.ar(EnvGen.kr(Env.adsr(0, 1, 0, 0, 1, -20), gate, freq, 0, 0.2, 2), 0.5, 0.05).distort * Line.kr(-2, 0, 0.5)
      + Pulse.ar(EnvGen.kr(Env.adsr(0, 1, 0, 0, 1, -20), gate, freq, 0, 0.5, 2), 0.5, 0.03, 0.1)
      + Saw.ar(freq * 2, 0.0025, 0.25)
      + LFNoise0.ar(freq * 8, 0.005, 0.05)
      * EnvGen.kr(Env.perc(0, 0.12, 1, 8));
    );
    Out.ar(0, source);
  }).store;
)

 

~sinKick = Synth(\SinKick);
~sawKick = Synth(\SawKick);
~fsinKick = Synth(\FSinKick);
~aquareKick = Synth(\SquareKick);
~distKick = Synth(\FSinKick_dist);
~noiseKick = Synth(\FSinKick_noise);
~saw2Kick = Synth(\FSinKick_saw);
~square2Kick = Synth(\FSinKick_square);
~highKick = Synth(\FSinKick_high);
~highSawKick = Synth(\FSinKick_high_saw);
~releaseKick = Synth(\FSinKick_release);
~noise2Kick = Synth(\FSinKick_noise2);
~lastKick = Synth(\FSinKick_last);

 

SinやSawでとりあえずそれっぽい音を作り、それに重ねていく形でコーディング。
ただSuperColliderの知識が足りないので、高音域にSawやNoiseを重ねてなんとなくで作るという形で進めました。
抜けが悪いから高音域、中音域に追加しつつ余韻が足りないからReleaseを伸ばしたりと、DAWであればサンプリングしたキックをEQで加工していくところをコードで書くことがとても難しく、どうやったら再現できるのだろうかというところはとても楽しく作ることができました。

ただ満足にいくものが出来ていないので、原理や出力、SuperColliderの機能を理解してまた挑みたいと思ってます。

※発表の最後に、参考としてみんな大好きVengeanceのキックを鳴らしましたがやっぱり良かったです。

CodaのZen-CodingをHTML5 Boilerplate的なアレで

普段コーディングで使っているエディタがCoda(Mac専用)なのですが、
プラグインのTEA for Codaを入れるとZen-Codingが使えるようになります。
(もしかしたらVer.古いかもしれません

Zen-Codingとはなんぞやというところで、


div#container>div.logo+ul#nav>li.navList0$*5>a

でこれを解釈というか展開というかおまじないをすると

<div id="container"></div>

こんな感じに展開してくれます。
サイトの骨組みを作る時に非常に助かっています。
これ以外にも様々なテンプレートのようなものが存在し、自分でも作ることが可能です。

よく使う一例として


html:5

を展開すると


 

と展開できます。

と思いきや、lang=”en”になってたりしませんか?
きっと日本語圏の人は「lang=”ja”になって欲しい!」と勝手に解釈して無理矢理進めます!

ということで変更してみましょう!

変更するファイルは
/User/hogehoge/Library/Application Support/Coda/Plug-ins/TEA for Coda.codaplugin

これでパッケージの内容を表示から開くとFinderで開くと思いますので
Support/Library/zencoding/zen_settings.py
を開きます。

そうすると10行目あたりに

'variables': {
'lang': 'en',
'locale': 'en',
'charset': 'UTF-8',
'profile': 'xhtml',

というのがあるので変更して保存します。
保存後は一度Codaを再起動しないと反映されませんのでご注意を。

これで基本的なhtmlができるので


div#container>div#header+div#content+div#footer
<div id="container"></div>

こんな風に展開していって構築していきます。

HTML5 Boilerplateを組み込んでみました!
というところで長くなりすぎてしまったため

まずZen-Codingの話をしなくてはならないというところで力尽きました
説明しようとすると割と内容が多いことに気づいたので
次回に・・・
持ち越し・・・
たいな・・・

Unibaの暑中見舞いARについて

弊社よりお送りしました暑中見舞いの参考動画です。
ご覧頂いた方も頂いていない方も是非Uniba.jpよりご覧ください。

記事はこちらよりどうぞ

Processingで学ぶプログラミングその2

お久しぶりです!
フロントエンドエンジニアの清水です。

Processingで学ぶプログラミングその1 から大分時間がたってしまいましたがProcessing連載の2回目になります。

まずはこの動画から見ていただきましょう!

前回はマウスカーソルの位置にオブジェクトが出ているだけでしたが、今回はクリックの際にレンダリングされるように変更しました。
また外部コントローラーとしてiPadを使用しました!
MacとiPadの通信はWi-Fi経由で接続しています。(通信速度の観点からアドホックで接続するとレイテンシーが少ないです。)
TouchOSCというアプリを使用し、Processing側でiPadから送られてきたOSCを受け取りオブジェクトをレンダリングするように変更しています。

時間が空いてしまいましたので面白いものを見せられるようにと頑張りました。
外部入力を使用するという少し背伸びした形になりましたが、非常にProcessing熱が上がっております!
今後の連載(?)にご期待下さい。

ソースコード

import oscP5.*;
import netP5.*;

OscP5 oscP5;

void setup(){
  smooth();
  size(1680, 1050);
  colorMode(RGB);
  noStroke();
  background(#000000);
  oscP5 = new OscP5(this,8000);
  frameRate(60);
  noCursor();
}

void draw(){
}

void erase()
{
  background(0);
}

void mouseMoved(float x , float y ) {
  float r = random(1, 50);

  float R = random(0, 255);
  float G = random(0, 255);
  float B = random(0, 255);
  float a = random(0, 255);

  float xs = random(-15, 15);
  float ys = random(-15, 15);

  float z = random(-50, 50);

  ellipse(x+xs, y+ys, r, r);
  fill(R, G, B, a);
}

void oscEvent(OscMessage theOscMessage) {
    if(theOscMessage.checkAddrPattern("/reset") == true )
     {
       erase();
       return;
     }

  println("touch osc"+theOscMessage);
  float xValue = theOscMessage.get(0).floatValue();
  float yValue = theOscMessage.get(1).floatValue();

  println(xValue+", "+yValue);
  mouseMoved(xValue*width, yValue*height);
}

Processingで学ぶプログラミングその1

お久しぶりです。
フロントエンドエンジニアの清水です。

以前からプログラミングを学びたい!
とは思いつつもなかなか続けることが難しく三日坊主になっていました。
そんなわけで実行結果が見た目でわかりやすく確認できるProcessingで少しずつ学んでいこうと考えています。
プログラミングがデキる人にとってみたらそんなことかと思われるかもしれませんが、続けていけたらいいなと思っています。

というわけで簡単に書いてみました。

void setup(){
  smooth();
  size(400, 400);
  colorMode(RGB);
  noStroke();
  background(#ffffff);
}

void draw(){
  float x = mouseX;
  float y = mouseY;

  float r = random(1, 15);

  float R = random(0, 255);
  float G = random(0, 255);
  float B = random(0, 255);
  float a = random(0, 255);

  ellipse(x, y, r, r);
  fill(R, G, B, a);
}

実行結果

メインループで回りっぱなしなのでレンダリングされ続けます。
マウスの位置にオブジェクトが置かれるぐらいしか書いていませんが、クリックで散らばったり出来ると見た目にも面白いですね。

とは言いつつも構築方法のリテラシーが低いので、少しずつ色々な方法を学んでいけたらと思っています。
積み重ねて習慣にして行きたいです!

それではまた!

ユニバ株式会社 Uniba Inc.のサイトをリニューアル致しました

ユニバ株式会社 Uniba Inc.のサイトをリニューアル致しました。

html5やcss3などを使用し構築されています。
是非一度ご覧いただけると幸いです。

uniba.jp

@anywhere [サイトにtwit機能を追加出来るAPI]

初めましてこんにちは!
主にフロントのデザインやコーディングをやっている清水と申します。
宜しくお願いします!

ということで一つ目の記事は先日発表された@anywhereについての投稿です。
@anywhereを使用すればサイト上にtwitterの機能が追加できる便利なAPI。

機能としては
・usernameをオートリンク
・usernameの情報をカードで表示
・フォローボタン
・つぶやけるボックス
・ログイン/ログアウト機能
となっています。

詳しい仕様はこちら -> http://dev.twitter.com/anywhere/begin

というわけでUnibaRDのtwitterアカウントの紹介を含めて実装してみました。

@UnibaRD

DOMでセレクターを指定してあげれば後は自動的にリンクやフォローボタンが実装出来ます。

まずは@anywhereでStart using it nowから登録。
項目に沿って情報を入力して登録完了するとAPIキーが発行されます。
後はそれをコピーして埋め込むだけです。

<script src="http://platform.twitter.com/anywhere.js?id=某APIキー"></script>
 

usernameにオートリンクさせたい場合は以下のように記述します。
usernameの頭に@がついていないと実行されないので注意が必要です。

 <script type="text/javascript">
	twttr.anywhere(function(twitter) {
		twitter("某セレクター").linkifyUsers();
	});

アカウントの情報を表示させるには以下のように記述します。

	twttr.anywhere(function(twitter) {
		twitter.hovercards();
		twitter("某セレクター").hovercards();
	});
<div id="某セレクター">@某</div>

フォローボタンは以下のように記述します。

	twttr.anywhere(function(twitter) {
		twitter("某セレクター").followButton("@某");
	});
<div id="某セレクター"></div>

これだけで簡単に機能が追加出来るようになりました。
twitterのAPIにあまり明るくないのですが非常に簡単に実装出来ました!
ログイン/ログアウトとツイートボックスは時間がある時に実装してみたいと思います。

UstreamやATND等でこの機能を活用すれば、アカウント一覧のフォローボタンリスト等が作れるのではないかと思います。
アイディア次第で色々出来そうです!
こういったものを利用して何か作りたいですね。

末筆になりますが@UnibaRDを宜しくお願い致します!

※2010.04.22 スクリプトが記事以外にも影響を与えているため一時的にスクリプトを外しております。

preload preload preload