mirror of
https://github.com/denizsafak/abogen.git
synced 2026-07-18 13:40:27 +02:00
feat: Enhance Supertonic voice mixer controls with range inputs and display labels
This commit is contained in:
@@ -262,6 +262,11 @@ body {
|
|||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Ensure the HTML hidden attribute always wins over component display rules. */
|
||||||
|
[hidden] {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
.modal__overlay {
|
.modal__overlay {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
inset: 0;
|
inset: 0;
|
||||||
|
|||||||
@@ -31,6 +31,8 @@ const setupVoiceMixer = () => {
|
|||||||
const supertonicVoiceSelect = app.querySelector('[data-role="supertonic-voice"]');
|
const supertonicVoiceSelect = app.querySelector('[data-role="supertonic-voice"]');
|
||||||
const supertonicStepsInput = app.querySelector('[data-role="supertonic-steps"]');
|
const supertonicStepsInput = app.querySelector('[data-role="supertonic-steps"]');
|
||||||
const supertonicSpeedInput = app.querySelector('[data-role="supertonic-speed"]');
|
const supertonicSpeedInput = app.querySelector('[data-role="supertonic-speed"]');
|
||||||
|
const supertonicStepsLabel = app.querySelector('[data-role="supertonic-steps-display"]');
|
||||||
|
const supertonicSpeedLabel = app.querySelector('[data-role="supertonic-speed-display"]');
|
||||||
const speedInput = document.getElementById("preview-speed");
|
const speedInput = document.getElementById("preview-speed");
|
||||||
const importInput = document.getElementById("voice-import-input");
|
const importInput = document.getElementById("voice-import-input");
|
||||||
const headerActions = document.querySelector(".voice-mixer__header-actions");
|
const headerActions = document.querySelector(".voice-mixer__header-actions");
|
||||||
@@ -290,6 +292,7 @@ const setupVoiceMixer = () => {
|
|||||||
const desired = Number(state.draft.supertonic?.speed ?? 1.0);
|
const desired = Number(state.draft.supertonic?.speed ?? 1.0);
|
||||||
if (!Number.isNaN(desired)) {
|
if (!Number.isNaN(desired)) {
|
||||||
speedInput.value = String(desired);
|
speedInput.value = String(desired);
|
||||||
|
setRangeFill(speedInput);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -591,9 +594,18 @@ const setupVoiceMixer = () => {
|
|||||||
}
|
}
|
||||||
if (supertonicStepsInput) {
|
if (supertonicStepsInput) {
|
||||||
supertonicStepsInput.value = String(state.draft.supertonic?.total_steps ?? 5);
|
supertonicStepsInput.value = String(state.draft.supertonic?.total_steps ?? 5);
|
||||||
|
setRangeFill(supertonicStepsInput);
|
||||||
}
|
}
|
||||||
if (supertonicSpeedInput) {
|
if (supertonicSpeedInput) {
|
||||||
supertonicSpeedInput.value = String(state.draft.supertonic?.speed ?? 1.0);
|
supertonicSpeedInput.value = String(state.draft.supertonic?.speed ?? 1.0);
|
||||||
|
setRangeFill(supertonicSpeedInput);
|
||||||
|
}
|
||||||
|
if (supertonicStepsLabel) {
|
||||||
|
supertonicStepsLabel.textContent = String(state.draft.supertonic?.total_steps ?? 5);
|
||||||
|
}
|
||||||
|
if (supertonicSpeedLabel) {
|
||||||
|
const speed = Number(state.draft.supertonic?.speed ?? 1.0);
|
||||||
|
supertonicSpeedLabel.textContent = `${(Number.isFinite(speed) ? speed : 1.0).toFixed(2)}×`;
|
||||||
}
|
}
|
||||||
applyProviderToUI();
|
applyProviderToUI();
|
||||||
renderSelectedVoices();
|
renderSelectedVoices();
|
||||||
@@ -1016,8 +1028,13 @@ const setupVoiceMixer = () => {
|
|||||||
const value = Number(supertonicStepsInput.value || "5");
|
const value = Number(supertonicStepsInput.value || "5");
|
||||||
state.draft.supertonic.total_steps = clamp(value, 2, 15);
|
state.draft.supertonic.total_steps = clamp(value, 2, 15);
|
||||||
supertonicStepsInput.value = String(Math.round(state.draft.supertonic.total_steps));
|
supertonicStepsInput.value = String(Math.round(state.draft.supertonic.total_steps));
|
||||||
|
if (supertonicStepsLabel) {
|
||||||
|
supertonicStepsLabel.textContent = supertonicStepsInput.value;
|
||||||
|
}
|
||||||
|
setRangeFill(supertonicStepsInput);
|
||||||
markDirty();
|
markDirty();
|
||||||
});
|
});
|
||||||
|
setRangeFill(supertonicStepsInput);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (supertonicSpeedInput) {
|
if (supertonicSpeedInput) {
|
||||||
@@ -1026,11 +1043,17 @@ const setupVoiceMixer = () => {
|
|||||||
const normalized = clamp(value, 0.7, 2.0);
|
const normalized = clamp(value, 0.7, 2.0);
|
||||||
state.draft.supertonic.speed = normalized;
|
state.draft.supertonic.speed = normalized;
|
||||||
supertonicSpeedInput.value = normalized.toFixed(2);
|
supertonicSpeedInput.value = normalized.toFixed(2);
|
||||||
|
if (supertonicSpeedLabel) {
|
||||||
|
supertonicSpeedLabel.textContent = `${normalized.toFixed(2)}×`;
|
||||||
|
}
|
||||||
|
setRangeFill(supertonicSpeedInput);
|
||||||
if (speedInput) {
|
if (speedInput) {
|
||||||
speedInput.value = String(normalized);
|
speedInput.value = String(normalized);
|
||||||
|
setRangeFill(speedInput);
|
||||||
}
|
}
|
||||||
markDirty();
|
markDirty();
|
||||||
});
|
});
|
||||||
|
setRangeFill(supertonicSpeedInput);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (voiceFilterSelect) {
|
if (voiceFilterSelect) {
|
||||||
@@ -1052,6 +1075,10 @@ const setupVoiceMixer = () => {
|
|||||||
state.draft.supertonic.speed = clamp(speed, 0.7, 2.0);
|
state.draft.supertonic.speed = clamp(speed, 0.7, 2.0);
|
||||||
if (supertonicSpeedInput) {
|
if (supertonicSpeedInput) {
|
||||||
supertonicSpeedInput.value = state.draft.supertonic.speed.toFixed(2);
|
supertonicSpeedInput.value = state.draft.supertonic.speed.toFixed(2);
|
||||||
|
setRangeFill(supertonicSpeedInput);
|
||||||
|
}
|
||||||
|
if (supertonicSpeedLabel) {
|
||||||
|
supertonicSpeedLabel.textContent = `${state.draft.supertonic.speed.toFixed(2)}×`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -73,14 +73,14 @@
|
|||||||
{% endfor %}
|
{% endfor %}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="field">
|
<div class="field field--slider">
|
||||||
<label for="supertonic-quality">Supertonic quality (total steps)</label>
|
<label for="supertonic-quality">Supertonic quality (total steps) <span class="tag" data-role="supertonic-steps-display">5</span></label>
|
||||||
<input type="number" id="supertonic-quality" data-role="supertonic-steps" min="2" max="15" value="5">
|
<input type="range" id="supertonic-quality" data-role="supertonic-steps" min="2" max="15" step="1" value="5">
|
||||||
<p class="hint">2 = fastest/lowest quality, 15 = slowest/highest quality.</p>
|
<p class="hint">2 = fastest/lowest quality, 15 = slowest/highest quality.</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="field">
|
<div class="field field--slider">
|
||||||
<label for="supertonic-speaker-speed">Supertonic speed</label>
|
<label for="supertonic-speaker-speed">Supertonic speed <span class="tag" data-role="supertonic-speed-display">1.00×</span></label>
|
||||||
<input type="number" id="supertonic-speaker-speed" data-role="supertonic-speed" min="0.7" max="2.0" step="0.05" value="1.0">
|
<input type="range" id="supertonic-speaker-speed" data-role="supertonic-speed" min="0.7" max="2.0" step="0.05" value="1.0">
|
||||||
</div>
|
</div>
|
||||||
<p class="hint">Supertonic voice mixing is not implemented yet. Stub target: <a href="https://github.com/Topping1/Supertonic-Voice-Mixer" target="_blank" rel="noreferrer">Supertonic-Voice-Mixer</a>.</p>
|
<p class="hint">Supertonic voice mixing is not implemented yet. Stub target: <a href="https://github.com/Topping1/Supertonic-Voice-Mixer" target="_blank" rel="noreferrer">Supertonic-Voice-Mixer</a>.</p>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user