package {
import de.popforge.audio.output.Audio;
import de.popforge.audio.output.AudioBuffer;
import de.popforge.audio.output.Sample;
import de.popforge.gui.Slider;
import de.popforge.parameter.MappingNumberExponential;
import de.popforge.parameter.MappingNumberLinear;
import de.popforge.parameter.Parameter;
import de.popforge.utils.Formatter;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.PixelSnapping;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.filters.BitmapFilter;
import flash.filters.BitmapFilterQuality;
import flash.filters.BlurFilter;
import flash.filters.ColorMatrixFilter;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.media.SoundMixer;
import flash.utils.ByteArray;
[SWF(width=256,height=256,frameRate=60, backgroundColor=0)]
public class SpectrumRange extends Sprite {
private static const ZERO_POINT:Point = new Point(0, 0);
private var _paramFreq:Parameter;
private var _phase:Number;
private var _frequency:Number;
private var _slider:Slider;
private var _spectrum:Bitmap;
private var _spectrumBitmap:BitmapData;
private var _data:ByteArray;
private var _filters:Array;
public function SpectrumRange() {
this.stage.scaleMode = StageScaleMode.NO_SCALE;
this.stage.align = StageAlign.TOP_LEFT;
this._spectrumBitmap = new BitmapData(256, 256, false, 0);
this._spectrum = this.addChild(new Bitmap(this._spectrumBitmap, PixelSnapping.NEVER, false)) as Bitmap;
this._filters = [
new BlurFilter(4, 4, BitmapFilterQuality.LOW),
new ColorMatrixFilter([
0.995, 0, 0, 0, 0,
0, 0.75, 0, 0, 0,
0, 0, 0.99, 0, 0,
0, 0, 0, 0, 0
])
];
this._data = new ByteArray();
var buffer: AudioBuffer = new AudioBuffer(4, Audio.STEREO, Audio.BIT16, Audio.RATE44100);
buffer.onInit = onAudioBufferInit;
buffer.onComplete = onAudioBufferComplete;
this._paramFreq = new Parameter(new MappingNumberLinear(110, 11008), this._frequency = 440);
this._slider = this.addChild(new Slider(this._paramFreq, Math.min(500, this.stage.stageWidth * 0.8))) as Slider;
this._phase = 0;
this.stage.addEventListener(Event.RESIZE, this._handleResize);
this._handleResize();
}
private function _handleResize(e:Event = null):void {
this._spectrum.width = this.stage.stageWidth;
this._spectrum.height = this.stage.stageHeight;
this._slider.x = (stage.stageWidth - this._slider.width) >> 1;
this._slider.y = (stage.stageHeight - 30);
}
private function onAudioBufferInit(buffer:AudioBuffer):void {
buffer.start();
this.addEventListener(Event.ENTER_FRAME, this.renderSpectrum);
}
private function onAudioBufferComplete(buffer:AudioBuffer):void {
var samples:Array = buffer.getSamples();
var sample:Sample;
var amplitude:Number;
for (var i:int = 0 ; i < samples.length ; i++) {
sample = samples[i];
amplitude = Math.sin(this._phase * Math.PI * 2);
sample.left = sample.right = amplitude < 0 ? -1 : 1; this._frequency += (this._paramFreq.getValue() - this._frequency) * .0001;
this._phase += this._frequency / Audio.RATE44100;
}
buffer.update();
}
private function renderSpectrum(e:Event = null):void {
try {
SoundMixer.computeSpectrum(this._data, true);
this._spectrumBitmap.lock();
for each (var fil:BitmapFilter in this._filters) {
this._spectrumBitmap.applyFilter(this._spectrumBitmap, this._spectrumBitmap.rect, ZERO_POINT, fil);
}
var rect:Rectangle = new Rectangle(0, 0, 1, 0);
for (var i:Number = 0; i < 256; i++) {
rect.x = i;
rect.width = 1;
rect.height = this._data.readFloat() * 128;
rect.y = 256 - rect.height;
this._spectrumBitmap.fillRect(rect, 0x80ffffff);
}
this._spectrumBitmap.unlock();
} catch (e:Error) {
trace(e);
}
}
}
}