feat(lotus): report the local mic level to the host (cinny #146)
The host had only a boolean `speaking` for yourself, throttled to 500 ms, so
nothing on the call bar showed that the mic was actually picking you up.
- lotusMicLevel.ts: one shared local mic sampler (a clone of the published
track, ~10 Hz RMS, while a mic is published, muted or not), shared per
call view model so there is one AudioContext.
- MicLevelQuantizer: 0–3 bars (≈ −46/−36/−26 dBFS), rising at once and
falling one bar per sample so it doesn't flicker between words.
- fromWidget io.lotus.mic_level { bars } only when the value changes; 0 while
muted or with no mic. Opt-in with the host state stream (lotusCallState=1).
- "Talking while muted" (#37) now reads the same sampler instead of running
its own; same gate and behaviour.
Verified in a local call with a fake-tone mic: the host receives 0–3 as the
tone rises/falls (about 4 messages/s while it changes), 0 on mute and levels
again on unmute; muted + tone still raises speakingWhileMuted and the host's
"You're muted" notice. Lotus/room suites pass on Node 22 (148 tests).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PPmy3tPq869XDW4njjVaKA
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
44023a4c84
commit
cee6bab9a6
@@ -32,6 +32,7 @@ import { widget } from "../widget";
|
||||
import { startLotusCallState } from "../lotus/lotusCallState";
|
||||
import { startLotusFocus } from "../lotus/lotusFocus";
|
||||
import { startLotusControls } from "../lotus/lotusControls";
|
||||
import { startLotusMicLevel } from "../lotus/lotusMicLevel";
|
||||
import { startLotusAudioInject } from "../lotus/lotusAudioInject";
|
||||
import { startLotusQuality } from "../lotus/lotusQuality";
|
||||
import { startLotusDecorations } from "../lotus/lotusDecorations";
|
||||
@@ -304,6 +305,8 @@ export const InCallView: FC<InCallViewProps> = ({
|
||||
// [cinny #43] layout / settings / reactions over the widget API, plus a
|
||||
// screensharing + layout report, replacing the host's DOM access.
|
||||
useEffect(() => startLotusControls(vm), [vm]);
|
||||
// [cinny #146] Local mic level for the host's mute-button meter.
|
||||
useEffect(() => startLotusMicLevel(vm), [vm]);
|
||||
// [lotus] Handle the host's io.lotus.inject_audio action to mix a soundboard
|
||||
// clip into the call as a separate track (#3). No-op unless the host sends it.
|
||||
useEffect(() => startLotusAudioInject(vm), [vm]);
|
||||
|
||||
Reference in New Issue
Block a user