flash on 2010-1-6

by mirkofresa
♥0 | Line 700 | Modified 2010-01-06 21:36:09 | MIT License
play

ActionScript3 source code

/**
 * Copyright mirkofresa ( http://wonderfl.net/user/mirkofresa )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/iRn1
 */

package {
    import flash.display.Sprite
    import flash.text.TextField
    import flash.text.TextFieldAutoSize
    import flash.display.SimpleButton
    import flash.media.Sound
    import flash.events.*
    import flash.utils.setTimeout
 
    public class GenerateAudio extends Sprite {
 
private var bassline:Bassline = new Bassline()
private var sound:Sound = new Sound()
private var playing:Boolean = false
 
private var indicators:Array = []
private var vumeter:VUMeter = new VUMeter()
 
public function GenerateAudio() {
clock.frequency[0] = 8.0
bassline.glider.frequency[0] = 8.0 / 2
var bg:Sprite = new Sprite()
drawRoundedRectangle(bg.graphics, 0, 0.5,0,0,440,175)
addChild(bg)
 
 
var label:TextField = new TextField()
label.defaultTextFormat = titleTextFormat
label.width = 195
label.autoSize = TextFieldAutoSize.CENTER
label.text = "Bassline"
label.y = 5
label.x = 10
addChild(label)
 
label = new TextField()
label.defaultTextFormat = buttonTextFormat
label.width = 195
label.autoSize = TextFieldAutoSize.CENTER
label.text = "Bassline experiment v1.1 (c) 2009 Joost Diepenmaat\njoost@zeekat.nl http://joost.zeekat.nl"
label.y = 50
label.x = 240
addChild(label)
 
 
var button:ToggleButton = new ToggleButton("POW",false,0x700000,0xf00000)
button.x = 10
button.y = 50
addChild(button)
button.onOn = function():void { playing = true }
button.onOff = function():void { playing = false }
 
var dial:DialButton = new DialButton("SPD",20,0.5,20)
dial.x = 35
dial.y = 50
addChild(dial)
dial.onChange = function(value:Number):void {
clock.frequency[0] = value
bassline.glider.frequency[0] = value / 2
}
 
for (var i:int = 0; i < 16; i++) {
var b:DialButton = new DialButton("Freq",Math.round(Math.random()*128),-1.0,127.0,0x00dddd)
b.x = 35 + 25 * i
b.y = 100
addChild(b)
b.onChange = (function(ii:int):Function {
return function(value:Number):void {
var index:uint = Math.round(value)
bassline.seq["note"+ii][0] = index == -1 ? -1.0 : MIDI_NOTES[index]
}
}
)(i)
var tb:ToggleButton = new ToggleButton("Acc",false,0x700000,0xf00000)
tb.x = 35 + 25 * i
tb.y = 125
addChild(tb)
tb.onOn = (function(ii:int):Function {
return function():void {
bassline.accent["note"+ii][0] = 1.0
}
}
)(i)
tb.onOff = (function(ii:int):Function {
return function():void {
bassline.accent["note"+ii][0] = 0.0
}
}
)(i)
 
tb = new ToggleButton("Glide",false,0x700000,0xf00000)
tb.x = 35 + 25 * i
tb.y = 150
addChild(tb)
tb.onOn = (function(ii:int):Function {
return function():void {
bassline.slide["note"+ii][0] = 1.0
}
}
)(i)
tb.onOff = (function(ii:int):Function {
return function():void {
bassline.slide["note"+ii][0] = 0.0
}
}
)(i)
 
 
tb = new ToggleButton(i.toString(),false,0x007000,0x00f000,0)
tb.x = 35 + 25 * i
tb.y = 75
addChild(tb)
indicators.push(tb)
}
 
 
var dial2:DialButton = new DialButton("FRQ",0.2,0.0,0.5)
dial2.x = 60
dial2.y = 50
addChild(dial2)
dial2.onChange = function(value:Number):void {
bassline.interpolateF.input[0] = value
}
 
var dial3:DialButton = new DialButton("Q",0.2,0.0,1.0)
dial3.x = 85
dial3.y = 50
addChild(dial3)
dial3.onChange = function(value:Number):void {
bassline.interpolateQ.input[0] = value
}
 
var dial4:DialButton = new DialButton("Decay",0.888,0.0,1.0)
dial4.x = 110
dial4.y = 50
addChild(dial4)
dial4.onChange = function(value:Number):void {
bassline.decay.decay[0] = 1.0 - Math.pow(1.0 - (0.5 + value /4),8)
}
 
var dialMod:DialButton = new DialButton("Mod",0.2,0.0,1.0)
dialMod.x = 135
dialMod.y = 50
addChild(dialMod)
dialMod.onChange = function(value:Number):void {
bassline.envMod.inputC[0] = value
}
 
var dialAcc:DialButton = new DialButton("Acc",0.5,0.2,4.0)
dialAcc.x = 160
dialAcc.y = 50
addChild(dialAcc)
dialAcc.onChange = function(value:Number):void {
bassline.accentStrength.inputC[0] = value
}
 
var dialVol:DialButton = new DialButton("Vol",0.5,0.0,1.0)
dialVol.x = 185
dialVol.y = 50
addChild(dialVol)
dialVol.onChange = function(value:Number):void {
bassline.volume.inputC[0] = value
}
 
 
vumeter.x = 10
vumeter.y = 75
addChild(vumeter)
 
 
var rbutton:ToggleButton = new ToggleButton("RAND",false,0x909090,0xf0f0f0)
knobs.pop()
rbutton.x = 210
rbutton.y = 50
addChild(rbutton)
rbutton.onOn = function():void {
randomize();
var id:Object
id = flash.utils.setTimeout(function():void { rbutton.setValue(false) }, 200 )
}
rbutton.onOff = function():void {}
 
randomize()
 
sound.addEventListener(SampleDataEvent.SAMPLE_DATA,generateSound)
 
sound.play()
}
 
public function generateSound(event:flash.events.SampleDataEvent):void {
if (playing) {
clock.run(2048)
bassline.run(2048)
 
 
var avg:Number = 0.0
for ( var c:int=0; c<2048; c++ ) {
var out:Number = Math.min(1.0,bassline.volume.output[c])
avg += Math.abs(out)
event.data.writeFloat(out)
event.data.writeFloat(out)
}
for (var i:int=0; i < 16; i++) {
indicators[i].setValue(i == bassline.seq.step)
}
vumeter.setValue(avg/2048)
}
else {
for ( c=0; c<2090; c++ ) {
event.data.writeFloat(0.0);
event.data.writeFloat(0.0);
}
}
}
    }
}
 
 
// shorthand to create new sample vectors
function buffer():Vector.<Number> {
    return new Vector.<Number>(4000,true)
}
 
function randomize():void {
    for (i = 1; i < knobs.length; i++) {
knobs[i].randomize()
    }
}
 
var clock:Clock = new Clock()

import flash.display.DisplayObject;
import flash.display.Shape;
import flash.display.Sprite;
import flash.text.TextField;
import flash.text.TextFormat;
import flash.text.TextFieldAutoSize;
import flash.display.SimpleButton;
import flash.events.*
 
var buttonTextFormat:TextFormat = new TextFormat()
buttonTextFormat.font = "Verdana"
buttonTextFormat.color = 0xffffff
buttonTextFormat.size = 5
buttonTextFormat.bold = true
 
var titleTextFormat:TextFormat = new TextFormat()
titleTextFormat.font = "Verdana"
titleTextFormat.color = 0xffffff
titleTextFormat.size = 25
titleTextFormat.bold = true
 
var knobs:Array = []
 
function drawRoundedRectangle(graphics:flash.display.Graphics,color:uint,alpha:Number,x1:Number,y1:Number,x2:Number,y2:Number,rounded:Number = 2.0):void {
    with (graphics) {
lineStyle(1,0)
beginFill(color,alpha)
moveTo(x1+rounded,y1)
lineTo(x2-rounded,y1)
curveTo(x2,y1,x2,y1+rounded)
lineTo(x2,y2-rounded)
curveTo(x2,y2,x2-rounded,y2)
lineTo(x1+rounded,y2)
curveTo(x1,y2,x1,y2-rounded)
lineTo(x1,y1+rounded)
curveTo(x1,y1,x1+rounded,y1)
endFill()
    }
}
 
function drawLabel(sprite:Sprite, text:String, color:uint=0xffffff,bgcolor:uint=0xd0d0d0, bgalpha:Number=0.5):void {
    drawRoundedRectangle(sprite.graphics, bgcolor, bgalpha,0,0,20,20)
    var label:TextField = new TextField()
    label.selectable = false
    label.defaultTextFormat = buttonTextFormat
    label.width = 1
    label.autoSize = TextFieldAutoSize.LEFT
    label.text = text
    label.y = 10
    sprite.addChild(label)
    label.x = (20.0 - label.textWidth) / 2.0 - 1.7
}
 
 
 
class ToggleButton extends Sprite {
    public var onState:Shape
    public var offState:Shape
    public var onOff:Function
    public var onOn:Function
    private var state:Boolean
 
    public function ToggleButton(text:String,startState:Boolean,upcolor:uint,downcolor:uint,bgcolor:uint = 0xd0d0d0,bgalpha:Number=0.5) {
buttonMode = true
        useHandCursor = true
drawLabel(this, text, 0xffffff,bgcolor, bgalpha)
 
onState = createShape(10,0, downcolor)
offState = createShape(10,0, upcolor)
onState.y = offState.y = 2
onState.x = offState.x = 5
 
state = startState
 
addEventListener(MouseEvent.CLICK, function():void {
if (onOn != null && onOff != null) {
setValue(!state)
}
})
 
updateState()
addChild(onState)
addChild(offState)
knobs.push(this)
    }
 
    public function setValue(val:Boolean):void {
state = val
if (state && onOn != null) onOn()
if (!state && onOff != null) onOff()
updateState()
    }
 
    private function updateState():void {
if (state) {
onState.visible=true
offState.visible=false
}
else {
onState.visible=false
offState.visible=true
}
    }
 
    private function createShape(size:Number,edgeColor:uint,fillColor:uint):Shape {
var sp:Shape = new Shape()
with (sp.graphics) {
beginFill(fillColor)
drawCircle(size/2,size/2,size/2)
endFill()
lineStyle(size/10,edgeColor)
drawCircle(size/2,size/2,size/2)
lineStyle(undefined)
beginFill(0,0.3)
drawCircle(size/2,size/2,size/3)
endFill()
lineStyle(size/10,0xffffe0,0.3)
moveTo(size*.80,size*.5)
curveTo(size*.80,size*.80,size*.5,size*.80)
}
return sp
    }
    public function randomize():void {
setValue(Math.random() < 0.5)
    }
}
 
class DialButton extends Sprite {
    public var shape:Shape = new Shape()
    public var onChange:Function
    private var value:Number
    private var min:Number
    private var max:Number
    private var color:uint
 
    public function DialButton(text:String,startValue:Number,min:Number,max:Number,color:uint=0xd0d0d0) {
this.min = min
this.max = max
buttonMode = false
value = startValue
 
drawLabel(this, text)
 
// shape is the dialing part of the graphics:
// the value is indicated by rotating shape
with (shape.graphics) {
clear()
rotation = 0
lineStyle(1,0)
beginFill(color)
drawCircle(0,0,5)
endFill()
moveTo(0,-5)
lineTo(0,-1)
}
shape.x = 10
shape.y = 7
updateDisplay()
addChild(shape)
 
 
var y:Number = 0.0
function drag(event:MouseEvent):void {
var delta:Number = ((event.stageY - y) * (max - min)) / 100
setValue(Math.min(max,Math.max(min,value - delta)))
}
 
function upevent(event:MouseEvent):void {
root.removeEventListener(MouseEvent.MOUSE_MOVE,drag)
root.removeEventListener(MouseEvent.MOUSE_UP,upevent)
}
 
 
addEventListener(MouseEvent.MOUSE_DOWN, function(event:MouseEvent):void {
y = event.stageY
root.addEventListener(MouseEvent.MOUSE_MOVE,drag)
root.addEventListener(MouseEvent.MOUSE_UP, upevent)
})
knobs.push(this)
    }
 
    public function setValue(val:Number):void {
value = val
if (onChange != null) onChange(value)
updateDisplay()
    }
 
    private function updateDisplay():void {
shape.rotation = (value-min)* (320/(max - min)) - 160
    }
 
    public function randomize():void {
setValue(Math.random() * (max - min) + min)
    }
 
}
 
class VUMeter extends Sprite {
    private var indicator:Shape = new Shape()
    public function VUMeter() {
drawRoundedRectangle(graphics, 0, 0.5, 0,0,20,95)
addChild(indicator)
    }
 
    public function setValue(val:Number):void {
indicator.graphics.clear()
var color:uint
val = Math.min(1,Math.max(0,Math.abs(val)))
if (val * 83 < 8) return;
if (val < 0.5) {
color = 0xa0a000
}
else if (val < 0.8) {
color = 0x00f000
}
else {
color = 0xff0000
}
drawRoundedRectangle(indicator.graphics, color, 1, 4,8 + (1 - val) * 83,16,91)
    }
}
const SAMPLE_RATE:Number = 44100.0
 
const MIDI_NOTES:Array = []
 
function midiNoteToFrequency(note:uint):Number {
    return 440.0 * Math.pow(2.0,(note-69.0)/12.0)
}
 
for (var i:int =0; i < 128; i++) {
    MIDI_NOTES.push(midiNoteToFrequency(i))
}
 
class Oscillator {
    public var output:Vector.<Number> = buffer();
    public var frequency:Vector.<Number> = buffer();
    private var phase:Number = 0.0;
    private var phaseStep:Number = 0.0;
    public function run(frames:uint):void {
for (var i:uint = 0; i < frames; i++) {
phaseStep = frequency[i] / (SAMPLE_RATE / 2)
if (phase < 1.0) {
output[i] = 0.5;
}
else {
output[i] = -0.5;
}
phase += phaseStep;
if (phase >= 2.0) {
phase -= 2.0;
}
}
    }
}
 
class Sequencer {
    public var output:Vector.<Number> = buffer()
    public var trigger:Vector.<Number> = buffer()
    public var note0:Vector.<Number> = buffer()
    public var note1:Vector.<Number> = buffer()
    public var note2:Vector.<Number> = buffer()
    public var note3:Vector.<Number> = buffer()
    public var note4:Vector.<Number> = buffer()
    public var note5:Vector.<Number> = buffer()
    public var note6:Vector.<Number> = buffer()
    public var note7:Vector.<Number> = buffer()
    public var note8:Vector.<Number> = buffer()
    public var note9:Vector.<Number> = buffer()
    public var note10:Vector.<Number> = buffer()
    public var note11:Vector.<Number> = buffer()
    public var note12:Vector.<Number> = buffer()
    public var note13:Vector.<Number> = buffer()
    public var note14:Vector.<Number> = buffer()
    public var note15:Vector.<Number> = buffer()
 
    public var triggerOut:Vector.<Number> = buffer()
    public var step:uint = 0;
    private var trigHigh:Boolean = true
    private var lastNote:Number = 0.0
    public function run(frames:uint):void {
for (var i:uint = 0; i < frames; i++) {
if (trigger[i] > 0.5) {
if (!trigHigh) {
if (++step > 15) step -= 16
trigHigh = true
}
}
else {
trigHigh = false
}
switch (step) {
case 0:
this.output[i] = this.note0[0]
break
case 1:
this.output[i] = this.note1[0]
break
case 2:
this.output[i] = this.note2[0]
break
case 3:
this.output[i] = this.note3[0]
break
case 4:
this.output[i] = this.note4[0]
break
case 5:
this.output[i] = this.note5[0]
break
case 6:
this.output[i] = this.note6[0]
break
case 7:
this.output[i] = this.note7[0]
break
case 8:
this.output[i] = this.note8[0]
break
case 9:
this.output[i] = this.note9[0]
break
case 10:
this.output[i] = this.note10[0]
break
case 11:
this.output[i] = this.note11[0]
break
case 12:
this.output[i] = this.note12[0]
break
case 13:
this.output[i] = this.note13[0]
break
case 14:
this.output[i] = this.note14[0]
break
case 15:
this.output[i] = this.note15[0]
break
}
if (output[i] == -1.0) {
output[i] = lastNote
triggerOut[i] = 0.0
}
else {
lastNote = output[i]
triggerOut[i] = trigger[i]
}
}
 
    }
}
 
 
class Clock {
    public var output:Vector.<Number> = buffer()
    public var frequency:Vector.<Number> = buffer()
    private var phase:Number = 0.0
    
    public function run(frames:uint):void {
var step:Number = frequency[0] / SAMPLE_RATE
for (var i:uint = 0; i < frames; i++) {
if (phase <= 0.1) {
output[i] = 1.0
}
else {
output[i] = 0.0
}
phase += step
if (phase >= 1.0) phase -= 1.0
}
    }
}
 
class SimpleOnePoleFilter {
    public var input:Vector.<Number> = buffer()
    public var output:Vector.<Number> = buffer()
    public var frequency:Vector.<Number> = buffer()
    private var prev:Number = 0.0
    public function run(frames:uint):void {
var a:Number = SAMPLE_RATE / (frequency[0] * 2 * Math.PI)
for (var i:uint = 0; i < frames; i++) {
prev = output[i] = prev + ((input[i] - prev) / a)
}
    }
}
 
// http://www.musicdsp.org/showArchiveComment.php?ArchiveID=29
class SimpleResonantFilter {
    public var input:Vector.<Number> = buffer()
    public var output:Vector.<Number> = buffer()
    public var frequency:Vector.<Number> = buffer() // between 0 .. +/- 0.5
    public var q:Vector.<Number> = buffer() // between 0 .. 1
    private var buf0:Number = 0.0
    private var buf1:Number = 0.0
    public function run(frames:uint):void {
for (var i:uint = 0; i < frames; i++) {
var f:Number = Math.min(0.5,frequency[i])
var qq:Number = Math.min(0.95,q[i])
var fb:Number = qq + qq / (1.0 - f)
buf0 = buf0 + f * (input[i] - buf0 + fb * (buf0 - buf1))
output[i] = buf1 = buf1 + f * (buf0 - buf1)
}
    }
}
 
class Decay {
    public var trigger:Vector.<Number> = buffer()
    public var output:Vector.<Number> = buffer()
    public var decay:Vector.<Number> = buffer()
    private var trigHigh:Boolean = true
    private var state:Number = 0.0
    public function run(frames:uint):void {
var d:Number = Math.max(0.0,Math.min(1.0,decay[0]))
for (var i:uint = 0; i < frames; i++) {
if (trigger[i] > 0.5) {
if (!trigHigh) {
state = 1.0
trigHigh = true
}
}
else {
trigHigh = false
}
output[i] = state
state *= d
}
    }
}
 
class MultiplyAA {
    public var input1:Vector.<Number> = buffer()
    public var input2:Vector.<Number> = buffer()
    public var output:Vector.<Number> = buffer()
    public function run(frames:uint):void {
for (var i:uint = 0; i < frames; i++) {
output[i] = input1[i] * input2[i]
}
    }
}
 
class MultiplyCA {
    public var inputC:Vector.<Number> = buffer()
    public var inputA:Vector.<Number> = buffer()
    public var output:Vector.<Number> = buffer()
    public function run(frames:uint):void {
for (var i:uint = 0; i < frames; i++) {
output[i] = inputC[0] * inputA[i]
}
    }
}
 
class AddAA {
    public var input1:Vector.<Number> = buffer()
    public var input2:Vector.<Number> = buffer()
    public var output:Vector.<Number> = buffer()
    public function run(frames:uint):void {
for (var i:uint = 0; i < frames; i++) {
output[i] = input1[i] + input2[i]
}
    }
}
 
 
class Interpolate {
    public var input:Vector.<Number> = buffer()
    public var output:Vector.<Number> = buffer()
    private var buffer:Number = 0.0
    public function run(frames:uint):void {
for (var i:uint = 0; i < frames; i++) {
output[i] = input[0] - ( input[0] - buffer) * ((frames - i) / frames)
}
buffer = output[i-1]
    }
}
 
class InterpolateAA {
    public var input:Vector.<Number> = buffer()
    public var output:Vector.<Number> = buffer()
    public var onoff:Vector.<Number> = buffer()
    public var frequency:Vector.<Number> = buffer()
    private var buffer:Number = 0.0
    public function run(frames:uint):void {
for (var i:uint = 0; i < frames; i++) {
if (onoff[i] > 0.5) {
var diff:Number = input[i] - buffer
buffer = output[i] = buffer + diff * 20 * frequency[0] / SAMPLE_RATE
}
else {
buffer = output[i] = input[i]
}
}
    }
}
 
class Bassline {
    public var osc:Oscillator = new Oscillator()
    public var seq:Sequencer = new Sequencer()
    public var accent:Sequencer = new Sequencer()
    public var accentDecay:Decay = new Decay()
    public var accentAmp:MultiplyAA = new MultiplyAA()
    public var accentStrength:MultiplyCA = new MultiplyCA()
    public var glider:InterpolateAA = new InterpolateAA()
    public var accentAdd:AddAA = new AddAA()
    public var slide:Sequencer = new Sequencer()
 
    public var decay:Decay = new Decay()
    public var filter:SimpleResonantFilter = new SimpleResonantFilter()
    public var interpolateF:Interpolate = new Interpolate()
    public var interpolateQ:Interpolate = new Interpolate()
    public var amp:MultiplyAA = new MultiplyAA()
    public var envMod:MultiplyCA = new MultiplyCA()
    public var envModAdd:AddAA = new AddAA()
    public var volume:MultiplyCA = new MultiplyCA()
    public function Bassline() {
filter.input = osc.output
filter.q = interpolateQ.output
decay.trigger = seq.triggerOut
glider.input = seq.output
slide.trigger = clock.output
glider.onoff = slide.output
osc.frequency = glider.output
 
seq.trigger = clock.output
 
accent.trigger = clock.output
accentAmp.input1 = accent.output
accentAmp.input2 = clock.output
accentDecay.trigger = accentAmp.output
accentDecay.decay[0] = 0.999
accentStrength.inputA = accentDecay.output
 
envMod.inputA = accentStrength.output
envModAdd.input1 = envMod.output
envModAdd.input2 = interpolateF.output
filter.frequency = envModAdd.output
 
accentAdd.input1 = accentStrength.output
accentAdd.input2 = decay.output
amp.input1 = accentAdd.output
amp.input2 = filter.output
 
volume.inputA = amp.output
    }
    public function run(frames:uint):void {
// order is important here, as always
 
// sequencer parts first
seq.run(frames)
slide.run(frames)
accent.run(frames)
 
// glider/oscillator
glider.run(frames)
osc.run(frames)
 
// decay & accent (both used in envmod)
decay.run(frames)
accentAmp.run(frames)
accentDecay.run(frames)
accentStrength.run(frames)
accentAdd.run(frames)
 
// envmod
envMod.run(frames)
envModAdd.run(frames)
 
// lowpass filter
interpolateF.run(frames)
interpolateQ.run(frames)
filter.run(frames)
 
// amplitude / volume
amp.run(frames)
volume.run(frames)
    }
}
 
 
class Drums {
    
}