OscBox
周波数を指定して音を鳴らせます。
右クリックメニューでオブジェクトの追加や削除、波形の変更などができます。
/**
* Copyright lla ( http://wonderfl.net/user/lla )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/rT4a
*/
package{
import flash.display.Sprite;
import flash.ui.ContextMenu;
import flash.ui.ContextMenuItem;
import flash.events.ContextMenuEvent;
[SWF(width="300", height="300")]
public class OscBoxTest extends Sprite{
public function OscBoxTest(){
//stage.quality = flash.display.StageQuality.LOW;
//stage.frameRate = 5;
var menu: ContextMenu = new ContextMenu();
var item: ContextMenuItem = new ContextMenuItem("addChild");
item.addEventListener(
ContextMenuEvent.MENU_ITEM_SELECT,
function(e: ContextMenuEvent): void{
var obj:OscBox = new OscBox(440, 0);
obj.x = stage.mouseX;
obj.y = stage.mouseY;
stage.addChild(obj);
}
);
menu.customItems.push(item);
contextMenu = menu;
var box:OscBox = new OscBox(261,0);
box.x = box.y = 50;
stage.addChild(box);
var box2:OscBox = new OscBox(330,0);
box2.x = box2.y = 75;
stage.addChild(box2);
var box3:OscBox = new OscBox(392,4);
box3.x = box3.y = 100;
stage.addChild(box3);
var box4: NumberBox2 = new NumberBox2(Oscil.volume*100);
box4.x = box4.y = 125;
box4.setCaption("Volume", "%");
box4.border = true;
box4.align();
box4.callBack = function(v: Number): void{
v = Math.max(0, Math.min(200, v));
box4.number = v;
Oscil.volume = v/100.0;
};
stage.addChild(box4);
//trace("ok");
}
}
}
import flash.ui.ContextMenu;
import flash.ui.ContextMenuItem;
import flash.events.ContextMenuEvent;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.text.TextField;
import flash.display.Sprite;
class OscBox extends flash.display.Sprite{
public var oscil: Oscil;
public var toggle: Toggle;
public var numberBox: NumberBox2;
public function OscBox(hz: Number , oscType: int){
super();
oscil = new Oscil(oscType);
oscil.hz = hz;
toggle = new Toggle();
numberBox = new NumberBox2(hz);
numberBox.x = toggle.width + 0.5;
addChild(toggle);
addChild(numberBox);
//Object 削除用
var menu: ContextMenu = new ContextMenu();
var item: ContextMenuItem = new ContextMenuItem("removeChild");
item.addEventListener(
ContextMenuEvent.MENU_ITEM_SELECT,
function(e: ContextMenuEvent): void{
parent.removeChild(e.contextMenuOwner);
}
);
menu.customItems.push(item);
numberBox.setCaption(Oscil.names[oscType], "Hz");
//波形変更menu
var f: Function = function(i: uint): Function {
return function(e: ContextMenuEvent): void{
numberBox.prefix.text = Oscil.names[i];
numberBox.align();
oscil.changeWaveType(i);
};
};
for(var i:int = 0; i < Oscil.names.length; i++){
var item2: ContextMenuItem = new ContextMenuItem(Oscil.names[i]);
item2.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, f(i));
menu.customItems.push(item2);
}
contextMenu = menu;
numberBox.callBack = function(num: Number): void{ oscil.hz = num; };
toGreen();
toggle.callBack = function(bool: Boolean): void{
oscil.togglePlay();
if(bool){
toRed();
} else {
toGreen();
}
};
this.addEventListener(MouseEvent.MOUSE_DOWN, startDragging);
this.addEventListener(MouseEvent.MOUSE_UP, stopDragging);
}
public function toRed(): void{
numberBox.changeColor(0xFF9999);
toggle.backgroundColor = 0xFF9999;
}
public function toGreen(): void{
numberBox.changeColor(0xCCFF99);
toggle.backgroundColor = 0xCCFF99;
}
public function startDragging(e: MouseEvent): void{
if(numberBox.infix.hitTestPoint(e.stageX, e.stageY)){ return;}
parent.addChild(this);
startDrag();
}
public function stopDragging(e: MouseEvent): void{
stopDrag();
}
}
import flash.events.MouseEvent;
import flash.text.TextField;
class Toggle extends flash.text.TextField{
public var bool: Boolean;
public var callBack: Function;
public function Toggle(){
super();
callBack = dummy;
text = " ";
border = true;
background = true;
//autoSize = flash.text.TextFieldAutoSize.LEFT;
selectable = false;
width = 13;
height = 19;
addEventListener(MouseEvent.MOUSE_DOWN, turn);
}
public function turn(e: MouseEvent): void{
bool = !bool;
text = bool ? "X" : " ";
callBack(bool);
//trace([width, height]);
}
public static function dummy(b: Boolean): void{
}
}
import flash.events.Event;
import flash.events.MouseEvent;
import flash.text.TextField;
import flash.display.Sprite;
class NumberBox2 extends flash.display.Sprite{
public var infix: TextField;
public var number: Number;
public var callBack: Function; //Number->Void;
public var prefix: TextField;
public var suffix: TextField;
public var border: Boolean;
public function NumberBox2(n: Number){
super();
number = n;
callBack = function(_: Number): void{};
prefix = new TextField();
infix = new TextField();
suffix = new TextField();
infix.text = String(number);
prefix.text = suffix.text = "";
prefix.autoSize = flash.text.TextFieldAutoSize.LEFT;
infix.autoSize = flash.text.TextFieldAutoSize.LEFT;
suffix.autoSize = flash.text.TextFieldAutoSize.LEFT;
//prefix.border = infix.border = suffix.border = true;
prefix.background = infix.background = suffix.background = true;
addChild(infix);
addChild(prefix);
addChild(suffix);
align();
infix.restrict = "-.0-9";
infix.type = flash.text.TextFieldType.INPUT;
addEventListener(Event.ADDED_TO_STAGE, addEvents);
}
public function addEvents(e: Event): void{
infix.addEventListener(MouseEvent.MOUSE_DOWN, startSlideNumber);
stage.addEventListener(MouseEvent.MOUSE_UP, stopSlideNumber);
//infix.addEventListener(flash.events.TextEvent.TEXT_INPUT, editNumber);
infix.addEventListener(flash.events.Event.CHANGE, changeNumber);
addEventListener(MouseEvent.MOUSE_DOWN, startDragging);
addEventListener(MouseEvent.MOUSE_UP, stopDragging);
}
public function setCaption(prefixText: String, suffixText: String): void{
prefix.text = prefixText;
suffix.text = suffixText;
align();
}
public function changeColor(color: uint): void{
prefix.backgroundColor = infix.backgroundColor = suffix.backgroundColor = color;
}
public function drawBorder(): void{
graphics.lineStyle(1);
graphics.drawRect(0, 0, width, height);
}
public function align(): void{
infix.x = prefix.width ;
suffix.x = prefix.width + infix.width ;
graphics.clear();
if(border){
drawBorder();
}
}
public function startDragging(e: MouseEvent): void{
if(infix.hitTestPoint(e.stageX, e.stageY)){ return;}
parent.addChild(this);
startDrag();
}
public function stopDragging(e: MouseEvent): void{
stopDrag();
}
public function changeNumber(e: flash.events.Event): void {
number = parseFloat(infix.text);
if(isNaN(number) || isFinite(number)){
number = 0;
}
align();
callBack(number);
}
public function startSlideNumber(e: MouseEvent): void{
offsetY = e.stageY;
stage.addEventListener(MouseEvent.MOUSE_MOVE, slideNumber);
}
public function stopSlideNumber(e: MouseEvent): void{
stage.removeEventListener(MouseEvent.MOUSE_MOVE, slideNumber);
}
public var offsetY : Number;
public function slideNumber(e: MouseEvent): void{
number += -(e.stageY - offsetY);
offsetY = e.stageY;
callBack(number);
infix.text = String(int(number)) ;
align();
e.updateAfterEvent();
}
}
import flash.events.Event;
import flash.text.TextField;
import flash.display.Sprite;
import flash.media.Sound;
import flash.media.SoundChannel;
import flash.events.SampleDataEvent;
class Oscil {
public var soundChannel: SoundChannel;
public var sound: Sound;
public var hz: Number;
public var latency: Number;
public var offsetY : Number;
public var playing: Boolean;
public var osc: Function; //SampleDataEvent->Void;
public var bufSize: int; //8192 4096 2048
public static var volume: Number = 0.4;
//private var stage(default, null): flash.display.Stage;
public function Oscil(n: int){
playing = false;
//stage = flash.Lib.current.stage;
offsetY = 0;
hz = 0;
soundChannel = new SoundChannel();
sound = new Sound();
bufSize = 8192;
//osc = genWave(selectWaveType(n));
osc = function(_:SampleDataEvent): void{};
changeWaveType(n);
}
public static var names: Array = [
"tri ", "sine ", "saw ", "sq ", "tableCos128 ", "tableCos4 "];
public function selectWaveType(n: int): Function{
switch(n) {
case 1: return sine;
case 2: return saw;
case 3: return sq;
case 4: makeCosTable(128); return tableCos;
case 5: makeCosTable(4); return tableCos;
default: return tri;
};
}
public function changeWaveType(n: int): void{
sound.removeEventListener(SampleDataEvent.SAMPLE_DATA, osc);
osc = genWave(selectWaveType(n));
sound.addEventListener(SampleDataEvent.SAMPLE_DATA, osc);
}
public var table: Array;
public var table_length: int;
public function makeCosTable(len: int): void{
table_length = len;
table = new Array();
for(var i:int = 0; i<len; i++){
table[i] = Math.cos(Math.PI*2 * i / (len+0.0));
}
}
public function tableCos(wt: Number): Number{
return table[int((table_length * wt) % table_length)];
}
//f((i + e.position) / 44100.0 * hz)
//->f(x += 1/44100.0*hz)
public function genWave(f: Function): Function{
return function(e: SampleDataEvent): void{
latency = (e.position / 44.1 - soundChannel.position);
var wt: Number = e.position / 44100.0 * hz;
var diff: Number = 1 / 44100.0 * hz;
var n: Number;
for(var i:int = 0; i<bufSize; i++){
n = f(wt) * volume;
//n = f(i + e.position);
e.data.writeFloat(n);
e.data.writeFloat(n);
wt += diff;
}
}
}
public static function sq(t: Number): Number {
var x: Number = saw(t);
return (0 < x ? 1 : (0 == x ? 0 : -1));
}
public static function tri(w: Number): Number{
var n: Number = Math.abs(4*(w - Math.floor(w + 0.5)))-1;
return n;
}
public static function saw(w: Number): Number{
var n: Number = 2*(w - Math.floor(w + 0.5));
return n;
}
//f(Math.PI*2 * t/44100.0*hz)
public static function sine(w: Number): Number{
var n: Number = Math.sin(Math.PI * 2 * w);
//var w: Number = Math.PI * 2 / 44100.0;
//var n: Number = Math.sin(t * w * hz);
return n;
}
public function callPlay(_: Event): void{
if(playing){ return; }
soundChannel = sound.play();
playing = true;
}
public function callStop(_: Event): void{
soundChannel.stop();
playing = false;
}
public function togglePlay(): void{
if(!playing) {
soundChannel = sound.play();
playing = true;
} else {
soundChannel.stop();
playing = false;
}
}
}