fix(voice): amplitude meter was masked by the dross-rec keyframe animation (2.14.1)
CSS animations override normal declarations — the old box-shadow pulse painted over the level-driven shadow. .metered now disables the fallback pulse; added sqrt gain so speech registers visibly. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "void-server",
|
"name": "void-server",
|
||||||
"version": "2.14.0",
|
"version": "2.14.1",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
@@ -95,12 +95,18 @@ export async function renderDrossBubble() {
|
|||||||
const analyser = actx.createAnalyser(); analyser.fftSize = 256;
|
const analyser = actx.createAnalyser(); analyser.fftSize = 256;
|
||||||
src.connect(analyser);
|
src.connect(analyser);
|
||||||
const buf = new Uint8Array(analyser.frequencyBinCount);
|
const buf = new Uint8Array(analyser.frequencyBinCount);
|
||||||
|
mic.classList.add('metered'); // disables the fallback pulse; amplitude takes over
|
||||||
const tick = () => {
|
const tick = () => {
|
||||||
if (!recording) { actx.close().catch(() => {}); mic.style.removeProperty('--voicelevel'); return; }
|
if (!recording) {
|
||||||
|
actx.close().catch(() => {});
|
||||||
|
mic.style.removeProperty('--voicelevel'); mic.classList.remove('metered');
|
||||||
|
return;
|
||||||
|
}
|
||||||
analyser.getByteTimeDomainData(buf);
|
analyser.getByteTimeDomainData(buf);
|
||||||
let peak = 0;
|
let peak = 0;
|
||||||
for (const v of buf) peak = Math.max(peak, Math.abs(v - 128));
|
for (const v of buf) peak = Math.max(peak, Math.abs(v - 128));
|
||||||
mic.style.setProperty('--voicelevel', (peak / 128).toFixed(3));
|
// sqrt curve + gain: normal speech peaks ~0.1–0.4 raw, which read as barely-alive
|
||||||
|
mic.style.setProperty('--voicelevel', Math.min(1, Math.sqrt(peak / 48)).toFixed(3));
|
||||||
requestAnimationFrame(tick);
|
requestAnimationFrame(tick);
|
||||||
};
|
};
|
||||||
tick();
|
tick();
|
||||||
|
|||||||
@@ -781,9 +781,12 @@ body.drawer-open #scrim { opacity: 1; pointer-events: auto; }
|
|||||||
.dross-clip-txt{flex:1;color:var(--text);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
.dross-clip-txt{flex:1;color:var(--text);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
||||||
.dross-clip audio{display:none}
|
.dross-clip audio{display:none}
|
||||||
|
|
||||||
/* voice 2.14: live level ring + textarea flash (post-transcribe, no keyboard pop) */
|
/* voice 2.14.1: amplitude meter. .metered kills the keyframe pulse — CSS animations
|
||||||
.dross-mic.rec{position:relative;box-shadow:0 0 0 calc(2px + 14px * var(--voicelevel, 0)) rgba(255,79,46,calc(0.12 + 0.45 * var(--voicelevel, 0)));transition:box-shadow 90ms linear}
|
override normal declarations, so the old dross-rec box-shadow was masking the meter. */
|
||||||
.dross-mic.rec svg{transform:scale(calc(1 + 0.35 * var(--voicelevel, 0)));transition:transform 90ms linear}
|
.dross-mic.rec.metered{animation:none;position:relative;
|
||||||
|
box-shadow:0 0 0 calc(2px + 22px * var(--voicelevel, 0)) rgba(255,79,46,calc(0.15 + 0.5 * var(--voicelevel, 0)));
|
||||||
|
transition:box-shadow 70ms linear}
|
||||||
|
.dross-mic.rec.metered svg{transform:scale(calc(1 + 0.5 * var(--voicelevel, 0)));transition:transform 70ms linear}
|
||||||
.dross-inwrap textarea{overflow-y:auto;max-height:120px;transition:height 120ms ease}
|
.dross-inwrap textarea{overflow-y:auto;max-height:120px;transition:height 120ms ease}
|
||||||
.dross-inwrap textarea.flash{border-color:var(--dross-glow);box-shadow:0 0 0 2px var(--dross-soft)}
|
.dross-inwrap textarea.flash{border-color:var(--dross-glow);box-shadow:0 0 0 2px var(--dross-soft)}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user