Hatena::ブログ(Diary)

flashrod このページをアンテナに追加 RSSフィード

2006-11-02

flashrod2006-11-02

AS3でサウンドスペクトラムを視覚化する 00:13  AS3でサウンドスペクトラムを視覚化するを含むブックマーク

サウンドスペクトラムの視覚化というのはメディアプレイヤーなんかで音楽を再生すると光の粒子が動いたり線がうにょうにょ動いたりするあれのことなのだ。

Flashでサウンドスペクトラムというと、ここが有名みたいだ。no titleみなさんセンスが良すぎる。

さて実際のコードはこのページの例が短くて分かりやすい。no title

これを参考に書いてみた。

package {
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.geom.ColorTransform;
    import flash.geom.Rectangle;
    import flash.media.Sound;
    import flash.media.SoundChannel;
    import flash.media.SoundMixer;
    import flash.net.URLRequest;
    import flash.utils.ByteArray;
    public class Spectrum extends Sprite {
        private var bytes:ByteArray = new ByteArray();
        private var spectrum:Array = new Array(256);
        private var bd:BitmapData = new BitmapData(640, 480, false, 0x000000);
        private var tonedown:ColorTransform = new ColorTransform(0.999, 0.999, 0.999);
        public function Spectrum() {
            addChild(new Bitmap(bd));
            var sound:Sound = new Sound();
            sound.load(new URLRequest("sound.mp3"));
            var channel:SoundChannel = sound.play();
            addEventListener(Event.ENTER_FRAME, enterFrame);
        }
        private function enterFrame(event:Event):void {
            SoundMixer.computeSpectrum(bytes, true, 0);
            for (var i:int = 0; i < 256; ++i) {
                spectrum[i] = bytes.readFloat();
            }
            bd.scroll(2, -1);
            bd.fillRect(new Rectangle(0, 0, 2, bd.height), 0x000000);
            bd.colorTransform(bd.rect, tonedown);
            for (var x:int = 0; x < 256; ++x) {
                var v:Number = spectrum[x];
                var h:int = v * 256;
                var y:int = bd.height - (256/2) + x/2;
                bd.fillRect(new Rectangle(x, y-h, 1, h+1), Color.HSBtoRGB(x/256, 1, 1));
            }
        }
    }
}

やってることは上の例とほとんど同じで、違うのは以下のようなことだけ。

ちなみに埋め込んだmp3を再生する場合はこうだ。

    [Embed(source='sound.mp3')] private static const Sound0:Class;
…
        var sound:Sound = new Sound0();

非常に簡単。MP3プレイヤー程度なら簡単に作れそうだ。

ところで Flashはマイクからの入力もできるんだけど、マイク音は SoundMixer.computeSpectrum() じゃとれなかった。どうしたらできるんだろう?

SoundMixer.computeSpectrum()が戻すバイト列の仕様は、リファレンスガイドによると、

  • 浮動小数点
  • 範囲は-1.0〜+1.0
  • 値の数は 512個固定
  • 最初の256個が左チャンネルで次の256個が右チャンネル

と書いてある。実際のところは

  • バイト列の長さは2048なので、2048/512=4で、1つの値=4バイトということは単精度
  • ByteArray.readFloat()で単精度数値を先頭から順に取れる。
  • 値の範囲は 0〜1.0

な様子。

デモはここ(音が鳴るので注意)

sound spectrum

ところでサンプルに鳴らしているMP3ファイルは「フリー MP3」でぐぐって一番上に出てきたサイクルツイスタースリム通販/最新エアロバイク【即納・送料無料】からサイズが小さくてスペクトラムが派手そうな「新・新世界」を使用させていただいている。

ここでベートーヴェン交響曲第7番とかにしておけばのだめ人気に乗っかることができたかもしれなかったのだけど、実はファイルサイズが大きすぎてアップロードできなかったのだ。残念。