Noise Instrument
/**
* Copyright linktale ( http://wonderfl.net/user/linktale )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/x9a3
*/
/**
真ん中の円に触れるとドラムパターンと、トーンパターンが変わります。
http://linktale.net/
*/
package {
import com.flashdynamix.utils.SWFProfiler;
import flash.display.Sprite;
[SWF(backgroundColor="0xffffff", frameRate="40")]
public class Trick extends Sprite {
public function Trick() {
//SWFProfiler.init(stage, this);
Wonderfl.disable_capture();
//ここのパラメータを変えると見た目が変わります。
var trick:Sprite = new Kyu( this, stage.stageWidth / 2, stage.stageHeight / 2, 15, 2.5, 0x333333, 1, 2.0);
addChild( trick );
}
}
}
import flash.display.DisplayObjectContainer;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import org.si.sion.effector.SiEffectSpeakerSimulator;
import org.si.sion.effector.SiEffectStereoChorus;
import org.si.sion.effector.SiEffectStereoDelay;
import org.si.sion.events.SiONTrackEvent;
import org.si.sion.sequencer.SiMMLTrack;
import org.si.sion.SiONDriver;
import org.si.sion.SiONVoice;
import org.si.sion.utils.SiONPresetVoice;
import org.si.sound.DrumMachine;
class Kyu extends Sprite {
//const
private const DEBUG:Boolean = true; //デバッグモード
private const AROUND_NAMI_A:Number = 0.2;
private const AROUND_NAMI_POS:Number = 0.3;
//parent stage
private var _w:Number;
private var _h:Number;
private var _centerX:Number;
private var _centerY:Number;
//main
private var _namiColor:uint //波の色
private var _cellW:int = 1; //セルの横幅
private var _cellH:int = 1; //セルの縦幅
private var _cellAmount:int; //セルの横位置
private var _cellCnt:int; //セルの数
private var _cellList:Array = new Array(); //セルリスト
private var _mouseArea:Number = 20.0;
//nami
private var _period:Number = 2.0; //周期T
private var _aMin:Number = 0.0; //振幅の最小値(まるめ)
private var _f:Number = 3.0; //振幅数
private var _t:int = 1; //波時間
private var _namiSpring:Number = 0.01; //ばね
private var _namiFriction:Number = 0.8; //跳ね
private var _upRate:Number;
//kyu
private var _kyuRadius:int = 150; //球の半径
private var _kyuDefPos:Array = new Array(); //球のデフォルトポジション
//count
private var _loopCnt:int = 0; //loop回数
//mouse
private var _mousexNow:Number;
private var _mouseyNow:Number;
private var _mousexPre:Number;
private var _mouseyPre:Number;
//sion
private var sionDriver:SiONDriver;
private var drumMachine:DrumMachine;
private var epianoVoice:SiONVoice;
private var presetVoice:SiONPresetVoice;
private var notes:Array;
private var toneList:Array;
private var toneNoList:Array;
//button
private var changeDrumMachineBtn:Sprite;
public function Kyu( pStage:DisplayObjectContainer, pX:int, pY:int, pW:int, pH:int, pColor:uint, pAmount:int, pUpRate:Number ) {
//stage
_w = pStage.stage.stageWidth;
_h = pStage.stage.stageHeight;
_centerX = pX;
_centerY = pY;
//nami
_namiColor = pColor;
_cellW = pW;
_cellH = pH;
_cellAmount = pAmount;
_upRate = pUpRate;
//kyu
var kyuLength:int = 2 * Math.PI * _kyuRadius;
//cell
_cellCnt = kyuLength / _cellAmount;
//mouse
_mousexNow = _mousexPre = _centerX;
_mouseyNow = _mouseyPre = _centerY;
initKyu();
initSion();
initButton();
}
private function initKyu():void {
setCell();
addEventListener( Event.ENTER_FRAME, loop );
}
private function initSion():void {
// マトリックス各行に割り当てるノートを設定
notes = [70, 67, 65, 60, 58, 55, 53, 48];
// ドライバの生成
sionDriver = new SiONDriver(2048);
// ドラムマシンの生成
drumMachine = new DrumMachine(
Math.floor(Math.random() * 32),
Math.floor(Math.random() * 18),
Math.floor(Math.random() * 17),
Math.floor(Math.random() * 5),
Math.floor(Math.random() * 5),
Math.floor(Math.random() * 3)
);
// エレクトリックピアノ音をプリセット音声リストから取得
toneList = new Array("bass","bell","brass","guitar","lead","percus","piano","se","special","strpad","wind","world");
toneNoList = new Array(54,18,20,18,42,38,20,1,5,25,8,7);
presetVoice = new SiONPresetVoice();
var no:uint = Math.floor(Math.random() * toneList.length);
var tone:String = toneList[no];
var tone_num:String = toneNoList[no];
epianoVoice = presetVoice["valsound."+tone+tone_num];
//trace("valsound." + tone + tone_num);
// ビートイベントハンドラの設定
sionDriver.setBeatCallbackInterval(1);
sionDriver.addEventListener(SiONTrackEvent.BEAT, onBeat);
// タイマ割り込みの設定
//sionDriver.setTimerInterruption(1, _onTimerInterruption);
// BPM の設定
sionDriver.bpm = 70;
// slot1 にエフェクタを設定する
sionDriver.effector.initialize();
sionDriver.effector.slot1 = [new SiEffectStereoChorus(), new SiEffectStereoDelay(500)];
// ドライバの再生開始(エフェクトリセット無し)とリズム再生開始
sionDriver.play(null, false);
drumMachine.play();
}
private function initButton():void {
var radius:Number = 50;
changeDrumMachineBtn = new Sprite();
changeDrumMachineBtn.graphics.beginFill(_namiColor);
changeDrumMachineBtn.graphics.drawCircle(0, 0, radius);
//changeDrumMachineBtn.graphics.drawEllipse(-_kyuRadius / rate / 2, -_kyuRadius / rate / 2 / 20, _kyuRadius / rate, _kyuRadius / rate / 20);
changeDrumMachineBtn.graphics.drawRect(0, 0, 3, radius * 2);
changeDrumMachineBtn.graphics.endFill();
changeDrumMachineBtn.x = _centerX;
changeDrumMachineBtn.y = _centerY;
changeDrumMachineBtn.addEventListener(MouseEvent.ROLL_OVER, changeDrumMachineOver);
changeDrumMachineBtn.addEventListener(MouseEvent.ROLL_OUT, changeDrumMachineOut);
addChild(changeDrumMachineBtn);
}
private function changeDrumMachineOver(e:MouseEvent):void {
var btn:Sprite = e.currentTarget as Sprite;
btn.alpha = 0.85;
sionDriver.stop();
presetVoice = new SiONPresetVoice();
var no:uint = Math.floor(Math.random() * toneList.length);
var tone:String = toneList[no];
var tone_num:String = toneNoList[no];
epianoVoice = presetVoice["valsound."+tone+tone_num];
//trace("valsound." + tone + tone_num);
sionDriver.play(null, false);
drumMachine.stop();
drumMachine = new DrumMachine(
Math.floor(Math.random() * 32),
Math.floor(Math.random() * 18),
Math.floor(Math.random() * 17),
Math.floor(Math.random() * 5),
Math.floor(Math.random() * 5),
Math.floor(Math.random() * 3)
);
drumMachine.play();
}
private function changeDrumMachineOut(e:MouseEvent):void {
var btn:Sprite = e.currentTarget as Sprite;
btn.alpha = 1.0;
}
//セルをセット
private function setCell():void {
var cell:Cell;
var x:Number, y:Number, dx:Number, dy:Number, angle:Number, rotation:Number;
//セルの配置
for (var i:uint = 0; i < _cellCnt; i++ ) {
//セルのデフォルト位置を定義
cell = new Cell( _cellW, _cellH, _namiColor );
//セルのバーチャル位置セット
cell._x = i * _cellAmount;
cell._y = _centerY;
//球のデフォルト位状態をセット
angle = Math.PI * 2 / _cellCnt * i - Math.PI / 2;
x = _kyuRadius * Math.cos(angle) + _centerX;
y = _kyuRadius * Math.sin(angle) + _centerY;
dx = x - _centerX;
dy = y - _centerY;
angle = Math.atan2(dy, dx);
rotation = ( angle - Math.PI / 2 ) * 180 / Math.PI;
_kyuDefPos.push(new Array(x-cell._x, y-cell._y, x, y, rotation));
//セル配置
addChild(cell);
_cellList.push(cell);
}
}
private function onBeat(e:SiONTrackEvent):void {
changeDrumMachineBtn.rotation += 4.5;
}
private function loop(e:Event):void {
mouseSet();
namiMove(); //描画
_loopCnt++;
}
private function mouseSet():void {
_mousexPre = _mousexNow;
_mouseyPre = _mouseyNow;
_mousexNow = mouseX;
_mouseyNow = mouseY;
}
//波を動かす処理
private function namiMove():void {
var x:Number, y:Number, dx:Number, dy:Number, dist:Number ,angle:Number;
for (var i:uint = 0; i < _cellCnt; i++ ) {
dx = _cellList[i].x - _kyuDefPos[i][2];
dy = _cellList[i].y - _kyuDefPos[i][3];
dist = Math.sqrt( dx * dx + dy * dy );
if ( Math.abs(_cellList[i]._a) <= AROUND_NAMI_A && dist <= AROUND_NAMI_POS) {
//丸め処理
_cellList[i].x = _kyuDefPos[i][2];
_cellList[i].y = _kyuDefPos[i][3];
_cellList[i]._a = 0;
}else {
//定常波の方程式
y = _cellList[i]._a * Math.sin( _t / _period - i * _cellAmount / _f );
angle = _kyuDefPos[i][4] * Math.PI / 180 - Math.PI / 2;
x = Math.cos(angle) * y;
y = Math.sin(angle) * y;
y += _centerY;
_cellList[i]._vx = _cellList[i]._x + x;
_cellList[i]._vy = y; //描画
//加速度をばねる
springA(_cellList[i]); //振幅を変化
//一時変換
_cellList[i].x = _cellList[i]._vx + _kyuDefPos[i][0];
_cellList[i].y = _cellList[i]._vy + _kyuDefPos[i][1];
_cellList[i].rotation = _kyuDefPos[i][4];
}
//マウスチェック
//addMouseValue(_cellList[i]);
checkWave( i, mouseX, mouseY, _upRate );
}
_t++; //波時間を進める
}
//波の振幅をばねで計算
private function springA( pCell:Cell ):void {
var dx:Number, ax:Number;
dx = _aMin - pCell._a;
ax = dx * _namiSpring;
pCell._avx += ax;
pCell._avx *= _namiFriction;
pCell._a += pCell._avx;
}
private function addMouseValue( pCell:Cell ):void{
var dx:Number, dy:Number, dist:Number, per:Number;
dx = pCell.x - _mousexNow;
dy = pCell.y - _mouseyNow;
dist = Math.sqrt( dx * dx + dy * dy );
per = ( _w - dist ) / _w;
pCell._a += (_mousexNow - _mousexPre) * per * 0.1;
}
//マウスチェック
private function checkWave(pI:int, pTargetX:Number, pTargetY:Number, namiRate:Number ):void {
var dx:Number = _cellList[pI].x - pTargetX;
var dy:Number = _cellList[pI].y - pTargetY;
var dist:Number = Math.sqrt( dx * dx + dy * dy );
if (dist < _mouseArea) {
wavePattern(pI, namiRate);
}
}
//波パターン
private function wavePattern(pI:int, upRate:Number):void {
var i:uint, y:Number;
var startI:int = pI - 100; if (startI < 0) { startI = 0; }
var endI:int = pI + 100; if (endI > _cellCnt) { endI = _cellCnt; }
var dist:Number;
for (i = startI; i < endI; i++) {
dist = Math.abs((pI - i)); if (dist == 0) { dist = 1.0; }
y = 1 / dist * upRate;
_cellList[i]._a += y;
}
if (_loopCnt % 6 == 0) {
//0~127
var note:int = 127 - Math.floor((pI / _cellList.length) * 127);
var track:SiMMLTrack;
track = sionDriver.noteOn(note, epianoVoice, 1);
track.velocity = 5;
track.effectSend1 = 48;
}
}
}
import flash.display.Sprite;
class Cell extends Sprite {
public var _x:Number = 0;
public var _y:Number = 0;
public var _vx:Number = 0;
public var _vy:Number = 0;
public var _w:int = 0;
public var _h:int = 0;
public var _rotaion:Number = 0;
public var _color:int = 0;
public var _a:Number = 0.0; //振幅
public var _avx:Number = 0.0; //振幅の速度
public function Cell( pW:Number = 1, pH:Number = 1, pColor:uint = 0x000000 ) {
_w = pW;
_h = pH;
_color = pColor;
graphics.beginFill(_color);
graphics.drawRect( -_w / 2, 0, _w, _h);
graphics.endFill();
}
}