-- region V1: 6 op, too complex
do
-- sets the amount of operator 'op' in the superfm output mix
-- (1 <= op <= 6)
-- fmamp :: Int -> Pattern Double -> ControlPattern
let fmamp op = pF ("amp" ++ show op)
-- sets the ratio for operator 'op'.
-- the frequency is note * ratio + detune Hz
-- (1 <= op <= 6)
-- fmratio :: Int -> Pattern Double -> ControlPattern
let fmratio op = pF ("ratio" ++ show op)
-- set the detune for operator 'op'
-- fmdetune :: Int -> Pattern Double -> ControlPattern
let fmdetune op = pF ("detune" ++ show op)
-- set the modulation of oerator opa by operator opb
-- if opa == opb, then the modulation amount is multiplied by the
-- 'feedback' parameter
-- fmmod :: Int -> Int -> Pattern Double -> ControlPattern
let fmmod opa opb = pF ("mod" ++ show opa ++ show opb)
-- feedback
-- fmfeedback :: Pattern Double -> ControlPattern
let fmfeedback = pF "feedback"
-- Envelope definition: each operator has an envelop with 4 steps
-- fmeglevel :: Int -> Int -> Pattern Double -> ControlPattern
let fmeglevel op step = pF ("eglevel" ++ show op ++ show step)
-- Envelope definition: sets the rate at which the envelope moves
-- between steps.  Low numbers are slow, high numbers are fast.
-- fmegrate :: Int -> Int -> Pattern Double -> ControlPattern
let fmegrate op step = pF ("egrate" ++ show op ++ show step)
let fmparam function (x:xs) = foldr (#) (function 1 x) (zipWith function [2..] xs)
let fmamps = fmparam fmamp
let fmratios = fmparam fmratio
let fmdetunes = fmparam fmdetune
let envrate op = fmparam (fmegrate op)
let envlevel op = fmparam (fmeglevel op)
d1
    $ s "superfm"
    |+| note (scale "aeolian" (
      -- arp "pinkyup" "[0,4,7,12] [0,5,7,9]"
      "[0,4,6]"
      + "[0(<3 3 <3 1> <5 [5 3]>>,8)]*2"
      + "0 2"
      - 7
    ))
    # gain (range 0 1.8 "^77")
    # fmfeedback (range 0 2 "^78")
    # fmamps    ["^15", "^16", "^17", "^18", "^19", "^20"]
    # fmratios  ["^31", "^32", "^33", "^34", "^35", "^36"]
    # fmdetunes ["^51", "^52", "^53", "^54", "^55", "^56"]
    # fmmod 1 1 1
    # fmmod 1 2 0
    # fmmod 2 3 0
    # fmmod 3 4 0
    # fmmod 4 5 0
    # fmmod 5 6 0
    # envlevel 1 [1, 0.5, 0, 0, 0, 0]
    # envrate  1 [10, 0.1, 0.1, 1, 0, 0]
    # envlevel 2 [1, 0, 0, 0, 0, 0]
    # envrate  2 [1, 0.3, 0.7, 1, 0, 0]
    # envlevel 3 [1, 0.2, 0, 1, 0, 0]
    # envrate  3 [10, 0.5, 0.4, 1, 0, 0]
    # lpf 1000
    # room 0.3
-- endregion V1

-- region V2 minimaliste
do
-- sets the amount of operator 'op' in the superfm output mix
-- (1 <= op <= 6)
-- fmamp :: Int -> Pattern Double -> ControlPattern
let fmamp op = pF ("amp" ++ show op)
-- sets the ratio for operator 'op'.
-- the frequency is note * ratio + detune Hz
-- (1 <= op <= 6)
-- fmratio :: Int -> Pattern Double -> ControlPattern
let fmratio op = pF ("ratio" ++ show op)
-- set the detune for operator 'op'
-- fmdetune :: Int -> Pattern Double -> ControlPattern
let fmdetune op = pF ("detune" ++ show op)
-- set the modulation of oerator opa by operator opb
-- if opa == opb, then the modulation amount is multiplied by the
-- 'feedback' parameter
-- fmmod :: Int -> Int -> Pattern Double -> ControlPattern
let fmmod opa opb = pF ("mod" ++ show opa ++ show opb)
-- feedback
-- fmfeedback :: Pattern Double -> ControlPattern
let fmfeedback = pF "feedback"
-- Envelope definition: each operator has an envelop with 4 steps
-- fmeglevel :: Int -> Int -> Pattern Double -> ControlPattern
let fmeglevel op step = pF ("eglevel" ++ show op ++ show step)
-- Envelope definition: sets the rate at which the envelope moves
-- between steps.  Low numbers are slow, high numbers are fast.
-- fmegrate :: Int -> Int -> Pattern Double -> ControlPattern
let fmegrate op step = pF ("egrate" ++ show op ++ show step)
let fmparam function (x:xs) = foldr (#) (function 1 x) (zipWith function [2..] xs)
let fmamps = fmparam fmamp
let fmratios = fmparam fmratio
let fmdetunes = fmparam fmdetune
let envrate op = fmparam (fmegrate op)
let envlevel op = fmparam (fmeglevel op)
-- Params
let lfodepth = pF "lfodepth"
let lfofreq = pF "lfofreq"
-- Nova
let midiOn  ch pat = someCyclesBy ch pat
let midiOff ch pat = someCyclesBy (1 - ch) pat
d1 $ "jazz*<2!16 4!16>" # lpf 2000 # gain (1 - (0.5 * (1 - "^77")))
d2
  $ midiOn "^42" (off "q" ((# room 0.2) . (|* gain 0.8)))
  $ midiOn "^43" (degradeBy "0 1!5 0.5 0.25")
  $ midiOn "^41" rev
  $ s "superfm"
    |+| note (scale "aeolian" (
      -- arp "pinkyup" "[0,4,7,12] [0,5,7,9]"
      "<[1 2] [2 <3 [3 4]>]>"
      + "[0,6,10]"
      + "[0(<3 3 <3 1> <5 [5 3]>>,8)]*2"
      + "0 2"
      - 7
    ))
    # gain (range 0 1 "^77")
    # fmfeedback (range 0 400 "^78")
    # lfofreq (range 500 1000 "^79")
    # lfodepth (range 0 1 "^80")
    -- # fmamps    ["^15", "^17", "^19"]
    # fmratios  [range 0 100 "^31", range 0 100 "^33", range 0 100 "^35"]
    -- # fmdetunes ["^32", "^53", "^55"]
    # fmmod 1 1 (range 0 4 "^16")
    # fmmod 1 2 (range 0 4 "^32")
    # fmmod 1 3 (range 0 4 "^52")
    # fmmod 2 1 "^18"
    # fmmod 2 2 "^34"
    # fmmod 2 3 "^54"
    # fmmod 3 1 "^20"
    # fmmod 3 2 "^36"
    # fmmod 3 3 "^56"
    # fmmod 3 4 1
    # fmmod 4 5 1
    # fmmod 5 6 1
    # envlevel 1 [1, perlin, perlin, 0, 0, 0]
    # envrate  1 [perlin, 1, 1, 0, 0, 0]
    # envlevel 2 [1, 1, 1, 0, 0, 0]
    # envrate  2 [1, 0, 1, 0, 0, 0]
    # envlevel 3 [1, 0, 1, slow 4 sine, slow 8 cosine, 1]
    # envrate  3 [1, fast 4 sine, 1, 1, 1, 1]
    # envlevel 4 [1, 1, 1, 1, 1, 1]
    # envrate  4 [1, 1, 1, 1, 1, 1]
    # envlevel 5 [1, 1, 1, 1, 1, 1]
    # envrate  5 [1, 1, 1, 1, 1, 1]
    -- # envlevel 6 [1, 1, 1, 1, 1, 1]
    -- # envrate  6 [1, 1, 1, 1, 1, 1]
-- endregion V2
