forked from: Lissajous
drag down and tune me!
♥0 |
Line 177 |
Modified 2009-10-22 08:49:33 |
MIT License
archived:2017-03-30 05:34:23
ActionScript3 source code
/**
* Copyright fukt ( http://wonderfl.net/user/fukt )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/jmlQ
*/
// forked from tdpt's Lissajous
//
// drag down and tune me!
//
package {
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Graphics;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.events.SampleDataEvent;
import flash.geom.ColorTransform;
import flash.media.Sound;
import flash.media.SoundChannel;
[SWF(backgroundColor="0x000000", frameRate="24", width="465", height="465")]
public class Lissajous extends Sprite {
private const _step : Number = 0.01;
private var _bitmap : BitmapData;
private var _delay : ColorTransform;
private var _lastPosition : Number;
private var _freqX : Number = 440;
private var _freqY : Number = 480.03;
private var _oscX : Oscillator;
private var _oscY : Oscillator;
private var _mousePress : Boolean = false;
private var _lastFreqY : Number;
private var _lastMouseY : Number;
private var _channel : SoundChannel;
public function Lissajous() {
var sp : Sprite = new Sprite();
var g : Graphics = sp.graphics;
g.clear();
g.beginFill(0x000000);
g.drawRect(0, 0, stage.stageWidth, stage.stageHeight);
g.endFill();
addChild(sp);
_bitmap = new BitmapData(stage.stageWidth, stage.stageHeight, true, 0x00000000);
addChild(new Bitmap(_bitmap) );
_delay = new ColorTransform(1, 1, 1, 1, -8, -32, -16);
_oscX = new Oscillator();
_oscY = new Oscillator();
var sound : Sound = new Sound();
sound.addEventListener(SampleDataEvent.SAMPLE_DATA, sound_sampleDataHandler);
_channel = sound.play();
_lastPosition = _channel.position;
addEventListener(Event.ENTER_FRAME, enterFrameHandler);
stage.addEventListener(MouseEvent.MOUSE_DOWN, stage_mouseDownHandler);
}
private function sound_sampleDataHandler(event : SampleDataEvent) : void {
for (var i : int = 0; i < 5120; i++) {
_oscX.frequency = _freqX;
_oscY.frequency = _freqY;
var value : Number = (_oscX.getValue(event.position + i)
+ _oscY.getValue(event.position + i) ) * 0.1;
event.data.writeFloat(value);
event.data.writeFloat(value);
}
}
private function enterFrameHandler(event : Event) : void {
_bitmap.lock();
_bitmap.colorTransform(_bitmap.rect, _delay);
var w : int = stage.stageWidth / 2;
var h : int = stage.stageHeight / 2;
var position : Number = _channel.position;
for (var i : Number = _lastPosition; i < position; i += _step) {
var x : Number = _oscX.getValue(Fs * i * 0.1) * w + w;
var y : Number = _oscY.getValue(Fs * i * 0.08) * h + h;
_bitmap.setPixel32(x, y, 0xffffffff);
}
_lastPosition = position;
_bitmap.unlock();
}
private function stage_mouseDownHandler(event : MouseEvent) : void {
if (_mousePress) return;
_mousePress = true;
stage.addEventListener(MouseEvent.MOUSE_MOVE, stage_mouseMoveHandler);
stage.addEventListener(MouseEvent.MOUSE_UP, stage_mouseUpHandler);
stage.addEventListener(Event.MOUSE_LEAVE, stage_mouseLeaveHandler);
_lastFreqY = _freqY;
_lastMouseY = mouseY;
}
private function stage_mouseMoveHandler(event : MouseEvent) : void {
if (!_mousePress) return;
_freqY = _lastFreqY * Math.pow(2, (_lastMouseY - mouseY) / 12 * 0.001);
}
private function stage_mouseUpHandler(event : MouseEvent) : void {
mouseRelease();
}
private function stage_mouseLeaveHandler(event : Event) : void {
mouseRelease();
}
private function mouseRelease() : void {
if (!_mousePress) return;
_mousePress = false;
stage.removeEventListener(MouseEvent.MOUSE_MOVE, stage_mouseMoveHandler);
stage.removeEventListener(MouseEvent.MOUSE_UP, stage_mouseUpHandler);
stage.removeEventListener(Event.MOUSE_LEAVE, stage_mouseLeaveHandler);
}
}
}
// sampling rate (fixed)
const Fs : Number = 44100;
class OscillatorWaveForm {
public static const SAW : String = "saw";
public static const SQUARE : String = "square";
public static const SIN : String = "sin";
public static const TRIANGLE : String = "triangle";
}
class Oscillator {
private static const _RPS : Number = 2 * Math.PI / Fs;
private static const _PI : Number = Math.PI;
private static const _2PI : Number = 2 * Math.PI;
private var _offset : int;
private var _frequency : Number;
private var _lastFrequency : Number;
private var _waveForm : String;
private var _valid : Boolean;
private var _waveFunc : Function;
public function Oscillator() {
_offset = 0;
_frequency = 440;
_lastFrequency = frequency;
_waveForm = OscillatorWaveForm.SIN;
_valid = false;
}
public function get waveForm() : String {
return _waveForm;
}
public function set waveForm(value : String) : void {
if (_waveForm == value) return;
_waveForm = value;
_valid = false;
}
public function get frequency() : Number {
return _frequency;
}
public function set frequency(value : Number) : void {
_frequency = value;
}
public function getValue(position : int) : Number {
if (!_valid) {
validate();
_valid = true;
}
if (_lastFrequency != _frequency) {
// smoothing
_offset = (_offset + position) * _lastFrequency / _frequency - position;
_lastFrequency = _frequency;
}
return _waveFunc( (_offset + position) * _RPS * _frequency);
}
private function validate() : void {
switch(_waveForm) {
case OscillatorWaveForm.SAW :
_waveFunc = saw;
break;
case OscillatorWaveForm.SQUARE :
_waveFunc = square;
break;
case OscillatorWaveForm.TRIANGLE :
_waveFunc = triangle;
break;
case OscillatorWaveForm.SIN :
_waveFunc = Math.sin;
break;
default :
throw new Error(_waveForm);
}
}
private static function square(t : Number) : Number {
t = t % _2PI;
return (t < _PI)? 1 : -1;
}
private static function saw(t : Number) : Number {
t = t % _2PI;
return t / _PI - 1;
}
private static function triangle(t : Number) : Number {
t = t % _2PI;
return (t < _PI)? 2 * t / _PI - 1 : 3 - 2 * t / _PI;
}
}