diff options
| author | s-ol <s+removethis@s-ol.nu> | 2025-04-05 17:48:50 +0000 |
|---|---|---|
| committer | s-ol <s+removethis@s-ol.nu> | 2025-04-07 10:33:17 +0000 |
| commit | 7e3d7e1c273cd292a4e5b7184ee889ec08e1ce8a (patch) | |
| tree | 8cc3fbf368edb10c61dce399946e71fb385a6709 | |
| parent | template strings as syntax sugar for Ops (diff) | |
| download | alive-7e3d7e1c273cd292a4e5b7184ee889ec08e1ce8a.tar.gz alive-7e3d7e1c273cd292a4e5b7184ee889ec08e1ce8a.zip | |
lib: add link-time/spring
| -rw-r--r-- | alv-lib/link-time.moon | 65 |
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 |
