Refactor the speaker detection logic into observeSpeaker and add tests (#2814)
* Refactor the speaker detection logic into observeSpeaker and add tests @robintown the tests pass, but some of the values were off by 1ms from what I was expecting. Please can you sanity check them? * Extra test cases and clean up * Make distinctUntilChanged part of the observable itself * More suggestions from code review
This commit is contained in:
36
src/state/observeSpeaker.ts
Normal file
36
src/state/observeSpeaker.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
Copyright 2024 New Vector Ltd.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only
|
||||
Please see LICENSE in the repository root for full details.
|
||||
*/
|
||||
import {
|
||||
Observable,
|
||||
audit,
|
||||
merge,
|
||||
timer,
|
||||
filter,
|
||||
startWith,
|
||||
distinctUntilChanged,
|
||||
} from "rxjs";
|
||||
|
||||
/**
|
||||
* Require 1 second of continuous speaking to become a speaker, and 60 second of
|
||||
* continuous silence to stop being considered a speaker
|
||||
*/
|
||||
export function observeSpeaker(
|
||||
isSpeakingObservable: Observable<boolean>,
|
||||
): Observable<boolean> {
|
||||
const distinct = isSpeakingObservable.pipe(distinctUntilChanged());
|
||||
|
||||
return distinct.pipe(
|
||||
// Either change to the new value after the timer or re-emit the same value if it toggles back
|
||||
// (audit will return the latest (toggled back) value) before the timeout.
|
||||
audit((s) =>
|
||||
merge(timer(s ? 1000 : 60000), distinct.pipe(filter((s1) => s1 !== s))),
|
||||
),
|
||||
// Filter the re-emissions (marked as: | ) that happen if we toggle quickly (<1s) from false->true->false|->..
|
||||
startWith(false),
|
||||
distinctUntilChanged(),
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user