module Sound.Tidal.Params where

import qualified Data.Map.Strict as Map

import Sound.Tidal.Pattern
import Sound.Tidal.Utils
import Data.Maybe (fromMaybe)
import Data.Word (Word8)

-- | group multiple params into one
grp :: [String -> ControlMap] -> Pattern String -> ControlPattern
grp [] _ = empty
grp fs p = splitby <$> p
  where splitby name = Map.unions $ map (\(v, f) -> f v) $ zip (split name) fs
        split :: String -> [String]
        split = wordsBy (==':')

mF :: String -> String -> ControlMap
mF name v = fromMaybe Map.empty $ do f <- readMaybe v
                                     return $ Map.singleton name (VF f)

mI :: String -> String -> ControlMap
mI name v = fromMaybe Map.empty $ do i <- readMaybe v
                                     return $ Map.singleton name (VI i)

mS :: String -> String -> ControlMap
mS name v = Map.singleton name (VS v)

-- | Grouped params

sound :: Pattern String -> ControlPattern
sound = grp [mS "s", mF "n"]

s :: Pattern String -> ControlPattern
s = sound

cc :: Pattern String -> ControlPattern
cc = grp [mF "ccn", mF "ccv"]

nrpn :: Pattern String -> ControlPattern
nrpn = grp [mI "nrpn", mI "val"]

-- | Singular params

pF :: String -> Pattern Double -> ControlPattern
pF name = fmap (Map.singleton name . VF)

pI :: String -> Pattern Int -> ControlPattern
pI name = fmap (Map.singleton name . VI)

pS :: String -> Pattern String -> ControlPattern
pS name = fmap (Map.singleton name . VS)

pX :: String -> Pattern [Word8] -> ControlPattern
pX name = fmap (Map.singleton name . VX)

-- | patterns for internal sound routing
toArg :: Pattern String -> ControlPattern
toArg = pS "toArg"

from :: Pattern Double -> ControlPattern
from = pF "from"

to :: Pattern Double -> ControlPattern
to = pF "to"

-- | a pattern of numbers that speed up (or slow down) samples while they play.
accelerate :: Pattern Double -> ControlPattern
accelerate       = pF "accelerate"


-- | Amplitude; like @gain@, but linear.
amp :: Pattern Double -> ControlPattern
amp = pF "amp"

-- | a pattern of numbers to specify the attack time (in seconds) of an envelope applied to each sample. Only takes effect if `release` is also specified.
attack :: Pattern Double -> ControlPattern
attack = pF "attack"

-- | a pattern of numbers from 0 to 1. Sets the center frequency of the band-pass filter.
bandf :: Pattern Double -> ControlPattern
bandf = pF "bandf"

-- | a pattern of numbers from 0 to 1. Sets the q-factor of the band-pass filter.y
bandq :: Pattern Double -> ControlPattern
bandq = pF "bandq"

{- | a pattern of numbers from 0 to 1. Skips the beginning of each sample, e.g. `0.25` to cut off the first quarter from each sample.

Using `begin "-1"` combined with `cut "-1"` means that when the sample cuts itself it will begin playback from where the previous one left off, so it will sound like one seamless sample. This allows you to apply a synth param across a long sample in a way similar to `chop`:

@
cps 0.5

d1 $ sound "breaks125*8" # unit "c" # begin "-1" # cut "-1" # coarse "1 2 4 8 16 32 64 128"
@

This will play the `breaks125` sample and apply the changing `coarse` parameter over the sample. Compare to:

@
d1 $ (chop 8 $ sounds "breaks125") # unit "c" # coarse "1 2 4 8 16 32 64 128"
@

which performs a similar effect, but due to differences in implementation sounds different.
-}
begin, legato, clhatdecay, crush :: Pattern Double -> ControlPattern
channel, coarse :: Pattern Int -> ControlPattern
begin = pF "begin"
-- | choose the physical channel the pattern is sent to, this is super dirt specific
channel = pI "channel"

--legato controls the amount of overlap between two adjacent synth sounds
legato = pF "legato"

clhatdecay = pF "clhatdecay"
-- | fake-resampling, a pattern of numbers for lowering the sample rate, i.e. 1 for original 2 for half, 3 for a third and so on.
coarse = pI "coarse"
-- | bit crushing, a pattern of numbers from 1 (for drastic reduction in bit-depth) to 16 (for barely no reduction).
crush = pF "crush"
{- |
In the style of classic drum-machines, `cut` will stop a playing sample as soon as another samples with in same cutgroup is to be played.

An example would be an open hi-hat followed by a closed one, essentially muting the open.

@
d1 $ stack [
  sound "bd",
  sound "~ [~ [ho:2 hc/2]]" # cut "1"
  ]
@

This will mute the open hi-hat every second cycle when the closed one is played.

Using `cut` with negative values will only cut the same sample. This is useful to cut very long samples

@
d1 $ sound "[bev, [ho:3](3,8)]" # cut "-1"
@

Using `cut "0"` is effectively _no_ cutgroup.
-}
cut :: Pattern Int -> ControlPattern
cut = pI "cut"

-- | a pattern of numbers from 0 to 1. Applies the cutoff frequency of the low-pass filter.
cutoff :: Pattern Double -> ControlPattern
cutoff = pF "cutoff"

cutoffegint :: Pattern Double -> ControlPattern
cutoffegint = pF "cutoffegint"

decay :: Pattern Double -> ControlPattern
decay = pF "decay"
-- | a pattern of numbers from 0 to 1. Sets the level of the delay signal.
delay :: Pattern Double -> ControlPattern
delay = pF "delay"
-- | a pattern of numbers from 0 to 1. Sets the amount of delay feedback.
delayfeedback :: Pattern Double -> ControlPattern
delayfeedback = pF "delayfeedback"
-- | a pattern of numbers from 0 to 1. Sets the length of the delay.
delaytime :: Pattern Double -> ControlPattern
delaytime = pF "delaytime"

detune :: Pattern Double -> ControlPattern
detune = pF "detune"

-- DJ filter
djf :: Pattern Double -> ControlPattern
djf = pF "djf"

-- | when set to `1` will disable all reverb for this pattern. See `room` and `size` for more information about reverb.
dry :: Pattern Double -> ControlPattern
dry = pF "dry"
{- the same as `begin`, but cuts the end off samples, shortening them;
 e.g. `0.75` to cut off the last quarter of each sample.
-}
end :: Pattern Double -> ControlPattern
end = pF "end"

freq :: Pattern Double -> ControlPattern
freq = pF "freq"

-- | a pattern of numbers that specify volume. Values less than 1 make
-- the sound quieter. Values greater than 1 make the sound louder. For
-- the linear equivalent, see @amp@.
gain :: Pattern Double -> ControlPattern
gain = pF "gain"

gate :: Pattern Double -> ControlPattern
gate = pF "gate"
hatgrain :: Pattern Double -> ControlPattern
hatgrain = pF "hatgrain"
-- | a pattern of numbers from 0 to 1. Applies the cutoff frequency of the high-pass filter.
hcutoff :: Pattern Double -> ControlPattern
hcutoff = pF "hcutoff"
-- | a pattern of numbers to specify the hold time (in seconds) of an envelope applied to each sample. Only takes effect if `attack` and `release` are also specified.
hold :: Pattern Double -> ControlPattern
hold = pF "hold"
-- | a pattern of numbers from 0 to 1. Applies the resonance of the high-pass filter.
hresonance :: Pattern Double -> ControlPattern
hresonance = pF "hresonance"
kriole :: Pattern Int -> ControlPattern
kriole = pI "kriole"
lagogo :: Pattern Double -> ControlPattern
lagogo = pF "lagogo"
lclap :: Pattern Double -> ControlPattern
lclap = pF "lclap"
lclaves :: Pattern Double -> ControlPattern
lclaves = pF "lclaves"
lclhat :: Pattern Double -> ControlPattern
lclhat = pF "lclhat"
lcrash :: Pattern Double -> ControlPattern
lcrash = pF "lcrash"
leslie :: Pattern Double -> ControlPattern
leslie = pF "leslie"
lrate :: Pattern Double -> ControlPattern
lrate = pF "lrate"
lsize :: Pattern Double -> ControlPattern
lsize = pF "lsize"
lfo :: Pattern Double -> ControlPattern
lfo = pF "lfo"
lfocutoffint :: Pattern Double -> ControlPattern
lfocutoffint = pF "lfocutoffint"
lfodelay :: Pattern Double -> ControlPattern
lfodelay = pF "lfodelay"
lfoint :: Pattern Double -> ControlPattern
lfoint = pF "lfoint"
lfopitchint :: Pattern Double -> ControlPattern
lfopitchint = pF "lfopitchint"
lfoshape :: Pattern Double -> ControlPattern
lfoshape = pF "lfoshape"
lfosync :: Pattern Double -> ControlPattern
lfosync = pF "lfosync"
lhitom :: Pattern Double -> ControlPattern
lhitom = pF "lhitom"
lkick :: Pattern Double -> ControlPattern
lkick = pF "lkick"
llotom :: Pattern Double -> ControlPattern
llotom = pF "llotom"
{- | A pattern of numbers. Specifies whether delaytime is calculated relative to cps. When set to 1, delaytime is a direct multiple of a cycle.
-}
lock :: Pattern Double -> ControlPattern
lock = pF "lock"
-- | loops the sample (from `begin` to `end`) the specified number of times.
loop :: Pattern Double -> ControlPattern
loop = pF "loop"
lophat :: Pattern Double -> ControlPattern
lophat = pF "lophat"
lsnare :: Pattern Double -> ControlPattern
lsnare = pF "lsnare"
-- | specifies the sample or note number to be used
n :: Pattern Double -> ControlPattern
n = pF "n"
note :: Pattern Double -> ControlPattern
note = pF "note"
{- |
Pushes things forward (or backwards within built-in latency) in time. Allows for nice things like _swing_ feeling:

@
d1 $ stack [
 sound "bd bd/4",
 sound "hh(5,8)"
 ] # nudge "[0 0.04]*4"
@

--pitch model -}

degree, mtranspose, ctranspose, harmonic, stepsPerOctave, octaveRatio :: Pattern Double -> ControlPattern
degree = pF "degree"
mtranspose = pF "mtranspose"
ctranspose = pF "ctranspose"
harmonic = pF "ctranspose"
stepsPerOctave = pF "stepsPerOctave"
octaveRatio = pF "octaveRatio"


--Low values will give a more _human_ feeling, high values might result in quite the contrary.

nudge :: Pattern Double -> ControlPattern
nudge = pF "nudge"
octave :: Pattern Int -> ControlPattern
octave = pI "octave"
offset :: Pattern Double -> ControlPattern
offset = pF "offset"
ophatdecay :: Pattern Double -> ControlPattern
ophatdecay = pF "ophatdecay"
{- | a pattern of numbers. An `orbit` is a global parameter context for patterns. Patterns with the same orbit will share hardware output bus offset and global effects, e.g. reverb and delay. The maximum number of orbits is specified in the superdirt startup, numbers higher than maximum will wrap around.
-}
orbit :: Pattern Int -> ControlPattern
orbit = pI "orbit"

overgain :: Pattern Double -> ControlPattern
overgain = pF "overgain"

overshape :: Pattern Double -> ControlPattern
overshape = pF "overshape"

-- | a pattern of numbers between 0 and 1, from left to right (assuming stereo), once round a circle (assuming multichannel)
pan :: Pattern Double -> ControlPattern
pan = pF "pan"
-- | a pattern of numbers between -inf and inf, which controls how much multichannel output is fanned out (negative is backwards ordering)
panspan :: Pattern Double -> ControlPattern
panspan = pF "span"
-- | a pattern of numbers between 0.0 and 1.0, which controls the multichannel spread range (multichannel only)
pansplay :: Pattern Double -> ControlPattern
pansplay = pF "splay"
-- | a pattern of numbers between 0.0 and inf, which controls how much each channel is distributed over neighbours (multichannel only)
panwidth :: Pattern Double -> ControlPattern
panwidth = pF "panwidth"
-- | a pattern of numbers between -1.0 and 1.0, which controls the relative position of the centre pan in a pair of adjacent speakers (multichannel only)
panorient :: Pattern Double -> ControlPattern
panorient = pF "orientation"

pitch1 :: Pattern Double -> ControlPattern
pitch1 = pF "pitch1"
pitch2 :: Pattern Double -> ControlPattern
pitch2 = pF "pitch2"
pitch3 :: Pattern Double -> ControlPattern
pitch3 = pF "pitch3"
portamento :: Pattern Double -> ControlPattern
portamento = pF "portamento"
-- | used in SuperDirt softsynths as a control rate or "speed"
rate :: Pattern Double -> ControlPattern
rate = pF "rate"
-- | a pattern of numbers to specify the release time (in seconds) of an envelope applied to each sample. Only takes effect if `attack` is also specified.
release :: Pattern Double -> ControlPattern
release = pF "release"
-- | a pattern of numbers from 0 to 1. Specifies the resonance of the low-pass filter.
resonance :: Pattern Double -> ControlPattern
resonance = pF "resonance"
-- | a pattern of numbers from 0 to 1. Sets the level of reverb.
room :: Pattern Double -> ControlPattern
room = pF "room"
sagogo :: Pattern Double -> ControlPattern
sagogo = pF "sagogo"
sclap :: Pattern Double -> ControlPattern
sclap = pF "sclap"
sclaves :: Pattern Double -> ControlPattern
sclaves = pF "sclaves"
scrash :: Pattern Double -> ControlPattern
scrash = pF "scrash"
semitone :: Pattern Double -> ControlPattern
semitone = pF "semitone"
-- | wave shaping distortion, a pattern of numbers from 0 for no distortion up to 1 for loads of distortion.
shape :: Pattern Double -> ControlPattern
shape = pF "shape"
-- | a pattern of numbers from 0 to 1. Sets the perceptual size (reverb time) of the `room` to be used in reverb.
size :: Pattern Double -> ControlPattern
size = pF "size"
slide :: Pattern Double -> ControlPattern
slide = pF "slide"
-- | a pattern of numbers which changes the speed of sample playback, i.e. a cheap way of changing pitch. Negative values will play the sample backwards!
speed :: Pattern Double -> ControlPattern
speed = pF "speed"
squiz :: Pattern Double -> ControlPattern
squiz = pF "squiz"
-- | a pattern of strings. Selects the sample to be played.
s' :: Pattern String -> ControlPattern
s' = pS "s"
stutterdepth :: Pattern Double -> ControlPattern
stutterdepth = pF "stutterdepth"
stuttertime :: Pattern Double -> ControlPattern
stuttertime = pF "stuttertime"
sustain :: Pattern Double -> ControlPattern
sustain = pF "sustain"
tomdecay :: Pattern Double -> ControlPattern
tomdecay = pF "tomdecay"
{- | used in conjunction with `speed`, accepts values of "r" (rate, default behavior), "c" (cycles), or "s" (seconds).
Using `unit "c"` means `speed` will be interpreted in units of cycles, e.g. `speed "1"` means samples will be stretched to fill a cycle.
Using `unit "s"` means the playback speed will be adjusted so that the duration is the number of seconds specified by `speed`.
-}
unit :: Pattern String -> ControlPattern
unit = pS "unit"
velocity :: Pattern Double -> ControlPattern
velocity = pF "velocity"
vcfegint :: Pattern Double -> ControlPattern
vcfegint = pF "vcfegint"
vcoegint :: Pattern Double -> ControlPattern
vcoegint = pF "vcoegint"
voice :: Pattern Double -> ControlPattern
voice = pF "voice"
-- | formant filter to make things sound like vowels, a pattern of either `a`, `e`, `i`, `o` or `u`. Use a rest (`~`) for no effect.
vowel :: Pattern String -> ControlPattern
vowel = pS "vowel"

voweli :: Pattern Int -> ControlPattern
voweli = pI "vowel"

waveloss :: Pattern Double -> ControlPattern
waveloss = pF "waveloss"

-- MIDI-specific params

dur :: Pattern Double -> ControlPattern
dur = pF "dur"
modwheel :: Pattern Double -> ControlPattern
modwheel = pF "modwheel"
expression :: Pattern Double -> ControlPattern
expression = pF "expression"
sustainpedal :: Pattern Double -> ControlPattern
sustainpedal = pF "sustainpedal"

-- Tremolo Audio DSP effect | params are "tremolorate" and "tremolodepth"
tremolorate, tremolodepth :: Pattern Double -> ControlPattern
tremolorate = pF "tremolorate"
tremolodepth = pF "tremolodepth"

-- Phaser Audio DSP effect | params are "phaserrate" and "phaserdepth"
phaserrate, phaserdepth :: Pattern Double -> ControlPattern
phaserrate = pF "phaserrate"
phaserdepth = pF "phaserdepth"

-- More SuperDirt effects
-- frequency shifter
fshift, fshiftphase, fshiftnote :: Pattern Double -> ControlPattern
fshift = pF "fshift"
fshiftphase = pF "fshiftphase"
fshiftnote = pF "fshiftnote"
-- triode (tube distortion)
triode :: Pattern Double -> ControlPattern
triode = pF "triode"
-- krush (like Sonic Pi's shape/bass enhancer)
krush, kcutoff :: Pattern Double -> ControlPattern
krush = pF "krush"
kcutoff = pF "kcutoff"
-- octer (like Sonic Pi's octaver effect)
octer, octersub, octersubsub :: Pattern Double -> ControlPattern
octer = pF "octer"
octersub = pF "octersub"
octersubsub = pF "octersubsub"
-- ring modulation
ring, ringf, ringdf :: Pattern Double -> ControlPattern
ring = pF "ring"
ringf = pF "ringf"
ringdf = pF "ringdf"
-- noisy fuzzy distortion
distort :: Pattern Double -> ControlPattern
distort = pF "distort"

-- Spectral freeze
freeze :: Pattern Double -> ControlPattern
freeze = pF "freeze"

-- Spectral delay
xsdelay :: Pattern Double -> ControlPattern
xsdelay = pF "xsdelay"

tsdelay :: Pattern Double -> ControlPattern
tsdelay = pF "tsdelay"

-- Spectral conform
real :: Pattern Double -> ControlPattern
real = pF "real"

imag :: Pattern Double -> ControlPattern
imag = pF "imag"

-- Spectral enhance
enhance :: Pattern Double -> ControlPattern
enhance = pF "enhance"

partials :: Pattern Double -> ControlPattern
partials = pF "partials"

-- Spectral comb
comb :: Pattern Double -> ControlPattern
comb = pF "comb"

-- Spectral smear
smear :: Pattern Double -> ControlPattern
smear = pF "smear"

-- Spectral scramble
scram :: Pattern Double -> ControlPattern
scram = pF "scram"

-- Spectral binshift
binshift :: Pattern Double -> ControlPattern
binshift = pF "binshift"

-- High pass sort of spectral filter
hbrick :: Pattern Double -> ControlPattern
hbrick = pF "hbrick"

-- Low pass sort of spectral filter
lbrick :: Pattern Double -> ControlPattern
lbrick = pF "lbrick"

-- aliases
att, bpf, bpq, chdecay, ctf, ctfg, delayfb, dfb, delayt, dt, det, gat, hg, hpf, hpq, lag, lbd, lch, lcl, lcp, lcr, lfoc, lfoi
   , lfop, lht, llt, loh, lpf, lpq, lsn, ohdecay, phasdp, phasr, pit1, pit2, pit3, por, rel, sz, sag, scl, scp
   , scr, sld, std, stt, sus, tdecay, tremdp, tremr, vcf, vco, voi
 :: Pattern Double -> ControlPattern
att = attack
bpf = bandf
bpq = bandq
chdecay = clhatdecay
ctf = cutoff
ctfg = cutoffegint
delayfb = delayfeedback
dfb = delayfeedback
delayt = delaytime
dt = delaytime
det = detune
gat = gate
hg = hatgrain
hpf = hcutoff
hpq = hresonance
lag = lagogo
lbd = lkick
lch = lclhat
lcl = lclaves
lcp = lclap
lcr = lcrash
lfoc = lfocutoffint
lfoi = lfoint
lfop = lfopitchint
lht = lhitom
llt = llotom
loh = lophat
lpf = cutoff
lpq = resonance
lsn = lsnare
ohdecay = ophatdecay
phasdp = phaserdepth
phasr = phaserrate
pit1 = pitch1
pit2 = pitch2
pit3 = pitch3
por = portamento
rel = release
sag = sagogo
scl = sclaves
scp = sclap
scr = scrash
sz = size
sld = slide
std = stutterdepth
stt = stuttertime
sus = sustain
tdecay = tomdecay
tremdp = tremolodepth
tremr = tremolorate
vcf = vcfegint
vco = vcoegint
voi = voice

midinote :: Pattern Double -> ControlPattern
midinote = note . (subtract 60 <$>)

drum :: Pattern String -> ControlPattern
drum = n . (subtract 60 . drumN <$>)

drumN :: Num a => String -> a
drumN "bd" = 36
drumN "sn" = 38
drumN "lt" = 43
drumN "ht" = 50
drumN "ch" = 42
drumN "oh" = 46
drumN "cp" = 39
drumN "cl" = 75
drumN "ag" = 67
drumN "cr" = 49
drumN _ = 0


-- SuperDirt MIDI Params

array :: Pattern [Word8] -> ControlPattern
array = pX "array"
midichan :: Pattern Double -> ControlPattern
midichan = pF "midichan"
control :: Pattern Double -> ControlPattern
control = pF "control"

ccn :: Pattern Double -> ControlPattern
ccn = pF "ccn"
ccv :: Pattern Double -> ControlPattern
ccv = pF "ccv"

polyTouch :: Pattern Double -> ControlPattern
polyTouch = pF "polyTouch"

midibend :: Pattern Double -> ControlPattern
midibend = pF "midibend"

miditouch :: Pattern Double -> ControlPattern
miditouch = pF "miditouch"

nrpnn :: Pattern Int -> ControlPattern
nrpnn = pI "nrpn"
nrpnv :: Pattern Int -> ControlPattern
nrpnv = pI "val"

ctlNum :: Pattern Double -> ControlPattern
ctlNum = pF "ctlNum"

frameRate :: Pattern Double -> ControlPattern
frameRate = pF "frameRate"
frames :: Pattern Double -> ControlPattern
frames = pF "frames"
hours :: Pattern Double -> ControlPattern
hours = pF "hours"

midicmd :: Pattern String -> ControlPattern
midicmd = pS "midicmd"
command :: Pattern String -> ControlPattern
command = midicmd

minutes :: Pattern Double -> ControlPattern
minutes = pF "minutes"
progNum :: Pattern Double -> ControlPattern
progNum = pF "progNum"
seconds :: Pattern Double -> ControlPattern
seconds = pF "seconds"
songPtr :: Pattern Double -> ControlPattern
songPtr = pF "songPtr"
uid :: Pattern Double -> ControlPattern
uid = pF "uid"
val :: Pattern Double -> ControlPattern
val = pF "val"

{- | `up` is now an alias of `note`. -}
up :: Pattern Double -> ControlPattern
up = note

cps :: Pattern Double -> ControlPattern
cps = pF "cps"

-- generic names for mapping to e.g. midi controls
button0 :: Pattern Double -> ControlPattern
button0 = pF "button0"
button1 :: Pattern Double -> ControlPattern
button1 = pF "button1"
button2 :: Pattern Double -> ControlPattern
button2 = pF "button2"
button3 :: Pattern Double -> ControlPattern
button3 = pF "button3"
button4 :: Pattern Double -> ControlPattern
button4 = pF "button4"
button5 :: Pattern Double -> ControlPattern
button5 = pF "button5"
button6 :: Pattern Double -> ControlPattern
button6 = pF "button6"
button7 :: Pattern Double -> ControlPattern
button7 = pF "button7"
button8 :: Pattern Double -> ControlPattern
button8 = pF "button8"
button9 :: Pattern Double -> ControlPattern
button9 = pF "button9"
button10 :: Pattern Double -> ControlPattern
button10 = pF "button10"
button11 :: Pattern Double -> ControlPattern
button11 = pF "button11"
button12 :: Pattern Double -> ControlPattern
button12 = pF "button12"
button13 :: Pattern Double -> ControlPattern
button13 = pF "button13"
button14 :: Pattern Double -> ControlPattern
button14 = pF "button14"
button15 :: Pattern Double -> ControlPattern
button15 = pF "button15"
button16 :: Pattern Double -> ControlPattern
button16 = pF "button16"
button17 :: Pattern Double -> ControlPattern
button17 = pF "button17"
button18 :: Pattern Double -> ControlPattern
button18 = pF "button18"
button19 :: Pattern Double -> ControlPattern
button19 = pF "button19"
button20 :: Pattern Double -> ControlPattern
button20 = pF "button20"
button21 :: Pattern Double -> ControlPattern
button21 = pF "button21"
button22 :: Pattern Double -> ControlPattern
button22 = pF "button22"
button23 :: Pattern Double -> ControlPattern
button23 = pF "button23"
button24 :: Pattern Double -> ControlPattern
button24 = pF "button24"
button25 :: Pattern Double -> ControlPattern
button25 = pF "button25"
button26 :: Pattern Double -> ControlPattern
button26 = pF "button26"
button27 :: Pattern Double -> ControlPattern
button27 = pF "button27"
button28 :: Pattern Double -> ControlPattern
button28 = pF "button28"
button29 :: Pattern Double -> ControlPattern
button29 = pF "button29"
button30 :: Pattern Double -> ControlPattern
button30 = pF "button30"
button31 :: Pattern Double -> ControlPattern
button31 = pF "button31"

slider0 :: Pattern Double -> ControlPattern
slider0 = pF "slider0"
slider1 :: Pattern Double -> ControlPattern
slider1 = pF "slider1"
slider2 :: Pattern Double -> ControlPattern
slider2 = pF "slider2"
slider3 :: Pattern Double -> ControlPattern
slider3 = pF "slider3"
slider4 :: Pattern Double -> ControlPattern
slider4 = pF "slider4"
slider5 :: Pattern Double -> ControlPattern
slider5 = pF "slider5"
slider6 :: Pattern Double -> ControlPattern
slider6 = pF "slider6"
slider7 :: Pattern Double -> ControlPattern
slider7 = pF "slider7"
slider8 :: Pattern Double -> ControlPattern
slider8 = pF "slider8"
slider9 :: Pattern Double -> ControlPattern
slider9 = pF "slider9"
slider10 :: Pattern Double -> ControlPattern
slider10 = pF "slider10"
slider11 :: Pattern Double -> ControlPattern
slider11 = pF "slider11"
slider12 :: Pattern Double -> ControlPattern
slider12 = pF "slider12"
slider13 :: Pattern Double -> ControlPattern
slider13 = pF "slider13"
slider14 :: Pattern Double -> ControlPattern
slider14 = pF "slider14"
slider15 :: Pattern Double -> ControlPattern
slider15 = pF "slider15"
slider16 :: Pattern Double -> ControlPattern
slider16 = pF "slider16"
slider17 :: Pattern Double -> ControlPattern
slider17 = pF "slider17"
slider18 :: Pattern Double -> ControlPattern
slider18 = pF "slider18"
slider19 :: Pattern Double -> ControlPattern
slider19 = pF "slider19"
slider20 :: Pattern Double -> ControlPattern
slider20 = pF "slider20"
slider21 :: Pattern Double -> ControlPattern
slider21 = pF "slider21"
slider22 :: Pattern Double -> ControlPattern
slider22 = pF "slider22"
slider23 :: Pattern Double -> ControlPattern
slider23 = pF "slider23"
slider24 :: Pattern Double -> ControlPattern
slider24 = pF "slider24"
slider25 :: Pattern Double -> ControlPattern
slider25 = pF "slider25"
slider26 :: Pattern Double -> ControlPattern
slider26 = pF "slider26"
slider27 :: Pattern Double -> ControlPattern
slider27 = pF "slider27"
slider28 :: Pattern Double -> ControlPattern
slider28 = pF "slider28"
slider29 :: Pattern Double -> ControlPattern
slider29 = pF "slider29"
slider30 :: Pattern Double -> ControlPattern
slider30 = pF "slider30"
slider31 :: Pattern Double -> ControlPattern
slider31 = pF "slider31"