feat: matrix per-color step state and push

This commit is contained in:
clement
2026-06-28 22:31:44 +02:00
parent 3eb6426f61
commit 9f7f8558d4
2 changed files with 67 additions and 6 deletions
+48 -6
View File
@@ -39,12 +39,12 @@
// -- default color defs reproduce the historical global variation table --
~matDefaultColorDefs = {
[ nil,
(stretch: 1.0, octave: 0, amp: 1.0, inst: nil, cutoff: nil, pan: nil),
(stretch: 0.5, octave: 0, amp: 1.0, inst: nil, cutoff: nil, pan: nil),
(stretch: 1.0, octave: 1, amp: 1.0, inst: nil, cutoff: nil, pan: nil),
(stretch: 2.0, octave: 0, amp: 1.0, inst: nil, cutoff: nil, pan: nil),
(stretch: 1.0, octave: -1, amp: 1.05, inst: nil, cutoff: nil, pan: nil),
(stretch: 0.5, octave: 0, amp: 1.2, inst: nil, cutoff: nil, pan: nil) ]
(stretch: 1.0, octave: 0, amp: 1.0, inst: nil, cutoff: nil, pan: nil, steps: Array.fill(16, nil)),
(stretch: 0.5, octave: 0, amp: 1.0, inst: nil, cutoff: nil, pan: nil, steps: Array.fill(16, nil)),
(stretch: 1.0, octave: 1, amp: 1.0, inst: nil, cutoff: nil, pan: nil, steps: Array.fill(16, nil)),
(stretch: 2.0, octave: 0, amp: 1.0, inst: nil, cutoff: nil, pan: nil, steps: Array.fill(16, nil)),
(stretch: 1.0, octave: -1, amp: 1.05, inst: nil, cutoff: nil, pan: nil, steps: Array.fill(16, nil)),
(stretch: 0.5, octave: 0, amp: 1.2, inst: nil, cutoff: nil, pan: nil, steps: Array.fill(16, nil)) ]
};
~matColorDefs = ~matColorDefs ? Array.fill(~matVoices.size, { ~matDefaultColorDefs.value });
@@ -435,6 +435,48 @@ File.exists(~matDir).not.if({ ("mkdir -p " ++ ~matDir.quote).systemCmd });
}
};
// -- ~matStepsEmpty : true when no step has a note (all rests) --
~matStepsEmpty = { |steps| steps.isNil or: { steps.every({ |s| s.isNil }) } };
// -- ~matSetStep : write one step (degree \rest/nil clears), re-source, echo --
~matSetStep = { |vi, color, stepIdx, degree, vel|
((vi >= 0 and: { vi < ~matVoices.size }) and: { color >= 1 and: { color <= 6 } }
and: { stepIdx >= 0 and: { stepIdx < 16 } }).if({
var steps = ~matColorDefs[vi][color][\steps];
((degree == \rest) or: { degree.isNil }).if({
steps[stepIdx] = nil
}, {
steps[stepIdx] = (degree: degree.asInteger, vel: vel.asFloat.clip(0, 1))
});
~matLastColor[vi] = -1;
(~lp[\matPlaying] and: { ~matApplyBar.notNil }).if({ ~matApplyBar.(~lp[\matBar]) });
~matStepsPush.(vi, color)
})
};
// -- ~matStepsPush : send one color's 16 steps (degree, vel); rest -> (-99, 0) --
~matStepsPush = { |vi, color|
~toscSend !? {
var flat = ~matColorDefs[vi][color][\steps].collect({ |s|
s.isNil.if({ [-99, 0] }, { [s[\degree], s[\vel]] })
}).flatten;
~toscSend.valueArray(["/matrix/steps", vi, color] ++ flat)
}
};
OSCdef(\mat_step, { |msg, time, addr|
var deg;
~toscTouch !? { ~toscTouch.(addr) };
deg = ((msg[4] ? -99) == -99).if({ \rest }, { msg[4] });
~matSetStep.((msg[1] ? 0).asInteger, (msg[2] ? 1).asInteger, (msg[3] ? 0).asInteger,
deg, (msg[5] ? 0))
}, '/matrix/step');
OSCdef(\mat_steps_get, { |msg, time, addr|
~toscTouch !? { ~toscTouch.(addr) };
(1..6).do { |c| ~matStepsPush.((msg[1] ? 0).asInteger, c) }
}, '/matrix/steps/get');
// -- ~matModPush : send 16 mod triples (source,target,depth) flattened --
~matModPush = {
~toscSend !? {
+19
View File
@@ -365,6 +365,25 @@ pass = pass and: { ~matColorDefs[6][2][\inst] == \do_strike };
pass = pass and: { ~matVariation.(\acid, 1, 5).asStream.next(()).notNil };
// --- Step sequencer state (Task 1) ---
pass = pass and: { ~matStepsEmpty.notNil and: { ~matSetStep.notNil and: { ~matStepsPush.notNil } } };
// default: every color's steps is a 16-slot all-nil array -> empty
pass = pass and: { ~matColorDefs[5][2][\steps].size == 16 };
pass = pass and: { ~matStepsEmpty.(~matColorDefs[5][2][\steps]) };
// set a step, then not empty; step holds degree+vel
~trigLog = nil;
~toscSend = { |path ...args| ~trigLog = ([path] ++ args) };
~matSetStep.(5, 2, 3, 7, 0.8);
pass = pass and: { ~matColorDefs[5][2][\steps][3][\degree] == 7 };
pass = pass and: { ~matColorDefs[5][2][\steps][3][\vel] == 0.8 };
pass = pass and: { ~matStepsEmpty.(~matColorDefs[5][2][\steps]).not };
pass = pass and: { ~trigLog[0] == "/matrix/steps" and: { ~trigLog[1] == 5 } };
pass = pass and: { ~trigLog.size == 35 }; // path + vi + color + 32 vals
// rest clears the step
~matSetStep.(5, 2, 3, \rest, 0);
pass = pass and: { ~matColorDefs[5][2][\steps][3].isNil };
pass = pass and: { ~matStepsEmpty.(~matColorDefs[5][2][\steps]) };
pass.if(
{ "TEST PASS".postln },
{ "TEST FAIL".postln }