2011.04.27 yossy a.k.a. 会長
はいどうも~。お鼻mzmzmzmzmzmzエンジニアの吉田です。
4月も下旬となり世の中からだんだんマスクマンが減ってきた今日この頃ですが、
あたくしは必須ですよ。まったくつらいわね。気が滅入っちゃうワ。
そんなワケで、今日はFlashでなんか作りたい衝動にかられたから、
なんか作ってやると決めたわよ。
そうね、「T-Qualizer」というイカすTシャツでもパクってやろうかしら。
T-Qualizerについては
ココや http://www.tqualizer.com/
ココを http://item.rakuten.co.jp/keitaistrap/50/
参考にするといいわ。
T-Qualizerを簡単に紹介してあげると、
Tシャツにイコライザ的な模様が描かれていて、
それが音に反応して、模様が動く、って
ただそれだけのTシャツよ。素敵じゃない?
$29.95ポッキリで円高の今ならお買い得なのよ。
これがあればフェスで大人気間違いなしね。
あたしも買っちゃおうかしら。
でも、このTシャツ、実際に動かすときは単4電池が4本も必要なの。
しかも、洗濯は手洗いして、24時間以上日陰干しして、しっかりと乾燥
してあげないと、ショートで故障するかもしれないって。そんなの大変ね。
でも、今回はFlashでパクってやろうと企んでいるから、
必要なのはFlashPlayerだけよ。洗濯も必要ないし、エコでしょ?
というおネエな口調はここまでにしておき、
さっそく作ってみましょうか。
■完成させるもの
Tシャツの絵の上にイコライザ的な模様があり
マイクのボリュームによって模様が動くという
なんの役にも立たないSWFファイル。
■作り方
衝動的な開発なのでやっつけで作るのもいいですが、モジュール化させる
お勉強も兼ねて少しだけ拡張しやすい感じで作ってみます。
必要なものは、
・ベースとなるTシャツ
・イコライザ的な模様
の2つですが、イコライザ的な模様は、
複数の種類を用意しておけば、
いろいろなパターンのものを作れるようにしたい感じです。
というわけで、イコライザ的な模様は、単一のswfとして外だしし、
ベースとなるTシャツからそれを呼び出してあげるようにします。
となると、ベースとなるTシャツが必要とする機能は、
・Tシャツ的な絵
・イコライザ的な模様の呼び出し
・マイクのボリューム情報の取得
・ボリュームによるイコライザ的な模様の制御
といったところでしょうか。
イコライザ的な模様の制御をするには、制御の仕方を
事前に検討しておく必要がありそうです。
今回は、イコライザ的な模様に5段階のレベルを用意してあげることにしました。
イコライザ的な模様では、ムービークリップで5フレーム分に絵を用意しておき、
これをベースとなるTシャツから制御してもらうことにしましょう。
ベースとなるTシャツでは、マイクボリュームを0~100の
レベルで取得できるようにしておき、20レベルごとに
イコライザ的な模様のフレームの移動を制御します。
ただ、これだとカクカクしてしまいそうなので、
5フレーム分の各レベルにおいて、音量レベルの20段階
ごとに、alpha値も制御してあげるようにしてみます。
イコライザ的な模様の方は、フレームを5つ作って、
各フレームに絵を用意してあげるだけでOKですね。
(正確には音量ゼロ用のフレーム+5フレームで、
6フレーム作ってます。)
そんなわけで、できあがったイコライザ的swfはこちら。
ただひたすらにフレームが繰り返されているだけなので
ただひたすらにイコライザ的な何かが動いている感じです。
ちなみに、ファイル名は equalizer.swf としています。
あ、そうそう、周波数を解析して本当のイコライザを作るとか、そういうわけではありません。
今回はあくまでも、T-QualizerのTシャツもどきを作るだけなのです。
続いて、ベースとなるTシャツを作ってみます。
適当にTシャツ的な絵を書いてシンボルにしてあげます。
このシンボルのインスタンス名は tshirt です。
で、ASを加えていきましょう。
ベースとなるTシャツから、イコライザ的なSWFを読み込みます。
public class Main extends MovieClip { private var _loader:Loader; private var _loaderInfo:LoaderInfo; public function Main() { _loader = new Loader(); _loader.load( new URLRequest("equalizer.swf") ); _loaderInfo = _loader.contentLoaderInfo; _loaderInfo.addEventListener(Event.INIT, onLoaderInfoInit); } private function onLoaderInfoInit(e:Event):void { MovieClip(_loader.content).stop(); _loader.x = - Math.abs(_loaderInfo.width / 2); _loader.y = - Math.abs(_loaderInfo.height / 4); tshirt.addChild(_loader); } }
public class Main extends MovieClip { private var _loader:Loader; private var _loaderInfo:LoaderInfo; public function Main() { _loader = new Loader(); _loader.load( new URLRequest("equalizer.swf") ); _loaderInfo = _loader.contentLoaderInfo; _loaderInfo.addEventListener(Event.INIT, onLoaderInfoInit); slider.addEventListener(SliderEvent.THUMB_DRAG, onSliderChange); } private function onLoaderInfoInit(e:Event):void { MovieClip(_loader.content).stop(); _loader.x = - Math.abs(_loaderInfo.width / 2); _loader.y = - Math.abs(_loaderInfo.height / 4); tshirt.addChild(_loader); } private function onSliderChange(e:SliderEvent) { var val:Number = e.value; lightEqualizer(val); } private function lightEqualizer(val:Number) { var frame:Number = Math.ceil(val / 20) + 1; var alpha:Number = (val - (frame-2) * 20) / 20; var mc:MovieClip = MovieClip(_loader.content); mc.gotoAndStop(frame); if(mc.equalizer !=null) { mc.equalizer.alpha = alpha; } } }
なんとなく音楽を交えた動作確認もしてみたいので、
再生ボタンと停止ボタンを作って、こんなコードを追加してみます。
public class Main extends MovieClip { private var _loader:Loader; private var _loaderInfo:LoaderInfo; private var _sound:Sound; private var _soundChannel:SoundChannel; private var _positionTimer:Timer; public function Main() { _loader = new Loader(); _loader.load( new URLRequest("equalizer.swf") ); _loaderInfo = _loader.contentLoaderInfo; _loaderInfo.addEventListener(Event.INIT, onLoaderInfoInit); playBtn.addEventListener(MouseEvent.CLICK, onPlayBtnClick); stopBtn.addEventListener(MouseEvent.CLICK, onStopBtnClick); } private function onLoaderInfoInit(e:Event):void { MovieClip(_loader.content).stop(); _loader.x = - Math.abs(_loaderInfo.width / 2); _loader.y = - Math.abs(_loaderInfo.height / 4); tshirt.addChild(_loader); } private function onPlayBtnClick(e:MouseEvent) { _sound = new Sound( new URLRequest("revolution.mp3") ) _soundChannel = _sound.play(); _positionTimer = new Timer(50); _positionTimer.addEventListener(TimerEvent.TIMER, positionTimerHandler); _positionTimer.start(); } private function onStopBtnClick(e:MouseEvent) { _soundChannel.stop(); _positionTimer.removeEventListener(TimerEvent.TIMER, positionTimerHandler); } private function positionTimerHandler(e:TimerEvent) { var val:Number; val = (_soundChannel.leftPeak + _soundChannel.rightPeak)/2 * 100; lightEqualizer(val); } }
こんな感じで動作確認ができました。
※ボリュームはSoundChannelオブジェクトのleftPeakとrightPeakを足して2で割ってるだけ。
というわけで最後に、実際にマイクの音量から動作確認してみます。
public class Main extends MovieClip { private var _loader:Loader; private var _loaderInfo:LoaderInfo; private var _mic:Microphone; public function Main() { _loader = new Loader(); _loader.load( new URLRequest("equalizer.swf") ); _loaderInfo = _loader.contentLoaderInfo; _loaderInfo.addEventListener(Event.INIT, onLoaderInfoInit); } private function onLoaderInfoInit(e:Event):void { MovieClip(_loader.content).stop(); _loader.x = - Math.abs(_loaderInfo.width / 2); _loader.y = - Math.abs(_loaderInfo.height / 4); tshirt.addChild(_loader); setupMicrophone(); } private function lightEqualizer(val:Number) { var frame:Number = Math.ceil(val / 20) + 1; var alpha:Number = (val - (frame-2) * 20) / 20; var mc:MovieClip = MovieClip(_loader.content); mc.gotoAndStop(frame); if(mc.equalizer !=null) { mc.equalizer.alpha = alpha; } } private function setupMicrophone():void { _mic = Microphone.getMicrophone(); _mic.setLoopBack(); _mic.setSilenceLevel(0); _positionTimer = new Timer(50); _positionTimer.addEventListener(TimerEvent.TIMER, timerHandler); _positionTimer.start(); } private function timerHandler(e:TimerEvent) { if (_mic is Microphone) { lightEqualizer(_mic.activityLevel); } } }
(マイクが接続されていると、その音量でイコライザ的な模様が動きます)
※ボリュームレベルはMicrophoneオブジェクトのactivityLevelを取得してるだけ。
というわけで、Flashでくだらない何かを作ってみるだけのブログ記事でした。
デワデワ。