SoundMixer.computeSpectrumをとりあえず使ってみる
どうも。最近、Flashを知らない人に対してとっさに「ホームページとかでバーッと動くやつです」みたいな説明をしてしまって自分のボキャブラリーを呪いました、ナカムラです。
今回は勉強と趣味と実益を兼ねて、普段使わないクラスやメソッドを使ってみようかと思います。さしあたって扱ってみるのはSoundMixer.computeSpectrum。それではどうぞ。
まず、「とりあえず使う」ことの目的を設定しておきます。
- ・同じく使った事のない人をターゲットに、公式リファレンスのそれよりシンプルで、すぐ使えるサンプルコードを提供すること
- ・そのサンプルコードの作成を通して機能を正確に把握すること
こういう感じでできると、試作とフィードバックができて良いのではないかなー、と。
今回は試行錯誤の一歩として
- リファレンスを読む
- サンプルコードをいじる
- コード解説の意味を把握する(コードをコメントで解説できるようにする)
という手順でやってみます。
以下、リファレンスのサンプルコードをいじってみたもの。
ドキュメントクラスに設定して音源のパスを設定すれば動きます。
package { import flash.display.*; import flash.events.*; import flash.filters.*; import flash.media.*; import flash.net.*; import flash.utils.*; public class SoundMixer_computeSpectrumExample extends Sprite { //波形の基準位置設定 private const PLOT_HEIGHT:int = stage.stageHeight / 2; //チャンネル毎のByteArray取得範囲 private const CHANNEL_LENGTH:int = 256; private var _byteArray:ByteArray = new ByteArray(); private var _blurFilter:BlurFilter; //サウンドの再生・毎フレームイベント設定 public function SoundMixer_computeSpectrumExample() { var sound:Sound = new Sound(); var req:URLRequest = new URLRequest( "audiofile_path" ); sound.load( req ); var channel:SoundChannel; channel = sound.play(); addEventListener( Event.ENTER_FRAME, enterFrameHandler ); channel.addEventListener( Event.SOUND_COMPLETE, playbackCompleteHandler ); //描画した波形にフィルタをかけてみる _blurFilter = new BlurFilter( 5, 5, 3 ); filters = [ _blurFilter ]; } //毎フレームサウンドの波形取得・線描画 private function enterFrameHandler( e:Event ):void { //_byteArrayにサウンド波形の値を設定 SoundMixer.computeSpectrum( _byteArray, false, 0 ); var g:Graphics = graphics; g.clear(); g.lineStyle( 0, 0x000000 ); g.moveTo( 0, PLOT_HEIGHT ); //ひとまず左チャンネルだけ取得して描画 var n:Number = 0; for ( var i:int = 0; i < CHANNEL_LENGTH; i++ ) { //32ビットの浮動小数値をreadFloatで取得 //インデックス指定なしでbyteArrayを走査できるのは、 //readFloatを実行する毎に読み取りヘッダが移動するから?要調査 n = ( _byteArray.readFloat() * PLOT_HEIGHT ); g.lineTo( i, PLOT_HEIGHT - n ); } } //サウンドの再生が終わったらイベント解除 private function playbackCompleteHandler( e:Event ):void { removeEventListener( Event.ENTER_FRAME, enterFrameHandler ); } } }
あんまりシンプルにできてなくて恐縮ですが、結局のところ、コード解説の冒頭にある「その時点でのサウンド波形を(左右のチャンネルあわせて)最大512分割し、一つあたりの値を-1.0~1.0の範囲で表現したbyteArrayを返してくれる」という部分が肝要のようです。
この値をどう取り扱うかがアイデアの出しどころですね。
今回はブラーをかけただけですが、次回以降はWonderflも活用しつつ、別の使い方や波形の生成等をやってみようかなと。
ByteArray.readFloat()の部分はバイナリに強い弊社トポロジカルFlasherのtaro君に解説してもらってなんとなく理解できましたが、また別項で調べてみたいと思います。