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
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; |
|
};
|
|
|