feat: web matrix mixer per-instrument strips
CI build oscope-of / build-check (push) Has been cancelled
CI build oscope-of / build-check (push) Has been cancelled
This commit is contained in:
@@ -142,3 +142,14 @@ button.queued { animation: queued-blink 600ms ease-in-out infinite alternate; }
|
||||
.tl-bar.in-loop { background: #1a2a1a; border-color: #2a5a2a; color: #4d9; }
|
||||
.tl-bar.tl-head { background: #fa0; border-color: #fc0; color: #000; }
|
||||
.tl-bar.tl-head.in-loop { background: #fa0; border-color: #fc0; color: #000; }
|
||||
|
||||
/* --- Matrix mixer: 16-strip volume + mute --- */
|
||||
.matrix-mixer { display: flex; gap: 4px; margin: 12px 0; overflow-x: auto;
|
||||
-webkit-overflow-scrolling: touch; padding-bottom: 4px; }
|
||||
.mix-strip { display: flex; flex-direction: column; align-items: center; gap: 4px;
|
||||
min-width: 40px; flex-shrink: 0; }
|
||||
.mix-fader { writing-mode: vertical-lr; direction: rtl; width: 28px; height: 110px;
|
||||
accent-color: #4c8; cursor: pointer; -webkit-appearance: slider-vertical; appearance: slider-vertical; }
|
||||
.mix-mute { width: auto; padding: 4px 6px; font-size: 11px; }
|
||||
.mix-mute.on { background: #622; border-color: #c44; color: #f88; font-weight: 700; }
|
||||
.mix-label { font-size: 10px; color: #9af; text-align: center; word-break: break-all; }
|
||||
|
||||
@@ -407,6 +407,69 @@ function initTimelinePointer() {
|
||||
});
|
||||
}
|
||||
|
||||
// --- Matrix mixer: 16-voice per-strip volume + mute ---
|
||||
const mixerLevel = {};
|
||||
const mixerMuted = {};
|
||||
MATRIX_VOICES.forEach(v => { mixerLevel[v] = 0.8; mixerMuted[v] = false; });
|
||||
|
||||
function renderMixer() {
|
||||
const container = document.getElementById("matrix-mixer");
|
||||
if (!container) return;
|
||||
container.innerHTML = "";
|
||||
MATRIX_VOICES.forEach(voice => {
|
||||
const strip = document.createElement("div");
|
||||
strip.className = "mix-strip";
|
||||
strip.dataset.voice = voice;
|
||||
|
||||
const fader = document.createElement("input");
|
||||
fader.type = "range";
|
||||
fader.min = "0";
|
||||
fader.max = "1.5";
|
||||
fader.step = "0.05";
|
||||
fader.value = String(mixerLevel[voice]);
|
||||
fader.className = "mix-fader";
|
||||
fader.dataset.voice = voice;
|
||||
|
||||
const muteBtn = document.createElement("button");
|
||||
muteBtn.className = "mix-mute";
|
||||
muteBtn.textContent = "M";
|
||||
|
||||
const label = document.createElement("span");
|
||||
label.className = "mix-label";
|
||||
label.textContent = voice;
|
||||
|
||||
fader.addEventListener("input", () => {
|
||||
const v = +fader.value;
|
||||
mixerLevel[voice] = v;
|
||||
// Moving the fader unmutes + sends immediately
|
||||
if (mixerMuted[voice]) {
|
||||
mixerMuted[voice] = false;
|
||||
strip.classList.remove("muted");
|
||||
muteBtn.classList.remove("on");
|
||||
}
|
||||
send("/launch/vol", voice, v);
|
||||
});
|
||||
|
||||
muteBtn.addEventListener("click", () => {
|
||||
mixerMuted[voice] = !mixerMuted[voice];
|
||||
if (mixerMuted[voice]) {
|
||||
muteBtn.classList.add("on");
|
||||
strip.classList.add("muted");
|
||||
send("/launch/vol", voice, 0);
|
||||
} else {
|
||||
muteBtn.classList.remove("on");
|
||||
strip.classList.remove("muted");
|
||||
send("/launch/vol", voice, mixerLevel[voice]);
|
||||
}
|
||||
});
|
||||
|
||||
strip.appendChild(fader);
|
||||
strip.appendChild(muteBtn);
|
||||
strip.appendChild(label);
|
||||
container.appendChild(strip);
|
||||
});
|
||||
}
|
||||
|
||||
// --- Matrix audio-reactive glow (trigger envelope; math in matrix_glow.js) ---
|
||||
const voiceLevel = new Array(MATRIX_VOICES.length).fill(0);
|
||||
let glowRaf = null;
|
||||
@@ -634,6 +697,7 @@ document.addEventListener("DOMContentLoaded", () => {
|
||||
renderMatrix();
|
||||
renderTimeline();
|
||||
initTimelinePointer();
|
||||
renderMixer();
|
||||
|
||||
// Name input: rename selected preset and update button labels
|
||||
const melName = document.getElementById("mel-name");
|
||||
|
||||
@@ -170,6 +170,7 @@
|
||||
<div id="matrix-timeline" class="matrix-timeline"></div>
|
||||
<div id="matrix-grid"></div>
|
||||
</div>
|
||||
<div id="matrix-mixer" class="matrix-mixer"></div>
|
||||
</section>
|
||||
</div>
|
||||
<script type="module">import * as G from "./matrix_glow.js"; window.MatrixGlow = G;</script>
|
||||
|
||||
Reference in New Issue
Block a user