Document adaptive buffer limits and preserve failed-open backoff

This commit is contained in:
evgeny committed 2026-10-16 17:18:13 +02:00
1 parent b463fc3309
commit 0c26daf3f5
3 files changed
+18 -1

No files matched your search

+14
View File
@@ -175,6 +175,20 @@ RX продолжает работать, рация снимает PTT, авт
Сброс контекста и уничтожение владельца дожидаются worker до освобождения miniaudio-контекста. Сброс контекста и уничтожение владельца дожидаются worker до освобождения miniaudio-контекста.
Штатное закрытие исправного устройства сохраняет синхронный порядок. Штатное закрытие исправного устройства сохраняет синхронный порядок.
`AudioDevice` подстраивает буфер по подтверждённым backend XRUN: WASAPI DATA_DISCONTINUITY
на входе, ALSA EPIPE, PulseAudio capture hole/overflow и playback underflow. Notification
только увеличивает атомарный счётчик, решение и лог выполняются в GUI recovery timer.
Исходные параметры, включая Linux capture period=10мс, сохраняются до повторных сбоев.
Первая секунда после start исключена; нужны ошибки в двух опросах за 5с. Период увеличивается
на 5мс, не чаще раза в 5с, до общей запрошенной ёмкости 100мс с учётом числа периодов.
Фактический размер согласует backend; исходный или уже достигнутый больший размер не уменьшается.
При достижении предела повторные сбои логируются без новых перезапусков. Подобранный запрос
сохраняется при recovery, сбрасывается при смене устройства/сессии; стабильный звук не вызывает reopen.
Подстройка микрофона закрывает устройство асинхронно, останавливая TX worker и сохраняя RX.
Общая capture-сессия отсоединяет callbacks до close и заново подготавливает потребителей после init.
Новая подписка во время close откладывается, stop удаляет её без ожидания backend.
Первое переоткрытие после подстройки не использует backoff; при ошибке открытия действует обычный retry.
В desktop-видеозвонке Windows/Linux камера живёт в отдельном процессе того же В desktop-видеозвонке Windows/Linux камера живёт в отдельном процессе того же
`vibechat --call-camera-worker`. Служебный вход выполняется до конфига, БД и `vibechat --call-camera-worker`. Служебный вход выполняется до конфига, БД и
single-instance lock. Перечисление устройств, Qt/V4L2, преобразование и освобождение single-instance lock. Перечисление устройств, Qt/V4L2, преобразование и освобождение
+1 -1
View File
@@ -215,7 +215,7 @@ bool AudioDevice::needsRecovery() {
bool AudioDevice::retryReady() const { return !m_device && !closing() && m_clock.elapsed() >= m_retryAt; } bool AudioDevice::retryReady() const { return !m_device && !closing() && m_clock.elapsed() >= m_retryAt; }
void AudioDevice::retryLater() { void AudioDevice::retryLater() {
if (m_resizePending) { m_retryAt = m_clock.elapsed(); m_retryDelay = 250; return; } if (m_resizePending) { m_resizePending = false; m_retryAt = m_clock.elapsed(); m_retryDelay = 250; return; }
m_retryAt = m_clock.elapsed() + m_retryDelay; m_retryAt = m_clock.elapsed() + m_retryDelay;
DEBUG_WARN(DEBUG_CATEGORY_CALL, "audio: %s retry in %dms", m_role, m_retryDelay); DEBUG_WARN(DEBUG_CATEGORY_CALL, "audio: %s retry in %dms", m_role, m_retryDelay);
m_retryDelay = std::min(m_retryDelay * 2, 2000); m_retryDelay = std::min(m_retryDelay * 2, 2000);
@@ -345,6 +345,9 @@ static void buffer_tuning_policy() {
tuning.begin(now + 100, 33, 3); now += 5000; tuning.begin(now + 100, 33, 3); now += 5000;
REQUIRE(tuning.observe(now, 1) == AudioBufferTuning::Unchanged); REQUIRE(tuning.observe(now, 1) == AudioBufferTuning::Unchanged);
REQUIRE(tuning.observe(now + 200, 1) == AudioBufferTuning::Limit && tuning.requestedMs == 33); REQUIRE(tuning.observe(now + 200, 1) == AudioBufferTuning::Limit && tuning.requestedMs == 33);
tuning = {}; tuning.baseMs = 20; tuning.begin(0, 10, 3); // Backend может округлить исходный запрос вниз.
REQUIRE(tuning.observe(1100, 1) == AudioBufferTuning::Unchanged);
REQUIRE(tuning.observe(1300, 1) == AudioBufferTuning::Increase && tuning.requestedMs == 25);
ma_context context{}; context.backend = ma_backend_pulseaudio; ma_context context{}; context.backend = ma_backend_pulseaudio;
auto config = ma_device_config_init(ma_device_type_capture); config.periodSizeInMilliseconds = 20; auto config = ma_device_config_init(ma_device_type_capture); config.periodSizeInMilliseconds = 20;
AudioDevice::requestLowLatency(&context, config); AudioDevice::requestLowLatency(&context, config);