34 void Push(int64_t start, std::vector<std::vector<float>> samples)
36 if (samples.size() !=
static_cast<size_t>(channel_count) || samples.empty())
return;
37 const int64_t count = samples.front().size();
38 for (
const auto& channel : samples) {
39 if (channel.size() !=
static_cast<size_t>(count))
return;
41 if (!count || start + count <= position)
return;
44 const int64_t trim = std::max<int64_t>({0, position - start, count - max_samples});
45 for (
auto& channel : samples) channel.erase(channel.begin(), channel.begin() + trim);
47 queued_samples += count - trim;
48 const auto insertion = std::upper_bound(blocks.begin(), blocks.end(), start,
49 [](int64_t value,
const Block& block) { return value < block.start; });
50 blocks.insert(insertion, Block{start, std::move(samples)});
51 while (queued_samples > max_samples && !blocks.empty()) {
52 queued_samples -= blocks.front().samples.front().size();
57 void PushTimestamp(int64_t timestamp, int64_t epoch, AVRational time_base,
58 int sample_rate, std::vector<std::vector<float>> samples)
60 if (samples.empty() || samples.front().empty())
return;
61 int64_t start = av_rescale_q(timestamp - epoch, time_base, AVRational{1, sample_rate});
67 const int64_t tolerance = std::max(1, sample_rate / 1000);
68 if (timestamp_started && start >= next_timestamp_sample - tolerance
69 && start <= next_timestamp_sample + tolerance) {
70 start = next_timestamp_sample;
72 next_timestamp_sample = start +
static_cast<int64_t
>(samples.front().size());
73 timestamp_started =
true;
74 Push(start, std::move(samples));
84 std::vector<std::vector<float>>
Read(
int count)
86 std::vector<std::vector<float>> result(channel_count, std::vector<float>(count, 0.0f));
87 const int64_t end = position + count;
88 for (
const auto& block : blocks) {
89 const int64_t first = std::max(position, block.start);
90 const int64_t last = std::min(end, block.start +
static_cast<int64_t
>(block.samples.front().size()));
91 if (last <= first)
continue;
92 for (
int channel = 0; channel < channel_count; ++channel) {
93 std::copy_n(block.samples[channel].begin() + (first - block.start), last - first,
94 result[channel].begin() + (first - position));
98 for (
auto it = blocks.begin(); it != blocks.end();) {
99 if (it->start +
static_cast<int64_t
>(it->samples.front().size()) <= position) {
100 queued_samples -= it->samples.front().size();
101 it = blocks.erase(it);