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
type stage = { fx : Effect.t; mutable on : bool }
type t = { mutable stages : stage list }
let create (effects : Effect.t list) : t = { stages = List.map (fun fx -> { fx; on = false }) effects }
let standard () : t =
create [ Drive.fx (); Eq.fx (); Modulation.fx (); Delay.fx (); Reverb.fx (); Dynamics.fx () ]
let prefixed (name : string) (knobs : Effect.knob list) : Effect.knob list =
{ name = name ^ ".on"; control = Switch; initial = 0. }
:: List.map (fun (k : Effect.knob) -> { k with name = name ^ "." ^ k.name }) knobs
let standard_knobs : Effect.knob list =
List.concat_map
(fun (name, knobs) -> prefixed name knobs)
[
("drive", Drive.knobs);
("eq", Eq.knobs);
("modulation", Modulation.knobs);
("delay", Delay.knobs);
("reverb", Reverb.knobs);
("dynamics", Dynamics.knobs);
]
let knobs (t : t) : Effect.knob list = List.concat_map (fun s -> prefixed s.fx.name s.fx.knobs) t.stages
let set (t : t) (name : string) (x : float) : unit =
match String.index_opt name '.' with
| None -> ()
| Some i ->
let stage = String.sub name 0 i and knob = String.sub name (i + 1) (String.length name - i - 1) in
List.iter
(fun s -> if s.fx.name = stage then if knob = "on" then s.on <- Control.on x else s.fx.set knob x)
t.stages
let order (t : t) : string list = List.map (fun s -> s.fx.name) t.stages
let reorder (t : t) (names : string list) : unit =
let named = List.filter_map (fun n -> List.find_opt (fun s -> s.fx.name = n) t.stages) names in
t.stages <- named @ List.filter (fun s -> not (List.memq s named)) t.stages
let process (t : t) (out : Signal.stereo) : unit = List.iter (fun s -> if s.on then s.fx.process out) t.stages
let meter (t : t) (name : string) : float =
List.find_map
(fun s -> List.find_map (fun (m, x) -> if s.fx.name ^ "." ^ m = name then Some x else None) (s.fx.meters ()))
t.stages
|> Option.value ~default:0.