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
|
import Op, Value, ValueInput, EventInput, ColdInput, match
from require 'core.base'
all_same = (list) ->
for v in *list[2,]
if v != list[1]
return false
list[1]
class switch_ extends Op
@doc: "(switch i v0 [v1 v2...]) - switch between multiple inputs
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 (floor)ed and the matching argument (starting from 0) is reproduced."
setup: (inputs) =>
{ i, values } = match 'any *any', inputs
i_type = i\type!
assert i_type == 'bool' or i_type == 'num', "#{@}: i has to be bool or num"
typ = all_same [v\type! for v in *values]
@out = Value typ
super
i: ValueInput i
values: [ValueInput 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!
--class switch_pause extends Op
-- @doc: "(switch- i v0 [v1 v2...]) - switch and pause multiple inputs
--
--like (switch ...) except that the unused inputs are paused."
--
-- setup: (@i, ...) =>
-- @choices = { ... }
--
-- typ = @choices[1].type
-- for inp in *@choices[2,]
-- assert inp.type == typ, "not all values have the same type: #{typ} != #{inp.type}"
--
-- @out = Stream typ
-- @out
--
-- tick: =>
-- i = @i\unwrap!
-- active = switch i
-- when true
-- @choices[1]
-- when false
-- @choices[2]
-- else
-- i = 1 + (math.floor i) % #@choices
-- @choices[i]
--
-- @out\set if active
-- active\unwrap!
class edge extends Op
@doc: "(edge bool) - convert rising edges to bangs"
new: => super 'bang'
setup: (inputs) =>
{ value } = match 'bool', inputs
super value: EventInput
tick: =>
now = @inputs.value!
if now and not @last
@out\set true
@last = now
class default extends Op
@doc: "(default stream default) - provide a default value for an event stream
starts out as default but forwards events from stream.
default defaults to zero."
setup: (params) =>
{ value, init } = match 'any any', inputs
super
value: EventInput value
init: ColdInput init
@out = Value value\type!
@out\set @inputs.init\unwrap!
tick: =>
{ :value } = @inputs
if value\dirty!
@out\set value!
{
'switch': switch_
:edge
:default
}
|