From c3fdb11e659b1483210f6733dd0e68992068de35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=27=C3=A9lectron=20rare?= <108685187+electron-rare@users.noreply.github.com> Date: Sat, 27 Jun 2026 20:09:22 +0200 Subject: [PATCH] fix(sound): filter sweep + edge-trigger gestures --- sound_algo/data_only/concert_fx.scd | 16 ++++++++++++++-- sound_algo/data_only/concert_gestures.scd | 8 ++++---- sound_algo/data_only/scene_concert.scd | 5 ++++- 3 files changed, 22 insertions(+), 7 deletions(-) diff --git a/sound_algo/data_only/concert_fx.scd b/sound_algo/data_only/concert_fx.scd index c6e86c2..45c17da 100644 --- a/sound_algo/data_only/concert_fx.scd +++ b/sound_algo/data_only/concert_fx.scd @@ -30,10 +30,22 @@ SynthDef(\cc_ev_swell, { |out=0, revOut, amp=0.3| s.sync; ~ccStutter = nil; ~ccMaster = ( - filterTo: { |cut=20000, time=0.3| ~doFilter !? { |f| f.set(\cutoff, cut.clip(120, 20000)) } }, + filterTo: { |cut=20000, time=0.3| + ~doFilter !? { |f| + var from = ~ccCutNow ? 20000; + var tgt = cut.clip(120, 20000); + var steps = (time * 30).max(1).round.asInteger; + ~ccCutRamp !? { |r| r.stop }; + ~ccCutNow = tgt; + ~ccCutRamp = Routine({ + steps.do { |i| f.set(\cutoff, from.blend(tgt, (i + 1) / steps)); (time / steps).wait }; + }).play(AppClock); + }; + }, dip: { ~doFilter !? { |f| + ~ccCutRamp !? { |r| r.stop }; f.set(\cutoff, 300); - AppClock.sched(0.18, { f.set(\cutoff, 20000); nil }); } }, + AppClock.sched(0.18, { f.set(\cutoff, 20000); ~ccCutNow = 20000; nil }); } }, stutterOn: { |dur=0.6| ~doMaster !? { |m| ~ccStutter ?? { ~ccStutter = Synth.before(m, \cc_master_stutter, [\out, 0, \mix, 0]) }; diff --git a/sound_algo/data_only/concert_gestures.scd b/sound_algo/data_only/concert_gestures.scd index f67e1ba..8cc497d 100644 --- a/sound_algo/data_only/concert_gestures.scd +++ b/sound_algo/data_only/concert_gestures.scd @@ -48,10 +48,10 @@ var meanY = { |a, b| (((a ? ())[\y] ? 0.5) + ((b ? ())[\y] ? 0.5)) * 0.5 }; fire: { ~ccFire.(\swell) })); // --- harmony family --- -~ccGestureAdd.((name:\stepR, family:\harmony, hold:0.5, cooldown:1.0, +~ccGestureAdd.((name:\stepR, family:\harmony, edge: true, hold:0.5, cooldown:1.0, detect: { |pose, prev| (pose[\center][\cx] ? 0.5) > 0.70 }, fire: { ~ccHarmony[\root] = (~ccHarmony[\root] + 2).clip(33, 57) })); -~ccGestureAdd.((name:\stepL, family:\harmony, hold:0.5, cooldown:1.0, +~ccGestureAdd.((name:\stepL, family:\harmony, edge: true, hold:0.5, cooldown:1.0, detect: { |pose, prev| (pose[\center][\cx] ? 0.5) < 0.30 }, fire: { ~ccHarmony[\root] = (~ccHarmony[\root] - 2).clip(33, 57) })); ~ccGestureAdd.((name:\leanFwd, family:\harmony, hold:0.4, cooldown:1.0, @@ -62,7 +62,7 @@ var meanY = { |a, b| (((a ? ())[\y] ? 0.5) + ((b ? ())[\y] ? 0.5)) * 0.5 }; detect: { |pose, prev| var s=pose[\skel]; s.notNil and: { ((((s[\shL] ? ())[\y]?0.35)+((s[\shR] ? ())[\y]?0.35))*0.5) > (((((s[\hipL] ? ())[\y]?0.6)+((s[\hipR] ? ())[\y]?0.6))*0.5) - 0.20) } }, fire: { ~ccHarmony[\pad] = \dark })); -~ccGestureAdd.((name:\tilt, family:\harmony, hold:0.4, cooldown:1.2, +~ccGestureAdd.((name:\tilt, family:\harmony, edge: true, hold:0.4, cooldown:1.2, detect: { |pose, prev| var s=pose[\skel]; s.notNil and: { var mid = ((((s[\shL] ? ())[\x]?0.4)+((s[\shR] ? ())[\x]?0.6))*0.5); (((s[\nose] ? ())[\x]?0.5) - mid).abs > 0.06 } }, @@ -71,7 +71,7 @@ var meanY = { |a, b| (((a ? ())[\y] ? 0.5) + ((b ? ())[\y] ? 0.5)) * 0.5 }; ~ccHarmony[\scale] = keys.wrapAt(i + 1) })); // --- melody family --- -~ccGestureAdd.((name:\armRaise, family:\melody, hold:0.4, cooldown:1.0, +~ccGestureAdd.((name:\armRaise, family:\melody, edge: true, hold:0.4, cooldown:1.0, detect: { |pose, prev| var s=pose[\skel]; var w=~poseWrist.notNil.if({~poseWrist.values.detect({|v| v.notNil})}); (s.notNil and: { w.notNil }) and: { diff --git a/sound_algo/data_only/scene_concert.scd b/sound_algo/data_only/scene_concert.scd index f83802a..7e6ea60 100644 --- a/sound_algo/data_only/scene_concert.scd +++ b/sound_algo/data_only/scene_concert.scd @@ -52,8 +52,11 @@ var on = g[\detect].(pose, prev) == true; if(on) { if(st[\holdT] <= 0) { st[\holdT] = now }; + // edge gestures fire once on the false->true transition (re-arm + // only after the detect drops); held gestures re-fire per cooldown. if(((now - st[\holdT]) >= (g[\hold] ? 0)) - and: { (now - st[\lastFire]) > (g[\cooldown] ? 0.5) }) { + and: { (now - st[\lastFire]) > (g[\cooldown] ? 0.5) } + and: { (g[\edge] != true) or: { st[\fired].not } }) { st[\lastFire] = now; st[\holdT] = now; st[\fired] = true; g[\fire].(); };