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.
67 lines
2.3 KiB
67 lines
2.3 KiB
#pragma once |
|
|
|
#include <cstdint> |
|
#include <cstring> |
|
#include <mutex> |
|
#include <vector> |
|
|
|
/* Кольцевой буфер кадров переменной длины (SPSC, mutex-protected). |
|
* |
|
* Producer (uasync-поток) и consumer (аудио-поток). Память предвыделена одним |
|
* блоком — ноль аллокаций на кадр. При переполнении дропается старейший кадр |
|
* (семантика джиттер-буфера). |
|
*/ |
|
class AudioFrameRing { |
|
public: |
|
AudioFrameRing(int capacity, int slotSize) |
|
: cap_(capacity), slotSize_(slotSize), |
|
buf_((size_t)capacity * (size_t)slotSize, 0), |
|
lens_((size_t)capacity, 0) {} |
|
|
|
/* Producer: положить кадр. Возвращает false если len > slotSize. |
|
* При переполнении дропает старейший кадр (успех). */ |
|
bool push(const uint8_t* data, int len) { |
|
if (len <= 0 || len > slotSize_) return false; |
|
std::lock_guard<std::mutex> lk(mtx_); |
|
if (count_ == cap_) { |
|
head_ = (head_ + 1) % cap_; /* drop oldest */ |
|
count_--; |
|
} |
|
std::memcpy(buf_.data() + (size_t)tail_ * slotSize_, data, (size_t)len); |
|
lens_[(size_t)tail_] = (uint16_t)len; |
|
tail_ = (tail_ + 1) % cap_; |
|
count_++; |
|
return true; |
|
} |
|
|
|
/* Consumer: взять старейший кадр. Возвращает длину (0 = пусто). */ |
|
int pop(uint8_t* out, int outCap) { |
|
std::lock_guard<std::mutex> lk(mtx_); |
|
if (count_ == 0) return 0; |
|
int len = (int)lens_[(size_t)head_]; |
|
if (out && len > 0 && len <= outCap) |
|
std::memcpy(out, buf_.data() + (size_t)head_ * slotSize_, (size_t)len); |
|
head_ = (head_ + 1) % cap_; |
|
count_--; |
|
return len; |
|
} |
|
|
|
void clear() { |
|
std::lock_guard<std::mutex> lk(mtx_); |
|
head_ = tail_ = count_ = 0; |
|
} |
|
|
|
int size() const { |
|
std::lock_guard<std::mutex> lk(mtx_); |
|
return count_; |
|
} |
|
|
|
int capacity() const { return cap_; } |
|
|
|
private: |
|
int cap_, slotSize_; |
|
int head_ = 0, tail_ = 0, count_ = 0; |
|
std::vector<uint8_t> buf_; |
|
std::vector<uint16_t> lens_; |
|
mutable std::mutex mtx_; |
|
};
|
|
|