yoppa.org


『演奏するプログラミング、ライブコーディングの思想と実践 – Show Us Your Screens』 ―はじめに

演奏するプログラミング、ライブコーディングの思想と実践
Show Us Your Screens

はじめに

ほとんどの場合、プログラマーという職業は裏方の仕事で、表に出てくることはありません。そうした裏方の人々による成果であるアプリケーションやシステムのソースコードも、多くの製品/プロダクトにおいて外部から秘匿され、開発に関わった関係者しかその内部を見ることはできません。一般の利用者にとって、ソースコードはブラックボックス化された謎の存在であり、それを生み出しているプログラマーたちも得体の知れない存在です。

外部から秘匿されることで、コードは神格化され、魔法のような存在として奉られるようなります。ブラックボックス化した箱は、人々から多額の金を吸い上げ、資本家にとっての価値を生み出しながらどんどん巨大化していきます。プログラマーも、そうした巨大なブラックボックスに奉仕する存在として、コードという秘技を駆使して支える存在となっていきます。

さらに現代は、コードがプログラマーからも秘匿されつつあります。巨大なアプリケーションやIT システムは一人のプログラマーが全て把握することはもはや不可能であり、ユニット化されたコードの一部を書き換える要員としてしか関われません。将来はAIがコーディングを行い、人間のプログラマーは必要なくなると予想する人たちもいます。

現代のプログラマーは、もしかしたら、産業革命直前の職人のような立場なのかもしれません。職人が弟子に受け継いできた秘技は、巨大な資本に吸収され、工場労働者のように単純な流れ作業をする存在となっていくかもしれません。プログラムは巨大化したIT システムの一部であり、個人の所有が困難になっていきます。

1810年代初頭のイギリスで、産業革命にともなう機械使用の普及により失業の怖れを感じた手工業者・労働者たちが、機械を破壊する運動を起こしました。ラッダイト運動です。この運動は、後の労働運動の先駆けとなりました。

もう一度、個人の手にコードを取り戻しましょう。
それが、ライブコーディングです。

コーディングするという行為自体を楽しみましょう。個人の楽しみとして、楽器を弾くように、詩を書いたり編み物をするように、コーディングするという活動自体を楽しむのです。ライブコーディングを通して、初めて自分で書いたプログラムが動いた時の感動を思い出しましょう。コーディングは仕事のためにいやいや書くものではなく、未知の世界へと足を踏み入れるエキサイティングな行為だったはずです。そして、その喜びを周囲の人たちにも伝えましょう。

ライブコーディングは、コーディングの喜びをストレートに表現する手段としてとても優れた方法です。コードをリアルタイムに音や映像に変換してパフォーマンスすることで、普段コードに触れない人たちにも、プログラミングはこんなに楽しい行為なのだ、クールな表現活動なのだということを、とてもわかりやすく、そして魅力的に伝えることが可能です。

ライブコーディングの世界はオープンに開かれています。オープンソースのアプリケーションをインストールするだけで、誰でもライブコーディングを始められます。ライブコーディングのコミュニティは、互いに緩やかに連携しながら国際的に拡がっています。誰でも受け入れる、とても自由なカルチャーです。

あなたも、本書を踏み台にして、世界にはばたくライブコーダーになりましょう。

2018年12月
田所 淳


第12回: 最終課題のヒント2 – Patatapを作ってみる

Ptatap

前回に引き続き、最終課題「インタラクションを表現する」のヒントになりそうなトピックスを紹介します。

Patatap (https://patatap.com/) はとてもシンプルなインタラクションで構成された作品です。キーボードを操作すると、それぞれのキーにシンプルなアニメーションが割り振られていて、同時にサンプリングされたサウンドが鳴るようになっています。仕組みはとても単純なのですが、キーボードをリズムにあわせてタイピングすることで音と映像が同期して、まるでVJのパフォーマンスをしているような気分を味わえます。キーボードの組み合わせは無限にあるので、いつまでも飽きることがありません。

今回は、p5.jsをつかって、このPatatapのようなインタラクションを作るにはどうすれば良いのか考えていきます。

スライド資料

サンプルプログラム


第10回: 最終課題の提出について / Sonic Piで外部サンプルを読み込む

Freesound

今回は、Sonic Piに外部のサンプルを読み込む方法について紹介します。Sonic Piには楽器(Synth)を演奏する機能と、サンプリングされた音(Sample)を演奏する機能がありました。前回紹介したSonic Piでオリジナルな楽器を定義することができる方法と同様に、外部のサウンドファイルをSonic Piに取り込んで、今まで使用してきたSampleと同じように使用することが可能です。外部のサウンドファイルが活用できるようになると、FreesoundLANDR SamplesDirt-Samplesなどの外部の膨大なサンプル音源が使用できるようになり演奏の幅が大きく拡がります。様々なサンプルをダウンロードして、オリジナルな表現を探っていきましょう!

最終課題

  • 最終課題 : Sonic Piを使用した音楽作品を制作
  • Sonic Piを使用して、3分以内の音楽作品を制作してください
  • 提出するもの
    • Sonic Piで録音したサウンドファイル (3分以内)
      • SoundCloudにアップロードしてURLを記載 – 詳細はスライド資料を参照
    • 作成したSonic Piのプログラム (ファイルを添付)
    • 作品タイトル
    • 作品についての解説 : 100〜200文字程度
    • 提出締切 : 2019年1月7日
  • 提出は、Oh-Meijiのレポートシステムから
  • 1月9日の最終講義で、優秀作品の鑑賞会を行います!

スライド資料


第11回: 最終課題のヒント – インタラクションを表現する

今回は、最終課題のテーマ「インタラクションを表現する」に沿って作品を制作する際のヒントを、サンプルを交えて解説していきます。マウスやキーボードを使用したインタラクション、音を使用したインタラクション、映像を使用したインタラクション、センサーを使用したインタラクションなど様々な入力を処理する方法について紹介します。

スライド資料

最終課題について

最終課題のテーマ「インタラクションを表現する」

外部からの何らかのアクションに対して反応する(インタラクション)作品を、この講義で学んだp5.jsを用いて表現してください。プログラムは、p5.jsを使用していることを条件とします。ただし、他のプログラムと組み合わせても構いません。

ユーザーのアクションはマウスやキーボードだけとは限りません。

  • 映像
  • ネットワーク
  • 各種センサー

など様々な入力に対するインタラクションを斬新なアイデアで表現してください。

提出するもの

  • OpenProcessingに提出した作品のURL
  • 作品タイトル
  • 作品解説 : 200〜400文字程度

提出方法・締切

  • SFC-SFSのレポートシステムより提出
  • 2019年1月7日締切

第13回 : 最終課題のヒント – インタラクション

Reactive Books, John Maeda, 1995 – 1999

最終課題のテーマは「インタラクション」です。

今回は、この最終課題のテーマ「インタラクション」について、課題制作のヒントになりそうなトピックスをとりあげていきます。マウスやキーボードを使用した基本的なインタラクションから、音を使用したインタラクション(ofxFft)、映像を使用したインタラクション(ofxOpenCV、ofxCv) など応用的な内容までカバーしていきます。

最終課題について

最終課題のテーマ「インタラクション」

外部からの何らかのアクションに対して反応する作品を制作し発表してください。openFrameworksを使用していることを条件としますが、他のプログラムと組み合わせても構いません。

ユーザーのアクションはマウスやキーボードだけとは限りません。

  • 映像
  • ネットワーク
  • 各種センサー

など様々な入力を元にしてインタラクションについて面白いアイデアを実現してください。

スライド資料

サンプルファイル


第9回 : Sonic Pi + SuperCollider 1 – Sonic Piで自作Synthをつくる

この講義の前半はSonic Piを使用してライブコーディングを活用した作曲やパフォーマンスについて学びました。そして中盤から後半にかけて、SuperColliderを使用した音響合成の基礎を学んできました。Sonic Piが和声やリズムや旋律といった音楽のマクロな構造を記述するための言語とすると、SuperColliderは波形単位で音を生成するミクロな構造の創作でした。いよいよ今回からは、Sonic PiとSuperColliderを融合して、音のミクロな構造からマクロな構造まで全てを統合していきます。

今回はまず始めの一歩として、SuperColliderで定義した簡単な楽器定義(SynthDef)を、Sonic Piに読み込んで実際に演奏するところまでを解説します。

スライド資料

サンプルコード

//SuperColliderとSonic Piの連携

//基本形
SynthDef("piTest", {
    //出力先のバスを引数で設定
    arg out_bus = 0;
    //440HzのSin波生成
    var mix = SinOsc.ar(440).dup;
    //Envelope生成
    var env = EnvGen.ar(Env.perc(0.0, 1.0, 1.0), doneAction: 2);
    //Envelope適用
    mix = mix * env;
    Out.ar(out_bus, mix);
}
//ファイルの出力先を指定
).writeDefFile("/Users/tado/Desktop/my-synths");

//音程(note)と音量(amp)を受け取る
SynthDef("piTest", {
    //音程と音量を引数を指定
    arg note = 52, amp = 1, out_bus = 0;
    //音程(MIDI番号)から周波数へ
    var freq = note.midicps;
    //周波数をSin波に適用
    var mix = SinOsc.ar(freq).dup;
    var env = EnvGen.ar(Env.perc(0.0, 1.0, 1.0), doneAction: 2);
    mix = mix * env;
    Out.ar(out_bus, mix);
}
).writeDefFile("/Users/tado/Desktop/my-synths");

//エンベロープとPanを適用
SynthDef("piTest", {
    arg out_bus = 0, note = 52, amp = 1, attack = 0, release = 1, pan=0;
    var freq = note.midicps;
    var mix = SinOsc.ar(freq);
    var env = EnvGen.ar(Env.perc(attack, release, 1.0), doneAction: 2);
    //Panを適用
    mix = Pan2.ar(mix * env, pan);
    Out.ar(out_bus, mix);
}
).writeDefFile("/Users/tado/Desktop/my-synths");

//Moog風楽器
SynthDef("piTest", {
    arg out_bus = 0, note = 52, amp = 1, attack = 0, release = 1, detune = 1.01, pan=0;
    var freq = note.midicps;
    var mix =  MoogFF.ar(
        Pulse.ar([freq,freq*0.5], 0.8),
        freq*2.5,
        128
    );
    var env = EnvGen.ar(Env.perc(attack, release, amp), doneAction: 2);
    mix = Pan2.ar(mix * env, pan);
    Out.ar(out_bus, mix);
}
).writeDefFile("/Users/tado/Desktop/my-synths");

第10回: p5.jsで3Dグラフィクスをプログラミング

ここまで、この講義ではp5.jsを用いた2次元のグラフィクスやアニメーションを取り扱ってきました。p5.jsでは、2次元のだけでなく、3次元のグラフィクスやアニメーションを描画することが可能です。

p5.jsの3D描画には、WebGLというウェブブラウザで3次元コンピュータグラフィックスを表示させるための標準仕様を使用してレンダリングを行います。WebGLはグラフィクスカード(GPU)を用いて描画を行うため、とても高速な3Dグラフィクスの表示を可能にしています。

今回は、p5.jsでの3D表示の基本から始めて、アルゴリズムを用いた生成的な3Dグラフィクス表現までを目指します。

スライド資料

サンプルプログラム


第12回: Shader (GLSL) によるGPUプログラミング

Shaderとは、もともとは3Dコンピュータグラフィクスで、シェーディング (陰影処理) をするプログラムのことを指していました。従来は、開発者やデザイナーは、グラフィクスカード (GPU) に固定機能として実装された定形の処理しか使えませんでした (固定機能シェーダー)。2000年代に入って、プログラマブル・シェーダーが登場します。これまでブラックボックスだったシェーダー自体が、プログラム可能になりました。OpenGLではGLSLというプログラミング言語が策定されシェーダーをプログラムすることが可能です。画面上の膨大なピクセル情報を、高い並列処理性能を持つGPUで実行することにより、CPUで実行するよりもはるかに高いパフォーマンスを実現できるようになりました。

今回は、このShaderをopenFrameworksから操作して高度な表現に挑戦します。

スライド資料

サンプルファイル


SuperCollider基礎 2 – 変調合成 (RM, AM, FM)

先週学んだSuperColliderで「楽器」を定義する SynthDef を利用して、様々な音響合成の手法について実際に音を聞きながら学んでいきます。まず今回は、ある信号のパラメーターをもう一つの信号で変化(変調)させる「変調合成」という手法について紹介します。変調合成は、信号の何を変調するのかによって、AM(RM)、FMという種類に分けられます。それぞれの変調合成の音色の違いなどに注意しながら、SuperColliderでの実現のやり方を学んでいきましょう。

スライド資料

コードサンプル

// SuperColliderによる音響合成変調合成1- RMとAM
// RM変調
SynthDef("test-rm",{
    var car, mod, rm;
    mod = SinOsc.ar(880, 0, 1.0);
    car = SinOsc.ar([440,442], 0, 0.5);
    rm = car * mod;
    Out.ar(0, rm);
}).play;


// RM変調2 - マウスでModulatorの周波数を変更
SynthDef("test-rm",{
    var car, mod, rm;
    mod = SinOsc.ar(MouseX.kr(1, 4000, 1), 0, 1.0);
    car = SinOsc.ar([440,442], 0, 0.5);
    rm = car * mod;
    Out.ar(0, rm);
}).play;

// RM変調3 - 2つのModulator
SynthDef("test-rm",{
    var car, mod1, mod2, rm;
    car = SinOsc.ar(440, 0, 0.5);
    mod1 = SinOsc.ar(MouseX.kr(1, 4000, 1), 0, 1.0);
    mod2 = SinOsc.ar([1/6.1,1/7.9]);
    rm = car * (mod1 * mod2);
    Out.ar(0, rm);
}).play;

// AM変調
SynthDef("test-am",{
    var car, mod, rm;
    mod = SinOsc.ar(MouseX.kr(1, 4000, 1), 0, 0.5, 0.5);
    car = SinOsc.ar([440,442], 0, 0.5);
    rm = car * mod;
    Out.ar(0, rm);
}).play;

SynthDef.new("test-am",{
    var car, mod1, mod2, am;
    car = SinOsc.ar(440, 0, 0.5);
    mod1 = SinOsc.ar(MouseX.kr(1, 4000, 1), 0, 0.5, 0.5);
    mod2 = SinOsc.ar([1/8,1/7]);
    am = car * (mod1 * mod2);
    Out.ar(0, am);
}).play;

// AM + LFNoise
(
SynthDef("rand-am",{
    arg freq = 440, amp = 0.5, modFreq = 400;
    var car, mod1, mod2, am;
    car = SinOsc.ar(freq, 0, amp);
    mod1 = SinOsc.ar(LFNoise1.kr(5.reciprocal, modFreq), pi.rand, 0.5, 0.5);
    mod2 = SinOsc.ar(LFNoise1.kr([1/8, 1/7])0, 0.5, 0.5);
    am = car * (mod1 * mod2);
    Out.ar(0, am);
}).add;
)

(
Synth("rand-am", ["freq", 110, "amp", 0.2, "modFreq", 1200]);
Synth("rand-am", ["freq", 220, "amp", 0.2, "modFreq", 200]);
Synth("rand-am", ["freq", 440, "amp", 0.2, "modFreq", 200]);
Synth("rand-am", ["freq", 880, "amp", 0.2, "modFreq", 100]);
Synth("rand-am", ["freq", 1780, "amp", 0.05, "modFreq", 20]);
)

//FM基本
SynthDef("test-fm", {
    arg cfreq = 440, mfreq = 111, index = 200;
    var car, mod;
    mod = SinOsc.ar(mfreq, 0, index);
    car = SinOsc.ar([cfreq, cfreq*1.01] + mod, 0, 0.5);
    Out.ar(0, car);
}).play;

//FMマウスで操作
SynthDef("test-fm",{
    var car, mod;
    mod = SinOsc.ar(MouseX.kr(1, 1000, 1), 0,
        MouseY.kr(1, 10000, 1));
    car = SinOsc.ar([440,442] + mod, 0, 0.5);
    Out.ar(0, car);
}).play;

//FM応用
(
SynthDef("fm1", { arg freq = 440, detune = 2, carPartial = 1, modPartial = 1, index = 3, mul = 0.2;
    var mod, car;
    mod = SinOsc.ar(
        [freq, freq+detune] * modPartial, 0,
        freq * index * LFNoise1.kr(1/10)
    );
    car = SinOsc.ar((freq * carPartial) + mod, 0, mul);
    Out.ar(0, car);
}).add;
)

(
Synth("fm1", ["modPartial", 2.4]);
Synth("fm1", ["modPartial", 2.401]);
Synth("fm1", ["freq", 110, "modPartial", 3.1213, "index", 10]);
Synth("fm1", ["freq", 220, "modPartial", 10.99, "index", 20]);
)
//FM + エフェクト
(
SynthDef("fm2", { arg bus = 0, freq = 440, detune = 2, carPartial = 1, modPartial = 1, index = 3, mul = 0.1;
    var mod, car;
    mod = SinOsc.ar(
        [freq, freq+detune] * modPartial,
        0,
        freq * index * LFNoise1.kr(10.reciprocal).abs
    );
    car = SinOsc.ar((freq * carPartial) + mod, 0, mul);
    Out.ar(bus, car);
}).add;

SynthDef("preDelay", { arg inbus = 2;
    ReplaceOut.ar(
        4,
        DelayN.ar(In.ar(inbus, 1), 0.048, 0.048)
    )
}).add;

SynthDef("combs", {
    ReplaceOut.ar(
        6,
        Mix.arFill(7, { CombL.ar(In.ar(4, 1), 0.1, LFNoise1.kr(Rand(0, 0.1), 0.04, 0.05), 15) })
    )
}).add;

SynthDef("allpass", { arg gain = 0.2;
    var source;
    source = In.ar(6, 1);
    4.do({source = AllpassN.ar(source, 0.050, [Rand(0, 0.05), Rand(0, 0.05)], 1) });
    ReplaceOut.ar(8, source * gain)
}).add;

SynthDef("theMixer", { arg gain = 1;
    ReplaceOut.ar(
        0,
        Mix.ar([In.ar(2, 1), In.ar(8, 2)]) * gain
    )
}).add;
)

(
Synth("fm2", ["bus", 2, "freq", 440, "modPartial", 2.4]);
Synth("fm2", ["bus", 2, "freq", 448, "modPartial", 2.401]);
Synth.tail(s, "preDelay");
Synth.tail(s, "combs");
Synth.tail(s, "allpass");
Synth.tail(s, "theMixer", ["gain", 0.64]);
)

第9回: p5.js Libraryを使う 2 – p5.soundでサウンドプログラミング (2)

今回も前回に引き続きp5.soundを使用したサウンドプログラミングを行います。今回は、前回最後に紹介したFFTによるサウンドの解析の手法を発展させてサウンドのビジュアライズに挑戦します。FFTによって分析されたスペクトルの情報を、色や大きさに変換することで、音を様々な手法で視覚化していきます。

スライド資料

サンプルプログラム