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
|
import Op, Value, Input, Error, match from require 'core.base'
all_same = (list) ->
for v in *list[2,]
if v != list[1]
return false
list[1]
switch_ = Value.meta
meta:
name: 'switch'
summary: "Switch between multiple inputs."
examples: { '(switch i v0 [v1 v2…])' }
description: "
- when `i` is `true`, the first value is reproduced.
- when `i` is `false`, the second value is reproduced.
- when `i` is a `num`, it is [math/floor][]ed and the matching argument
(indexed starting from 0) is reproduced."
value: class extends Op
setup: (inputs) =>
{ i, values } = match 'any *any', inputs
i_type = i\type!
assert i_type == 'bool' or i_type == 'num', Error 'argument', "i has to be bool or num"
typ = all_same [v\type! for v in *values]
@out = Value typ if not @out or typ != @out.type
super
i: Input.value i
values: [Input.value v for v in *values]
tick: =>
{ :i, :values } = @inputs
active = switch i!
when true
values[1]
when false
values[2]
else
i = 1 + (math.floor i!) % #values
values[i]
@out\set active and active!
route = Value.meta
meta:
name: 'route'
summary: "Route between multiple inputs."
examples: { '(route i v0 [e1 e2…])' }
description: "
- when `i` is `true`, the first event stream is reproduced.
- when `i` is `false`, the second event stream is reproduced.
- when `i` is a `num`, it is [math/floor][]ed and the matching argument
(indexed starting from 0) is reproduced."
value: class extends Op
setup: (inputs) =>
{ i, values } = match 'any *any', inputs
i_type = i\type!
assert i_type == 'bool' or i_type == 'num', Error 'argument', "i has to be bool or num"
typ = all_same [v\type! for v in *values]
@out = Value typ if not @out or typ != @out.type
super
i: Input.value i
values: [Input.value v for v in *values]
tick: =>
{ :i, :values } = @inputs
active = switch i!
when true
values[1]
when false
values[2]
else
i = 1 + (math.floor i!) % #values
values[i]
if active and active\dirty!
@out\set active!
route = Value.meta
meta:
name: 'edge'
summary: "Convert rising edges to bangs."
examples: { '(edge bool)' }
value: class extends Op
new: => super 'bang'
setup: (inputs) =>
{ value } = match 'bool', inputs
super value: Input.value value
tick: =>
now = @inputs.value!
if now and not @state.last
@out\set true
@state.last = now
{
'switch': switch_
:route
:edge
}
|