サウンドの視覚化の勉強の一環として「SoundMixer」を使用してみた。
サウンドのボリュームやパンで使用する「SoundChannel」にも「leftpeak」「rightpeak」もどうやら音のデータの振幅を取得できるようだけども、細かいデータでたくさんのMovieclipに割り当てる場合は、「ByteArray」のほうが良さそうなので試してみました。
サウンドの読み込みなどは省略します。
目次
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;
}
}
}
サウンドに関する処理について詳しく書かれているブログを発見したのでリンクしておきます
今回作成したプログラム
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;
}
}
}