Sound Library のテスト
package
{
import flash.display.GradientType;
import flash.display.Graphics;
import flash.display.SimpleButton;
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.events.SampleDataEvent;
import flash.media.Sound;
import flash.utils.ByteArray;
[SWF(frameRate=1)]
public class MasterTest_10_Milstone extends Sprite
{
private var oscs:Vector.<OSC>
public function MasterTest_10_Milstone()
{
init()
}
private function init():void
{
oscs = new Vector.<OSC>()
for (var i:int = 0; i < 20; i++)
{
/*new SineOSC().generateEnvelop(0,1,50,0,100)
return*/
var osc:OSC
switch(i)
{
/**/
case 0:
osc = new SineOSC()
break;
case 1:
osc = new SawOSC()
break;
case 2:
osc = new TriangleOSC()
break;
case 3:
osc = new Bass()
break;
case 4:
osc = new NoiseOSC()
osc.filters.push(new ResonatFilter(ResonatFilter.BPF, 800, .9))
break;
/**/
default:
//osc = new SineOSC()
break;
}
oscs[i] = osc;
osc.frequency = 480
osc.generateEnvelop(0,1,50,0,100)
osc.play()
var btn:Sprite = new Sprite()
var g:Graphics = btn.graphics
g.beginFill(0xFF0000);
g.drawRect(0, 0, 30, 30);
addChild(btn)
btn.x = 100 * i
btn.buttonMode = true;
btn.name = i.toString()
btn.addEventListener(MouseEvent.CLICK,onClickBtn)
}
//Master.getInstance().addEventListener(SampleDataEvent.SAMPLE_DATA, onSampleData)
var count:int = 0
function onSampleData(e:SampleDataEvent):void
{
count++ //trace("ons")
if (count % 20 == 0)
oscs[3].play()
}
}
private function onClickBtn(e:MouseEvent):void
{
trace("onClickBtn")
var index:int = int(Sprite(e.target).name)
trace(oscs[index].filters.length)
oscs[index].play()
}
}
}
import flash.display.Sprite;
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.events.SampleDataEvent;
import flash.media.Sound;
import flash.utils.ByteArray;
class Master extends EventDispatcher
{
static public const PI2:Number = Math.PI * 2;
static public const SAMPLE_RATE:uint = 44100;
static public const TIME_PER_BYTE:Number = 1000/44100;
static public var LATENCY:uint = 2048 //2048~8192
static private var instance:Master
private const _LATENCY:uint = LATENCY
private var oscs:Vector.<OSC>
private var sound:Sound
protected var phase:Number = 0
static public function getInstance():Master
{
if (instance) {
return instance
}else {
instance = new Master()
return instance
}
}
public function Master()
{
oscs = new Vector.<OSC>()
sound = new Sound()
sound.addEventListener(SampleDataEvent.SAMPLE_DATA, update)
sound.play()
}
public function addOSC(osc:OSC):OSC
{
oscs.push(osc)
return osc
}
public function removeOSC(osc:OSC):OSC
{
var index:int = oscs.indexOf(osc)
oscs.splice(index, 1);
return osc;
}
private function update(e:SampleDataEvent):void
{
dispatchEvent(e)
var oscs:Vector.<OSC> = this.oscs
var n:int = _LATENCY
var data:ByteArray = e.data
for each(var osc:OSC in oscs)
osc.update()
for (var i:int = 0; i < n; i++)
{
var s:Number = 0;
for each(var osc1:OSC in oscs)
s += osc1.sample[i];
data.writeFloat(s)
data.writeFloat(s)
}
}
}
class OSC extends EventDispatcher
{
protected const PI:Number = Math.PI
protected const PI2:Number = Math.PI * 2;
protected const LATENCY:int = Master.LATENCY
protected const SAMPLE_RATE:uint = Master.SAMPLE_RATE;
protected const TIME_PER_BYTE:Number = 1000.0 / SAMPLE_RATE;
private var master:Master;
private var _listen:Boolean;
private var _frequency:Number;
protected var _amplifier:Number;
protected var envelopTime:Number;
protected var envelop:Vector.<Number>
protected var _filters:Vector.<SoundFilter>
protected var phase:Number = 0;
protected var deltPhase:Number;
protected var initAmplifier:Number;
protected var lastAmplifier:Number;
protected var envelopValue:Vector.<Number>;
protected var envelopInterval:Vector.<Number>;
protected var envelopLength:int
protected var _random:Function = Math.random
public var volume:Number;
public var sample:Vector.<Number>;
public var isMute:Boolean
public function OSC()
{
init()
}
private function init():void
{
master = Master.getInstance();
_frequency = 440;
_listen = true;
deltPhase = PI2 * _frequency / SAMPLE_RATE;
volume = .2;
generateEnvelop(0,1,50,0,100)
sample = new Vector.<Number>(LATENCY);
_filters = new Vector.<SoundFilter>();
master.addOSC(this)
}
public function generateEnvelop(init:Number, ...arg):void
{
initAmplifier = init;
envelopValue = new Vector.<Number>()
envelopInterval = new Vector.<Number>()
var n:int = arg.length >> 1;//int(arg.length / 2)
var previousValue:Number = initAmplifier
var prevInterval:Number = 0;
for (var i:int = 0; i < n; i++)
{
var ii:int = i << 1 // i*2
envelopInterval[i] = arg[ii + 1]+prevInterval;
envelopValue[i] = (arg[ii] - previousValue) / ((arg[ii + 1]/1000)*SAMPLE_RATE);
previousValue = arg[ii]
prevInterval = envelopInterval[i]
}
lastAmplifier = previousValue;
envelopTime = prevInterval
envelopLength = n
trace("generateEnvelop")
trace(arg)
trace(envelopValue)
trace(envelopInterval)
trace("--------------")
}
public function update():void
{
}
public function play():void
{
//listen = true
envelopTime = 0
_amplifier = initAmplifier
}
public function get listen():Boolean { return _listen; }
public function set listen(value:Boolean):void
{
if (_listen == value) return;
_listen = value;
if (value)
master.addOSC(this);
else
master.removeOSC(this);
}
public function get frequency():Number { return _frequency; }
public function set frequency(value:Number):void
{
_frequency = value;
deltPhase = PI2 * _frequency / SAMPLE_RATE;
}
public function get amplifier():Number { return _amplifier; }
public function get filters():Vector.<SoundFilter> { return _filters; }
public function set filters(value:Vector.<SoundFilter>):void
{
_filters = value;
}
}
class SineOSC extends OSC
{
override public function update():void
{
var n:int = LATENCY
var m:int = envelopLength-1;
for (var i:int = 0; i < n; i++)
{
phase = (phase + deltPhase) % PI2;
envelopTime += TIME_PER_BYTE;
for (var j:int = 0; j <= m; j++) {
if (envelopTime <= envelopInterval[j])
{
_amplifier += envelopValue[j];
break;
}
else if (envelopTime > envelopInterval[m])
{
_amplifier=lastAmplifier
break;
}
};
sample[i] = Math.sin(phase) * _amplifier * volume;
}
var nn:uint = _filters.length
for (var ii:int = 0; ii < nn; ii++) _filters[0].process(sample);
}
}
class SawOSC extends OSC
{
override public function update():void
{
var envelopInterval:Vector.<Number> = this.envelopInterval
var envelopValue:Vector.<Number> = this.envelopValue
var n:int = LATENCY
var m:int = envelopLength-1;
for (var i:int = 0; i < n; i++)
{
phase = (phase + deltPhase) % PI2;
envelopTime += TIME_PER_BYTE;
for (var j:int = 0; j <= m; j++) {
if (envelopTime <= envelopInterval[j])
{
_amplifier += envelopValue[j];
break;
}
else if (envelopTime > envelopInterval[m])
{
_amplifier = lastAmplifier;
break;
}
};
sample[i] = (-phase / PI + 1) * _amplifier * volume;
}
var nn:uint = _filters.length
for (var ii:int = 0; ii < nn; ii++) _filters[0].process(sample);
}
}
class SquareOSC extends OSC
{
override public function update():void
{
var envelopInterval:Vector.<Number> = this.envelopInterval
var envelopValue:Vector.<Number> = this.envelopValue
var n:int = LATENCY
var m:int = envelopLength-1;
for (var i:int = 0; i < n; i++)
{
phase = (phase + deltPhase) % PI2;
envelopTime += TIME_PER_BYTE;
for (var j:int = 0; j <= m; j++) {
if (envelopTime <= envelopInterval[j])
{
_amplifier += envelopValue[j];
break;
}
else if (envelopTime > envelopInterval[m])
{
_amplifier = lastAmplifier;
break;
}
};
sample[i] = ((phase > PI)?1: -1) * _amplifier * volume;
}
var nn:uint = _filters.length
for (var ii:int = 0; ii < nn; ii++) _filters[0].process(sample);
}
}
class TriangleOSC extends OSC
{
override public function update():void
{
var envelopInterval:Vector.<Number> = this.envelopInterval
var envelopValue:Vector.<Number> = this.envelopValue
var n:int = LATENCY
var m:int = envelopLength-1;
for (var i:int = 0; i < n; i++)
{
phase = (phase + deltPhase) % PI2;
envelopTime += TIME_PER_BYTE;
for (var j:int = 0; j <= m; j++) {
if (envelopTime <= envelopInterval[j])
{
_amplifier += envelopValue[j];
break;
}
else if (envelopTime > envelopInterval[m])
{
_amplifier = lastAmplifier;
break;
}
};
var s:Number = (phase / PI - 1)
if (s > 0) sample[i] = (s * 2 -1) * _amplifier * volume;
else sample[i] = (s * -2 -1) * _amplifier * volume;
}
var nn:uint = _filters.length
for (var ii:int = 0; ii < nn; ii++) _filters[0].process(sample);
}
}
class NoiseOSC extends OSC
{
override public function update():void
{
var envelopInterval:Vector.<Number> = this.envelopInterval
var envelopValue:Vector.<Number> = this.envelopValue
var n:int = LATENCY
var m:int = envelopLength-1;
for (var i:int = 0; i < n; i++)
{
phase = (phase + deltPhase) % PI2;
envelopTime += TIME_PER_BYTE;
for (var j:int = 0; j <= m; j++) {
if (envelopTime <= envelopInterval[j])
{
_amplifier += envelopValue[j];
break;
}
else if (envelopTime > envelopInterval[m])
{
_amplifier = lastAmplifier;
break;
}
};
sample[i] = (Math.random() * 2 - 1) * _amplifier * volume;
}
var nn:uint = _filters.length
for (var ii:int = 0; ii < nn; ii++) _filters[0].process(sample);
}
}
class Bass extends OSC
{
public var initFrequency:uint = 300
public var endFrequency:uint = 10
public var length:uint = 2000
override public function play():void
{
super.play()
frequency = initFrequency
}
override public function update():void
{
var m:int = envelopLength-1
var n:int = LATENCY
for (var i:int = 0; i < n; i++)
{
this.frequency += (endFrequency - frequency) / length
phase = (phase + deltPhase) % PI2;
envelopTime += TIME_PER_BYTE;
for (var j:int = 0; j <= m; j++) {
if (envelopTime <= envelopInterval[j])
{
_amplifier += envelopValue[j];
break;
}
else if (envelopTime > envelopInterval[m])
{
_amplifier = lastAmplifier;
break;
}
};
sample[i] = Math.sin(phase) * amplifier * volume;
}
var nn:uint = _filters.length
for (var ii:int = 0; ii < nn; ii++) _filters[0].process(sample);
}
}
class SoundFilter {
protected var osc:OSC
public function addOSC(osc:OSC):void
{
this.osc = osc
}
public function process(sample:Vector.<Number>):void
{
}
}
class ResonatFilter extends SoundFilter
{
private var buf0:Number = 0 ;
private var buf1:Number = 0 ;
private var cutoff:Number;
private var q:Number;
private var type:int;
static public const LPF:uint = 0;
static public const BPF:uint = 1;
static public const HPF:uint = 2;
public function ResonatFilter(type:int,cutoff:Number=440,q:Number=0.5)
{
this.type = type;
this.cutoff = cutoff
this.q = q
}
override public function process(sample:Vector.<Number>):void
{
// f and fb calculation
var f:Number = 2.0 * Math.sin(Math.PI * cutoff / Master.SAMPLE_RATE);
var fb:Number = q + q/(1.0 - f);
var n:int = Master.LATENCY;
var hp:Number;
var bp:Number;
for (var i:int = 0; i < n; i++)
{
hp = sample[i] - buf0;
bp = buf0 - buf1;
buf0 = buf0 + f * (hp + fb * bp);
buf1 = buf1 + f * (buf0 - buf1);
sample[i] = (type == 0)?buf1:(type == 1)?bp:hp;
}
}
}