dsplib 1.1.0
C++ DSP library for MATLAB-like coding
Loading...
Searching...
No Matches
buffer.h
1#pragma once
2
3#include <functional>
4#include <dsplib/span.h>
5#include <dsplib/math.h>
6
7namespace dsplib {
8
9template<class Fn>
11{
12public:
13 explicit ScopeGuard(Fn f)
14 : f_(std::move(f)) {
15 }
16 ~ScopeGuard() {
17 f_();
18 }
19 ScopeGuard(const ScopeGuard&) = delete;
20 ScopeGuard& operator=(const ScopeGuard&) = delete;
21
22private:
23 Fn f_;
24};
25
33template<typename T>
35{
36public:
37 static_assert(!std::is_same_v<T, bool>, "boolean buffer is not supported");
38 static_assert(std::is_trivially_copyable<T>(), "type must be trivially copyable");
39
44 FIFOBuffer() = default;
45
51 void write(span_t<T> data) noexcept {
52 if (data.empty()) {
53 return;
54 }
55 buf_.insert(buf_.end(), data.begin(), data.end());
56 }
57
62 void write(const T& value) noexcept {
63 buf_.push_back(value);
64 }
65
71 int read(mut_span_t<T> out) noexcept {
72 const int n = min(out.size(), int(buf_.size()));
73 if (n == 0) {
74 return 0;
75 }
76
77 std::memcpy(out.data(), buf_.data(), n * sizeof(T));
78 if (n == buf_.size()) {
79 buf_.clear();
80 } else {
81 std::memmove(buf_.data(), buf_.data() + n, (buf_.size() - n) * sizeof(T));
82 buf_.resize(buf_.size() - n);
83 }
84 return n;
85 }
86
92 std::vector<T> read(int n) noexcept {
93 n = min(n, buf_.size());
94 std::vector<T> out(n);
95 this->read(out);
96 return out;
97 }
98
103 [[nodiscard]] int size() const noexcept {
104 return buf_.size();
105 }
106
111 [[nodiscard]] bool empty() const noexcept {
112 return buf_.empty();
113 }
114
119 void reset() noexcept {
120 buf_.clear();
121 }
122
128 [[nodiscard]] span_t<T> view() const noexcept {
129 return make_span(buf_);
130 }
131
132private:
133 std::vector<T> buf_;
134};
135
145template<typename T>
147{
148public:
150 using Callback = std::function<void(span_t<T>)>;
151
152 static_assert(!std::is_same_v<T, bool>, "boolean buffer is not supported");
153 static_assert(std::is_trivially_copyable<T>(), "type must be trivially copyable");
154
161 explicit ChunkBuffer(int chunk_size)
162 : chunk_size_{chunk_size} {
163 DSPLIB_ASSERT(chunk_size > 1, "chunk size must be greater than 1");
164 buf_.reserve(chunk_size * 2);
165 }
166
181 void write(span_t<T> data, Callback fn) {
182 if (data.empty()) {
183 return;
184 }
185
186 DSPLIB_ASSERT(!in_write_, "recursive write call detected");
187 in_write_ = true;
188 const auto guard = ScopeGuard([this] {
189 in_write_ = false;
190 });
191
192 if (buf_.empty() && (data.size() % chunk_size_ == 0)) {
193 const auto* pdata = data.data();
194 int psize = data.size();
195 while (psize >= chunk_size_) {
196 fn(make_span(pdata, chunk_size_));
197 pdata += chunk_size_;
198 psize -= chunk_size_;
199 }
200 } else {
201 buf_.insert(buf_.end(), data.begin(), data.end());
202 const auto* pdata = buf_.data();
203 int psize = buf_.size();
204 while (psize >= chunk_size_) {
205 fn(make_span(pdata, chunk_size_));
206 pdata += chunk_size_;
207 psize -= chunk_size_;
208 }
209 std::memmove(buf_.data(), buf_.data() + buf_.size() - psize, psize * sizeof(T));
210 buf_.resize(psize);
211 }
212 }
213
223 void flush(Callback fn) {
224 DSPLIB_ASSERT(!in_write_, "flush during callback is unsafe");
225 in_write_ = true;
226 const auto guard = ScopeGuard([this] {
227 in_write_ = false;
228 });
229
230 fn(span_t<T>(buf_.data(), buf_.size()));
231 buf_.clear();
232 }
233
239 void reset() {
240 DSPLIB_ASSERT(!in_write_, "reset during callback is unsafe");
241 buf_.clear();
242 }
243
250 int size() const noexcept {
251 return buf_.size();
252 }
253
254private:
255 int chunk_size_;
256 std::vector<T> buf_;
257 bool in_write_{false};
258};
259
260} // namespace dsplib
Accumulates data samples and processes them in fixed-size chunks.
Definition buffer.h:147
void reset()
Clear buffer contents Resets buffer to empty state. Preserves allocated capacity.
Definition buffer.h:239
std::function< void(span_t< T >)> Callback
Callback type for processing full chunks.
Definition buffer.h:150
void flush(Callback fn)
Process remaining data.
Definition buffer.h:223
int size() const noexcept
Get current number of accumulated samples.
Definition buffer.h:250
ChunkBuffer(int chunk_size)
Construct a chunk buffer with specified chunk size.
Definition buffer.h:161
void write(span_t< T > data, Callback fn)
Add data to buffer and process complete chunks.
Definition buffer.h:181
A thread-unsafe FIFO buffer for trivially copyable data types.
Definition buffer.h:35
bool empty() const noexcept
Check if buffer empty.
Definition buffer.h:111
void write(span_t< T > data) noexcept
Write data to buffer.
Definition buffer.h:51
FIFOBuffer()=default
Default constructor Creates an empty buffer with default capacity.
span_t< T > view() const noexcept
Get read-only view of buffer.
Definition buffer.h:128
int size() const noexcept
Get current element count.
Definition buffer.h:103
void reset() noexcept
Clear buffer contents Removes all elements. Preserves allocated capacity.
Definition buffer.h:119
void write(const T &value) noexcept
Write single element (copy)
Definition buffer.h:62
std::vector< T > read(int n) noexcept
Read data to new vector.
Definition buffer.h:92
int read(mut_span_t< T > out) noexcept
Read data from buffer.
Definition buffer.h:71
Definition buffer.h:11
Definition span.h:27
Definition span.h:295