refactor(matrix): drop dead per-color mod API
CI build oscope-of / build-check (push) Has been cancelled

Remove 4 SC functions (matSetColorMod/Pose, matColorMod/PosePush),
2 web OSC handlers (/matrix/colormod /colorpose), and the test
blocks that called them. Superseded by per-voice system; OSCdefs
were already gone. Legacy field read paths and colorDef fields
preserved for preset migration.
This commit is contained in:
L'électron rare
2026-06-29 17:00:24 +02:00
parent 5063e5929a
commit 8daad4040b
3 changed files with 2 additions and 120 deletions
-57
View File
@@ -772,63 +772,6 @@ OSCdef(\mat_steps_get, { |msg, time, addr|
}
};
// -- ~matSetColorMod : set/clear a color's capture effect; validate; re-source; echo --
~matSetColorMod = { |vi, color, source, target, depth|
((vi >= 0 and: { vi < ~matVoices.size }) and: { color >= 1 and: { color <= 6 } }).if({
var name = ~matVoices[vi];
var src = ((source == \none) or: { source.isNil }).if({ nil }, { source.asSymbol });
var tgt = ((target == \none) or: { target.isNil }).if({ nil }, { target.asSymbol });
var d = (depth ? 0).asFloat.clip(0, 1);
var ok = (src.isNil or: tgt.isNil) or: {
~matModSources.includes(src) and: { (~matModTargets[name] ? []).includes(tgt) } };
ok.if({
~matColorDefs[vi][color][\mod] = (src.isNil or: tgt.isNil).if({ nil },
{ (source: src, target: tgt, depth: d) });
~matLastColor[vi] = -1;
(~lp[\matPlaying] and: { ~matApplyBar.notNil }).if({ ~matApplyBar.(~lp[\matBar]) });
~matColorModPush.(vi, color)
})
})
};
// -- ~matSetColorPose : add/replace a pose binding in a color (dedup poseId; empty clears) --
~matSetColorPose = { |vi, color, poseId, action|
((vi >= 0 and: { vi < ~matVoices.size }) and: { color >= 1 and: { color <= 6 } }).if({
var pid = poseId.asSymbol;
((pid == '') or: { pid == \none }).if({
~matColorDefs[vi][color][\pose] = []
}, {
~matColorDefs[vi][color][\pose] = (~matColorDefs[vi][color][\pose] ? [])
.reject({ |b| b[\poseId] == pid }) ++ [ (poseId: pid, action: (action ? \trigger).asSymbol) ];
});
~matColorPosePush.(vi, color)
})
};
// -- ~matColorModPush : send one color's mod binding to surfaces --
~matColorModPush = { |vi, color|
((vi >= 0 and: { vi < ~matVoices.size }) and: { color >= 1 and: { color <= 6 } }).if({
~toscSend !? {
var m = ~matColorDefs[vi][color][\mod];
~toscSend.("/matrix/colormod", vi, color,
(m.isNil).if({ "none" }, { m[\source].asString }),
(m.isNil).if({ "none" }, { m[\target].asString }),
(m.isNil).if({ 0 }, { m[\depth] }))
}
})
};
// -- ~matColorPosePush : send one color's pose bindings to surfaces --
~matColorPosePush = { |vi, color|
((vi >= 0 and: { vi < ~matVoices.size }) and: { color >= 1 and: { color <= 6 } }).if({
~toscSend !? {
var list = ~matColorDefs[vi][color][\pose] ? [];
var flat = list.collect({ |b| [b[\poseId].asString, b[\action].asString] }).flatten;
~toscSend.valueArray(["/matrix/colorpose", vi, color, list.size] ++ flat)
}
})
};
OSCdef(\mat_voicemod, { |msg, time, addr|
~toscTouch !? { ~toscTouch.(addr) };
~matSetVoiceMod.((msg[1] ? 0).asInteger, (msg[2] ? 0).asInteger, msg.copyToEnd(3))
+2 -43
View File
@@ -412,37 +412,6 @@ pass = pass and: { ~ev[\freq].isNil };
// --- Per-color mod + pose state (Task 1) ---
pass = pass and: { ~matColorDefs[5][2][\mod].isNil }; // default no effect
pass = pass and: { ~matColorDefs[5][2][\pose].isArray and: { ~matColorDefs[5][2][\pose].isEmpty } };
pass = pass and: { ~matSetColorMod.notNil and: { ~matSetColorPose.notNil } };
~trigLog = nil; ~toscSend = { |path ...args| ~trigLog = ([path] ++ args) };
~matSetColorMod.(5, 2, \rHandY, \cutoff, 0.7); // acid supports cutoff
pass = pass and: { ~matColorDefs[5][2][\mod][\target] == \cutoff };
pass = pass and: { ~trigLog[0] == "/matrix/colormod" and: { ~trigLog[1] == 5 } };
~matSetColorMod.(0, 1, \rHandY, \cutoff, 0.7); // kick has no cutoff -> reject
pass = pass and: { ~matColorDefs[0][1][\mod].isNil };
~matSetColorMod.(5, 2, \none, \none, 0); // clears
pass = pass and: { ~matColorDefs[5][2][\mod].isNil };
~matSetColorPose.(5, 2, \poseA, \trigger);
pass = pass and: { ~matColorDefs[5][2][\pose][0][\poseId] == \poseA };
~matColorDefs[5][2][\pose] = [];
// dedup: setting the same poseId twice keeps one entry
~matColorDefs[5][2][\pose] = [];
~matSetColorPose.(5, 2, \poseD, \trigger);
~matSetColorPose.(5, 2, \poseD, \gate);
pass = pass and: { ~matColorDefs[5][2][\pose].size == 1 };
pass = pass and: { ~matColorDefs[5][2][\pose][0][\action] == \gate };
~matColorDefs[5][2][\pose] = [];
// colorpose push echo
~trigLog = nil;
~matSetColorPose.(5, 2, \poseE, \trigger);
pass = pass and: { ~trigLog[0] == "/matrix/colorpose" and: { ~trigLog[1] == 5 } };
~matColorDefs[5][2][\pose] = [];
// out-of-bounds set must not raise / not corrupt
~matSetColorMod.(-1, 1, \rHandY, \cutoff, 0.5);
~matSetColorMod.(5, 7, \rHandY, \cutoff, 0.5);
pass = pass and: { true };
// Fix 1: fresh color pose arrays and distinct per color
pass = pass and: { (~matColorDefs[5][1][\pose] === ~matColorDefs[5][2][\pose]).not };
@@ -498,8 +467,8 @@ try { ~matPoseFire.(\unknown) } { |e| pass = false };
~matColorDefs[5][3][\pose] = [];
// --- Per-color mod/pose persistence + migration (Task 3) ---
~matSetColorMod.(4, 3, \rHandY, \amp, 0.5);
~matSetColorPose.(4, 3, \poseM, \gate);
~matColorDefs[4][3][\mod] = (source: \rHandY, target: \amp, depth: 0.5);
~matColorDefs[4][3][\pose] = [ (poseId: \poseM, action: \gate) ];
~matSave.("cp grid");
~matColorDefs = Array.fill(~matVoices.size, { ~matDefaultColorDefs.value });
pass = pass and: { ~matLoad.("cp grid") };
@@ -518,16 +487,6 @@ pass = pass and: { ~matColorDefs[4][1][\mod][\target] == \cutoff }; // voice m
pass = pass and: { ~matColorDefs[4][3][\pose][0][\poseId] == \poseL }; // pose -> its color
File.delete(~matDir +/+ "legc.matrix");
// colorpose OSCdef list-format parse (web sends vi color n pairs)
~cpMsg = ["/matrix/colorpose", 5, 2, 2, "poseA", "trigger", "poseB", "gate"];
~matColorDefs[5][2][\pose] = Array.fill((~cpMsg[3]).asInteger, { |k|
(poseId: (~cpMsg[4 + (k*2)]).asSymbol, action: (~cpMsg[5 + (k*2)]).asSymbol) });
pass = pass and: { ~matColorDefs[5][2][\pose].size == 2 };
pass = pass and: { ~matColorDefs[5][2][\pose][1][\poseId] == \poseB };
pass = pass and: { ~matColorDefs[5][2][\pose][1][\action] == \gate };
// n=0 clears
~matColorDefs[5][2][\pose] = Array.fill(0, { nil });
pass = pass and: { ~matColorDefs[5][2][\pose].isEmpty };
// --- New iPhone mod sources (Task 1) ---
// ~matModOrder must have 19 entries
@@ -530,26 +530,6 @@ on("/matrix/steps", (args) => {
}
});
on("/matrix/colormod", (args) => {
const vi=Math.round(Number(args[0])), c=Math.round(Number(args[1]));
if (vi>=0&&vi<MATRIX_VOICES.length&&c>=1&&c<=6&&matColorDefs[vi][c]) {
const src=String(args[2]??"none");
matColorDefs[vi][c].mod = (src==="none") ? null : {source:src, target:String(args[3]??"none"), depth:Number(args[4])||0};
saveMatState();
if (isOpenFor(vi) && cdColor === c) renderPattern(vi);
}
});
on("/matrix/colorpose", (args) => {
const vi=Math.round(Number(args[0])), c=Math.round(Number(args[1])), n=Math.round(Number(args[2]));
if (vi>=0&&vi<MATRIX_VOICES.length&&c>=1&&c<=6&&matColorDefs[vi][c]) {
matColorDefs[vi][c].pose = [];
for (let k=0;k<n;k++){ const b=3+k*2; matColorDefs[vi][c].pose.push({poseId:String(args[b]),action:String(args[b+1])}); }
saveMatState();
if (isOpenFor(vi) && cdColor === c) renderPattern(vi);
}
});
on("/matrix/voicemod", (args) => {
const { vi, list } = parseVoiceMod(args);
if (vi >= 0 && vi < MATRIX_VOICES.length) {