In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

光テルミン

光センサ(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;
            }
        }
    }
}