既存のサウンドを読み込んだりストリーミングしたりする代わりに、オーディオデータを動的に生成することもできます。オーディオデータを生成するには、Sound オブジェクトの
sampleData
イベントのイベントリスナーを割り当てる必要があります(
sampleData
イベントは、SampleDataEvent クラスで定義されています)。この環境では、Sound オブジェクトはファイルからサウンドデータを読み込みません。代わりに、このイベントに割り当てた関数を使用して自身にストリーミングされるサウンドデータのソケットとして機能します。
Sound オブジェクトに
sampleData
イベントリスナーを追加すると、サウンドバッファーに追加するデータが定期的に要求されます。このバッファーには、Sound オブジェクトで再生するデータが格納されます。Sound オブジェクトの
play()
メソッドを呼び出すと、新しいサウンドデータの要求時に
sampleData
イベントが送出されます(Sound オブジェクトがファイルから mp3 データを読み込んでいない場合のみ)。
SampleDataEvent オブジェクトには、
data
プロパティがあります。イベントリスナーでは、この
data
オブジェクトに ByteArray オブジェクトを書き込みます。このオブジェクトに書き込んだバイト配列は、バッファーに格納されたサウンドデータに追加され、Sound オブジェクトで再生されます。バッファー内のバイト配列は、-1 ~ 1 の浮動小数点数値のストリームです。各浮動小数点数値は、サウンドサンプルの 1 つのチャンネル(左または右)の振幅を表します。サウンドは、1 秒間に 44,100 回サンプリングされます。各サンプルには、バイト配列の浮動小数点数値としてインターリーブされた、左または右のチャンネルが格納されます。
ハンドラー関数では、
ByteArray.writeFloat()
メソッドを使用して、
data
プロパティ(
sampleData
イベント)に書き込みます。例えば、次のコードでは正弦波が生成されます。
var mySound = new air.Sound();
mySound.addEventListener(air.SampleDataEvent.SAMPLE_DATA, sineWaveGenerator);
mySound.play();
function sineWaveGenerator(event)
{
for (i = 0; i < 8192; i++)
{
var n = Math.sin((i + event.position) / Math.PI / 4);
event.data.writeFloat(n);
event.data.writeFloat(n);
}
}
Sound.play()
を呼び出すと、アプリケーションがイベントハンドラーの呼び出しを開始し、サウンドサンプルデータを要求します。データの供給を中止するか、
SoundChannel.stop()
を呼び出すまでは、サウンドが再生される間、アプリケーションはイベントを送信し続けます。
イベントの待ち時間はプラットフォームによって異なりますが、AIR の将来のバージョンでは変更される可能性があります。特定の待ち時間に依存するのではなく、計算して求めてください。待ち時間を計算するには、次の式を使用します。
(SampleDataEvent.position / 44.1) - SoundChannelObject.position
イベントリスナーの各呼び出しでは、SampleDataEvent オブジェクトの
data
プロパティに 2048 ~ 8192 サンプルを指定します。最適なパフォーマンスを得るためには、できるだけ多くのサンプル数を指定します(最大 8192)。用意するサンプルが少なければ少ないほど、再生中にクリック音およびポップ音が発生する可能性が高くなります。この動作は、プラットフォームによって異なります。また、ブラウザーのサイズを変更したときなど、様々な状況で発生します。2048 サンプルだけを指定した場合、あるプラットフォームで機能するコードが、別のプラットフォームで実行した場合は機能しなくなる可能性があります。できるだけ待ち時間を小さくする必要がある場合は、データの量をユーザーが選択できるようにすることを検討してください。
sampleData
イベントリスナーの 1 回の呼び出しごとのサンプル数を 2048 未満にすると、残りのサンプルの再生後にアプリケーションが停止します。その後、SoundComplete イベントが送出されます。