aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authors-ol <s+removethis@s-ol.nu>2025-04-05 17:48:50 +0000
committers-ol <s+removethis@s-ol.nu>2025-04-07 10:33:17 +0000
commit7e3d7e1c273cd292a4e5b7184ee889ec08e1ce8a (patch)
tree8cc3fbf368edb10c61dce399946e71fb385a6709
parenttemplate strings as syntax sugar for Ops (diff)
downloadalive-7e3d7e1c273cd292a4e5b7184ee889ec08e1ce8a.tar.gz
alive-7e3d7e1c273cd292a4e5b7184ee889ec08e1ce8a.zip
lib: add link-time/spring
-rw-r--r--alv-lib/link-time.moon65
1 files changed, 64 insertions, 1 deletions
diff --git a/alv-lib/link-time.moon b/alv-lib/link-time.moon
index 251ee6c..a043516 100644
--- a/alv-lib/link-time.moon
+++ b/alv-lib/link-time.moon
@@ -314,7 +314,7 @@ ad = Constant.meta
delta = 0
if trigger
- @state = -attack
+ @state = if attack > 0 then -attack else decay
elseif clock
return if @state == 0
@@ -341,6 +341,68 @@ ad = Constant.meta
vis: => type: 'bar', bar: @.out!
+spring = Constant.meta
+ meta:
+ name: 'spring'
+ summary: "Integrate impulses using easing"
+ examples: { '(spring [clock] evt0 [evt1…])' }
+ description: "
+Every arriving `evt` triggers an impulse that is integrated as `clock` ticks.
+Returns a num~ stream that starts at 0.
+
+- `clock` should be a `link/clock~` stream. This argument can be omitted
+ and the stream be passed as a dynamic definition in `*clock*` instead.
+- `evt!` are !-streams of structs.
+ The following struct keys can be specified:
+ - `amp`: amplitude of the impulse
+ - `dur`: duration of the impulse (beats)"
+
+ value: class extends Op
+ pattern = -evt['link/clock'] + evt!*0
+ setup: (inputs, scope) =>
+ { clock, events } = pattern\match inputs
+
+ super
+ clock: Input.hot clock or scope\get '*clock*'
+ events: [Input.hot e for e in *events]
+
+ @state or= { offset: 0, events: {} }
+ @setup_out '~', T.num, @state.offset
+
+ tick: =>
+ for inp in *@inputs.events
+ if evt = inp!
+ evt = {
+ i: 0
+ amp: evt.amp or 1
+ dur: evt.dur or 1
+ -- ease: evt.ease or "quad.out"
+ }
+ @state.events[evt] = true
+
+ if clock = @inputs.clock!
+ pre = clock.state\beat_at_time clock.time - clock.dt, 1
+ post = clock.state\beat_at_time clock.time, 1
+ delta = post - pre
+
+ accum = 0
+ for evt in pairs @state.events
+ evt.i += delta / evt.dur
+
+ if evt.i >= 1
+ @state.offset += evt.amp
+ @state.events[evt] = nil
+ elseif evt.i >= 0
+ t = evt.i
+
+ -- quad.out
+ -- t = 1 - t
+ -- t = 1 - t * t
+
+ accum += t * evt.amp
+
+ @out\set @state.offset + accum
+
Constant.meta
meta:
name: 'link-time'
@@ -355,3 +417,4 @@ Constant.meta
:phase
:decay
:ad
+ :spring