dynamic sound generate. ランダムな音。
ランダムに音をならします。
ずっと聞いてたら気持ち悪くなった。
/**
* Copyright sakef ( http://wonderfl.net/user/sakef )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/7op2
*/
package
{
import flash.display.Graphics;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.SampleDataEvent;
import flash.events.TimerEvent;
import flash.media.Sound;
import flash.media.SoundMixer;
import flash.utils.ByteArray;
import flash.utils.Timer;
[SWF(width="465", height="465", backgroundColor="0xFFFFFF", frameRate="40")]
public class Main extends Sprite
{
private static const SAMPLING:int = 2048; // バッファ
private static const SAMPLING_RATE:int = 44100; // サンプリングレート
private static const PI:Number = Math.PI * 2; // 1周期
private static const VOLUME:Number = 0.1; // ボリューム
private static const MAX:Number = 0.5; // 音の最大値
private var container:Array;
public function Main()
{
// コンテナ
container = [];
// タイマーの初期化
var t:Timer = new Timer(1000);
t.addEventListener(TimerEvent.TIMER, addSound);
t.start();
// サウンドの再生
var sound:Sound = new Sound;
sound.addEventListener(SampleDataEvent.SAMPLE_DATA, onSampleData);
sound.play();
addEventListener(Event.ENTER_FRAME, onFrame);
}
private function addSound(e:TimerEvent=null):void
{
// 周波数の計算
// 2 の (1 / 12) 乗を乗算すると音程を1段階上げる。
var freq:Number = 220 * Math.pow(2, (int(30*Math.random()))/12);
var s:SoundData = new SoundData(freq, 0.05, 0.05, 40, 1);
container.push(s);
}
// 波形を書き込む
private function onSampleData(e:SampleDataEvent):void
{
var data:ByteArray = e.data;
var pos:Number = e.position;
var len:int = container.length;
var s:SoundData;
var i:int, n:int;
for(i=0 ; i<SAMPLING ; i++)
{
var d:Number = 0;
n = len;
// データを足し合わせていく。
while(n--)
{
s = container[n] as SoundData;
var w:Number = (PI * s.frequency / SAMPLING_RATE);
d += VOLUME * s.volume * Math.sin(((pos + i) * w) % PI) * 0.4;
}
// データを範囲内に丸める
d = (d > -MAX)?(d):(MAX);
d = (d < MAX)?(d):(MAX);
// 書き込み
data.writeFloat(d);
data.writeFloat(d);
}
n = container.length;
while(n--)
{
s = (container[n] as SoundData);
s.renderSound();
if(s.state == 3) container.splice(n,1);
}
}
// スペクトラムを描写
private function onFrame(e:Event):void
{
var g:Graphics = graphics;
g.clear();
g.lineStyle(0.5, 0x555555);
g.drawRect(50, 50, 350, 280);
var bytes:ByteArray = new ByteArray();
SoundMixer.computeSpectrum(bytes, true, 0);
for (var i:int = 0; i < 50; i++)
{
var spec:Number = bytes.readFloat();
var h:int = 250 * spec;
g.moveTo(50 + 7*i, 330);
g.lineTo(50 + 7*i, 330-h);
}
}
}
}
// 音データを保持するクラス
class SoundData
{
public var frequency:Number;
public var volume:Number;
public var state:int;
private var fadeIn:Number;
private var fadeOut:Number;
private var show:Number;
private var volMax:Number;
private var count:int;
public function SoundData(frequency:Number, fadeIn:Number, fadeOut:Number, show:int, volMax:Number)
{
this.frequency = frequency;
this.fadeIn = fadeIn;
this.fadeOut = fadeOut;
this.show = show;
this.volMax = volMax;
this.volume = this.state = this.count = 0
}
public function renderSound():void
{
switch(state)
{
// 音をフェードインさせる
case 0:
volume += fadeIn;
if(volume>=volMax)
{
volume = volMax;
state = 1;
}
break;
// 音を流す
case 1:
count ++;
if(count == show) state = 2;
break;
// 音をフェードアウトさせる
case 2:
volume -= fadeOut;
if(volume <= 0)
{
state = 3;
volume = 0;
}
break;
}
}
}