Define bounded audio timeline and playback clock contracts
This commit is contained in:
1 parent
4939ee7fb0
commit
b5bd45c4da
2 files changed
+69
No files matched your search
@@ -0,0 +1,14 @@
|
||||
/* Снимок часов входящего аудио. PTS принадлежит шкале захвата удалённой стороны.
|
||||
* epoch — локальная эпоха устройства; source_epoch — поколение удалённого encoder.
|
||||
* valid=0 запрещает продвижение видео по этому снимку. measured отличает аппаратную
|
||||
* отметку от оценки backend. Тишина устройства/тоны удерживают PTS, remote mute — нет. */
|
||||
#ifndef CALL_CLOCK_H
|
||||
#define CALL_CLOCK_H
|
||||
#include <stdint.h>
|
||||
struct call_clock_snapshot {
|
||||
uint64_t epoch, source_epoch, played_samples, written_samples;
|
||||
int64_t pts_us;
|
||||
uint32_t held_back_us;
|
||||
int valid, measured;
|
||||
};
|
||||
#endif
|
||||
@@ -0,0 +1,55 @@
|
||||
/* Карта SoundTouch → PTS → устройство. Встроенные кольца, без аллокаций в DSP callback.
|
||||
* feed/source/read — один playback worker. read/silence/progress/clock синхронизирует
|
||||
* владелец с читателями clock; source/feed общих выходных данных не касаются.
|
||||
* reset — после остановки доступа. Source Reset обнуляет только локальную карту DSP.
|
||||
* Ограничения не меняют PCM: ошибка карты делает clock недостоверным до reset. */
|
||||
#ifndef CALL_TIMELINE_H
|
||||
#define CALL_TIMELINE_H
|
||||
#include "call_clock.h"
|
||||
#include "soundtouch/SourceSpan.h"
|
||||
#include <array>
|
||||
#include <cstddef>
|
||||
|
||||
class CallTimeline {
|
||||
public:
|
||||
void reset(uint64_t epoch);
|
||||
void feed(int64_t pts_us, unsigned samples, uint64_t source_epoch);
|
||||
void source(const soundtouch::SourceSpan& span);
|
||||
void read(unsigned samples);
|
||||
void silence(unsigned samples);
|
||||
void progress(uint64_t epoch, uint64_t position, int64_t at_us, int64_t received_us, bool measured);
|
||||
call_clock_snapshot clock(int64_t now_us);
|
||||
private:
|
||||
struct Span {
|
||||
uint64_t first = 0, epoch = 0;
|
||||
unsigned count = 0;
|
||||
double pts = 0, end = 0;
|
||||
bool valid = false;
|
||||
};
|
||||
template<size_t N> struct Ring {
|
||||
std::array<Span, N> data{};
|
||||
size_t head = 0, count = 0;
|
||||
Span& front() { return data[head]; }
|
||||
const Span& back() const { return data[(head + count - 1) % N]; }
|
||||
void pop() { head = (head + 1) % N; --count; }
|
||||
void clear() { head = count = 0; }
|
||||
bool push(const Span& s) {
|
||||
if (count == N) return false;
|
||||
data[(head + count++) % N] = s; return true;
|
||||
}
|
||||
};
|
||||
Ring<256> input; // >5с входа; SoundTouch звонка держит лишь несколько блоков.
|
||||
Ring<1024> ready;
|
||||
Ring<2048> output;
|
||||
uint64_t inputWritten = 0, generated = 0, consumed = 0, written = 0, epoch = 0;
|
||||
uint64_t anchorPosition = 0, minimumPosition = 0, lastSourceEpoch = 0;
|
||||
int64_t anchorTime = 0, anchorReceived = 0, lastPts = -1;
|
||||
double endPts = 0;
|
||||
uint64_t endEpoch = 0;
|
||||
int sourceError = 0;
|
||||
bool outputFailed = false, haveAnchor = false, measured = false, endValid = false;
|
||||
static double at(const Span& s, double position);
|
||||
const Span* findInput(uint64_t position) const;
|
||||
void appendOutput(const Span& s);
|
||||
};
|
||||
#endif
|
||||
Reference in new issue
Block a user