-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgamme.ml
178 lines (149 loc) · 4.62 KB
/
gamme.ml
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
(* type t = { dominante: Note.t; nom:Note.t -> string; ecarts: int list } *)
module type Spec =
sig
val dominante: Note.t
val nom:Note.t -> string
val ecarts: int list
end
module type Note =
sig
val n: Note.t
end
module MakeGammeMajeure(N:Note): Spec = struct
let dominante = N.n
let nom x = Note.to_string x^" Majeure"
let ecarts = [2;2;1;2;2;2;1]
end
module MakeGammeMineure(N:Note): Spec = struct
let dominante = N.n
let nom x = Note.to_string x^" Mineure"
let ecarts = [2;1;2;2;1;2;2]
end
module MakeGammePentaMajeure(N:Note): Spec = struct
let dominante = N.n
let nom x = Note.to_string x^" PentaM"
let ecarts = [2;2;3;2;3]
end
module MakeGammePentaMineure(N:Note): Spec = struct
let dominante = N.n
let nom x = Note.to_string x^" Pentam"
let ecarts = [3;2;2;3;2]
end
module MakeGammeBlues(N:Note): Spec = struct
let dominante = N.n
let nom x = Note.to_string x^" Blues"
let ecarts = [3;2;1;1;3;2]
end
module MakeGammeChromatique(N:Note): Spec = struct
let dominante = N.n
let nom x = Note.to_string x^" chromatique"
let ecarts = [1;1;1;1;1;1;1;1;1;1;1;1]
end
module type S = sig
include Spec
val map: (Note.t -> 'a) -> 'a list
val exists: (Note.t -> bool) -> bool
val for_all: (Note.t -> bool) -> bool
val iter: (Note.t -> unit) -> unit
val pr: Format.formatter -> unit -> unit
val next: Note.t -> Note.t
val interv: Note.t -> int -> Note.t
val seconde: Note.t -> Note.t
val tierce: Note.t -> Note.t
val quarte: Note.t -> Note.t
val quinte: Note.t -> Note.t
val sixte: Note.t -> Note.t
val septieme: Note.t -> Note.t
val octave: Note.t -> Note.t
end
(* g should contain the interval. By doubling a standard gamme we
should capture all interval until the octave. *)
let extract_interv_notes g note interv = Pp.prefix interv (Pp.remove_before note g)
module MakeGamme(G:Spec): S = struct
include G
let gamme_ =
let rec gen dom n l =
match l with
| [] -> []
| i::l' -> n:: gen dom (Note.decale_chrom n i) l'
in
gen G.dominante G.dominante G.ecarts
let degres = List.mapi (fun i n -> (n,i)) gamme_
(* 2 = seconde, 3 = tierce, ... *)
let interv note n =
let lnotes =
try
if n > 0 then extract_interv_notes (degres@degres) note n
else if n < 0 then extract_interv_notes (List.rev (degres@degres)) note (-n)
else assert false
with Not_found ->
let msg = "Note non présente dans la gamme "^(G.nom G.dominante)
^": "^Note.to_string note in
failwith msg
in
fst (Pp.last lnotes)
let next note = interv note 2
let map f = List.map f gamme_
let exists f = List.exists f gamme_
let for_all f = List.for_all f gamme_
let iter f = List.iter f gamme_
let pr fmt () =
let notes = map (fun x -> x) in
let notes_octave = notes@[List.hd notes] in
Format.fprintf fmt "%a@.@?" Note.pr_l notes_octave
let seconde note = interv note 2
let tierce note = interv note 3
let quarte note = interv note 4
let quinte note = interv note 5
let sixte note = interv note 6
let septieme note = interv note 7
let octave note = interv note 8
end
module M(N:Note) (MG:Note -> Spec): S = struct
module Spec = MG(N)
include Spec
module M = MakeGamme(Spec)
include M
end
module Majeure(N:Note): S = M(N)(MakeGammeMajeure)
module Mineure(N:Note): S = M(N)(MakeGammeMineure)
module Chromatique(N:Note): S = M(N)(MakeGammeChromatique)
module PentaMajeure(N:Note): S = M(N)(MakeGammePentaMajeure)
module PentaMineure(N:Note): S = M(N)(MakeGammePentaMineure)
module Blues(N:Note): S = M(N)(MakeGammeBlues)
type gammeStandard =
Majeur of Note.t
| Mineur of Note.t
| PentaM of Note.t
| Pentam of Note.t
| Blues of Note.t
let parseName n s =
match s with
| "blues" | "Blues" -> Blues n
| "pentam" | "Pentam" -> Pentam n
| "pentaM" | "PentaM" -> PentaM n
| "majeure" | "Majeure" | "majeur" | "Majeur" -> Majeur n
| "mineure" | "Mineure" | "mineur" | "Mineur" -> Mineur n
| _ -> raise Not_found
let gen_gamme(g:gammeStandard): (module S) =
match g with
| Majeur dom ->
let module Ggg = struct let n = dom end in
let module Gg:S = Majeure(Ggg) in
(module Gg: S)
| Mineur dom ->
let module Ggg = struct let n = dom end in
let module Gg = Mineure(Ggg) in
(module Gg: S)
| PentaM dom ->
let module Ggg = struct let n = dom end in
let module Gg = PentaMajeure(Ggg) in
(module Gg: S)
| Pentam dom ->
let module Ggg = struct let n = dom end in
let module Gg = PentaMineure(Ggg) in
(module Gg: S)
| Blues dom ->
let module Ggg = struct let n = dom end in
let module Gg = Blues(Ggg) in
(module Gg: S)