forked from: ドラムンベース(っぽいもの)
// forked from kappaLab's ドラムンベース(っぽいもの)
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 Drumnbass_3 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 Drumnbass_3()
{
init()
}
public function init():void
{
voices[0] = new Voice(60,.6,100,2000,6000)
voices[1] = new Voice(120,.2,100,500,600)
voices[2] = new Voice(80, .8,100,500,600)
voices[3] = new Voice(880,.2,100,500,600)
voices[4] = new Voice(660,.5,100,1000,1200)
voices[5] = new Voice(440,.5,100,1000,1200)
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 (c8 == 0 ||
c8 == 1 ||
c8 == 2 ||
c8 == 3 ) {
if (Math.random() > .3) {
voices[2].play();
particles[2].scaleX = particles[2].scaleY = 2
}else {
voices[3].play()
particles[3].scaleX = particles[3].scaleY = 2
}
}
if (c8 == 6 ||
c8 == 7 ) {
voices[1].play()
particles[1].scaleX = particles[1].scaleY = 2.5
}
if (count % 16 == 11) {
particles[0].scaleX = particles[0].scaleY = 3
voices[0].play()
}
if (count % 32 == 8) {
particles[4].scaleX = particles[4].scaleY = 3
voices[4].play()
}
if (count % 32 == 10 && Math.random()>.3){
particles[5].scaleX = particles[5].scaleY = 4
voices[5].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.abs(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;
}
}