Close out the twenty: what the gates taught
Three lessons worth more than the scenes: a slow axis has to move a large low-frequency area or the camera's own drift beats it, whole-frame luminance on the kick is the strobe the flash gate exists for and it arrives by accident, and a style trait expressed only as grain measures as no style at all. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -87,6 +87,7 @@ for (const spec of SONGS) {
|
||||
arrangement: spec.arrangement,
|
||||
brightness: spec.brightness,
|
||||
noise: spec.noise,
|
||||
noiseColour: spec.noiseColour ?? null,
|
||||
dynamics: spec.dynamics,
|
||||
seed: 1 + SONGS.indexOf(spec),
|
||||
});
|
||||
@@ -146,6 +147,39 @@ for (const axis of AXES) {
|
||||
if (bins.size < 3) problems.push(`${axis.label} occupies only ${bins.size}/5 of its range`);
|
||||
}
|
||||
|
||||
// --- what the bank CANNOT decouple ----------------------------------------
|
||||
// Spread on every axis is not the same as covering the space. Two axes that
|
||||
// move together mean whole combinations are unrepresentable, and a downstream
|
||||
// test would then attribute to the generator what is really a hole in the bank.
|
||||
//
|
||||
// The big one here is physical rather than fixable: spectral flatness measures
|
||||
// how noise-like a spectrum is, and a dark signal is one whose spectrum is
|
||||
// tilted, so "dark and very noisy" is only weakly reachable. Real material has
|
||||
// the same correlation. It is reported rather than engineered away.
|
||||
console.log('\n AXIS CORRELATION — |r| near 1 means the bank cannot vary these independently\n');
|
||||
const corr = (a, b) => {
|
||||
const ma = a.reduce((x, y) => x + y, 0) / a.length;
|
||||
const mb = b.reduce((x, y) => x + y, 0) / b.length;
|
||||
let num = 0, da = 0, db = 0;
|
||||
for (let i = 0; i < a.length; i++) {
|
||||
num += (a[i] - ma) * (b[i] - mb);
|
||||
da += (a[i] - ma) ** 2;
|
||||
db += (b[i] - mb) ** 2;
|
||||
}
|
||||
return num / (Math.sqrt(da * db) || 1e-9);
|
||||
};
|
||||
const series = Object.fromEntries(AXES.map(
|
||||
(a) => [a.key, built.map((b) => b.measured[a.key])]));
|
||||
for (let i = 0; i < AXES.length; i++) {
|
||||
for (let j = i + 1; j < AXES.length; j++) {
|
||||
const r = corr(series[AXES[i].key], series[AXES[j].key]);
|
||||
if (Math.abs(r) < 0.6) continue;
|
||||
console.log(` ${AXES[i].label} ↔ ${AXES[j].label}: r = ${r.toFixed(2)}` +
|
||||
(Math.abs(r) > 0.85 ? ' ← effectively one axis' : ''));
|
||||
if (Math.abs(r) > 0.85) problems.push(`${AXES[i].label} and ${AXES[j].label} are collinear (r ${r.toFixed(2)})`);
|
||||
}
|
||||
}
|
||||
|
||||
// Section kinds are the casting gate, so coverage of them is not optional: a
|
||||
// bank with no drop cannot reach the geometric, glitch or structural families
|
||||
// no matter how widely its tempo spreads.
|
||||
|
||||
Reference in New Issue
Block a user