Repository navigation
Expand file tree
/
Copy pathScales.hs
More file actions
244 lines (187 loc) · 8.46 KB
/
Copy pathScales.hs
File metadata and controls
244 lines (187 loc) · 8.46 KB
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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
{-# LANGUAGE GADTs,
MultiParamTypeClasses #-}
module Scales where
import Music (Scale(..),
AbstractPitch1(..), AbstractInt1(..),
AbstractPitch2(..), AbstractInt2(..),
Interval(..), Pitch(..), Transpose(..),
faInt, faPitch,
Name(..), Number(..), Quality(..), Accidental(..), Ficta(..))
import Shortcuts
import Util (rotate, rotateN)
data GenericScale where
GenericScale :: Scale s p i => s -> GenericScale
-- todo: represent/enforce scale length(s) with type-level Nats.
-- todo: make the basic scale type a list of *intervals* (not pitches). e.g. baseMajor = [M2, M2, m2, M2, M2, M2, m2] etc.
ficToAcc Raise = sharpen
ficToAcc Neutral = id
ficToAcc Lower = flatten
completeScale s i = let c = if i >= 0
then scale s ++
map (transpose (AbstractInt2 Perf (Compound Unison))) c
else map (transpose (AbstractInt2 Perf (Negative (Compound Unison)))) (reverse (scale s)) ++
map (transpose (AbstractInt2 Perf (Negative (Compound Unison)))) c
in if i >= 0
then c
else (head (scale s)) : c
infiniteScale s = completeScale s 1
scaleDegree s (AbstractPitch1 deg fic) =
let i = fromEnum deg
index = abs i
note = (completeScale s i) !! index
in (ficToAcc fic) note
-- Ionian | Hypoionian | Aeolian | Hypoaeolian | Dorian | Phrygian | Lydian | Mixolydian | Hypodorian | Hypophrygian | Hypolydian | Hypomixolydian | Locrian | Hypolocrian
transposeScale orig base new = let offset = interval base new
in map (transpose offset) orig
-- Diatonic:
basicIonian = map (\n -> AbstractPitch2 n Na) [C .. ]
data Ionian = Ionian AbstractPitch2 deriving Show
type Major = Ionian
instance Scale Ionian AbstractPitch1 AbstractInt1 where
tonic (Ionian t) = t
scale s = take 7 $ transposeScale basicIonian (AbstractPitch2 C Na) (tonic s)
applyScale = scaleDegree
data Dorian = Dorian AbstractPitch2 deriving Show
instance Scale Dorian AbstractPitch1 AbstractInt1 where
tonic (Dorian t) = t
scale s = take 7 $ transposeScale (rotate basicIonian) (AbstractPitch2 D Na) (tonic s)
applyScale = scaleDegree
data Phrygian = Phrygian AbstractPitch2 deriving Show
instance Scale Phrygian AbstractPitch1 AbstractInt1 where
tonic (Phrygian t) = t
scale s = take 7 $ transposeScale ((rotateN 2) basicIonian) (AbstractPitch2 E Na) (tonic s)
applyScale = scaleDegree
data Lydian = Lydian AbstractPitch2 deriving Show
instance Scale Lydian AbstractPitch1 AbstractInt1 where
tonic (Lydian t) = t
scale s = take 7 $ transposeScale ((rotateN 3) basicIonian) (AbstractPitch2 F Na) (tonic s)
applyScale = scaleDegree
data Mixolydian = Mixolydian AbstractPitch2 deriving Show
instance Scale Mixolydian AbstractPitch1 AbstractInt1 where
tonic (Mixolydian t) = t
scale s = take 7 $ transposeScale ((rotateN 4) basicIonian) (AbstractPitch2 G Na) (tonic s)
applyScale = scaleDegree
data Aeolian = Aeolian AbstractPitch2 deriving Show
type Minor = Aeolian
instance Scale Aeolian AbstractPitch1 AbstractInt1 where
tonic (Aeolian t) = t
scale s = take 7 $ transposeScale ((rotateN 5) basicIonian) (AbstractPitch2 A Na) (tonic s)
applyScale = scaleDegree
data Locrian = Locrian AbstractPitch2 deriving Show
instance Scale Locrian AbstractPitch1 AbstractInt1 where
tonic (Locrian t) = t
scale s = take 7 $ transposeScale ((rotateN 6) basicIonian) (AbstractPitch2 B Na) (tonic s)
applyScale = scaleDegree
-- Melodic minor scales:
basicMelodicMinor = [AbstractPitch2 C Na,
AbstractPitch2 D Na,
AbstractPitch2 E flat,
AbstractPitch2 F Na,
AbstractPitch2 G Na,
AbstractPitch2 (Up A) Na,
AbstractPitch2 (Up B) Na] ++ map (transpose (AbstractInt2 Perf (Compound Unison))) basicMelodicMinor
data MelodicMinor = MelodicMinor AbstractPitch2 deriving Show
instance Scale MelodicMinor AbstractPitch1 AbstractInt1 where
tonic (MelodicMinor t) = t
scale s = take 7 $ transposeScale basicMelodicMinor (AbstractPitch2 C Na) (tonic s)
applyScale = scaleDegree
-- Harmonic major scales:
basicHarmonicMajor = [AbstractPitch2 C Na,
AbstractPitch2 D Na,
AbstractPitch2 E Na,
AbstractPitch2 F Na,
AbstractPitch2 G Na,
AbstractPitch2 (Up A) flat,
AbstractPitch2 (Up B) Na] ++ map (transpose (AbstractInt2 Perf (Compound Unison))) basicHarmonicMajor
-- Harmonic minor scales:
basicHarmonicMinor = [AbstractPitch2 C Na,
AbstractPitch2 D Na,
AbstractPitch2 E flat,
AbstractPitch2 F Na,
AbstractPitch2 G Na,
AbstractPitch2 (Up A) flat,
AbstractPitch2 (Up B) Na] ++ map (transpose (AbstractInt2 Perf (Compound Unison))) basicHarmonicMinor
data AlteredPhrygian = AlteredPhrygian AbstractPitch2 deriving Show
instance Scale AlteredPhrygian AbstractPitch1 AbstractInt1 where
tonic (AlteredPhrygian t) = t
scale s = take 7 $ transposeScale (rotateN 4 basicHarmonicMinor) (AbstractPitch2 G Na) (tonic s)
applyScale = scaleDegree
data HarmonicMinor = HarmonicMinor AbstractPitch2 deriving Show
instance Scale HarmonicMinor AbstractPitch1 AbstractInt1 where
tonic (HarmonicMinor t) = t
scale s = take 7 $ transposeScale basicHarmonicMinor (AbstractPitch2 C Na) (tonic s)
applyScale = scaleDegree
-- Double harmonic scales:
basicDoubleHarmonic = [AbstractPitch2 C Na,
AbstractPitch2 D flat,
AbstractPitch2 E Na,
AbstractPitch2 F Na,
AbstractPitch2 G Na,
AbstractPitch2 (Up A) flat,
AbstractPitch2 (Up B) Na] ++ map (transpose (AbstractInt2 Perf (Compound Unison))) basicDoubleHarmonic
major :: AbstractPitch2 -> Major
major n = Ionian n
minor :: AbstractPitch2 -> Minor
minor n = Aeolian (n .-^ octave)
harmonicminor :: AbstractPitch2 -> HarmonicMinor
harmonicminor n = HarmonicMinor n
melodicminor :: AbstractPitch2 -> MelodicMinor
melodicminor n = MelodicMinor n
chromaticScale p@(AbstractPitch2 n a)
| (n == B) || (n == E) || (a == sharp) = p:(chromaticScale (AbstractPitch2 (succ n) Na))
| otherwise = p:(chromaticScale (AbstractPitch2 n sharp))
-- Modal:
-- modeII = [(D, Na), (E, Na), (F, Na), (G, Na), (A, Na), (B, Na), (C, Na)]
-- modeIII
-- modeIV
-- modeV
-- modeVI
-- modeVII
-- modeVIII
-- Messiaen's scales:
-- mode1 = [2,2,2,2,2]
-- mode2 = [1,2, 1,2, 1,2, 1,2]
-- mode3 = [2,1,1, 2,1,1, 2,1,1]
-- mode4 = [1,1,3,1, 1,1,3,1]
-- mode5 = [1,4,1, 1,4,1]
-- mode6 = [2,2,1,1, 2,2,1,1]
-- mode7 = [1,1,1,2,1, 1,1,1,2,1]
-- (measured in semitones)
hexachord :: AbstractPitch2 -> [AbstractPitch2]
hexachord p = [p, p .+^ _M2, p .+^ _M3, p .+^ _P4, p .+^ _P5, p .+^ _M6]
-- Guidonian Hexachords:
data HexachordPrima = HexachordPrima deriving Show
instance Scale HexachordPrima AbstractPitch1 AbstractInt1 where
tonic HexachordPrima = g .-^ (3 *^ _P8)
scale s = hexachord (tonic s)
applyScale = scaleDegree
data HexachordSecunda = HexachordSecunda deriving Show
instance Scale HexachordSecunda AbstractPitch1 AbstractInt1 where
tonic s = c .-^ (2 *^ _P8)
scale s = hexachord (tonic s)
applyScale = scaleDegree
data HexachordTertia = HexachordTertia deriving Show
instance Scale HexachordTertia AbstractPitch1 AbstractInt1 where
tonic s = f .-^ (2 *^ _P8)
scale s = hexachord (tonic s)
applyScale = scaleDegree
data HexachordQuarta = HexachordQuarta deriving Show
instance Scale HexachordQuarta AbstractPitch1 AbstractInt1 where
tonic s = g .-^ (2 *^ _P8)
scale s = hexachord (tonic s)
applyScale = scaleDegree
data HexachordQuinta = HexachordQuinta deriving Show
instance Scale HexachordQuinta AbstractPitch1 AbstractInt1 where
tonic s = c .-^ _P8
scale s = hexachord (tonic s)
applyScale = scaleDegree
data HexachordSexta = HexachordSexta deriving Show
instance Scale HexachordSexta AbstractPitch1 AbstractInt1 where
tonic s = f .-^ _P8
scale s = hexachord (tonic s)
applyScale = scaleDegree
data HexachordSeptima = HexachordSeptima deriving Show
instance Scale HexachordSeptima AbstractPitch1 AbstractInt1 where
tonic s = g .-^ _P8
scale s = hexachord (tonic s)
applyScale = scaleDegree