Instead of loading or streaming an existing sound, you
can generate audio data dynamically. You can generate audio data
when you assign an event listener for the
sampleData
event
of a Sound object. (The
sampleData
event is defined in
the SampleDataEvent class.) In this environment, the Sound object
doesn’t load sound data from a file. Instead, it acts as a socket
for sound data that is being streamed to it by using the function
you assign to this event.
When you add a
sampleData
event listener to
a Sound object, the object periodically requests data to add to
the sound buffer. This buffer contains data for the Sound object
to play. When you call the
play()
method of the
Sound object, it dispatches the
sampleData
event
when requesting new sound data. (This is true only when the Sound
object has not loaded mp3 data from a file.)
The SampleDataEvent object includes a
data
property.
In your event listener, you write ByteArray objects to this
data
object.
The byte arrays you write to this object add to buffered sound data
that the Sound object plays. The byte array in the buffer is a stream
of floating-point values from -1 to 1. Each floating-point value
represents the amplitude of one channel (left or right) of a sound
sample. Sound is sampled at 44,100 samples per second. Each sample
contains a left and right channel, interleaved as floating-point
data in the byte array.
In your handler function, you use the
ByteArray.writeFloat()
method
to write to the
data
property of the
sampleData
event.
For example, the following code generates a sine wave:
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);
}
}
When you call
Sound.play()
, the application
starts calling your event handler, requesting sound sample data.
The application continues to send events as the sound plays back
until you stop providing data, or until you call
SoundChannel.stop()
.
The latency of the event varies from platform to platform, and
could change in future versions of AIR. Do not depend on a specific
latency; calculate it instead. To calculate the latency, use the
following formula:
(SampleDataEvent.position / 44.1) - SoundChannelObject.position
Provide from 2048 through 8192 samples to the
data
property
of the SampleDataEvent object (for each call to the event listener).
For best performance, provide as many samples as possible (up to
8192). The fewer samples you provide, the more likely it is that
clicks and pops occur during playback. This behavior can differ
on various platforms and can occur in various situations—for example,
when resizing the browser. Code that works on one platform when
you provide only 2048 sample might not work as well when run on
a different platform. If you require the lowest latency possible,
consider making the amount of data user-selectable.
If you provide fewer than 2048 samples (per call to the
sampleData
event listener),
the application stops after playing the remaining samples. It then dispatches
a SoundComplete event.