Start in a maze (Javascriptでシンセ2)


前回の投稿したプログラムの説明です。動きは全く同じでしたがかなり作り直しました。
プログラムはこちら。(safariとかスマホでは再生できないです。。。)
機能は以下の通り。

  1. 「start!」ボタンを押すと音声が出力して、背景色が変わる。
  2. 上記の処理が繰り返し実行される。
  3. 繰り返しの処理は0から750ミリ秒の間でランダムのタイミングで実行される。
  4. 背景色はランダムに切り替わる。
  5. 「stop!」ボタンを押すと処理が停止する。

こんな感じのイメージ。

当初は全てhtml内に書き込んでいましたが、音再生部分はクラスにして外出しにしました。背景色用の処理もクラスにしていますが、こちらはどちらかと言うと実行側に近いのでhtmlにそのまま残してそのクラスから音声再生用のクラスを制御するようにしました。

まずは音再生クラスから(mysynth.js)

以下のような感じでシンプルにまとめました。この方法でかなり拡張しやすくなったと思います。

  • コンストラクタ
    インスタンス変数にAudioContexのオブジェクトを保持。
    (注) AudioContextが使えないブラウザ対応のためにコンストラクタでエラーが発生した場合は、インスタンス変数に使用不可である事を設定します。
  • setSound
    音量、音程、音色を設定
  • play
    setSoundで音の設定をして再生
  • stop
    音を停止

以下ソースコード。

続いてhtml側

全体的な構成は以下のような感じ。

  1. グローバルの変数
    RGBの最大値(MAX_VALUE)、setTimeout停止用のid(timeId)、音程値の配列(notes)、波形値の配列(oscType)を設定してプログラム全体の中で使用します。
  2. ColorBoxクラス
    背景色切替用のクラス
  3. startボタンクリック
    ColorBoxのインスタンスを生成して処理を開始
  4. stopボタンクリック
    処理を停止する

背景色切替クラス

このクラスで、背景色を変えながら音も奏でる処理を実行することになります。

  • コンストラクタ
    背景色の初期値、対象となる要素、色、音再生クラスのインスタンス、音に関する情報を設定
  • setColor
    RGBの色情報を設定
  • run
    これが結構肝でした。当初は背景色の設定とか音の再生などの処理の関数をsetIntervalのパラメータに設定して実行していたのですが、setIntervalの場合実行タイミングがパラメータの値で一定なので何かいい方法がないのかなぁとちょっと悩みました。結果、自分自身のインスタンスをパラメータにしてこの関数をsetTimeoutで再帰してやればいいんじゃない?と言う考えに至ったわけです。コールバックのパラメータは第3引数に追加すれば良いと言うことだったのでこの方法で実行確認。結果、よくできました!
  • stop
    音を停止

と言う感じで初の音声出力javascriptプログラムを作ってみました。とりあえずイメージを描いてプログラム描いてみるってのは面白いっすね。再帰とかちょっと収穫もあったし、またこの次は色々発展できればいいかなと思って、今回はこの辺にしておきます。

音程の周波数については以下のサイトを参考にしました。

音階と周波数の関係(平均律一覧表)