Source Code: 0-start.pl
Source Code: 1-intro.pl

OtoPerl - perl でライブ・サウンド生成しよう。
OtoPerl - live sound generation with Perl.

Haruka Kataoka

自己紹介

Haruka Kataoka 片岡ハルカ

  • 東京大学理学部情報科学科 学部卒(五十嵐研究室)
  • 株式会社アーキネットにて 1人エンジニア
  • 2009年末より自由業
  • Webサイト開発や、プラベートでPerlを利用

開発動機

動機1

  • PerlやPythonを使い、音声ファイルを出力して遊んでいた
  • →リアルタイムにできないだろうか?
  • 「(速度的に)無理じゃない?」と言われて逆にやってみたくなった

動機2

  • Dominik Eulberg インタビューから
  • テクノやアヴァンギャルド系の、コンピュータを中心に使用したライブに関する定番の批判
  • どうしても 演奏が地味になってしまう/何をしているかわからない。

「メールチェックライブ問題」

  • 解決策として…
  • 生演奏を入れる
  • デバイスを使う(センサー, Wiiリモコン...)
  • 実際にはPCからの出音に対し、生演奏やデバイス等の操作が「おまけ」「飛び道具」となりがちである。

逆に、キーボードを叩きまくるライブは?

  • 「仕事中毒のビジネスマンみたいな」
  • 「ソフトウェア開発の修羅場みたいな」
  • コーディングのみで即興演奏
  • コーディングしている所を見せつける事で、メールチェック…といった批判ができないくらいに
  • さらに、コーディングしている画面をプロジェクタで見せれば完璧!?

先行事例

Max/MSP, pd

  • ビジュアルプログラミングは、通常のプログラムに慣れたプログラマーには辛い

csound, Processing

  • コンパイルが必要で、コーディングによる即興演奏はできない

SuperCollider, Chuck, Impromptu

  • 専用言語を覚える必要があったり、元となっている言語の機能をフルに使えなかったりする
  • ライブでコーディングするには、すぐに、早く書けて、なんでもできる単語がよい。そんな便利な言語と言えば…やはり…

perl

  • なんでもできる!
  • 早い!(書くのが) 
  • かっこいい!

使用例

  • otoperld というサーバを起動すると、テストトーンが鳴ります。
  • コードを書いて otoperlc というスクリプトでポストします
  • モジュールをロードする際も otoperlc を使います
  • コードを編集してポストしなおすと、上書きされます
  • 波形を生成する wave という関数を上書きする事で、音色を サイン波 - 矩形波 - ノコギリ波 - 無音 と音を出したまま変更します。
Source Code: 3-examples.pl
  • 様々なシンセサイザー的サウンドを試します ( サイン波 - 矩形波 - AM - PWM - 音階 - エンベロープ - FMシンセ - ローパスフィルター )
Source Code: 4-file.pl 4-fileplay.pl
  • AIFFファイルのサウンドデータを読み込んで再生します。再生位置からサウンドデータを読み取る関数を上書きして、様々なエフェクトをかけます ( ピッチ変調 - コーラス効果 - ショートループ ) ( サンプル元として Akichans / "Dansei Lotion" (100yenLABEL) を使用しています。 )
Source Code: 5-noise.pl
  • 極端なFM変調を利用したノイズ・サウンドの例です。
Source Code: otoperl-sample.pl
  • github で配布中のサンプルファイル otoperl-sample.pl のサウンドです。

実装について

基本的な実装1

  • AudioUnit (CoreAudio) で音を出します。
  • AudioUnit からコールバックされるC関数からPerlで波形データを作るサブルーチンを呼び出し、波形データを AudioUnit に返します。

基本的な実装2

  • 波形データを作るPerlサブルーチンをevalで上書きする
  • HTTP::Server になって perl コードの POST を受け取り eval する

最初のotoperld実装

  • 結論:上手く行かなかった
  • Perl中に AudioUnit を呼び出す C を埋め込む方針
  • XS, Inline::C, SWIG を検討
  • Inline::C が簡単そうなので開始

ithreadsを使わない場合

  • AudioUnit からのコールバックは別スレッドになる
  • thread 間で Perl の関数呼び出し stack 等は共有されてしまう

Segmentation Fault

  • AudioUnit コールバックからの Perl stack へのアクセスと HTTP Server 側の stack へのアクセスがぶつかる
  • 両者の同期を取る方法が見つからず、この実装はできなかった。

ithreadsを使った場合

  • thread 間で stack が分離できる
  • 所謂(POSIX スレッド等の)スレッドと違い、実行コードも複製されている(インタプリタが複製されている)共有変数以外は、殆ど別プロセス

ithread

  • evalしたコードの変更が 別の ithread には反映されない
  • 共有変数でもサブルーチンを渡す事はできない
  • 殆どプロセスみたいな…
  • ithread 間で上書きされたコードを

別の実装案

  • AudioUnit駆動部分とPerlからの波形生成部分を別プロセスにして、UDP通信で波形データを送る実装アイデア(これは実装していない)

現在の実装

  • C のコードに perl を埋めこむ perlembed
  • HTTPサーバ と CoreAudio のコールバック の2スレッド
  • コードのevalとCoreAudioのコールバックは同じPerlインタプリタで。

C + embedded perl

  • これでうまく実装できた
  • 条件変数でコードのevalとAudioUnitからのコールバックを排他
  • この方針だと、AudioUnit化してDAWで実行できる様になるかも?

問題点

なんでも実行し放題, 危険!

  • otoperldはなんでも実行し放題。
  • IPフィルタとかの実装が必要
  • 複数のユーザが同時に1つのサーバにアクセスできるので、これを使って面白い演奏もできるかも。

use で死ぬ問題

  • evalしたコードに use や require が入っているとSegmentation fault で死ぬ。
  • モジュールのファイルを1つづつotoperlcで読み込ませる事は可能。
  • useできるとCPANモジュールが使えて便利なのに!

CPU利用率を下げたい

  • Core i5 MBP で、矩形波(ファミコンチックな音)6音同時再生で途切れだす。
  • Cとperl の繋ぎはこれ以上早くならないの?
  • Perl側マルチスレッド/プロセスで複数の音源を別々に実行→C側でミックス

今後の展開

実験的な用途に限らず、どんな曲でも作れる様に

  • シンセ
  • エフェクター
  • サンプラー
  • シーケンサー(MML風の)

外部との接続

  • オーディオ・イン
  • MIDI IN/OUT
  • デバイスへのアクセス

他言語での OtoX 展開

  • 以下の条件が合えば、他言語でも実装可
    • Cへの埋め込みができて
    • evalがある
  • OtoRuby とか OtoScheme とか…
  • つまり…

音の為の専用言語は不要!

  • 全てのプログラマーをサウンド・パフォーマーに!!