2 changed files with 69 additions and 0 deletions
@ -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 |
||||
Loading…
Reference in new issue