Files
utun2/tools/chatgui/src/audio_buffer_tuning.h
T

33 lines
1.7 KiB
C++

#pragma once
#include <algorithm>
#include <cstdint>
/* Только управляющий поток. Исходный запрос не меняется без повторных backend XRUN.
* Рост периода на 5мс, запрос полной ёмкости до 100мс; прогрев 1с, между изменениями 5с.
* Нужны два опроса с ошибками за 5с: пачка уведомлений одного сбоя не увеличивает буфер.
* Состояние живёт до смены устройства/сессии; begin() сохраняет подобранный размер при reopen. */
struct AudioBufferTuning {
enum Result { Unchanged, Increase, Limit };
unsigned requestedMs = 0, baseMs = 0, actualMs = 0, periods = 1;
int64_t settleUntil = 0, changeAfter = 0, firstFaultAt = -1;
unsigned faultPolls = 0;
void begin(int64_t now, unsigned actualPeriodMs, unsigned periodCount) {
actualMs = actualPeriodMs; periods = std::max(1u, periodCount);
settleUntil = now + 1000; firstFaultAt = -1; faultPolls = 0;
}
Result observe(int64_t now, unsigned glitches) {
if (!glitches || now < settleUntil) return Unchanged;
if (firstFaultAt < 0 || now - firstFaultAt > 5000) { firstFaultAt = now; faultPolls = 0; }
faultPolls = std::min(faultPolls + 1, 2u);
if (faultPolls < 2 || now < changeAfter) return Unchanged;
firstFaultAt = -1; faultPolls = 0; changeAfter = now + 5000;
unsigned current = std::max({actualMs, requestedMs, baseMs}), maximum = 100 / periods;
if (!current || current >= maximum) return Limit;
requestedMs = std::min(current + 5, maximum);
return Increase;
}
};