soundMixerによるサウンドの視覚化

サウンドの視覚化の勉強の一環として「SoundMixer」を使用してみた。

サウンドのボリュームやパンで使用する「SoundChannel」にも「leftpeak」「rightpeak」もどうやら音のデータの振幅を取得できるようだけども、細かいデータでたくさんのMovieclipに割り当てる場合は、「ByteArray」のほうが良さそうなので試してみました。

SoundMixierによる視覚化

soundmixier

サウンドの読み込みなどは省略します。

ENTER_FRAME内で再生データを取得するByteArrayオブジェクトを作成

private function loopHandler(e:Event):void {
			var bytes:ByteArray = new ByteArray();
			SoundMixer.computeSpectrum(bytes, false, 0);
}

まずはBytesArrayデータをEnterFrame内で宣言してサウンドを逐一バイトデータで取得するためのインスタンスを作成する

ENTER_FRAME内でサウンドをコントロールするSoundMixier.computeSpectrumメソッドを実行する

SoundMixierの引数は

  • 第一引数にSoundMixer.computeSpectrumの第1引数にByteArray Objectを渡すとその瞬間のサウンドキャプチャが渡したByteArray Objectに保存される
  • 第二引数はフーリエ変換するかどうかを真偽値で指定する(詳しくは分からないです)
  • 第三引数にサンプリング解像度で「0」が44.1kHz 「1」が22.05kHz 「2」が11.025となる 「0」が一番良い??高い??解像度ってこと?

ちなみに返されるデータは左の音「256」,右の音「256」を連結した「512」となる

bytesArray readFloatによる波形データを取り出し

private function loopHandler(e:Event):void {
          var bytes:ByteArray = new ByteArray();
			SoundMixer.computeSpectrum(bytes, false, 0);

			var lr:Number = bytes.readFloat();   //波形データを取り出す
			var date:Number = Math.max(0, 1 + lr*2);
}

readFloatメソッドによる戻り値はNubmer形のデータになる

取り出したデータをMovieClipに割り当てる場合など取り出したデータだと小さすぎるので調整Math.max()メソッドで大きい方を取得する(上記の例だと一番小さくても0.1の数値)

後は調整した数値をMovieClipのscale値に割り当てるなど

private function loopHandler(e:Event):void {
			var bytes:ByteArray = new ByteArray();
			SoundMixer.computeSpectrum(bytes, false, 1);
			//
			for (var i:int = 0; i < allList.length; i++) {
				for (var j:int = 0; j < allList[i].length; j++) {
					//
					var t:MovieClip = allList[i][j] as MovieClip;
					var lr:Number = bytes.readFloat();
					
					var date:Number = Math.max(0, 1 + lr*2);
					t.scaleX = t.scaleY = date;
				}
			}
		}

サウンドに関する処理について詳しく書かれているブログを発見したのでリンクしておきます

White Wheelsのメモ AS3覚え書き

今回作成したプログラム

package  {
	import flash.display.MovieClip;
	import flash.events.Event;
	import flash.geom.ColorTransform;
	import flash.utils.ByteArray;
	import flash.media.SoundMixer;
	/**
	 * ...
	 * @author ...
	 */
	public class soundMain extends MovieClip{
		private var allList:Array;
		
		public function soundMain() {
			//loadsound
			var sd:soundLoader = new soundLoader();
			
			//createmc
			allList = createMC();
			trace(allList.length);
			//loop
			addEventListener(Event.ENTER_FRAME, loopHandler);
		}
		
		private function loopHandler(e:Event):void {
			var bytes:ByteArray = new ByteArray();
			SoundMixer.computeSpectrum(bytes, false, 1);
			//
			for (var i:int = 0; i < allList.length; i++) {
				for (var j:int = 0; j < allList[i].length; j++) {
					//
					var t:MovieClip = allList[i][j] as MovieClip;
					var lr:Number = bytes.readFloat();
					
					var date:Number = Math.max(0, 1 + lr*2);
					t.scaleX = t.scaleY = date;
				}
			}
		}
		
		private function createMC():Array {
			var lrlist:Array = [];
			for (var i:int = 0; i < 2; i++) {
				var list:Array = [];
				for (var j:int = 0; j < 256; j++) {
					var mc:MovieClip = new ball();
					addChild(mc);
					list[j] = mc;
					mc.x = 50+(i*450)+mc.width * 1.2 * (j % 16);
					mc.y = 50+mc.height * 1.2 * int(j/ 16);
				}
				lrlist[i] = list;
			}
			return lrlist;
		}
		
	}

}