光テルミン
光センサ(CdS)を使ったテルミン。暗くするほど、音が高くなります。
// forked from kinkuma_design's 位相で変わるのこぎり波とか
// 光センサ(CdS)を使ったテルミン。暗くするほど、音が高くなります。
package
{
import flash.display.Sprite;
import flash.events.Event;
import flash.events.SampleDataEvent;
import flash.media.Sound;
import funnel.*;
[SWF(width = "465", height = "465", backgroundColor = "0x000000")]
public class cdsTheremin extends Sprite
{
public static const SINE:String = "sine";
public static const SAW:String = "saw";
public static const TRIANGLE:String = "triangle";
public static const SQUARE:String = "square";
public static const NOISE:String = "noise";
public static const PI2:Number = Math.PI * 2;
public static const SAMPLE_RATE:uint = 44100;
private var sound:Sound;
private var bufferSize:uint; //2048~8192
private var amp:Number; //音量
public var phase:Number; //位相
public var frequency:Number; //周波数 Hz
public var waveShape:String; //波形
private var gio:Gainer;
private var g:int = 0;
public function cdsTheremin()
{
init();
}
private function init():void
{
gio = new Gainer();
gio.addEventListener(FunnelEvent.READY, trace);
gio.addEventListener(FunnelErrorEvent.REBOOT_ERROR, trace);
gio.addEventListener(FunnelErrorEvent.CONFIGURATION_ERROR, trace);
gio.addEventListener(FunnelErrorEvent.ERROR, trace);
bufferSize = 2048;
phase = 0;
//この辺変えてみてください
amp = 0.1;
waveShape = SINE;
frequency = 440;
//--------------------
sound = new Sound();
sound.addEventListener(SampleDataEvent.SAMPLE_DATA, sampleDataEventHd);
sound.play();
gio.analogInput(0).filters = [new Scaler(0.2, 0.8, 3000, 100, Scaler.LINEAR, true)];
}
private function sampleDataEventHd(e:SampleDataEvent):void
{
frequency = gio.analogInput(0).value;
trace(gio.analogInput(0).value);
var i:uint;
var sample:Number;
for(i = 0; i < bufferSize; i++)
{
sample = getSample() * amp;
if(sample > 1)
{
sample = 1;
}
else if(sample < -1)
{
sample = -1;
}
e.data.writeFloat(sample);
e.data.writeFloat(sample);
addPhase();
}
}
private function getSample():Number
{
var sample:Number;
switch(waveShape)
{
//サイン波
case SINE:
sample = Math.sin(phase);
break;
//のこぎり波
case SAW:
sample = - phase / Math.PI + 1;
break;
//三角波
case TRIANGLE:
sample = (phase < Math.PI) ? -2 / Math.PI * phase + 1 : 2 / Math.PI * phase - 3;
break;
//矩形波
case SQUARE:
sample = (phase < Math.PI) ? -1 : 1;
break;
//ノイズ
case NOISE:
sample = Math.random() * 2 - 1;
break;
default:
sample = 0;
break;
}
return sample;
}
private function addPhase():void
{
var dPhase:Number = PI2 * frequency / SAMPLE_RATE;
phase += dPhase;
if(phase > PI2)
{
phase = phase % PI2;
}
}
}
}