MMLからWAV生成、そして自由な波形プログラミングへ

きっかけ

最近、Phel-langでMML文字列を埋め込んだコードからWAVファイルを生成するツール phel-mml2wav を作成しました。

初めは素のsin波だけを生成していましたが、波形を切り替えられるようにしたらたのしくなって、短時間で「瞬間シンセ」として現在の形を持つに致りました。

機能追加の歴程

  1.  **osc-fnを外部指定可能に** – sin波に限らず、短波、短切波、三角波なども生成できるように
  2.  **FM/モジュレーションによる挿入的な作音**
  3.  **:effects で音を加工できるように** – ゲイン・ボリュームの変更 – ディストーション (tanh) – tremolo (AM)

設計方針

波形を作る部分(オシレーター)と、それを加工する部分(エフェクター)を分離した構成にしました。

ギターで言うなら、「ピックアップの生の音」に「エフェクターの加工」を追加するといった感覚です。

  • osc-fn: (freq t amp idx total sr) -> float
  • :effects: [(fn [x sr] -> sequence)]

Sweet Child O’ Mineのイントロフレーズ

音符をMMLで書き起こし、下記のようなコードでWAVを生成しました:

(let [fp (php/fopen "example_sweet_child_intro.wav" "w")
      mml "T120 O4 L8 D->D-<AG>G<A>F+<A D->D-<AG>G<A>F+<A E->D-<AG>G<A>F+<A E->D-<AG>G<A>F+<A G->D-<AG>G<A>F+<A G->D-<AG>G<A>F+<A D->D-<AG>G<A>F+<A D->D-<AG>G<A>F+<A"
      osc-fn (fn [freq t amp idx total sr]
               (+ (* amp 0.8 (php/sin (* 2 php/M_PI freq t)))
                  (* amp 0.5 (php/sin (* 2 php/M_PI (* 2 freq) t)))
                  (* amp 0.3 (php/sin (* 2 php/M_PI (* 3 freq) t)))
                  (* amp 0.1 (php/sin (* 2 php/M_PI (* 4 freq) t)))))
      # ディストーション:サンプルごとに sr を受け取るように修正
      distortion (fn [wave sr]
                   (map |(* 0.4 (php/tanh (* 4 $))) wave))
      opts {:osc-fn osc-fn
            :effects [distortion]}]

  (converter/process-mml-to-wav-stream mml 44100 fp opts)
  (php/fclose fp))

mml は、MMLでSweet Child O’ Mine のイントロのギターフレーズを書いてあります。

osc-fn は、波長を作る関数です。倍音を含む波長を表現する配列を生成する関数です。

distortion は、ディストーション(歪みエフェクター)の加工を行なう関数です。

音量注意!

おわりに

今回の設計は、音を生成する部分と、それを加工する部分を分離することで、楽器のシンセ化を意識したものとなりました。

  • 波形は osc-fnで指定
  • エフェクトは :effectsの配列で指定

自作シンセの入り口としても楽しめると思います。ディレイなどのエフェクターも作ってみたいです。

コメントする

メールアドレスが公開されることはありません。 が付いている欄は必須項目です


reCaptcha の認証期間が終了しました。ページを再読み込みしてください。

This site uses Akismet to reduce spam. Learn how your comment data is processed.