Flash version 10 has significant feature about audio, SampleDataEvent. Until this version, there was no way to generate a sound wave easily. Some people have tried to do that by rather magical way of how to make actionscript 3 play generated pcm wave data in Flash 9, however, now we have a straightforward API from Flash 10. I think this is a great improvement for hobby programmers who are interested in computer generated music. While it's shame from some perspective. Just this API finally brings us a point where old BASIC and PLAY statement could do a quarter centry ago!
You would find a lot of examples about SampleDataEvent, but some of those are wrong or uncompleted, since I think this API have been changed so often in beta version. And I wrote my version of simplest example for exercise.
There are a couple of tricks you might trap.- If you get an error message: "Flex error: type was not found or was not a compile-time constant: SampleDataEvent", you have to specify the Flash version to 10.0.0. Set -target-player option or Flex builder's Project's Properties - ActionScript Compiler - HTML Wrapper
- Some documentation might use Event.SAMPLE_DATA, but this is not true.
// SineSound.as | |
// A simple sine sound. | |
// | |
// compile option | |
// mxmlc -target-player 10.0.0 SineSound.as | |
package { | |
import flash.display.Sprite; | |
import flash.events.SampleDataEvent; | |
import flash.media.Sound; | |
public class SineSound extends Sprite | |
{ | |
private var frequency:Number= 440; | |
private var gain:Number= 0.25; | |
private var rate:int= 44100; | |
private var pitch:Number= rate / frequency; | |
public function SineSound() | |
{ | |
var s:Sound= new Sound(); | |
s.addEventListener(SampleDataEvent.SAMPLE_DATA, makeWave); | |
s.play(); | |
} | |
private function makeWave(event:SampleDataEvent):void { | |
for (var i:int= 0; i < 8192; i++) { | |
var pos:int= i + event.position; | |
var phase:Number= (pos % pitch) / pitch; // 0 <= phase < pitch | |
var v:Number= Math.sin(2 * Math.PI * phase) * gain; | |
// var v:Number= phase < 0.5 ? gain : -gain; // Rectangle Wave | |
event.data.writeFloat(v); | |
event.data.writeFloat(v); | |
} | |
} | |
} | |
} | |