Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
73bf2133dc |
@@ -7,7 +7,7 @@ Please see LICENSE in the repository root for full details.
|
|||||||
|
|
||||||
import { describe, expect, it } from "vitest";
|
import { describe, expect, it } from "vitest";
|
||||||
|
|
||||||
import { MicLevelQuantizer } from "./lotusMicLevel";
|
import { MicLevelQuantizer, sameRooms } from "./lotusMicLevel";
|
||||||
|
|
||||||
describe("MicLevelQuantizer", () => {
|
describe("MicLevelQuantizer", () => {
|
||||||
it("maps RMS to 0–3 bars", () => {
|
it("maps RMS to 0–3 bars", () => {
|
||||||
@@ -35,3 +35,14 @@ describe("MicLevelQuantizer", () => {
|
|||||||
expect(q.push(0)).toBe(0);
|
expect(q.push(0)).toBe(0);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("sameRooms (EC #45)", () => {
|
||||||
|
it("compares rooms by identity and order", () => {
|
||||||
|
const a = {};
|
||||||
|
const b = {};
|
||||||
|
expect(sameRooms([a, b], [a, b])).toBe(true);
|
||||||
|
expect(sameRooms([a], [a, b])).toBe(false);
|
||||||
|
expect(sameRooms([a, b], [b, a])).toBe(false);
|
||||||
|
expect(sameRooms([{}], [{}])).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|||||||
@@ -46,6 +46,10 @@ const micPublication = (
|
|||||||
: null;
|
: null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** Pure: the same LiveKit rooms, in the same order (by identity). */
|
||||||
|
export const sameRooms = <T>(a: readonly T[], b: readonly T[]): boolean =>
|
||||||
|
a.length === b.length && a.every((r, i) => r === b[i]);
|
||||||
|
|
||||||
const samplers = new WeakMap<
|
const samplers = new WeakMap<
|
||||||
CallViewModel,
|
CallViewModel,
|
||||||
Observable<LocalMicSample | null>
|
Observable<LocalMicSample | null>
|
||||||
@@ -62,10 +66,15 @@ export function observeLocalMicSample$(
|
|||||||
const cached = samplers.get(vm);
|
const cached = samplers.get(vm);
|
||||||
if (cached) return cached;
|
if (cached) return cached;
|
||||||
const sampler$ = vm.allConnections$.pipe(
|
const sampler$ = vm.allConnections$.pipe(
|
||||||
|
map((data) => data.getConnections().map((c) => c.livekitRoom)),
|
||||||
|
// [EC #45] allConnections$ re-emits far more often than the set of
|
||||||
|
// LiveKit rooms changes; restarting the tap each time closed the
|
||||||
|
// AudioContext ~1×/s and emitted null, which reset the muted-speech
|
||||||
|
// gate so the "You're muted" nudge could never fire.
|
||||||
|
distinctUntilChanged(sameRooms),
|
||||||
switchMap(
|
switchMap(
|
||||||
(data) =>
|
(rooms) =>
|
||||||
new Observable<LocalMicSample | null>((subscriber) => {
|
new Observable<LocalMicSample | null>((subscriber) => {
|
||||||
const rooms = data.getConnections().map((c) => c.livekitRoom);
|
|
||||||
let ctx: AudioContext | null = null;
|
let ctx: AudioContext | null = null;
|
||||||
let clone: MediaStreamTrack | null = null;
|
let clone: MediaStreamTrack | null = null;
|
||||||
let timer: ReturnType<typeof setInterval> | undefined;
|
let timer: ReturnType<typeof setInterval> | undefined;
|
||||||
|
|||||||
Reference in New Issue
Block a user