From ece67bf1fbe701c1496067949c93a7e710d7bc10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=27=C3=A9lectron=20rare?= <108685187+electron-rare@users.noreply.github.com> Date: Mon, 29 Jun 2026 18:01:51 +0200 Subject: [PATCH] feat(matrix): res modulation target --- sound_algo/data_only/matrix.scd | 18 ++++++++++++------ sound_algo/data_only/test/test_matrix.scd | 15 +++++++++++++++ 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/sound_algo/data_only/matrix.scd b/sound_algo/data_only/matrix.scd index 93eb823..3ef646b 100644 --- a/sound_algo/data_only/matrix.scd +++ b/sound_algo/data_only/matrix.scd @@ -28,12 +28,12 @@ ~matModTargets = ~matModTargets ? IdentityDictionary[ \kick->[\amp,\pan,\rev], \hats->[\amp,\pan,\rev], \clap->[\amp,\pan,\rev], \perc->[\amp,\cutoff,\pan,\rev], - \sub->[\amp,\pan,\rev], \acid->[\amp,\cutoff,\pan,\rev], \arp->[\amp,\cutoff,\pan,\rev], - \lead->[\amp,\cutoff,\pan,\rev], \stab->[\amp,\cutoff,\pan,\rev], \pad->[\amp,\cutoff,\pan,\rev], + \sub->[\amp,\pan,\rev,\res], \acid->[\amp,\cutoff,\pan,\rev,\res], \arp->[\amp,\cutoff,\pan,\rev,\res], + \lead->[\amp,\cutoff,\pan,\rev,\res], \stab->[\amp,\cutoff,\pan,\rev,\res], \pad->[\amp,\cutoff,\pan,\rev,\res], \ride->[\amp,\pan,\rev], \rim->[\amp,\pan,\rev], \tom->[\amp,\pan,\rev], - \reese->[\amp,\cutoff,\pan,\rev], - \bells->[\amp,\pan,\rev], \sweep->[\amp,\pan,\rev], - \melody->[\amp,\cutoff,\pan,\rev], \chord->[\amp,\cutoff,\pan,\rev], + \reese->[\amp,\cutoff,\pan,\rev,\res], + \bells->[\amp,\pan,\rev,\res], \sweep->[\amp,\pan,\rev], + \melody->[\amp,\cutoff,\pan,\rev,\res], \chord->[\amp,\cutoff,\pan,\rev,\res], \fx->[\amp,\pan,\rev], \snare->[\amp,\pan,\rev], \crash->[\amp,\pan,\rev], \shaker->[\amp,\pan,\rev] ]; @@ -181,13 +181,19 @@ File.exists(~matDir).not.if({ ("mkdir -p " ++ ~matDir.quote).systemCmd }); var a = 0; list.do { |b| a = a + (~matModSourceVal.(b[\source]) * b[\depth]) }; a.clip(0, 1) }] + }, { + (tgt == \res).if({ + pairs = pairs ++ [\res, Pfunc { + var a = 0; list.do { |b| a = a + (~matModSourceVal.(b[\source]) * b[\depth]) }; + a.clip(0, 1) + }] }, { pairs = pairs ++ [\amp, Pfunc { var base = (spec[\amp] ? 1.0) * volOf.value; list.do { |b| base = base * (1 + (b[\depth] * (~matModSourceVal.(b[\source]) * 2 - 1))).max(0) }; base }] - }) }) }) + }) }) }) }) }; pairs }; diff --git a/sound_algo/data_only/test/test_matrix.scd b/sound_algo/data_only/test/test_matrix.scd index b92ab9d..7146271 100644 --- a/sound_algo/data_only/test/test_matrix.scd +++ b/sound_algo/data_only/test/test_matrix.scd @@ -456,6 +456,21 @@ pass = pass and: { pf.notNil and: { (pf.asStream.next(()) - 0.4).abs < 0.001 } }; ~matVoiceMods[\acid] = []; +// --- res target (cycle 1) --- +// res: additive, two sources sum and clip 0..1 +~matVoiceMods[\acid] = [ (source: \rHandY, target: \res, depth: 0.5), + (source: \bodyY, target: \res, depth: 0.5) ]; +~matModCache[\rHandY] = 1.0; ~matModCache[\bodyY] = 1.0; // 1*0.5 + 1*0.5 = 1.0 (clip) +pass = pass and: { + var pairs, pf; + pairs = ~matModPairs.(\acid, (amp: 1.0), { 1.0 }); + pf = pairs[pairs.indexOf(\res) + 1]; + pf.notNil and: { (pf.asStream.next(()) - 1.0).abs < 0.001 } +}; +~matVoiceMods[\acid] = []; +// res target is gated to res-voices: ~matModTargets[\hats] must NOT include \res +pass = pass and: { (~matModTargets[\hats] ? []).includes(\res).not }; +pass = pass and: { (~matModTargets[\acid] ? []).includes(\res) }; // disallowed target: kick has no cutoff in ~matModTargets -> gated out ~matVoiceMods[\kick] = [ (source: \bodyY, target: \cutoff, depth: 1.0) ]; pass = pass and: { ~matModPairs.(\kick, (amp: 1.0), { 1.0 }).includes(\cutoff).not };