-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathScale.purs
83 lines (69 loc) · 2.56 KB
/
Scale.purs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
module Backend.Scale (
Scale(..)
, scaleNotes
-- * Specification
, ScaleSpec
, defaultSpec
, renderSpec
) where
import Prelude
import Data.Generic.Rep (class Generic)
import Data.List (List, (:), fromFoldable)
import Data.Show.Generic (genericShow)
import MaxForLive.Conversions (class ToMax, class FromMax, class SimpleEnum)
import MaxForLive.Conversions as C
import Backend.Note (Note(..), InOctave(..))
import Backend.Note as N
{-------------------------------------------------------------------------------
Scales
-------------------------------------------------------------------------------}
data Scale =
Kurd9
| Hijaz
| Pelog
| Integral
| CelticMinor
derive instance genericScale :: Generic Scale _
instance showScale :: Show Scale where show = genericShow
instance fromMaxScale :: FromMax Scale where fromMax = C.maxToEnum
instance toMaxScale :: ToMax Scale where toMax = C.maxFromEnum
instance simpleEnumScale :: SimpleEnum Scale where
toSimpleEnum = C.genericToSimpleEnum
fromSimpleEnum = C.genericFromSimpleEnum
{-------------------------------------------------------------------------------
Notes in a scale
-------------------------------------------------------------------------------}
-- | Notes in the scale
--
-- The root note of the scale here doesn't matter, whatever is convenient.
-- We will anyway transpose it up or down as required.
scaleNotes :: Scale -> Array Note
scaleNotes Kurd9 = [ A , As , C , D , E , F , G , A , C ]
scaleNotes Hijaz = [ D , Ds , Fs , G , A , As , C , D ]
scaleNotes Pelog = [ A , As , C , E , F , A , As , C ]
scaleNotes Integral = [ A , As , C , D , E , F , A ]
scaleNotes CelticMinor = [ A , C , D , E , F , G , A , C ]
{-------------------------------------------------------------------------------
Specification of the scale of a handpan
-------------------------------------------------------------------------------}
type ScaleSpec = { scale :: Scale, doum :: InOctave, root :: InOctave }
-- | Default spec
--
-- These match the default in the patcher.
defaultSpec :: ScaleSpec
defaultSpec = {
scale: Kurd9
, doum: InOctave { octave: 3, note: C }
, root: InOctave { octave: 3, note: C }
}
-- | Rendering a spec
renderSpec :: ScaleSpec -> List InOctave
renderSpec { scale, doum, root } =
doum : render (scaleNotes scale)
where
render :: Array Note -> List InOctave
render =
fromFoldable
>>> map (\n -> InOctave { octave: 0, note: n })
>>> N.monotonic
>>> N.startWith root