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

Flash Player 9 以降、Adobe AIR 1.0 以降

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

サウンドデータは、512 バイトのデータを含む ByteArray オブジェクトとして返されます。このデータはそれぞれ -1 から 1 までの浮動小数点値を持ちます。これらの値は、再生中のサウンド波形のポイントの振幅を示します。 値はそれぞれが 256 個の値から成る 2 つのグループとして提供され、第 1 のグループは左ステレオチャンネルを表し、第 2 のグループは右ステレオチャンネルを表します。

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

次の図は、 computeSpectrum() メソッドから返されるデータを、 FFTMode パラメーターが true の場合と false の場合で比較したものです。この図でデータが使用されたサウンドでは、左チャンネルには大音量のベースサウンドが、右チャンネルにはドラム音が流れています。
フルサイズのグラフィックを表示
SoundMixer.computeSpectrum() メソッドから返される値
A.
fftMode=true

B.
fftMode=false

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

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

  • マイクまたは RTMP ストリームからのサウンドデータはグローバルな SoundMixer オブジェクトを通過しないので、 SoundMixer.computeSpectrum() メソッドはこれらのソースからデータを返しません。

  • 再生中の 1 つまたは複数のサウンドが現在のコンテンツサンドボックスの外部のソースから発生している場合は、セキュリティ制限により、 SoundMixer.computeSpectrum() メソッドはエラーをスローします。 SoundMixer.computeSpectrum() メソッドのセキュリティ制限について詳しくは、 サウンドのロード時および再生時のセキュリティ重要事項 および ロードされたメディアへのデータとしてのアクセス を参照してください。

ただし、AIR アプリケーションでは、アプリケーションセキュリティサンドボックス内のコンテンツ(AIR アプリケーションと共にインストールされたコンテンツ)は、これらのセキュリティ制限による制約を受けません。

簡易なサウンドビジュアライザの作成

次の例は、 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 バイトのデータ値を順次実行し、今回は右から左へと逆順にプロットします。この結果として生成される波形プロットから、次に示すような面白い鏡像効果が生まれます。