Add min/max value range to audio value sources
Add min_value and max_value fields to AudioValueSource so audio brightness can be mapped to a configurable range (e.g. silence = 30% brightness floor instead of fully black). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -91,6 +91,8 @@ class ValueSource:
|
|||||||
mode=data.get("mode") or "rms",
|
mode=data.get("mode") or "rms",
|
||||||
sensitivity=float(data.get("sensitivity") or 1.0),
|
sensitivity=float(data.get("sensitivity") or 1.0),
|
||||||
smoothing=float(data.get("smoothing") or 0.3),
|
smoothing=float(data.get("smoothing") or 0.3),
|
||||||
|
min_value=float(data.get("min_value") or 0.0),
|
||||||
|
max_value=float(data["max_value"]) if data.get("max_value") is not None else 1.0,
|
||||||
)
|
)
|
||||||
|
|
||||||
if source_type == "adaptive_time":
|
if source_type == "adaptive_time":
|
||||||
@@ -167,10 +169,12 @@ class AudioValueSource(ValueSource):
|
|||||||
into a scalar value for brightness modulation.
|
into a scalar value for brightness modulation.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
audio_source_id: str = "" # references a MonoAudioSource
|
audio_source_id: str = "" # references an audio source (mono or multichannel)
|
||||||
mode: str = "rms" # rms | peak | beat
|
mode: str = "rms" # rms | peak | beat
|
||||||
sensitivity: float = 1.0 # gain multiplier (0.1–5.0)
|
sensitivity: float = 1.0 # gain multiplier (0.1–5.0)
|
||||||
smoothing: float = 0.3 # temporal smoothing (0.0–1.0)
|
smoothing: float = 0.3 # temporal smoothing (0.0–1.0)
|
||||||
|
min_value: float = 0.0 # minimum output (0.0–1.0)
|
||||||
|
max_value: float = 1.0 # maximum output (0.0–1.0)
|
||||||
|
|
||||||
def to_dict(self) -> dict:
|
def to_dict(self) -> dict:
|
||||||
d = super().to_dict()
|
d = super().to_dict()
|
||||||
@@ -178,6 +182,8 @@ class AudioValueSource(ValueSource):
|
|||||||
d["mode"] = self.mode
|
d["mode"] = self.mode
|
||||||
d["sensitivity"] = self.sensitivity
|
d["sensitivity"] = self.sensitivity
|
||||||
d["smoothing"] = self.smoothing
|
d["smoothing"] = self.smoothing
|
||||||
|
d["min_value"] = self.min_value
|
||||||
|
d["max_value"] = self.max_value
|
||||||
return d
|
return d
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -142,6 +142,8 @@ class ValueSourceStore:
|
|||||||
mode=mode or "rms",
|
mode=mode or "rms",
|
||||||
sensitivity=sensitivity if sensitivity is not None else 1.0,
|
sensitivity=sensitivity if sensitivity is not None else 1.0,
|
||||||
smoothing=smoothing if smoothing is not None else 0.3,
|
smoothing=smoothing if smoothing is not None else 0.3,
|
||||||
|
min_value=min_value if min_value is not None else 0.0,
|
||||||
|
max_value=max_value if max_value is not None else 1.0,
|
||||||
)
|
)
|
||||||
elif source_type == "adaptive_time":
|
elif source_type == "adaptive_time":
|
||||||
schedule_data = schedule or []
|
schedule_data = schedule or []
|
||||||
@@ -225,6 +227,10 @@ class ValueSourceStore:
|
|||||||
source.sensitivity = sensitivity
|
source.sensitivity = sensitivity
|
||||||
if smoothing is not None:
|
if smoothing is not None:
|
||||||
source.smoothing = smoothing
|
source.smoothing = smoothing
|
||||||
|
if min_value is not None:
|
||||||
|
source.min_value = min_value
|
||||||
|
if max_value is not None:
|
||||||
|
source.max_value = max_value
|
||||||
elif isinstance(source, AdaptiveValueSource):
|
elif isinstance(source, AdaptiveValueSource):
|
||||||
if schedule is not None:
|
if schedule is not None:
|
||||||
if source.source_type == "adaptive_time" and len(schedule) < 2:
|
if source.source_type == "adaptive_time" and len(schedule) < 2:
|
||||||
|
|||||||
@@ -160,6 +160,32 @@
|
|||||||
<span id="value-source-smoothing-display">0.3</span>
|
<span id="value-source-smoothing-display">0.3</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="label-row">
|
||||||
|
<label for="value-source-audio-min-value" data-i18n="value_source.audio_min_value">Min Value:</label>
|
||||||
|
<button type="button" class="hint-toggle" onclick="toggleHint(this)" title="?" data-i18n-aria-label="aria.hint">?</button>
|
||||||
|
</div>
|
||||||
|
<small class="input-hint" style="display:none" data-i18n="value_source.audio_min_value.hint">Output when audio is silent (e.g. 0.3 = 30% brightness floor)</small>
|
||||||
|
<div class="range-with-value">
|
||||||
|
<input type="range" id="value-source-audio-min-value" min="0" max="1" step="0.01" value="0"
|
||||||
|
oninput="document.getElementById('value-source-audio-min-value-display').textContent = this.value">
|
||||||
|
<span id="value-source-audio-min-value-display">0</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="label-row">
|
||||||
|
<label for="value-source-audio-max-value" data-i18n="value_source.audio_max_value">Max Value:</label>
|
||||||
|
<button type="button" class="hint-toggle" onclick="toggleHint(this)" title="?" data-i18n-aria-label="aria.hint">?</button>
|
||||||
|
</div>
|
||||||
|
<small class="input-hint" style="display:none" data-i18n="value_source.audio_max_value.hint">Output at maximum audio level</small>
|
||||||
|
<div class="range-with-value">
|
||||||
|
<input type="range" id="value-source-audio-max-value" min="0" max="1" step="0.01" value="1"
|
||||||
|
oninput="document.getElementById('value-source-audio-max-value-display').textContent = this.value">
|
||||||
|
<span id="value-source-audio-max-value-display">1</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Adaptive Time of Day fields -->
|
<!-- Adaptive Time of Day fields -->
|
||||||
|
|||||||
Reference in New Issue
Block a user