aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authors-ol <s-ol@users.noreply.github.com>2020-07-11 17:12:01 +0000
committers-ol <s+removethis@s-ol.nu>2025-03-02 14:24:49 +0000
commit372c11a884ead1eb07d9b86fcb8b2ac5807dd1fb (patch)
treed10f63e5ce908cd04f7b2b16f8be3fec1db63693
parentmove util/switch to builtins (diff)
downloadalive-372c11a884ead1eb07d9b86fcb8b2ac5807dd1fb.tar.gz
alive-372c11a884ead1eb07d9b86fcb8b2ac5807dd1fb.zip
rename time/sequence to time/val-seq and add time/bang-seq
-rw-r--r--alv-lib/rhythm.moon10
-rw-r--r--alv-lib/time.moon87
2 files changed, 71 insertions, 26 deletions
diff --git a/alv-lib/rhythm.moon b/alv-lib/rhythm.moon
index 19dbdeb..770bd48 100644
--- a/alv-lib/rhythm.moon
+++ b/alv-lib/rhythm.moon
@@ -52,16 +52,16 @@ When fed a num~ or num! stream, outputs a bang if the corresponding step is on."
@out or= T.bang\mk_evt!
+ if trig\type! == T.bang
+ @state or= 1
+ else
+ @state = nil
+
super
trig: Input.hot trig
n: Input.cold n
k: Input.cold k
- if @inputs.trig\type! == T.bang
- @state or= 1
- else
- @state = nil
-
tick: =>
{ :trig, :n, :k } = @unwrap_all!
diff --git a/alv-lib/time.moon b/alv-lib/time.moon
index 09cc068..daa14ad 100644
--- a/alv-lib/time.moon
+++ b/alv-lib/time.moon
@@ -26,12 +26,12 @@ clock = Constant.meta
name: 'clock'
summary: "Create a clock source."
examples: { '(clock)', '(clock fps)' }
- description: "Creates a new clock event stream.
+ description: "Creates a new `time/clock!` stream.
The clock event stream is an IO that triggers other operators at a fixed
frame rate.
-- `fps` has to be an eval-time constant and defaults to `60` if omitted."
+- `fps` has to be a num= constant and defaults to `60` if omitted."
value: class extends Op
new: (...) =>
super ...
@@ -52,9 +52,9 @@ scale_time = Constant.meta
examples: { '(scale-time [clock] scale)' }
description: "Creates a new clock event stream scaled by `scale`.
-- `clock` should be a `time/clock` event stream. This argument can be omitted
+- `clock` should be a `time/clock!` stream. This argument can be omitted
and the stream be passed as a dynamic definition in `*clock*` instead.
-- `scale` should be a num-value."
+- `scale` should be a num~ stream."
value: class extends Op
new: (...) =>
super ...
@@ -78,9 +78,9 @@ lfo = Constant.meta
examples: { '(lfo [clock] freq [wave])' }
description: "Oscillates betwen `0` and `1` at the frequency `freq`.
-- `clock` should be a `time/clock` event stream. This argument can be omitted
+- `clock` should be a `time/clock!` stream. This argument can be omitted
and the stream be passed as a dynamic definition in `*clock*` instead.
-- `freq` should be a num-value.
+- `freq` should be a num~ stream.
- `wave` selects the wave shape from one of the following:
- `'sin'` (the default)
- `'saw'`
@@ -118,10 +118,10 @@ ramp = Constant.meta
examples: { '(ramp [clock] period [max])' }
description: "Ramps from `0` to `max` once every `period` seconds.
-- `clock` should be a `time/clock` event stream. This argument can be omitted
+- `clock` should be a `time/clock!` stream. This argument can be omitted
and the stream be passed as a dynamic definition in `*clock*` instead.
-- `period` should be a num-value.
-- `max` should be a num-value and defaults to `period` if omitted."
+- `period` should be a num~ stream.
+- `max` should be a num~ stream and defaults to `period` if omitted."
value: class extends Op
new: (...) =>
super ...
@@ -153,10 +153,10 @@ tick = Constant.meta
examples: { '(tick [clock] period)' }
description: "Counts upwards by one every `period` seconds.
-- `clock` should be a `time/clock` event stream. This argument can be omitted
+- `clock` should be a `time/clock!` stream. This argument can be omitted
and the stream be passed as a dynamic definition in `*clock*` instead.
-- `period` should be a num-value.
-- returns a `num` value that increases by 1 every `period`."
+- `period` should be a num~ stream.
+- returns a `num~` stream that increases by 1 every `period`."
value: class extends Op
new: (...) =>
super ...
@@ -185,9 +185,9 @@ every = Constant.meta
examples: { '(every [clock] period [evt])' }
description: "Emits `evt` as an event once every `period` seconds.
-- `clock` should be a `time/clock` event stream. This argument can be omitted
+- `clock` should be a `time/clock!` stream. This argument can be omitted
and the stream be passed as a dynamic definition in `*clock*` instead.
-- `period` should be a num-value.
+- `period` should be a num~ stream.
- `evt` can be a value of any type. It defaults to `bang`.
- the return type will be an event stream with the same type as `evt`."
value: class extends Op
@@ -211,18 +211,18 @@ every = Constant.meta
@state -= 1
@out\set @inputs.evt!
-sequence = Constant.meta
+val_seq = Constant.meta
meta:
- name: 'sequence'
+ name: 'val-seq'
summary: "Emit a sequence of values as events over time."
- examples: { '(sequence [clock] delay0 evt1 delay1 evt2 delay2…)' }
+ examples: { '(val-seq [clock] delay0 evt1 delay1 evt2 delay2…)' }
description: "
Emits `evt1`, `evt2`, … as events with delays `delay0`, `delay1`, … in between.
-- `clock` should be a `time/clock` event stream. This argument can be omitted
+- `clock` should be a `time/clock!` stream. This argument can be omitted
and the stream be passed as a dynamic definition in `*clock*` instead.
-- `delay0`, `delay1`, … must be num-values.
-- `evt1`, `evt2`, … must be values of the same type.
+- `delay0`, `delay1`, … must be num~ streams.
+- `evt1`, `evt2`, … must be signal streams of the same type.
- the return type will be an event stream with the same type as the `evt`s."
value: class extends Op
new: (...) =>
@@ -263,6 +263,49 @@ Emits `evt1`, `evt2`, … as events with delays `delay0`, `delay1`, … in betwe
if current.value and (change or current.value\dirty!)
@out\set current.value!
+bang_seq = Constant.meta
+ meta:
+ name: 'bang-seq'
+ summary: "Generate rhythms based on a sequence of delays"
+ examples: { '(bang-seq [clock] delay0 delay1…)' }
+ description: "
+Emits `bang!`s with delays `delay0`, `delay1`, … in between.
+
+- `clock` should be a `time/clock!` stream. This argument can be omitted
+ and the stream be passed as a dynamic definition in `*clock*` instead.
+- `delay0`, `delay1`, … must be num~ streams."
+
+ value: class extends Op
+ new: (...) =>
+ super ...
+ @out = T.bang\mk_evt!
+ @state or= { i: 1, t: 0 }
+
+ pattern = -evt.clock + sig.num*0
+ setup: (inputs, scope) =>
+ { clock, steps } = pattern\match inputs
+
+ super
+ clock: Input.hot clock or scope\get '*clock*'
+ steps: [Input.cold step for step in *steps]
+
+ tick: =>
+ if tick = @inputs.clock!
+ @state.t += tick.dt
+
+ bang = false
+ while true
+ current = @inputs.steps[@state.i]!
+ if @state.t >= current
+ @state.t -= current
+ @state.i = 1 + (@state.i % #@inputs.steps)
+ bang = true
+ else
+ break
+
+ if bang
+ @out\set true
+
{
:clock
'scale-time': scale_time
@@ -270,7 +313,9 @@ Emits `evt1`, `evt2`, … as events with delays `delay0`, `delay1`, … in betwe
:ramp
:tick
:every
- :sequence
+ 'val-seq': val_seq
+ 'bang-seq': bang_seq
+
'*clock*': with Clock 1/60
.meta =
name: '*clock*'