yoppa.org


Live Coding – note 01

ライブコーデイング(Live Coding)に関して調べものや考えたことを、メモとしてブログに残していこうかと。まず始めに、TOPLAPのライブコーディングのマニフェストを、ざっくり訳してみた。あくまで自分用のメモなので、日本語としてちょっと不自然な直訳で、かつニュアンスがちょっと間違っているかもしれないので、原文も併記。

全体を通して、TOPLAPの考える、Live Codingのあるべき姿が感じられて面白い。道具としてコードを書くのではなく、心や思想を表現する手段としてのコードといった感じ。また、コードを隠すな、バックアップするなというあたりに潔癖さを感じた。

マニフェスト草稿

http://toplap.org/wiki/ManifestoDraft を翻訳

以下のことを要望する:

  • 演奏者の思考を、全ての楽器にアクセスできるようにせよ。
  • 蒙昧主義 (反啓蒙主義) は危険だ。スクリーンを見せろ。
  • プログラムは、自身を書き換えることのできる楽器である。
  • プログラムは、超越的であるべきだ。人工言語とはそういうものだ。
  • コードは、そこから聞こえているものと同じように見えるべきだ、根本的なアルゴリズムはその視覚的な出力結果と同じように見えるべきだ。
  • ライブコーディングは道具ではない。アルゴリズムは思想だ。チェーンソーは道具だ。アルゴリズムが時としてチェーンソーより気付かれづらいのは、そのためだ。

我々は連続するインタラクションの深淵さを認めている。しかし、それに加えて以下のものを求める:

  • アルゴリズムの洞察
  • 心の機智の表現豊かで印象的な表出としての、アルゴリズムの熟練した即興
  • バックアップしない

我々は以下のように考えている:

  • オーディエンスはコードの全てを正しく理解させる必要はない。それは、ギターのパフォーマンスを見ている聴衆がギターの弾き方の詳細を知る必要がないのと同じことだ。
  • ライブコーディングは、タイピング操作の巧妙さと素晴しさを表現する印象的なディスプレイを伴なう
  • パフォーマンスは連続したインタラクション、パフォーマーのアートワークの空間の操作、ジェスチャー、表現の詳細に対する率直さを含む。
  • 伝統的な器楽による楽曲における、触覚的なタイミングの逸脱による表現は、コードには必要ない。なぜ過去を模倣するのか? コードを書いて思考を表現することは、それ自身がニュアンスや慣習の開拓になることは疑いようもない。

原文 (ManifestoDraft)

We demand:

  • Give us access to the performer’s mind, to the whole human instrument.
  • Obscurantism is dangerous. Show us your screens.
  • Programs are instruments that can change themselves
  • The program is to be transcended – Artificial language is the way.
  • Code should be seen as well as heard, underlying algorithms viewed as well as their visual outcome.
  • Live coding is not about tools. Algorithms are thoughts. Chainsaws are tools. That’s why algorithms are sometimes harder to notice than chainsaws.

We recognise continuums of interaction and profundity, but prefer:

  • Insight into algorithms
  • The skillful extemporisation of algorithm as an expressive/impressive display of mental dexterity
  • No backup (minidisc, DVD, safety net computer)

We acknowledge that:

  • It is not necessary for a lay audience to understand the code to appreciate it, much as it is not necessary to know how to play guitar in order to appreciate watching a guitar performance.
    Live coding may be accompanied by an impressive display of manual dexterity and the glorification of the typing interface.
  • Performance involves continuums of interaction, covering perhaps the scope of controls with respect to the parameter space of the artwork, or gestural content, particularly directness of expressive detail.
  • Whilst the traditional haptic rate timing deviations of expressivity in instrumental music are not approximated in code, why repeat the past? No doubt the writing of code and expression of thought will develop its own nuances and customs.

TidalCyclesとSuperColliderの連携 – 改訂版

TidalCycles 0.8からは、SuperColliderをベースにしたSuperDirtが標準の音響生成エンジンとなりました。そのため、以前は少し面倒だったSuperColliderで独自に作成した楽器(Synth)との連携が簡単になりました。

以下のチュートリアルは、SuperDirtのGithubリポジトリ内にあるチュートリアルをベースにしています。

セットアップ

以降のサンプルを動かすには、TidalCycles 0.8のセットアップが完了している必要があります。セットアップの手順は下記を参照してください。

基本 – 440Hzのサイン波

まず、シンプルなサンプルを作成してみましょう。440Hzのサイン波を生成するシンプルな楽器を定義します。

これを、Tidalから演奏するには、SuperDirtを起動した状態で以下のように呼び出します。

「sound」省略して「s」だけでも大丈夫です。

Tidal向けに定義されたSynthdefの特徴として、最終出力で、Out.ar(…) ではなく OffsetOut.ar(…) を使用していることに気付きます。これは、Tidalで複雑なリズムを生成する際に、できるだけ正確なタイミングでトリガーされるための工夫です。また、最終出力で、DirtPan.ar(…) を使用しています。これは、Tidalで設定したPanの指定を反映するためのものです。ただし、現状ではまだ反映されていません。また、現在の状態では音がずっと持続してしまい、リズムの切れ目が不明確です。

定位(Pan)と持続時間(Sustain)を設定

もう少し改良して、定位(pan)と音の持続時間(sustain)を設定できるようにしてみましょう。以下のようにSynthdefを修正します。

引数に、sustainとpanが追加されました。設定したsustainの値でエンベロープを生成しています。またpanの値をDirtPan.ar()に指定しています。

では、以下のようにTidalから演奏してみましょう。

左右交互に、0.2秒の長さで音が鳴るようになりました。

音程を設定

次に音程を指定できるようにしましょう。以下のように修正します。

Tidalからは、「n (またはnote)」という指定で音程を設定できます。nが9の時、A5(ピアノの中心のラ)の音程になります。例えば以下のようにして音程を指定します。

エンベロープを変更

エンベロープのカーブを調整することで、音の表情が変化します。例えば、よりパーカッシブなエンベロープに変更してみましょう。

持続時間を調整します。

応用

あとは、SuperColliderの様々なUGens(ユニットジェネレイター)を使用して複雑な音を生成していくことが可能です。例えば、Roland TR-808風のバスドラム。

これを、Tidalから演奏します。

さらに、先程の”testsynth”と同時に鳴らしてみましょう。

さらに、juxや、gapなどで操作してみます。

徐々に複雑なリズムが生成されるようになりました。様々な工夫でオリジナルな表現が可能となりそうです!


TidalCycles 0.8 リリース

TidalCyclesが0.8にアップデートして、いろいろな点で更新がありました。新機能をざっと解説します。

名称

これまでの名称は、「Tidal」でしたが、正式名称は「TidalCycles」、その省略形として「Tidal」と呼ぶということになりました。TidalCycles (or Tidal for short) おそらく、音楽配信サイトと名称が被るからだと思われます…

標準の音響生成エンジンがSuperDirtに

これまでのバージョンは、音を生成するエンジンとしてDirtという独自のプログラムを使用していたのですが、ver 0.8からは、SuperColliderをベースにしたSuperDirtの使用が標準となりました。ただし、以前の”classic” Dirtも併用することは可能です。

インストールが簡略化

SuperDirtが標準になったことから、インストールが大幅に簡略化されました。以下の環境を整備します。

Git

SuperDirtを使用する際に、Git(バージョン管理システム)が必要となります。OS Xであれば、Homebrewからインストール可能です。

Haskell + TidalCycles

OS Xであれば、homebrewを使用して簡単にインストール可能です。

あとは、Haskellのパッケージ管理システムのcabalを使用してTidalCyclesのライブラリをインストールします。

で完了です。

Atom

https://atom.io/からダウンロードしてインストールします。

インストールが完了したら、メニューから edit > settings > install でPackageのインストールを表示して、「Tydalcycles」で検索します。すると以下のプラグインが表示されますので、インストールします。

SuperCollider

SuperColliderのGithubから3.7以降のバージョンをインストールします。

SuperDirtのインストールと起動

SuperDirtのインストールはSuperCollider内から行います。まずSuperColliderを起動して、以下のコマンドを入力して選択した状態にして、command+enterで実行します。

Dirtのサンプルファイルを大量にダウンロードするので、時間がかかります。気長に待ちましょう。以下のメッセージがコンソールに表示されれば完了です。

ここで、全てのライブラリーを再度コンパイルする必要があるため、SuperColliderを再起動します。再起動したら、以下のコマンドを入力して、選択してcommand+enterで実行します。

コンソールに以下のメッセージが表示されたら、SuperDirtの起動が完了です。

Atomを起動して、メニューから、Packages > TidalCycles > Boot TidalCycles を選択してTidalを起動します。あとは、以下のようにテストのコードを入力して、音が出れば完了です!

SuperColliderとの連携が簡単に

SuperDirtの導入により、SuperColliderとの連携が大幅に簡略化されました。これは別稿にまとめます。


Tidalでライブコーディング! – 応用編 : SuperColliderとの連携

注意!! : TidalCycles 0.8からSuperDirtが標準となり、SuperColliderとの連携も大幅に簡略化されました。新しいバージョンでの連携方法は下記を参照してください。

前回の「Tidalでライブコーディング! – 実践編」に引き続いて、応用編です。

Tidalは、基本はDirtというサンプルファイルを再生する専用のプログラムでサンプルを再生しています。しかし、TidalにはOSC (Open Sound Control) を送出する機能があります。このOSC機能を利用することで、SuperColliderやMax/MSP、Pdなど様々な外部の音源を使用してTidalで作成したパターンを再生することが可能です。

今回は、TidalをSuperColliderを連携してみます。

基本: 簡単なサンプル

まずは簡単なサンプルで試してみます。Sin波を生成する楽器をSuperCollider側に作成します。

ここで1つ注意すべき点は、Tidalから演奏する楽器は一度鳴らし始めると自動的に停止することはありません。ですので、あらかじめエンベロープを設定しておき、一定の時間で音が終了するよう、doneAction:2を設定したエンベロープを適用しておく必要があります。

SynthDefの作成が完了したら、SuperColliderをBootして、作成したSynthDefを実行しておきます。

これに対応するTidal側のプログラムを作成します。まず、SuperColliderで作成した楽器と連携する準備をします。まず楽器 “scsine” を定義して、引数の初期値を設定しています。その上で、SuperColliderに渡すTidal側の変数を定義します。

あとは、変数を使用してパターンを作成していきます。

応用: 2つの楽器を定義して演奏

少し複雑なサンプルをみてみましょう。まず2つの楽器 “schh” と “scbass” を用意します。

この楽器を演奏するためのTidal側のプログラムは以下のようになります。


TidalをWindowsでセットアップする

Window環境でのTidal

Tidalは基本的にはUnixベースの環境を前提としているため、Windowsで動かすには、いろいろ設定が必要です。

TidalをWindowsで動かすために、まずCygwinという、Windowsオペレーティングシステム上で動作するUNIXライクな環境をインストールし、そこに必要なライブラリーをインストールした後、Tidalの環境を構築します。

Cygwinのインストール

下記のリンクからダウンロードします。

  • https://cygwin.com/install.html
  • 64bitOSの場合は、setup-x86_64.exe をダウンロードして実行
  • 32bitOSの場合は、setup-x86.exe をダウンロードして実行

インストーラーでインストールを進めると、途中でパッケージを選択する画面になります。ここで、下記のパッケージをsearchから検索して、表示されたパッケージのバージョン番号をチェックをしてインストールする設定にします。

screenshot_594.png

Portaudioのインストール

Portaudioは、パッケージ化されていないので、ダウンロードして手動でビルドする必要があります。まずPortaudioのダウンロードページに行き、安定板(2016年4月現在はpa_stable_v19_20140130.tgz)をダウンロードします。ダウンロードしたpa_stable_v19_20140130.tgzをCygwinのホームにコピーします。その上で、下記のコマンドでPortaudioをインストールします。

Libioのインストール

OSCをやりとりするためのライブラリーlibioもapt-cygではインストールできません。libioのサイトのDownloadにある最新の安定版(2016年4月現在はliblo 0.28)をダウンロードして、下記の手順でインストールします。

Dirtのインストール

Tidalで使用するサンプラー、Dirtをインストールします。Dirtはgithubからクローンします。

ダウンロードしたら、ビルドします。

Haskellのインストール

Tidalのベースとなっているプログラミング言語Haskellをインストールします。まずHaskellのインストールページを開きます。

自動的にWindowsでのインストールのページが表示されます。使用している環境にあわせて、32bit版か62bit版のHaskellのインストーラーをダウンロードします。ダウンロードが完了したら、インストーラーを起動してHaskellをインストールします。

Haskellをインストールしたら、Cygwinを再起動してください。

Tidalのインストール

Cygwinを起動して、下記のコマンドでTidalをインストールします。

これで、完了です!

Atomの設定

Windows版でも、Atomをエディターとして使用可能です。OS X版と同様に、まずAtomをインストールした後、Tidalパッケージを追加します。

TidalパッケージのSettingを開きます。ここでghci.exeへのパスを正しいものに変更します。

  • 例: C:\Program Files\Haskell Platform\7.10.3\bin\ghci.exe

screenshot_596.png

あとは、テストでコードを実行させてみて音が鳴れば、設定完了です!!


Tidalでライブコーディング! – 実践編

Tidalリズムの基本

前回の「Tidalでライブコーディング! – セットアップ編」に引き続いて、こんどはいよいよ実践編です。

Tidalのリズムの組み方の基本はとてもシンプルです。例えば以下の例。

これをcommand-enterで評価すると、バスドラムが一定間隔のリズムを刻みます。この1行の命令にいくつかTidalの命令のポイントが詰まっています。

まず先頭の”d1″の”d”は、Dirtシンセサイザーを演奏するということを意味します。Tidalでは、d1〜d9まで8つのDirtシンセのためのトラックが用意されていて、それぞれ別個にパターンを組んだものをリズムを同期させて演奏することが可能となっています。次の”$sound”でDirtのサンプルを再生する意味になり、最後の”bd”がサンプル名になっています。

Dirtに格納されているサンプルは、Dirtをインストールいたフォルダ以下の”samples”に入っています。ここにフォルダに分かれて整理されていて、例えば”bd”の場合は、”bd”フォルダ内の最初のサンプルファイル”BT0A0A7.wav”が演奏されます。もし、bdフォルダ内の別のファイルを演奏したい場合はコロン「:」で区切って”bd:1, bd:2, bd:3…”と指定していきます。

screenshot_523.png

現在のリズムは、各小節の先頭、1拍目でbdが演奏されています。これを以下のように変更してみましょう。

すると、1拍目と3拍目に演奏されるようになります。つまり、1行に書いた楽器がその小節の中で均等な間隔で演奏される仕組みです。これと同じリズムを以下のように書くこともできます。

さらに

というようにどんどん分割していけるわけです。

もちろん複数の音を鳴らすことも可能です。バスドラムとスネアを交互に鳴らしてみます。

休符は ~ で表現します。

演奏している音を止めるときはsilenceを指定します。

リズムを分割、ネスト

もう少し複雑な例をみてみましょう。

ここで新たに大括弧 [] が出てきています。これは、分割されたリズムの中でさらに分割することを意味します。この例では2拍目でスネアを2回演奏することを意味します。さらにこれを入れ子状に複雑に組み合せていくことも可能です。

音を混ぜる

“stack”という命令を使うと、1つのトラックの中に複数のリズムを重ねていくことが可能です。

というように書いていきます。実際には、例えば以下のようになります。コンマで区切ってどんどんパターンを追加してMixしていけます。

トラックごとに、音量や定位(パン)を指定することも可能です。|+| という記号で繋いで指定していきます。最後のトラックはランダムにパンを指定しています。

モジューレーション

Tidalではパート全体に対して、様々な変化を加える関数が多数用意されています。これらを組み合わせるととても複雑なパターンが生まれます。例えば、jux という関数は左右で音をずらしたり反転させることで、複雑な定位を生成します。

gap や chop を使うと、音が細かくぶつ切りになります。

毎回モジュレーションをかけるのではなく、特定のタイミングのみで適用することも可能です。たとえば、毎回4小節ごとにchopをかけ、6小節ごとにgapをかけてみましょう。everyという命令を使います。

さらに、juxのずらし方をすこしずつ変化させてみます。iterという命令をつかうと、数が小節ごとに増加していき指定した数でサイクルします。例えば、iter 4と指定すると、0, 1, 2, 3, 0, 1, 2, 3… というパターンが生まれます。

基本から徐々に積み上げていき、最終的にはとても複雑なリズムが生成されました!

次回につづく! (予定)


Tidalでライブコーディング! – セットアップ編

注意!! : TidalCyclesがver 0.8にアップデートされ、インストールが大幅に簡略化されました。新しいバージョンでのインストール方法はこちらを参照してください。

Tidalとは?

Tidalは、Alex McLean氏によって開発されたHaskellを拡張したライブコーディング(Live Coding)環境です。

そもそもライブコーディングとは何かというと、ざっくりと言うと、プログラムをリアルタイムに実行しながらコーディングする行為自体をパフォーマンスするジャンルです。主に、音楽や映像を生成することが多いですが、Webや詩などその適用範囲は拡がっています。

Tidalは、こうしたライブコーディングの環境の中でも、リズムパターンの生成に特化した環境となっています。シンプルな文法で複雑なリズムパターンをリアルタイムに生成し変奏していくことが可能となっています。どんなことができるのか理解するには、まずはデモ映像を観てみるのが早いかもしれません。

Tidalは、Mac OS X、Linux、Windowsで動きます。

Tidalのインストール

ここでは、OS Xの環境に絞って説明します。その他のOSのインストール方法は、オフィシャルのドキュメントを参照してください。

OS XのインストールではHomebrewを使用します。Homebrewが入っていない場合はまずインストールします。(既にHomebrewを使用している場合は必要ありません)。

Tidalは、大きく分けて2つのパートから構成されています。1つはリズムを生成するTidal本体。これはHaskellのパッケージとしてインストールします。2つ目は“Dirt”というサンプラーです。様々なリズムやシンセサイザー、効果音などがプリセットされていてHaskellから呼び出されてサウンドを生成します。ここでは触れませんが、応用として、TidalはDirtを使わずに外部のMIDI音源やソフトシンセ、さらには、Max/MSPやSuperColliderなどの言語とOSCで連携することも可能です。

Dirtをインストールしていきます。まずは必要なライブラリーをインストール。

その後、TidalとDirtを連携するため、Jackをインストールします。

Dirtの本体をGithubからダウンロードしてインストールします。まずインストールしたいディレクトリに移動してから以下のコマンドでインストールします。

次にHaskellの実行環境を構築します。TidalではGHCというHaskellのコンパイラとインタプリタを利用します。これもHomebrewから。

次にGHCのパッケージ管理システムであるcabalを利用して、Tidalの本体をインストールします。

これでインストールの完了です!

エディターのインストール

しかし、まだこれだけではTidalを使うことはできません。Tidalでは既存のテキストエディターからHaskellのインタプリタを呼び出して使用する仕組みになっています。オフィシャルに対応しているテキストエディターは、現状では、EmacsとAtomです。(Haskellを動作させることができるエディターであれば他でも使用できるものがあるかもしれません。)

ここでは、導入が簡単なAtomを使用する方法を紹介します。

Atomエディターを持っていない場合は、下記からダウンロードします。

Atomを起動して、settings > install の検索欄で「Tidal」を検索します。おそらくトップにTidalのプラグインが表示されるので、インストールします。

screenshot_516.png

実行してみる!

では、いよいよ実行してみましょう!

まず、Dirtをインストールしたディレクトリに移動して、Jackのデーモンを起動します。

次にDirtを起動します。

これで、準備完了です。次にAtomで新規ファイルを開き「xxx.tidal」というファイル名で保存します。するとファイルタイプが「Tidal」になるはずです。

この状態で、メニューバーから Package > Tidal > Boot Tidal を選択します。

試しに以下のパターンを入力してみます。

d1 $ sound “909 ~ bass bass:2”

リズムパターンが再生されるはず!? (実践編につづく予定)


openFrameworks + ofxMSATensorFlow でディープラーニングを試してみる (OS X版)

ディープラーニングとofxMSATensorFlow

最近、何かと話題のディープラーニング(Deep Learning / 深層学習 / 機械学習)。TensorFlow、Chainer、Caffeなど様々な便利なライブラリもフリーで入手可能で、ずいぶんと敷居が下がってきた印象だ。

そんな中、イケメン天才アーティストのMemo Akten氏によって、openFrameworksでTensorFlowが使用できる、ofxMSATensorFlowというアドオンが公開された。早速、OS Xで動かしてみたので、設定方法をシェア。

※ 動作を確認したOSは、OS X 10.11 (El Capitan) のみです。

インストール

まずは、Githubからアドオンの本体をダウンロード。従来のアドオンと同様に、openFrameworksのルート/addons/ofxMSATensorFlow に配置する。

  • https://github.com/memo/ofxMSATensorFlow

本来は、C++でTensorFlowを動かすためにいろいろ設定が必要なのだが、様々なプラットフォームごとにTensorFlowが環境構築されたシェアードライブラリが配布されている(親切!!)。ありがたく、これを使用する。OS Xの場合は、下記のリンクから ofxMSATensorFlow_lib_OSX_2016_02_21_v0.7_CPU.zip をダウンロードして解凍する。

  • https://github.com/memo/ofxMSATensorFlow/releases

中には libtensorflow_cc.so というライブラリが入っている。ofxMSATensorFlowではこれをホームディレクトリ直下のlibフォルダに配置して使用するように設定されている。以下のように設定

Xcodeでサンプルを動かしてみる

MemoさんはQTCreatorで動かしているようなのだが、できることなら手に馴染んでいるXcodeで動かしたい。以下のように設定して無事サンプルを動かすことができた。まずは、基本サンプルの example-basic で試してみる。

ProjectGeneratorで、example-basicフォルダを選択してインポートする。自動的にaddonにはofxMSATensorFlowが入っているはずなので、そのままプロジェクトをUpdateする。(少し時間がかかる)

screenshot_254.png

TensorFlowのライブラリは既にシェアドライブラリとして持っているので、addonフォルダ内のものは必要ない。addons/ofxMSATensorFlow/libs/tensorflow をフォルダごと参照を削除。

Slice 1.png

また、このサンプルは、ofApp.hやofApp.cpp、main.cppを使用していない。srcフォルダ内で赤くなっているファイルを削除する。

screenshot_257.png

ここに、先程のライブラリを追加する。libsフォルダを右クリックして、”Add Files to …” を選択。ファイルダイアログから、libフォルダ内の libtensorflow_cc.so を選択する。結果以下のようになるはず。

screenshot_256.png

あとは、Buildするだけ。こんな感じのサンプルが実行される(はず)!!

screenshot_258.png

MNISTを試してみる

MNIST(Mixed National Institute of Standards and Technology) とは、28x28pxの60000枚の学習サンプル、10000枚のテストサンプルからなる手書き数字画像データベースで、機械学習の世界ではこれを使って手書きの数字を認識させるのが “Hello World” 的な定番サンプルとなっている。ofxMSATensorFlowでもMNISTのサンプル example-mnist があるので、試してみる。

ただし、まず学習データが必要。こちらは別途ダウンロードする

  • https://github.com/memo/ofxMSATensorFlow/releases/download/v0.0/example-inception3-data.tar.gz

解凍したフォルダ model-deep と model-deep の2つを、example-mnist/bin/data以下に配置する。

あとは、先程の example-basic と同じ手順でビルドできるはず。マウスで描いた数字を瞬時に判別する。ディープラーニングすごい!!

screenshot_252.png


openFrameworks、なんでポインタを使うのか?

openFrameworksをワークショップや授業などで教えていると、ポインタの概念にさしかかった時に突然抽象的になってしまい、挫折する人が出てきてしまう。自分のためのメモも兼ねて、なぜポインタを使うのか、抽象的な解説ではなくopenFrameworksでの分かりやすい実例をベースにして考えてみた。

ダメな例

例えば、以下のように画像をランダムな場所に表示するShowImageという簡単なクラスをつくったとする。

ShowImage.hpp

ShowImage.cpp

これを、ofAppから繰り返し生成して配列に格納し、表示していく。画像ファイルの読み込みはofAppで行い、ShowImageクラスに読み込んだ画像を代入していく。

ofApp.h

ofApp.cpp

これを実行するとどうなるか。画像のファイルサイズにもよるが、みるみるうちにメモリを消費していき、FPSも極端に落ちていく。実行しているマシンのメモリサイズにもよるが、ずっと起動していると最終的にはアプリごと落ちる。全然ダメダメなプログラムだ。

ポインタで指し示す

では、どのようにすればパフォーマンスが改善するのか? 「ダメな例」の最大の問題は、ShowImageにイメージを代入しているので、ShowImageクラスをインスタンス化して画像を代入する毎に画像ファイルの容量だけメモリを消費している。代入しているということは、つまりは画像のデータをそのままコピーしている状態になっている。

ここで、ポインタを活用する。ポインタのざっくりしたイメージは、データの実態ではなく、その参照先を「指し示して(Point)」いる機能だ。例えば、先程の例だと巨大な画像データの実態そのものをコピーしてくるのではなく、あそこに画像のデータがあるよと「指し示す」ことができる。

ShowImageから画像を描画する際には、imageは実態ではなくその参照先を指し示すポインタ *image になったので、以下のようにアロー演算子 “->” を使用するように変更する。このアロー演算子の形が、まさに指し示す矢印の形になっている。

ざっくりとしたイメージを図示するとこんな感じか?

pointer_image2.jpg

改良したプログラム

「ダメな例」を修正して、画像像を直接コピーするのではなく、ポインタとして指し示すように変更したプログラムは以下のようになる。

ShowImage.hpp

ShowImage.cpp

ofApp.h

ofApp.cpp

これで、ずっと起動していてもイメージ1個だけのメモリしか消費せず、ShowImageからはそのイメージのデータを参照しているだけなので、安定して稼動するプログラムになるはず! (とはいえ、永久にオブジェクトを複製し続けるので、ずっと起動してると落ちるかも…)

追記: 参照渡し

何人かの方から、この例ではポインタではなく参照をつかったほうが良いのではないかという指摘がありました。どちらが適切なのか、ポインタと参照のどちらをまず覚えるべきなのか、いろいろ難しい議論ですが、とりあえず、ポインタ渡しではなく参照渡しをして描画する例を掲載します。(間違いあればご指摘を)。

ShowImage.hpp

ShowImage.cpp

ofApp.h

ofApp.cpp

たしかに、参照渡しを使うほうが、わかりやすいような気もしてきた… C++は奥深い…


openFrameworks + GLSLでクロマキー合成

screenshot_199

(追記) : すぐに使えるように、addon化してみた! (openFrameworks 0.9.0 〜)

ちょっと仕事でプログラムしていた際に調べたコネタ。

画像やムービー素材を背景に合成して表示したい場合、もとの素材がPNG形式などでアルファ値で透明度が指定されている場合は問題ないのだけれど、背景が黒や緑などの単色ベタ塗りになっていたときには、いわゆる「クロマキー」的な処理をする必要がある。

Shader(GLSL)を知らなかった頃は、画像の全てのPixel情報をとり出して、特定のチャンネルを描画しないなどの力技でやろうとしてみたけど、CPUへの負荷が尋常でないので、大きな画像素材では現実的ではない。

そこで、openFrameworks + GLSLでクロマキー合成をする方法を調べてみた。

WebGL用に実現しているブログがとてもわかり易く理解できた。

こちらを参考に、openFrameworks用に移植してみた。

まずはShaderのソース。vertex shaderは、こんな感じ。

  • chromaKey.vert

こちらは、テクスチャーの情報をfragment shaderに渡してるだけ。

次にfragment shader。

  • chromaKey.frag

キーの色と閾値をuniformにして、外部から指定できるようにしているのがポイント。これで汎用性のあるクロマキー合成用Shaderとして活用できる。

これをopenFrameworks側で利用する方法はこんな感じ。

  • ofApp.h

  • ofApp.cpp

閾値を設定することで、例えばちょっと背景との境界がボケている画像でも。

source

こんな感じできれに合成できる!

screenshot_198

もちろん動画でも簡単!

  • ofApp.h

  • ofApp.cpp

爆発もきれいに合成できました!

screenshot_199