You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

31 lines
1.5 KiB

#pragma once
#include <algorithm>
#include <cstdint>
/* Резерв готового PCM desktop. Размер callback задаёт нижнюю границу; недостача добавляет
* один блок, 10 секунд стабильного вывода убирают один. Частично сыгранный блок — сверх резерва.
* Только RX worker; время монотонное. Четыре PCM-слота доступны в AudioEventQueue<Playback, 12>. */
class VoicePlaybackBuffer {
public:
unsigned blocks = 2;
unsigned callbackFrames = 960;
void reset() { blocks = 2; callbackFrames = 960; stableSince = 0; lastGrowth = 0; lastSample = 0; probeUs = 10000000; }
void sample(int64_t nowUs, unsigned frames, bool missing) {
callbackFrames = frames;
unsigned minimum = std::clamp((frames + 959) / 960, 1u, 4u);
if (!stableSince || nowUs - lastSample > 1000000) stableSince = nowUs;
lastSample = nowUs;
if (minimum > blocks) { blocks = minimum; stableSince = nowUs; }
if (missing) {
stableSince = nowUs;
if (!lastGrowth || nowUs - lastGrowth >= 500000) {
blocks = std::min(blocks + 1, 4u); lastGrowth = nowUs;
probeUs = std::min(probeUs * 2, int64_t(300000000));
}
} else if (blocks > minimum && nowUs - stableSince >= probeUs) {
--blocks; stableSince = nowUs;
}
}
private:
int64_t stableSince = 0, lastGrowth = 0, lastSample = 0, probeUs = 10000000;
};