ネコでもわかる
インタラクティブサウンド
田中孝
2013-07-06
このワークショップでは
•
音の作り方
•
波形編集(基本)
•
インタラクティブサウンドの設計(考え方)
•
Unityスクリプトとかはやりません
→ゲームジャムで実践
その前段階の
レジュメ
サウンドデザイン インタラクションデザイン サウンド再生 ADX2LE_OSCBasicPlayer アプリケーション /adx2/0/playcueid OSC (udp) localhost通信 /StremingAssets/ NewProject.acf CueSheet_0.acbCRI Atom Craft
ビルド 出力ファイル 差し替え Processing ProcessingのoscP5 インゲーム プレビュー 作成中 最終出力
•
インタラクティブとは? 5分
•
ツール紹介 5分
•
Audacity
で録音、加工、wav保存 20分
•
インタラクティブサウンドを作ってみよう 20分
テルミンから学ぶ
•
チャレンジ(課題) 30分
簡単なアプリに音をつけてみる
•
発表 15分
•
まとめ
これからのサウンドデザインに求められるもの
インタラクティブとは?
•
インタラクティブ
何と対話?双方向?
何を使って?
•
CRI Atom Craft
ADX2LE OSC Player
processing
を使います。
サウンドデザイン インタラクションデザイン サウンド再生 ADX2LE_OSCBasicPlayer アプリケーション /adx2/0/playcueid OSC (udp) localhost通信 /StremingAssets/ NewProject.acf CueSheet_0.acbCRI Atom Craft
ビルド 出力ファイル 差し替え Processing ProcessingのoscP5 インゲーム プレビュー 作成中 最終出力
プレーヤー
プログラム
1
デザイン
3
2
サウンドデザイン
CRI Atom Craft
•
CRI Atom Craftを使って
音をデザインします
•
ADX2LEのサウンドオーサリング
ツールです。
http://www.adx2le.com/
ゲームジャムでも使う
デザイン
1
•
ADX2 OSC Player
を使って
音を鳴らします。
•
Unityで作られたADX2LEの
プレーヤーアプリです。
サウンド再生 ADX2LE_OSCBasicPlayer アプリケーション /StremingAssets/ NewProject.acf CueSheet_0.acb今回のワークショップでのみ使う
プレーヤー
2
•
Processingを使って
インタラクションを実現
します
•
Processingは電子アートとビジュアルデ
ザインの為のプログラム言語です。
インタラクションデザイン
Processing
ProcessingのoscP5
http://www.processing.org/
今回のワークショップでのみ使う
プログラム
3
•
波形素材
•
波形加工
波形素材
4
波形加工
5
•
波形素材は
ChipTuneのものを使用
•
チップチューンは矩形波形や三角波形、
ノイズなどシンプルな波形集です。
http://www.criware.jp/adx2/demo/download_j.php#chiptune
ゲームジャムでも使って
OK
波形素材
4
•
波形加工、録音、
wav出力
は
Audacityのものを使用
•
チップチューンは矩形波形や三角波形、
ノイズなどシンプルな波形集です。
http://audacity.sourceforge.net/
ゲームジャムでも使える
波形加工
5
Audacity
で録音、加工、wav保存
録音
•
Audacityを起動
•
赤いボタンを押す
マイクの入力レベル
波形の表示調整
•
境界線をドラッグして高さ変更
波形加工
波形の表示調整
•
ルーペで横方向の拡大縮小
波形加工
ステレオをモノラルへ
•
いくつか録音されていたらややこしいので
いらないものを「
X」ボタンで閉じる
メニューを選択
波形加工
マイクはモノラルマイクが多いので・・・
波形の入らない部分カット
•
入らない部分を範囲選択
波形加工
•
ドラッグして選択
•
Ctr+Xで選択した部
分がカットされる。
•
Ctr+Vでペーストも
可能
音を大きくする
•
正規化(ノーマライズ)する
波形加工
•
「エフェクト」メニューから「正規化
...」を選択
•
音が大きくなる
←みたいな波形だとあまり大きくならない
コンプレッサーなど使うと良い
ピッチを変更
•
正規化(ノーマライズ)する
波形加工
•
「エフェクト」メニューから「ピッチの変更
...」を選択
スライダーを右にす
ると高く、左にする
と低くなる
波形出力
•
正規化(ノーマライズ)する
波形加工
•
「ファイル」メニューから「書き出し
...」を選択
インタラクティブサウンドを
作ってみよう
テルミンから学ぶ
•
テルミンはロシアのテルミン
博士が作った楽器で、
アンテナに手をかざすと音が
出て、かざし方によって変化
します。
•
楽器=インタラクティブ
デザイン
テルミンの仕組み
•
右のアンテナに
近づくと音程が高く
離れると音程が低く
なります。
•
左のアンテナに
近づくと音が小さく
離れると音が大きく
なります。
デザイン
データ作成
•
ボリュームとピッチが
インタラクティブに
変化する音を作ります。
サウンドデザイン インタラクションデザイン サウンド再生 ADX2LE_OSCBasicPlayer アプリケーション /adx2/0/playcueid OSC (udp) localhost通信 /StremingAssets/ NewProject.acf CueSheet_0.acbCRI Atom Craft
ビルド 出力ファイル 差し替え Processing ProcessingのoscP5 インゲーム プレビュー 作成中 最終出力
デザイン
1
音を鳴らすキューを作る
•
再生すると三角波形が鳴るよう
にする
•
波形を追加して、キューにする
•
キューはADX2LEの音を再生する機能で
す。
デザイン
•
CRI Atom Craft
を起動
•
新規プロジェクト作成
1
2
•
マテリアルへ
波形を追加
1
2
デザイン
波形素材
•
キュー作成
2
ボリュームつまみを再現
•
ボリュームは縦で
•
指揮者が腕を上げる高さに
合わせて変化するようにデ
ザインする
•
AISACを使います
•
AISACはADX2LEの
音色パラメータをコントロールの為
の機能です。
デザイン
•
キュー選択
1
2
•
+ボタン押し、
AISACの追加...を選択
1
2
•
追加ボタンを押す
1
2
3
•
グラフを右肩下がりにする
1
2
•
音を確認する
1
2
3
4
デザイン
•
ピッチ変化用を追加する
•
ピアノや弦楽器のようなイ
メージでカーブをデザイン
する
•
もう一つ
AISACを使います。
ピッチアンテナを再現
デザイン
•
+ボタン押し、
AISACの追加...を選択
1
2
•
ピッチに変更し、追加ボタンを押す
1
3
2
4
デザイン
•
グラフを右肩上がりにする
1
2
•
音を確認する
1
2
3
4
デザイン
2つのコントロールができました
•
ツール上でもある程度確認できますが、
2つを同時にコントロールする他のアプリで動かすた
め、ツールから
ACF,ACBという
インタラクティブサウンドの元になるデータを出力し
ます。
「パディング使用フラグのチェックを外す
後でインゲームプレビューで波形追加などを行うため
以下の操作をしておきます。
•
キューシートフォルダを選択
•
「パディング使
...」のチェックを外しグレーにする
1
2
•
+ボタン押し、チェック確認、ビルド
1
2
•
キューシートを右クリックし、
「Atomキューシートバイナリ出力先フォルダをエクスプローラで開
く...」を選択
1
2
3
•
acf
、acbが作成されているのを確認
ACF
、ACBを利用する
•
CRI Atom Craft
の
データを
ADX2LE OSC Player
で再生する
サウンドデザイン インタラクションデザイン サウンド再生 ADX2LE_OSCBasicPlayer アプリケーション /adx2/0/playcueid OSC (udp) localhost通信 /StremingAssets/ NewProject.acfCRI Atom Craft
ビルド 出力ファイル 差し替え Processing ProcessingのoscP5 インゲーム プレビュー 作成中 最終出力
1
プレーヤー
デザイン
1
2
•
ADX2LE OSC Playerを起動
•
ブロックを解除する
•
起動する
ファイルをコピーする
•
バッチを実行する
C:\ADX2LE_Workshop\AtomCraftData\copy.bat
•
ACF,ACBファイルをコ
ピーしました。
ファイルコピー
C:ドライブにADX2LE_Workshopを
展開していないと正しく動作しないので
注意
•
ADX2LEOSCBasicPlayer_Dataを開く
•
StreamingAssetsを開く
•
ACB
、ACFを差し替える
1
2
4
3
•
先ほど
ツールで出力したフォルダから
inGamePreviewを開く
【参考】もしも手動でやる場合は以下のよう
な手順になります。
ファイルコピー
デザイン
•
ADX2LE OSC Playerの「Panic!」ボタンを押す
•
0:tri(キュー名)に変化していたらOK
2
1
•
「♪」を押すと音が鳴る、「■」で停止
•
真ん中のスライダーでピッチが変わる
•
左のスライダーで音量が変わる
1
2
3
4
プレーヤー
•
いちいちバッチを実行するのは面倒なので、
ビルド時に呼び出すようにします。
2
1
3
4
5
ファイルコピー
もっと直感的に
•
プレーヤーでも2つコントロールができましたが、
同時にコントロールしたいので、
マウスの位置(たて、よこ座標)が反応するような、
簡単なプログラムを用意しました。
•
サウンドデザインする上で簡単なプロトタイプを作
ると
ります。
プログラムからどんな風にコントロールされるか理
解を深めると、データ作成に有利な点が見つかるか
もしれません。
動作確認用のシンプルなもの
音以外のインタラクションを作る
•
processingで
インタラクティブ
サウンドを
コントロールします。
サウンドデザイン インタラクションデザイン サウンド再生 ADX2LE_OSCBasicPlayer アプリケーション /adx2/0/playcueid OSC (udp) localhost通信 /StremingAssets/ NewProject.acf CueSheet_0.acbCRI Atom Craft
ビルド 出力ファイル 差し替え Processing ProcessingのoscP5 インゲーム プレビュー 作成中 最終出力
プログラム
3
•
proessingが起動します
•
sketch_AISACXY.pdeを開く
1
2
3
•
を押して実行
•
を押して停止
import oscP5.*; import netP5.*; OscP5 oscP5; NetAddress myRemoteLocation; void setup() { size(480,240);
oscP5 = new OscP5(this,9000);
myRemoteLocation = new NetAddress("127.0.0.1",8000); } int playerState = 0; int mouseState = 0; void draw() { background(204); if(mousePressed) { if(mouseState == 0){ if(playerState == 0){
OscMessage myMessage = new OscMessage("/adx2/0/playcueid 0"); oscP5.send(myMessage, myRemoteLocation);
playerState = 1;
} else if(playerState == 1){
OscMessage myMessage = new OscMessage("/adx2/0/stop"); oscP5.send(myMessage, myRemoteLocation); playerState = 0; } mouseState = 1; } } else { mouseState = 0; } if(playerState == 0){ } else { OscMessage myMessage
= new OscMessage("/adx2/0/aisac 0 "+mouseX/480f); oscP5.send(myMessage, myRemoteLocation);
myMessage = new OscMessage("/adx2/0/aisac 1 "+(1f-mouseY/240f)); oscP5.send(myMessage, myRemoteLocation); ellipse(mouseX,mouseY,60,60); }
描画処理
ウィンドウを
480x240で表示
背景を
204色(グレー)で
楕円
60x60をマウスの位置に表示
1
2
3
プログラム
import oscP5.*; import netP5.*; OscP5 oscP5; NetAddress myRemoteLocation; void setup() { size(480,240);
oscP5 = new OscP5(this,9000);
myRemoteLocation = new NetAddress("127.0.0.1",8000);
} int playerState = 0; int mouseState = 0; void draw() { background(204); if(mousePressed) { if(mouseState == 0){ if(playerState == 0){
OscMessage myMessage = new OscMessage("/adx2/0/playcueid 0"); oscP5.send(myMessage, myRemoteLocation);
playerState = 1;
} else if(playerState == 1){
OscMessage myMessage = new OscMessage("/adx2/0/stop"); oscP5.send(myMessage, myRemoteLocation); playerState = 0; } mouseState = 1; } } else { mouseState = 0; } if(playerState == 0){ } else { OscMessage myMessage
= new OscMessage("/adx2/0/aisac 0 "+mouseX/480f); oscP5.send(myMessage, myRemoteLocation);
myMessage = new OscMessage("/adx2/0/aisac 1 "+(1f-mouseY/240f));
プログラムの流れ
起動直後一度呼ばれる
描画は毎度呼ばれる
1
2
プログラム
import oscP5.*; import netP5.*; OscP5 oscP5; NetAddress myRemoteLocation; void setup() { size(480,240);
oscP5 = new OscP5(this,9000);
myRemoteLocation = new NetAddress("127.0.0.1",8000); } int playerState = 0; int mouseState = 0; void draw() { background(204); if(mousePressed) { if(mouseState == 0){ if(playerState == 0){
OscMessage myMessage = new OscMessage("/adx2/0/playcueid 0"); oscP5.send(myMessage, myRemoteLocation);
playerState = 1;
} else if(playerState == 1){
OscMessage myMessage = new OscMessage("/adx2/0/stop"); oscP5.send(myMessage, myRemoteLocation);
playerState = 0; } mouseState = 1; } } else { mouseState = 0; } if(playerState == 0){ } else { OscMessage myMessage
= new OscMessage("/adx2/0/aisac 0 "+mouseX/480f); oscP5.send(myMessage, myRemoteLocation);
myMessage = new OscMessage("/adx2/0/aisac 1 "+(1f-mouseY/240f)); oscP5.send(myMessage, myRemoteLocation);
ellipse(mouseX,mouseY,60,60); }
通信処理
OSCインポート
OSCアドレスをセット
再生メッセージ
停止メッセージ
AISAC0メッセージ
AISAC1メッセージ
1
3
2
4
プログラム
import oscP5.*; import netP5.*; OscP5 oscP5; NetAddress myRemoteLocation; void setup() { size(480,240);
oscP5 = new OscP5(this,9000);
myRemoteLocation = new NetAddress("127.0.0.1",8000); } int playerState = 0; int mouseState = 0; void draw() { background(204); if(mousePressed) { if(mouseState == 0){ if(playerState == 0){
OscMessage myMessage = new OscMessage("/adx2/0/playcueid 0"); oscP5.send(myMessage, myRemoteLocation);
playerState = 1;
} else if(playerState == 1){
OscMessage myMessage = new OscMessage("/adx2/0/stop"); oscP5.send(myMessage, myRemoteLocation); playerState = 0; } mouseState = 1; } } else { mouseState = 0; } if(playerState == 0){ } else { OscMessage myMessage
= new OscMessage("/adx2/0/aisac 0 "+mouseX/480f); oscP5.send(myMessage, myRemoteLocation);
myMessage = new OscMessage("/adx2/0/aisac 1 "+(1f-mouseY/240f)); oscP5.send(myMessage, myRemoteLocation);