Player10でのこぎり波とか(位相をパラメータにした版)

2008/12/20

おはようございます。きんくまです。

kappa-labさんがブログで、以前に書いた波形のソースを使ってくれました。ありがとうございます。それで、あの時はよくわかんないまま適当にやってたんで、もう少し改良したバージョンを書いておきます。

sazamekiライブラリzkさんに以前お会いしたときに、位相に合わせて書いてみるといいよ。みたいな感じのことを教えていただいたので、書き直したのが以下のソースです。

なんで位相を意識するとよかったのかは、忘れてしまったw。うーん、今度思い出します。

あと、最近話題のwonderflにも投稿しました。
→位相で変わるのこぎり波とか
今回のと同じソースです。

package
{
  import flash.display.Sprite;
  import flash.events.Event;
  import flash.events.SampleDataEvent;
  import flash.media.Sound;

  public class Main 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; //波形

    public function Main()
    {
      init();
    }

    private function init():void
    {
      bufferSize = 2048;
      amp = 0.2;
      phase = 0;
      waveShape = SINE;
      frequency = 440;

      sound = new Sound();
      sound.addEventListener(SampleDataEvent.SAMPLE_DATA, sampleDataEventHd);
      sound.play();
    }

    private function sampleDataEventHd(e:SampleDataEvent):void
    {
      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;
      }
    }
  }

}

自作iPhoneアプリ 好評発売中!
フォルメモ - シンプルなフォルダつきメモ帳
ジッピー電卓 - 消費税や割引もサクサク計算!

ページトップへ戻る