{- |
MIDI controller data type and common controller definitions.

See <http://www.midi.org/techspecs/midimessages.php>.
-}
module Sound.MIDI.Controller (
   T, Value, fromInt, toInt,

   bankSelect, modulation, breathControl, footControl, portamentoTime,
   dataEntry, volume, balance, panorama, expression,
   effectControl1, effectControl2,
   generalPurpose1, generalPurpose2, generalPurpose3, generalPurpose4,
   vectorX, vectorY,
   soundController1, soundController2, soundController3,
   soundController4, soundController5, soundController6,
   soundController7, soundController8, soundController9,
   soundController10, portamentoControl,
   effect1Depth, effect2Depth, effect3Depth, effect4Depth, effect5Depth,

   bankSelectMSB, modulationMSB, breathControlMSB, footControlMSB,
   portamentoTimeMSB, dataEntryMSB, volumeMSB, balanceMSB,
   panoramaMSB, expressionMSB,
   effectControl1MSB, effectControl2MSB,
   generalPurpose1MSB, generalPurpose2MSB,
   generalPurpose3MSB, generalPurpose4MSB,

   bankSelectLSB, modulationLSB, breathControlLSB, footControlLSB,
   portamentoTimeLSB, dataEntryLSB, volumeLSB, balanceLSB,
   panoramaLSB, expressionLSB,
   effectControl1LSB, effectControl2LSB,
   generalPurpose1LSB, generalPurpose2LSB,
   generalPurpose3LSB, generalPurpose4LSB,

   soundVariation, timbre, harmonicIntensity,
   releaseTime, attackTime, brightness, decayTime,
   vibratoRate, vibratoDepth, vibratoDelay,
   reverbSendLevel, chorusSendLevel, legato,

   sustain, portamento, sustenuto, softPedal, hold2,
   generalPurpose5, generalPurpose6, generalPurpose7, generalPurpose8,
   externalEffectDepth, tremoloDepth, chorusDepth, celesteDepth, phaserDepth,

   dataIncrement, dataDecrement,
   nonRegisteredParameterLSB, nonRegisteredParameterMSB,
   registeredParameterLSB, registeredParameterMSB,
   ) where

import qualified Sound.MIDI.ControllerPrivate as CtrlP

import Sound.MIDI.Utility (checkRange, )


-- * MIDI controller data type


{-
In the future this will be the main type,
and @Controller@ becomes a synonym and is eventually removed.
-}
type T = CtrlP.Controller

fromInt :: Int -> T
fromInt = checkRange "Controller" CtrlP.Controller

toInt :: T -> Int
toInt = CtrlP.fromController


type Value = Int


-- * predefined MIDI controllers

-- ** simple names for controllers, if only most-significant bytes are used

bankSelect, modulation, breathControl, footControl, portamentoTime,
   dataEntry, volume, balance, panorama, expression,
   effectControl1, effectControl2,
   generalPurpose1, generalPurpose2, generalPurpose3, generalPurpose4 :: T
bankSelect      = bankSelectMSB
modulation      = modulationMSB
breathControl   = breathControlMSB
footControl     = footControlMSB
portamentoTime  = portamentoTimeMSB
dataEntry       = dataEntryMSB
volume          = volumeMSB
balance         = balanceMSB
panorama        = panoramaMSB
expression      = expressionMSB
effectControl1  = effectControl1MSB
effectControl2  = effectControl2MSB
generalPurpose1 = generalPurpose1MSB
generalPurpose2 = generalPurpose2MSB
generalPurpose3 = generalPurpose3MSB
generalPurpose4 = generalPurpose4MSB


-- ** aliases for general purpose controllers

vectorX, vectorY,
   soundVariation, timbre, harmonicIntensity,
   releaseTime, attackTime, brightness, decayTime,
   vibratoRate, vibratoDepth, vibratoDelay,
   reverbSendLevel, chorusSendLevel,
   externalEffectDepth, tremoloDepth, chorusDepth, celesteDepth, phaserDepth :: T

vectorX = generalPurpose1
vectorY = generalPurpose2

soundVariation    = soundController1
timbre            = soundController2
harmonicIntensity = soundController2
releaseTime       = soundController3
attackTime        = soundController4
brightness        = soundController5
decayTime         = soundController6
vibratoRate       = soundController7
vibratoDepth      = soundController8
vibratoDelay      = soundController9

reverbSendLevel = effect1Depth
chorusSendLevel = effect3Depth

externalEffectDepth = effect1Depth
tremoloDepth        = effect2Depth
chorusDepth         = effect3Depth
celesteDepth        = effect4Depth
phaserDepth         = effect5Depth


-- ** controllers for most-significant bytes of control values
bankSelectMSB, modulationMSB, breathControlMSB, footControlMSB,
   portamentoTimeMSB, dataEntryMSB,
   volumeMSB, balanceMSB, panoramaMSB, expressionMSB,
   effectControl1MSB, effectControl2MSB,
   generalPurpose1MSB, generalPurpose2MSB,
   generalPurpose3MSB, generalPurpose4MSB :: T

-- ** controllers for least-significant bytes of control values
bankSelectLSB, modulationLSB, breathControlLSB, footControlLSB,
   portamentoTimeLSB, dataEntryLSB,
   volumeLSB, balanceLSB, panoramaLSB, expressionLSB,
   effectControl1LSB, effectControl2LSB,
   generalPurpose1LSB, generalPurpose2LSB,
   generalPurpose3LSB, generalPurpose4LSB :: T

-- ** controllers of sound and global effects
sustain, portamento, sustenuto, softPedal, legato, hold2,
   soundController1, soundController2, soundController3,
   soundController4, soundController5, soundController6,
   soundController7, soundController8, soundController9,
   soundController10,
   generalPurpose5, generalPurpose6, generalPurpose7, generalPurpose8,
   portamentoControl,
   effect1Depth, effect2Depth, effect3Depth, effect4Depth, effect5Depth :: T

-- ** increment/decrement and parameter numbers
dataIncrement, dataDecrement,
   nonRegisteredParameterLSB, nonRegisteredParameterMSB,
   registeredParameterLSB, registeredParameterMSB :: T

bankSelectMSB             = toEnum 0x00  {-  00 00 -}
modulationMSB             = toEnum 0x01  {-  01 01 -}
breathControlMSB          = toEnum 0x02  {-  02 02 -}
footControlMSB            = toEnum 0x04  {-  04 04 -}
portamentoTimeMSB         = toEnum 0x05  {-  05 05 -}
dataEntryMSB              = toEnum 0x06  {-  06 06 -}
volumeMSB                 = toEnum 0x07  {-  07 07 -}
balanceMSB                = toEnum 0x08  {-  08 08 -}
panoramaMSB               = toEnum 0x0A  {-  10 0A -}
expressionMSB             = toEnum 0x0B  {-  11 0B -}
effectControl1MSB         = toEnum 0x0C  {-  10 0C -}
effectControl2MSB         = toEnum 0x0D  {-  11 0D -}

generalPurpose1MSB        = toEnum 0x10  {-  16 10 -}
generalPurpose2MSB        = toEnum 0x11  {-  17 11 -}
generalPurpose3MSB        = toEnum 0x12  {-  18 12 -}
generalPurpose4MSB        = toEnum 0x13  {-  19 13 -}

bankSelectLSB             = toEnum 0x20  {-  32 20 -}
modulationLSB             = toEnum 0x21  {-  33 21 -}
breathControlLSB          = toEnum 0x22  {-  34 22 -}
footControlLSB            = toEnum 0x24  {-  36 24 -}
portamentoTimeLSB         = toEnum 0x25  {-  37 25 -}
dataEntryLSB              = toEnum 0x26  {-  38 26 -}
volumeLSB                 = toEnum 0x27  {-  39 27 -}
balanceLSB                = toEnum 0x28  {-  40 28 -}
panoramaLSB               = toEnum 0x2A  {-  42 2A -}
expressionLSB             = toEnum 0x2B  {-  43 2B -}
effectControl1LSB         = toEnum 0x2C  {-  44 2C -}
effectControl2LSB         = toEnum 0x2D  {-  45 2D -}

generalPurpose1LSB        = toEnum 0x30  {-  48 30 -}
generalPurpose2LSB        = toEnum 0x31  {-  49 31 -}
generalPurpose3LSB        = toEnum 0x32  {-  50 32 -}
generalPurpose4LSB        = toEnum 0x33  {-  51 33 -}

sustain                   = toEnum 0x40  {-  64 40 -}
portamento                = toEnum 0x41  {-  65 41 -}
sustenuto                 = toEnum 0x42  {-  66 42 -}
softPedal                 = toEnum 0x43  {-  67 43 -}
legato                    = toEnum 0x44  {-  68 44 -}
hold2                     = toEnum 0x45  {-  69 45 -}
soundController1          = toEnum 0x46  {-  70 46 -}
soundController2          = toEnum 0x47  {-  71 47 -}
soundController3          = toEnum 0x48  {-  72 48 -}
soundController4          = toEnum 0x49  {-  73 49 -}
soundController5          = toEnum 0x4A  {-  74 4A -}
soundController6          = toEnum 0x4B  {-  75 4B -}
soundController7          = toEnum 0x4C  {-  76 4C -}
soundController8          = toEnum 0x4D  {-  77 4D -}
soundController9          = toEnum 0x4E  {-  78 4E -}
soundController10         = toEnum 0x4F  {-  79 4F -}

generalPurpose5           = toEnum 0x50  {-  80 50 -}
generalPurpose6           = toEnum 0x51  {-  81 51 -}
generalPurpose7           = toEnum 0x52  {-  82 52 -}
generalPurpose8           = toEnum 0x53  {-  83 53 -}
portamentoControl         = toEnum 0x54  {-  84 54 -}
effect1Depth              = toEnum 0x5B  {-  91 5B -}
effect2Depth              = toEnum 0x5C  {-  92 5C -}
effect3Depth              = toEnum 0x5D  {-  93 5D -}
effect4Depth              = toEnum 0x5E  {-  94 5E -}
effect5Depth              = toEnum 0x5F  {-  95 5F -}

dataIncrement             = toEnum 0x60  {-  96 60 -}
dataDecrement             = toEnum 0x61  {-  97 61 -}
nonRegisteredParameterLSB = toEnum 0x62  {-  98 62 -}
nonRegisteredParameterMSB = toEnum 0x63  {-  99 63 -}
registeredParameterLSB    = toEnum 0x64  {- 100 64 -}
registeredParameterMSB    = toEnum 0x65  {- 101 65 -}