Creating synth presets in Clojure

To speed up the creation of and maintenance of synth presets for rogue I created a little tool called rogue-presets. It is written in Clojure and provides a declarative way to write synth presets for the rogue synth.

The basic idea is that incremental changes to the synth defaults are stacked and merged and written out into LV2 preset files.

Here is a simple example

(def two_oscs
  (merge defaults
         (osc1 :level 1 :level_a 0.5)
         (osc2 :level 1 :level_a 0.5)))

(defpreset lead-pulse1 "Pulse Lead 1"
  two_oscs
  (osc1 :type pulse :width 0.25 :fine -0.05)
  (osc2 :type pulse :width 0.75 :fine 0.05)
  (filter1 :freq 440 :type lp_12db :q 0.2 :level 1)
  (env1 :attack 0.01 :curve 0.7)
  (env2 :attack 0.1 :sustain 0.25 :curve 0.7)
  (modulations [mod_env2 mod_flt1_freq 0.6])
  (reverb-fx))

and here a more complex one

(defpreset pad-arctic "Arctic Pad"
  defaults
  (osc1 :type fm1 :level 1)
  (osc2 :type saw :level 1 :coarse 12 :out_mod 2 :level_a 1) 
  (filter1 :type svf_lp :freq 220 :q 0.3 :level 1)
  (env1 :attack 0.3 :sustain 0.6 :release 1.2 :curve 0.7)
  (env2 :attack 1 :sustain 1 :release 1.22 :curve 0.7)
  (lfo1 :type lfo_tri :freq 2)
  (reverb-fx :bandwidth 0.75 :tail 1 :damping 0.25 :blend 0.75)
  (modulations [mod_lfo1 mod_osc1_pitch 0.2]
               [mod_lfo1 mod_flt1_freq 0.2]
               [mod_lfo1 mod_osc2_amp 0.2]
               [mod_env2 mod_flt1_freq 0.8]))

The general order is base settings, oscillators (osc1-4), filters (filter1-2), envelopes (env1-4), lfos (lfo1-4), effects and modulations.

The modulations section contains triples of source, target and amount. For example [mod_lfo1 mod_osc1_pitch 0.2] declares that lfo1 modulates the pitch of osc1 by 0.2.

I am still experimenting with this approach, but it feels promising.