forked from: ドラムンベース(っぽいもの)
package
{
import flash.display.Sprite
import flash.display.Shape
import flash.events.Event;
import flash.events.SampleDataEvent;
import flash.filters.BlurFilter;
import flash.media.Sound;
[SWF(backgroundColor=0x000000, frameRate=60)]
public class Breakbeats extends Sprite
{
private const PI2:Number = Math.PI * 2;
private const SAMPLE_RATE:Number = 44100;
private const LATENCY:int = 4410 //2048~8192
private var sound:Sound;
private var voices:Vector.<Voice> = new Vector.<Voice>()
private var particles:Vector.<Shape> = new Vector.<Shape>()
private var count:int = 0
public function Breakbeats()
{
init()
}
public function init():void
{
voices[0] = new Bass()
voices[1] = new Noise(.2,100,1000,1100)
voices[2] = new Noise(.2,100,5000,5100)
voices[3] = new Noise(.2,100,8000,10000)
var stageWidth:Number = stage.stageWidth
var stageHeight:Number = stage.stageHeight
var n:int = voices.length;
for (var i:int = 0; i < n; i++)
{
var s:Shape = new Shape()
var x:Number = stageHeight * Math.random() * .5 - stageHeight * .25;
var y:Number = stageHeight * Math.random() * .5 - stageHeight * .25;
s.graphics.beginFill(0xFFFFFF * Math.random());
s.graphics.drawCircle(x, y, Math.random() * 20 + 20);
s.alpha = .5
s.x = stage.stageWidth / 2;
s.y = stage.stageHeight / 2;
particles[i] = s
addChild(s)
}
addEventListener(Event.ENTER_FRAME,
function(e:Event):void {
var n:int = particles.length
for (var i:int = 0; i < n; i++)
{
var p:Shape = particles[i]
p.rotation += i % 2 * 2 - 1;
p.scaleX += (1 - p.scaleX) * .4;
p.scaleY += (1 - p.scaleY) * .4;
}
})
filters = [new BlurFilter(5, 5)]
sound = new Sound()
sound.addEventListener(SampleDataEvent.SAMPLE_DATA, updateVoice)
sound.play()
}
private function updateVoice(e:SampleDataEvent):void
{
var n:Number = LATENCY
count++
var c8:int = count %8
var c16:int = count %16
var c32:int = count %32
var c64:int = count % 64
if (count % 2 == 0 ) {
var ran:Number = Math.random()
if(ran > .6)
voices[1].play()
else if(ran > .3)
voices[2].play()
var ran2:Number = Math.random()
if (ran < .25)
voices[0].play()
}
if (count % 28 == 7)
voices[3].play()
else if (count % 28 == 21)
voices[3].play()
for (var i:int = 0; i < n; i++)
{
var sample:Number = 0
for each (var v:Voice in voices)
sample += v.pulse;
e.data.writeFloat(sample)
e.data.writeFloat(sample)
}
}
}
}
class Voice
{
private const PI2:Number = Math.PI * 2;
private const SAMPLE_RATE:Number = 44100;
private var phase:Number = 0
public var frequency:Number
public var volume:Number;
public var attack:int;
public var decay:int;
public var sustain:int;
private var position:int = 0
private var amplifier:Number = 0;
public function Voice(
frequency:Number = 440,
volume:Number = .2,
attack:int = 1000,
decay:int = 1000,
sustain:int = 5000 )
{
this.frequency = frequency
this.volume = volume
this.attack = attack
this.decay = decay
this.sustain = sustain
}
public function get pulse():Number
{
return Math.sin(updatePhase()) * updateAmplifier() * volume;
}
public function play():void
{
position = 0
}
public function updatePhase():Number
{
phase += PI2 * frequency / SAMPLE_RATE
phase %= PI2;
return phase
}
public function updateAmplifier():Number
{
var position:int = (this.position++ )
if (position >= sustain) {
amplifier = 0
}else if (position < attack) {
amplifier += 1/attack
}else if (position > (sustain-decay)) {
amplifier -= 1/decay
}
return amplifier;
}
}
class Bass extends Voice
{
public function Bass()
{
super(300,1,100,1000,5000)
}
public override function play():void
{
super.play()
frequency = 300
}
public override function get pulse():Number
{
this.frequency += (10 - frequency) / 2000;
return Math.sin(updatePhase()) * updateAmplifier() * volume;
}
}
class Sine extends Voice
{
public function Sine(
frequency:Number = 440,
volume:Number = .2,
attack:int = 1000,
decay:int = 1000,
sustain:int = 5000 )
{
super(frequency,volume,attack,decay,sustain)
}
public override function get pulse():Number
{
return Math.sin(updatePhase()) * updateAmplifier() * volume;
}
}
class Noise extends Voice
{
public function Noise(
volume:Number = .2,
attack:int = 1000,
decay:int = 1000,
sustain:int = 3000 )
{
super(440,volume,attack,decay,sustain)
}
public override function get pulse():Number
{
return (Math.random() * 2 - 1) * updateAmplifier() * volume;
}
}