mirror of
https://github.com/got-feedBack/feedBack.git
synced 2026-07-26 23:01:22 +00:00
fix(static): request raw stereo audio for the loopback capture track
Chromium treats a getDisplayMedia audio track as a voice call by default: echo cancellation, noise suppression, auto gain control and mono downmix. Music through that pipeline is the tester-reported "tin can" sound on ASIO/exclusive outputs. Request the raw path explicitly (EC/NS/AGC off, stereo, 48 kHz) — all constraints are best-effort so unsupported ones degrade silently instead of failing the capture. The [asio-diag] loopback line now dumps track.getSettings() so logs prove which processing actually applied. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
f5d448af5c
commit
34215fbd32
@ -614,9 +614,22 @@ import { S } from './player-state.js';
|
||||
let _lbStream = null, _lbCtx = null, _lbTap = null, _lbPageMuted = false;
|
||||
let _loopbackUnavailable = false; // sticky: probe once, then fall back
|
||||
async function _engageLoopback() {
|
||||
// Chromium's default capture pipeline treats the audio track as a
|
||||
// VOICE call: echo cancellation + noise suppression + AGC + mono
|
||||
// downmix. On music that is the "tin can" sound (tester 2026-07-12).
|
||||
// Request the raw stereo path explicitly — every constraint here is
|
||||
// best-effort (ideal-valued), so unsupported ones degrade silently
|
||||
// rather than failing the capture.
|
||||
const stream = await navigator.mediaDevices.getDisplayMedia({
|
||||
video: true,
|
||||
audio: { suppressLocalAudioPlayback: true },
|
||||
audio: {
|
||||
suppressLocalAudioPlayback: true,
|
||||
echoCancellation: false,
|
||||
noiseSuppression: false,
|
||||
autoGainControl: false,
|
||||
channelCount: 2,
|
||||
sampleRate: 48000,
|
||||
},
|
||||
});
|
||||
for (const t of stream.getVideoTracks()) t.stop(); // required, unused
|
||||
const track = stream.getAudioTracks()[0];
|
||||
@ -637,8 +650,19 @@ import { S } from './player-state.js';
|
||||
_lbPageMuted = (await api.setPageMuted(true)) === true;
|
||||
}
|
||||
if (window._asioDiagEnabled?.()) {
|
||||
// Full track settings: shows whether the raw-audio constraints
|
||||
// (no EC/NS/AGC, stereo) actually took — a track that still
|
||||
// reports echoCancellation=true or channelCount=1 explains
|
||||
// "tin can" quality reports directly from the log.
|
||||
const s = track.getSettings?.() || {};
|
||||
console.log('[asio-diag] loopback: suppressed=', suppressed,
|
||||
'pageMuted=', _lbPageMuted, 'rate=', _lbCtx.sampleRate);
|
||||
'pageMuted=', _lbPageMuted, 'rate=', _lbCtx.sampleRate,
|
||||
'track=', JSON.stringify({
|
||||
sampleRate: s.sampleRate, channelCount: s.channelCount,
|
||||
echoCancellation: s.echoCancellation,
|
||||
noiseSuppression: s.noiseSuppression,
|
||||
autoGainControl: s.autoGainControl,
|
||||
}));
|
||||
}
|
||||
await api.setRendererBus(true, 1.0);
|
||||
tap.active = true;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user