mirror of
https://codeberg.org/armin/noiz.git
synced 2026-09-01 05:50:52 +02:00
Add configurable peak hold grace time for VU meter
This commit is contained in:
parent
a7f62a7bd8
commit
34c0a4ccf4
1 changed files with 22 additions and 6 deletions
28
index.html
28
index.html
|
|
@ -219,6 +219,15 @@ footer .footer-track { flex: 1; min-width: 0; white-space: nowrap; overflow: hid
|
||||||
<option value="0.9">Fast</option>
|
<option value="0.9">Fast</option>
|
||||||
<option value="0.8">Very Fast</option>
|
<option value="0.8">Very Fast</option>
|
||||||
</select>
|
</select>
|
||||||
|
<span style="font-size:11px;color:#6b7089;margin-left:8px">Peak Hold:</span>
|
||||||
|
<select id="vuPeakHoldSelect">
|
||||||
|
<option value="0" selected>Off</option>
|
||||||
|
<option value="6">100ms</option>
|
||||||
|
<option value="12">200ms</option>
|
||||||
|
<option value="30">500ms</option>
|
||||||
|
<option value="60">1s</option>
|
||||||
|
<option value="120">2s</option>
|
||||||
|
</select>
|
||||||
<span style="font-size:11px;color:#6b7089;margin-left:8px">Crossfade:</span>
|
<span style="font-size:11px;color:#6b7089;margin-left:8px">Crossfade:</span>
|
||||||
<select id="crossfadeSelect">
|
<select id="crossfadeSelect">
|
||||||
<option value="0" selected>Off</option>
|
<option value="0" selected>Off</option>
|
||||||
|
|
@ -355,6 +364,8 @@ let peakData = [];
|
||||||
let smoothedData = [];
|
let smoothedData = [];
|
||||||
let vuPeakL = 0, vuPeakR = 0;
|
let vuPeakL = 0, vuPeakR = 0;
|
||||||
let vuSmoothL = 0, vuSmoothR = 0;
|
let vuSmoothL = 0, vuSmoothR = 0;
|
||||||
|
let vuPeakHoldL = 0, vuPeakHoldR = 0;
|
||||||
|
let vuPeakGrace = 0;
|
||||||
function bessi0(x) {
|
function bessi0(x) {
|
||||||
let s = 1, t = 1;
|
let s = 1, t = 1;
|
||||||
for (let k = 1; k <= 20; k++) {
|
for (let k = 1; k <= 20; k++) {
|
||||||
|
|
@ -572,10 +583,11 @@ function drawSpectrum() {
|
||||||
if (levelR > vuSmoothR) vuSmoothR = levelR; else vuSmoothR = vuSmoothR * vuSmooth + levelR * (1 - vuSmooth);
|
if (levelR > vuSmoothR) vuSmoothR = levelR; else vuSmoothR = vuSmoothR * vuSmooth + levelR * (1 - vuSmooth);
|
||||||
levelL = vuSmoothL;
|
levelL = vuSmoothL;
|
||||||
levelR = vuSmoothR;
|
levelR = vuSmoothR;
|
||||||
function drawVuRow(y, level, peak) {
|
function drawVuRow(y, level, peak, hold) {
|
||||||
const lit = Math.round(level * segCount);
|
const lit = Math.round(level * segCount);
|
||||||
if (level > peak) peak = level;
|
if (level > peak) { peak = level; hold = 0; }
|
||||||
else peak *= 0.990;
|
else if (hold < vuPeakGrace) { hold++; }
|
||||||
|
else { peak *= 0.990; }
|
||||||
for (let i = 0; i < segCount; i++) {
|
for (let i = 0; i < segCount; i++) {
|
||||||
const sx = segLeft + i * (segW + segG);
|
const sx = segLeft + i * (segW + segG);
|
||||||
const on = i < lit;
|
const on = i < lit;
|
||||||
|
|
@ -594,10 +606,12 @@ function drawSpectrum() {
|
||||||
vuctx.fillRect(sx, y, segW, rowH);
|
vuctx.fillRect(sx, y, segW, rowH);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return peak;
|
return [peak, hold];
|
||||||
}
|
}
|
||||||
vuPeakL = drawVuRow(0, levelL, vuPeakL);
|
const rL = drawVuRow(0, levelL, vuPeakL, vuPeakHoldL);
|
||||||
vuPeakR = drawVuRow(gap + rowH, levelR, vuPeakR);
|
vuPeakL = rL[0]; vuPeakHoldL = rL[1];
|
||||||
|
const rR = drawVuRow(gap + rowH, levelR, vuPeakR, vuPeakHoldR);
|
||||||
|
vuPeakR = rR[0]; vuPeakHoldR = rR[1];
|
||||||
}
|
}
|
||||||
animId = requestAnimationFrame(drawSpectrum);
|
animId = requestAnimationFrame(drawSpectrum);
|
||||||
}
|
}
|
||||||
|
|
@ -723,6 +737,7 @@ const errorEl = document.getElementById('error');
|
||||||
const windowSelect = document.getElementById('windowSelect');
|
const windowSelect = document.getElementById('windowSelect');
|
||||||
const decaySelect = document.getElementById('decaySelect');
|
const decaySelect = document.getElementById('decaySelect');
|
||||||
const barDecaySelect = document.getElementById('barDecaySelect');
|
const barDecaySelect = document.getElementById('barDecaySelect');
|
||||||
|
const vuPeakHoldSelect = document.getElementById('vuPeakHoldSelect');
|
||||||
const crossfadeSelect = document.getElementById('crossfadeSelect');
|
const crossfadeSelect = document.getElementById('crossfadeSelect');
|
||||||
const infoBtn = document.getElementById('infoBtn');
|
const infoBtn = document.getElementById('infoBtn');
|
||||||
const tagEditorOverlay = document.getElementById('tagEditorOverlay');
|
const tagEditorOverlay = document.getElementById('tagEditorOverlay');
|
||||||
|
|
@ -1685,6 +1700,7 @@ sortSelect.addEventListener('change', () => {
|
||||||
windowSelect.addEventListener('change', () => { windowType = windowSelect.value; });
|
windowSelect.addEventListener('change', () => { windowType = windowSelect.value; });
|
||||||
decaySelect.addEventListener('change', () => { peakDecay = parseFloat(decaySelect.value); });
|
decaySelect.addEventListener('change', () => { peakDecay = parseFloat(decaySelect.value); });
|
||||||
barDecaySelect.addEventListener('change', () => { barDecay = parseFloat(barDecaySelect.value); });
|
barDecaySelect.addEventListener('change', () => { barDecay = parseFloat(barDecaySelect.value); });
|
||||||
|
vuPeakHoldSelect.addEventListener('change', () => { vuPeakGrace = parseInt(vuPeakHoldSelect.value, 10); });
|
||||||
crossfadeSelect.addEventListener('change', () => { crossfadeDuration = parseFloat(crossfadeSelect.value); });
|
crossfadeSelect.addEventListener('change', () => { crossfadeDuration = parseFloat(crossfadeSelect.value); });
|
||||||
crossfadeDuration = parseFloat(crossfadeSelect.value);
|
crossfadeDuration = parseFloat(crossfadeSelect.value);
|
||||||
repeatSelect.addEventListener('change', () => { repeatMode = repeatSelect.value; });
|
repeatSelect.addEventListener('change', () => { repeatMode = repeatSelect.value; });
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue