Hey, I just want to shed some light into this.
Of course you can substitute SampleDataEvent by loadPCMFromByteArray even though
this ain’t exactly the same.
Here’s an example utilizing SampleDataEvent, which generates a one second long
squarewave:
package;
import openfl.display.Sprite;
import openfl.media.Sound;
import openfl.events.SampleDataEvent;
class Main extends Sprite
{
private var SampleRate = 44100;
private var ToneHertz = 256;
private var ToneVolume = 16000;
private var RunningSampleIndex=0;
private var SquareWavePeriod=0;
private var HalfSquareWavePeriod = 0;
private var sound:Sound = new Sound();
public function new()
{
super();
SquareWavePeriod = Std.int(SampleRate / ToneHertz);
HalfSquareWavePeriod = Std.int(SquareWavePeriod / 2);
sound.addEventListener(SampleDataEvent.SAMPLE_DATA, onSampleData);
sound.play();
}
private function onSampleData(event:SampleDataEvent):Void
{
for (i in 0...8192)
{
var SampleValue = (Std.int(RunningSampleIndex++ / HalfSquareWavePeriod) % 2 == 0) ? ToneVolume : -ToneVolume;
event.data.writeFloat(SampleValue);
event.data.writeFloat(SampleValue);
if (RunningSampleIndex == 44100)
{
sound.removeEventListener(SampleDataEvent.SAMPLE_DATA, onSampleData);
break;
}
}
}
}
If you take a look at the function onSampleData you’ll find
a for loop which increments up to 8192. This is actually our buffer of samples.
At a playback rate of 44100 hz this means we’re generating roughly 186ms of audio
which are written to a bytearray. (8192/44100*1000)
So whenever we’re running out of samples onSampleData will be called again and we
can do changes to the audio.
Now if we only want to generate a one second long squarewave we don’t really need
SampleDataEvent because we can generate the complete bytearray upfront and utilize
loadPCMFromByteArray.
Here’s another example:
package;
import openfl.display.Sprite;
import openfl.media.Sound;
import openfl.utils.ByteArray;
class Main extends Sprite
{
private var SampleRate = 44100;
private var ToneHertz = 256;
private var ToneVolume = 16000;
private var RunningSampleIndex=0;
private var SquareWavePeriod=0;
private var HalfSquareWavePeriod = 0;
private var sound:Sound = new Sound();
private var bytes:ByteArray = new ByteArray();
public function new()
{
super();
SquareWavePeriod = Std.int(SampleRate / ToneHertz);
HalfSquareWavePeriod = Std.int(SquareWavePeriod / 2);
for (i in 0...44100)
{
var SampleValue = (Std.int(RunningSampleIndex++ / HalfSquareWavePeriod) % 2 == 0) ? ToneVolume : -ToneVolume;
bytes.writeFloat(SampleValue);
bytes.writeFloat(SampleValue);
}
bytes.position = 0;
sound.loadPCMFromByteArray( bytes, Std.int(bytes.length / 4 / 2), "float", true, 44100);
sound.play();
}
}