fix(voice): allow stereo mics at 64 kbps and in the mic test (#3110)

This commit is contained in:
Hampus authored and GitHub committed 2026-10-02 14:11:19 +02:00
1 parent 69786d3b49
commit 4aa7a3e181
40 files changed
+93 -74

No files matched your search

@@ -715,6 +715,7 @@ export const VoiceTab: React.FC<VoiceTabProps> = observer(({voiceSettings, autoR
echoCancellation,
autoGainControl,
voiceProcessingMode,
stereoMicrophone: isStereoMicrophoneEnabled(),
}}
data-flx="user.voice-tab.mic-test-section"
/>
@@ -1,7 +1,11 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {createVoiceSoftClipNode} from '@app/features/voice/engine/VoiceSharedAudioContext';
import {type VoiceInputConfig, VoiceInputGraph} from '@app/features/voice/utils/VoiceInputProcessor';
import {
type VoiceInputChannelCount,
type VoiceInputConfig,
VoiceInputGraph,
} from '@app/features/voice/utils/VoiceInputProcessor';
export interface MicTestAudioGraph {
analyser: AnalyserNode;
@@ -16,6 +20,7 @@ interface CreateMicTestAudioGraphOptions {
signal: AbortSignal;
source: MediaStreamAudioSourceNode;
sourceTrack: MediaStreamTrack;
channelCount: VoiceInputChannelCount;
resolveConfig: () => VoiceInputConfig;
outputGain: number;
playbackTarget: AudioNode;
@@ -26,6 +31,7 @@ export function createMicTestAudioGraph({
signal,
source,
sourceTrack,
channelCount,
resolveConfig,
outputGain,
playbackTarget,
@@ -33,7 +39,7 @@ export function createMicTestAudioGraph({
}: CreateMicTestAudioGraphOptions): MicTestAudioGraph {
signal.throwIfAborted();
const audioContext = source.context as AudioContext;
const inputGraph = new VoiceInputGraph(audioContext, 1, resolveConfig);
const inputGraph = new VoiceInputGraph(audioContext, channelCount, resolveConfig);
inputGraph.setSourceNode(sourceTrack, source);
const analyser = audioContext.createAnalyser();
const delay = audioContext.createDelay(Math.max(1, playbackDelaySeconds + 0.25));
@@ -36,6 +36,7 @@ export interface MicTestSettings {
echoCancellation: boolean;
autoGainControl: boolean;
voiceProcessingMode: VoiceProcessingMode;
stereoMicrophone: boolean;
}
function readEffectiveNoiseSuppressionBackend(): VoiceNoiseSuppressionBackend {
@@ -77,6 +78,7 @@ export const useMicTest = (settings: MicTestSettings) => {
echoCancellation: settings.echoCancellation,
autoGainControl: settings.autoGainControl,
voiceProcessingMode: settings.voiceProcessingMode,
stereoMicrophone: settings.stereoMicrophone,
noiseSuppressionBackend,
}),
[
@@ -84,6 +86,7 @@ export const useMicTest = (settings: MicTestSettings) => {
settings.echoCancellation,
settings.inputDeviceId,
settings.outputDeviceId,
settings.stereoMicrophone,
settings.voiceProcessingMode,
noiseSuppressionBackend,
],
@@ -177,12 +180,17 @@ export const useMicTest = (settings: MicTestSettings) => {
return exhaustive;
}
}
const profile = resolveVoiceProcessing(settings, readEffectiveNoiseSuppressionBackend(), false);
const profile = resolveVoiceProcessing(
settings,
readEffectiveNoiseSuppressionBackend(),
settings.stereoMicrophone,
);
const baseAudioConstraints: MediaTrackConstraints & {voiceIsolation?: boolean} = {
echoCancellation: profile.echoCancellation,
noiseSuppression: profile.browserNoiseSuppression,
autoGainControl: profile.autoGainControl,
voiceIsolation: false,
...(profile.stereoCapture ? {channelCount: {ideal: 2}} : {}),
};
const useExactDeviceId = settings.inputDeviceId !== 'default';
const buildAudioConstraints = (exact: boolean): MediaTrackConstraints =>
@@ -227,6 +235,7 @@ export const useMicTest = (settings: MicTestSettings) => {
signal: controller.signal,
source: acquired.source,
sourceTrack,
channelCount: profile.stereoCapture ? 2 : 1,
resolveConfig: () => ({
backend: resolveVoiceProcessing(settings, readEffectiveNoiseSuppressionBackend(), false)
.noiseSuppressionBackend,