Shaderとは、もともとは3Dコンピュータグラフィクスで、シェーディング (陰影処理) をするプログラムのことを指していました。従来は、開発者やデザイナーは、グラフィクスカード (GPU) に固定機能として実装された定形の処理しか使えませんでした (固定機能シェーダー)。2000年代に入って、プログラマブル・シェーダーが登場します。これまでブラックボックスだったシェーダー自体が、プログラム可能になりました。OpenGLではGLSLというプログラミング言語が策定されシェーダーをプログラムすることが可能です。画面上の膨大なピクセル情報を、高い並列処理性能を持つGPUで実行することにより、CPUで実行するよりもはるかに高いパフォーマンスを実現できるようになりました。
今回は、このShaderをopenFrameworksから操作して高度な表現に挑戦します。
スライド資料
サンプルファイル
今回のサンプルプログラムは、WSのGithubリポジトリのweek12を参照してください。
今回も前回に引き続きProcessingによる音の可視化について探求していきます。今回は最終課題を見据えて、より実践的なプログラムをいくつか紹介していきます。
スライド資料
サンプルプログラム
本日使用したプログラムのサンプルは、以下からダウンロードしてください。
最終課題について
次回(24日)の講義で、最終課題を発表を希望する方は、以下から申し込みしてください。
最終課題: Processingを用いた音響の視覚化
Sonic Piを用いて生成した音響作品をProcessingで視覚化した、30秒から1分程度のオリジナルのオーディオ・ビジュアル作品を制作してください。
提出物:(重要!!)
- 音を生成したSonic Piのプログラムソース
- ビジュアルを生成するProcessingのプログラムソース
- Processingプログラムのスクリーンショット (一番かっこいい瞬間を捉える!)
締切
2017年7月31日
提出方法
3つの提出データ(Sonic Piソース、Processingソース、スクリーンショト)を圧縮せずにメールに添付して提出。その際に以下の情報もあわせて本文に入力してください。
- 作品タイトル
- 学籍番号
- 氏名
提出先
tadokoro+teu17@gmail.com
課題制作テンプレート
minimのFFTを使用した音響の可視化のプログラムのテンプレートです。課題制作に利用してください。
import ddf.minim.analysis.*;
import ddf.minim.*;
Minim minim;
AudioPlayer player;
FFT fft;
//FFTサイズ (2の冪乗で指定)
int fftSize = 512;
void setup() {
size(800, 600);
//minim初期化
minim = new Minim(this);
//サウンドファイル読み込み
player = minim.loadFile("recording.wav", fftSize);
//サウンドファイル再生
player.loop();
//FFTの初期化
fft = new FFT(player.bufferSize(), player.sampleRate());
}
void draw() {
background(0);
//左チャンネル
fft.forward(player.left);
for (int i = 0; i < fft.specSize(); i++) {
//スペクトラムデータは -> fft.getband(i);
}
//右チャンネル
fft.forward(player.right);
for (int i = 0; i < fft.specSize(); i++) {
//スペクトラムデータは -> fft.getband(i);
}
}
この講義では、前半にProcessing、後半はRhinoceros+Grasshopperを使用してメディアアートのためのプログラミングの基礎を学んできました。今回は、これまでのまとめと、ここから先へ進むためのステップについて解説します。
Processingの基礎を身に付けてから次に進む様々な手段がありますが、ここでは次の3つの方法を紹介します。
- Processingの機能を拡張する – ライブラリー (Libraries)
- Webブラウザ上で表現する – p5.js
- さらに高速化を追い求める – openFrameworks
ライブラリー(Libraries)とは、汎用性の高い複数のプログラムを、再利用可能な形でひとまとまりにしたものです。Processingでもライブラリーを活用して機能自体を拡張していくことが可能です。Processingのライブラリーを紹介するWebページを参照すると、膨大な量のライブラリーが公開されています。今回はライブラリーのインストール方法と代表的なライブラリーをいくつか紹介します。
p5.jsは、Javascript版のProcessingです。Javascriptをベースにしている最大の利点はWebブラウザー上で実行可能という点です。作成したスケッチをWebサーバー上ですぐに世界に向けて公開可能です。文法はProcessingをベースにしているので、習得も容易です。ただし、ベースとなる言語が違うため若干オリジナルのProcessingと異なる部分もあります。この差異に注意しつつ、p5.jsでのプログラミングの導入方法を解説します。
openFrameworksは、クリエイティブコーディングのためのC++のオープンソースツールキットです。その最大の利点はスピードです。Processingでは処理が追いつかずコマ落ちしてしまうような表現も高速な演算で実現可能です。より本格的な作品制作を目指す方にはProcessingを習得した後、openFrameworksにステップアップすることをお勧めします。openFrameworksには、Processingのライブラリーにあたるアドオン(addons)という拡張機能があり、膨大な数のアドオンが公開されているのも魅力の一つです。
自分の作品の表現形態やテーマにあわせて、次のステップへ進んでいきましょう!
スライド資料
この講義では、前半にProcessingを使用したインタラクティブなアニメーションの基本、後半はSonic Piを使用したサウンドプログラミングを行ってきました。今回はいよいよこの両者を融合して、音と映像を同時に用いた表現に挑戦していきたいと思います。
まず始めにProcessingを用いて音を視覚化する方法を検討します。単純に感覚的手法で視覚化するのではなく、音を周波数成分に分解しその変化を視覚的に表現します。ここでは、FFT(高速フーリエ変換)という手法を用います。
次に、この視覚化の手法を用いて、Sonic Piで作成してレコーディングした音をProcessingで読み込み、視覚化する方法について解説します。サウンドの解析には、Processingのコアライブラリである、Soundライブラリーを使用します。
スライド資料
サンプルコード
サウンドファイルの再生
//Soundライブラリーの読み込み
import processing.sound.*;
//サウンドプレイヤー
SoundFile soundfile;
void setup() {
//サウンドファイルを読み込んでプレイヤーを初期化
soundfile = new SoundFile(this, "sound.aiff");
//ループ再生
soundfile.loop();
}
void draw(){
}
マウスで再生スピードと音量を変化
//Soundライブラリーの読み込み
import processing.sound.*;
//サウンドプレイヤー
SoundFile soundfile;
void setup() {
size(800, 600);
//サウンドファイルを読み込んでプレイヤーを初期化
soundfile = new SoundFile(this, "sound.aiff");
//ループ再生
soundfile.loop();
}
void draw() {
background(0);
//マウスのX座標で再生スピードを設定
float rate = map(mouseX, 0, width, 0.0, 2.0);
//マウスのY座標で音量を設定
float amp = map(mouseY, 0, height, 1.0, 0.0);
//再生スピードを適用
soundfile.rate(rate);
//音量を適用
soundfile.amp(amp);
}
音量を円の直径に反映
//Soundライブラリーの読み込み
import processing.sound.*;
//サウンドプレイヤー
SoundFile soundfile;
//音量解析
Amplitude rms;
void setup() {
size(800, 600);
fill(0, 127, 255);
noStroke();
//サウンドファイルを読み込んでプレイヤーを初期化
soundfile = new SoundFile(this, "sound.aiff");
//ループ再生
soundfile.loop();
//音量解析を初期化
rms = new Amplitude(this);
//音量解析の入力を設定
rms.input(soundfile);
}
void draw() {
background(0);
//音量を解析して値を調整
float diameter = map(rms.analyze(), 0.0, 1.0, 0.0, width);
//取得した音量で円を描く
ellipse(width/2, height/2, diameter, diameter);
}
FFTによるスペクトラム表示
//Soundライブラリーの読み込み
import processing.sound.*;
//サウンドプレイヤー
SoundFile soundfile;
//オーディオデバイス
AudioDevice device;
//FFT(高速フーリエ変換)
FFT fft;
//FFTサイズ
int bands = 1024;
//グラフの高さのスケールを設定
float scale = 20.0;
void setup() {
size(800, 600);
fill(0, 127, 255);
noStroke();
//オーディオバッファーの設定
device = new AudioDevice(this, 44000, bands);
//サウンドファイルを読み込んでプレイヤーを初期化
soundfile = new SoundFile(this, "sound.aiff");
//ループ再生
soundfile.loop();
//FFTの初期化
fft = new FFT(this, bands);
fft.input(soundfile);
}
void draw() {
background(0);
//FFT解析実行
fft.analyze();
noFill();
stroke(255);
//線分の描画開始
beginShape();
//FFTのバンドの数だけくりかえし
for (int i = 0; i < bands; i++) {
//FFTの解析結果を高さにグラフを描く
vertex(i * width/float(bands), height - fft.spectrum[i] * height * scale);
}
//線分の描画終了
endShape();
}
引き続き、IoT植物生育データのビジュアライズについて考えていきます。
今回は、カメラで記録し続けた大量のデータをどのように扱っていけば良いのかについて考えます。openFrameworksに大量の画像ファイルを読み込むには、ofxThreadedImageLoaderを使用すると便利です。まず、ofxThreadedImageLoaderを使用して連番のデータをプログラムに読み込んで再生してみます。さらに、読み込んだデータを3Dオブジェクトのテクスチャーとして貼りこむ方法についても紹介します。
スライド資料
サンプルプログラム
今回のサンプルプログラムは、WSのGithubリポジトリのweek11を参照してください。
引き続きSonic Piを使った音楽プログラミングについて考えていきます。
今回は、Sonic Piにおけるプログラムの構造化とデータ構造に焦点を絞って解説していきます。構造化プログラミング言語における基本的なプログラム構造は「順次」「反復」「条件分岐」の3に代表されます。Sonic Piでもこの3つのプログラム構造を作成することが可能です。実際に音に出して確認しながらSonic Piにおけるプログラムの構造化を学びます。
もう1つデータ構造について考えます。Sonic Piでは「リスト」というデータ構造が多用されます。リストとはデータの一覧を構成するデータの型です。まず始めにリストの使用法を解説します。さらにSonic Piでは多くの和音(chord)と音階(scale)がリスト形式で定義されています。和音と音階の使用方、また和音や音階による即興について考えていきます。
スライド資料
課題: 和音、音階を利用して旋律を作る
- Sonic Piの和音(chord)もしくは音階(scale)を使用してループする旋律(メロディー)を作曲してください
課題の提出方法
- emailで提出
- To : tadokoro+teu17@gmail.com
- Subject: 課題7
- 作成したプログラムのソースコードを本文にカット&ペースト
- 本文に以下の内容を記入して提出
- 学籍番号
- 氏名
- 締切: 次回の講義開始時間 (7月10日 16:45) まで!
サンプルコード
# 回数を指定した反復
3.times do
play 50
sleep 0.5
sample :elec_blup
sleep 0.5
play 62
sleep 0.25
end
#反復のネスト(入れ子)
4.times do
sample :drum_heavy_kick
2.times do
sample :elec_blip2, rate: 2
sleep 0.25
end
sample :elec_snare
4.times do
sample :drum_tom_mid_soft
sleep 0.125
end
end
#条件分岐
i = 0
loop do
if i % 4 == 0 then
sample :drum_heavy_kick
else
sample :drum_cymbal_closed
end
sleep 0.125
i = i+1
end
#ifとone_in
loop do
if one_in(3)
sample :drum_heavy_kick
else
sample :drum_cymbal_closed
end
sleep 0.125
end
#ifとone_in2
loop do
if one_in(3)
sample :drum_heavy_kick
sleep 0.25
else
sample :drum_cymbal_closed
sleep 0.125
end
end
#複数のリズムの共存
live_loop :live do
sample :drum_heavy_kick
4.times do
sample :elec_blip2, rate: 2
sleep 1.0/8.0
end
sample :elec_snare
4.times do
sample :drum_tom_mid_soft
sleep 0.125
end
end
live_loop :live2 do
sample :drum_heavy_kick
3.times do
sample :elec_blip2, rate: 2
sleep 1.0/8.0
end
sample :elec_snare
4.times do
sample :drum_tom_mid_soft
sleep 0.125
end
end
#和音
play chord(:C4, :major)
sleep 1.0
play chord(:C4, :major7)
sleep 1.0
play chord(:C4, :minor)
sleep 1.0
play chord(:C4, :minor7)
sleep 1.0
play chord(:C4, :dim)
sleep 1.0
play chord(:C4, :dim7)
sleep 1.0
play chord(:C4, :sus2)
sleep 1.0
play chord(:C4, :sus4)
sleep 1.0
play chord(:C4, :augmented)
sleep 1.0
#アルペジオ
play_pattern_timed chord(:C4, :major), 0.25
sleep 0.5
play_pattern_timed chord(:C4, :major7), 0.25
sleep 0.5
play_pattern_timed chord(:C4, :minor), 0.25
sleep 0.5
play_pattern_timed chord(:C4, :minor7), 0.25
sleep 0.5
play_pattern_timed chord(:C4, :dim), 0.25
sleep 0.5
play_pattern_timed chord(:C4, :dim7), 0.25
sleep 0.5
play_pattern_timed chord(:C4, :add9), 0.25
sleep 0.5
#アルペジオ2
play_pattern_timed chord(:C4, :major), [0.25, 0.5]
sleep 0.5
play_pattern_timed chord(:C4, :major7), [0.25, 0.5]
sleep 0.5
play_pattern_timed chord(:C4, :minor), [0.25, 0.5]
sleep 0.5
play_pattern_timed chord(:C4, :minor7), [0.25, 0.5]
sleep 0.5
play_pattern_timed chord(:C4, :dim), [0.25, 0.5]
sleep 0.5
play_pattern_timed chord(:C4, :dim7), [0.25, 0.5]
sleep 0.5
play_pattern_timed chord(:C4, :add9), [0.25, 0.5]
sleep 0.5
#スケール(音階)
play_pattern_timed scale(:C4, :major), 0.25
sleep 0.5
play_pattern_timed scale(:C4, :minor), 0.25
sleep 0.5
play_pattern_timed scale(:C4, :aeolian), 0.25
sleep 0.5
play_pattern_timed scale(:C4, :ahirbhairav), 0.25
sleep 0.5
play_pattern_timed scale(:C4, :augmented), 0.25
sleep 0.5
play_pattern_timed scale(:C4, :augmented2), 0.25
sleep 0.5
play_pattern_timed scale(:C4, :bartok), 0.25
sleep 0.5
#スケールとchooseによる即興
use_synth :prophet
live_loop :live do
play choose(scale(:c3, :minor, num_octaves: 3)), cutoff: rrand(60, 100)
play choose(scale(:c4, :minor, num_octaves: 3)), cutoff: rrand(60, 100)
play choose(scale(:c5, :minor, num_octaves: 3)), cutoff: rrand(60, 100)
sleep 0.25
end
#ライヒ Piano Phase
notes = [:E4, :Fs4, :B4, :Cs5, :D5, :Fs4, :E4, :Cs5, :B4, :Fs4, :D5, :Cs5]
use_synth :prophet
with_fx :reverb do
live_loop :reich1 do
i = 0
12.times do
play (notes[i]), release: 0.4, pan: 0.8, cutoff: 80
sleep 0.15
i = i + 1
end
end
live_loop :reich2 do
i = 0
12.times do
play (notes[i])+12, release: 0.4, pan: -0.8, cutoff: 80
sleep 0.151
i = i + 1
end
end
end