生のサウンドデータへのアクセス

SoundMixer.computeSpectrum() メソッドを使用すると、アプリケーションは再生中の波形の生のサウンドデータを読み取ることができます。SoundChannel オブジェクトが再生中であれば、SoundMixer.computeSpectrum() メソッドはすべての SoundChannel オブジェクトを合成したサウンドデータを示します。

サウンドデータは、512 バイトのデータを含む ByteArray オブジェクトとして返されます。このデータはそれぞれ -1 から 1 までの浮動小数点値を持ちます。これらの値は、再生中のサウンド波形のポイントの振幅を示します。値は 256 バイトずつ 2 グループに分けて送信されます。うち 1 つめのグループは左ステレオチャンネル用、そしてもう 1 つのグループは右ステレオチャンネル用です。

FFTMode パラメータが true に設定されている場合は、SoundMixer.computeSpectrum() メソッドは、波形データではなく周波数スペクトルを返します。周波数スペクトルとは、最も低い周波数から最も高い周波数までのサウンド周波数で配列した振幅を示します。波形データを周波数スペクトルデータに変換するために、高速フーリエ変換 (FFT) が使用されます。その結果として生成される周波数スペクトルの値の範囲は、0 からおよそ 1.414 (2 の平方根) までです。

次の図は、FFTMode パラメータが true に設定されているときと false に設定されているときに computeSpectrum() メソッドから返されるデータを比較します。この図でデータが使用されたサウンドでは、左チャンネルには大音量のベースサウンドが、右チャンネルにはドラム音が流れています。
コード実行後の 3 つの円。"b" は "a" の右端と重なっています。"c" は "a" の右下と重なっていると同時に、"b" の左下とも重なっています。

computeSpectrum() メソッドは、低いビットレートで再サンプリングされたデータも返すことができます。通常、これによって細部が失われますが、よりスムーズな波形データまたは周波数データを得ることができます。stretchFactor パラメータは、computeSpectrum() メソッドデータがサンプリングされるレートを制御します。stretchFactor パラメータがデフォルトの 0 に設定されていると、サウンドデータは 44.1 KHz のレートでサンプリングされます。stretchFactor パラメータの値が増えるに従い、レートは半割になります。つまり、値が 1 であればレートは 22.05 KHz、値が 2 であればレートは 11.025 KHz となり、以下同様です。computeSpectrum() メソッドは、stretchFactor 値が高ければ、ステレオチャンネルごとに 256 バイトを返します。

SoundMixer.computeSpectrum() メソッドにもいくつか制限があります。

シンプルなサウンドビジュアライザの構築

次の例は、SoundMixer.computeSpectrum() メソッドを使用し、各フレームでアニメーション化されるサウンド波形のチャートを示します。

import flash.display.Graphics;
import flash.events.Event;
import flash.media.Sound;
import flash.media.SoundChannel;
import flash.media.SoundMixer;
import flash.net.URLRequest;

const PLOT_HEIGHT:int = 200;
const CHANNEL_LENGTH:int = 256;

var snd:Sound = new Sound();
var req:URLRequest = new URLRequest("bigSound.mp3");
snd.load(req);

var channel:SoundChannel;
channel = snd.play();
addEventListener(Event.ENTER_FRAME, onEnterFrame);
snd.addEventListener(Event.SOUND_COMPLETE, onPlaybackComplete);

var bytes:ByteArray = new ByteArray();

function onEnterFrame(event:Event):void
{
    SoundMixer.computeSpectrum(bytes, false, 0);
    
    var g:Graphics = this.graphics;
    
    g.clear();
    g.lineStyle(0, 0x6600CC);
    g.beginFill(0x6600CC);
    g.moveTo(0, PLOT_HEIGHT);
    
    var n:Number = 0;
        
    // left channel
    for (var i:int = 0; i < CHANNEL_LENGTH; i++) 
    {
        n = (bytes.readFloat() * PLOT_HEIGHT);
        g.lineTo(i * 2, PLOT_HEIGHT - n);
    }
    g.lineTo(CHANNEL_LENGTH * 2, PLOT_HEIGHT);
    g.endFill();
    
    // right channel
    g.lineStyle(0, 0xCC0066);
    g.beginFill(0xCC0066, 0.5);
    g.moveTo(CHANNEL_LENGTH * 2, PLOT_HEIGHT);
    
    for (i = CHANNEL_LENGTH; i > 0; i--) 
    {
        n = (bytes.readFloat() * PLOT_HEIGHT);
        g.lineTo(i * 2, PLOT_HEIGHT - n);
    }
    g.lineTo(0, PLOT_HEIGHT);
    g.endFill();
}

function onPlaybackComplete(event:Event)
{
    removeEventListener(Event.ENTER_FRAME, onEnterFrame);
}

この例では、まずサウンドファイルをロードして再生し、次にサウンドの再生中に onEnterFrame() メソッドをトリガーする Event.ENTER_FRAME イベントを監視します。onEnterFrame() メソッドは、サウンド波形データを bytes ByteArray オブジェクトに保存する SoundMixer.computeSpectrum() メソッドを呼び出します。

サウンド波形は、ベクター描画 API によってプロットされます。for ループは、左ステレオチャンネルを表す最初の 256 バイトのデータ値を順次実行し、Graphics.lineTo() メソッドを使用してポイントとポイントの間に線を描画します。2 つめの for ループは、次の 256 バイトのデータ値を順次実行し、今回は右から左へと逆順にプロットします。この結果として生成される波形プロットから、次に示すような面白い鏡像効果が生まれます。


 

このページに新しいコメントが追加された場合に、電子メールでの通知を希望する。 | コメントレポート

現在のページ: http://livedocs.adobe.com/flash/9.0_jp/main/00000296.html