Ring Daemon 16.0.0
Loading...
Searching...
No Matches
ringbuffer.h
Go to the documentation of this file.
1/*
2 * Copyright (C) 2004-2025 Savoir-faire Linux Inc.
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <https://www.gnu.org/licenses/>.
16 */
17#pragma once
18
19#include "audio_format.h"
20#include "noncopyable.h"
21#include "audio_frame_resizer.h"
22#include "resampler.h"
23
24#include <atomic>
25#include <condition_variable>
26#include <mutex>
27#include <chrono>
28#include <map>
29#include <vector>
30#include <fstream>
31
32namespace jami {
33
38{
39public:
40 using clock = std::chrono::high_resolution_clock;
41 using time_point = clock::time_point;
42 using FrameCallback = std::function<void(const std::shared_ptr<AudioFrame>&)>;
43
48 RingBuffer(const std::string& id, size_t size, AudioFormat format = AudioFormat::MONO());
49
54
55 const std::string& getId() const { return id; }
56
60 void flush(const std::string& ringbufferId);
61
62 void flushAll();
63
67 std::vector<std::string>
69
70 inline AudioFormat getFormat() const { return format_; }
71
72 inline void setFormat(const AudioFormat& format)
73 {
74 std::lock_guard l(writeLock_);
75 format_ = format;
76 resizer_.setFormat(format, format.sample_rate / 50);
77 }
78
82 void createReadOffset(const std::string& ringbufferId);
83
84 void createReadOffset(const std::string& ringbufferId, FrameCallback cb);
85
89 void removeReadOffset(const std::string& ringbufferId);
90
91 size_t readOffsetCount() const { return readoffsets_.size(); }
92
97 void put(std::shared_ptr<AudioFrame>&& data);
98
103 size_t availableForGet(const std::string& ringbufferId) const;
104
110 std::shared_ptr<AudioFrame> get(const std::string& ringbufferId);
111
117 size_t discard(size_t toDiscard, const std::string& ringbufferId);
118
123 size_t putLength() const;
124
125 size_t getLength(const std::string& ringbufferId) const;
126
127 inline bool isFull() const { return putLength() == buffer_.size(); }
128
129 inline bool isEmpty() const { return putLength() == 0; }
130
131 inline void setFrameSize(int nb_samples) { resizer_.setFrameSize(nb_samples); }
132
142 size_t waitForDataAvailable(const std::string& ringbufferId,
143 const time_point& deadline = time_point::max()) const;
144
148 void debug();
149
150 bool isAudioMeterActive() const { return rmsSignal_; }
151 void setAudioMeterState(bool state) { rmsSignal_ = state; }
152
153private:
154 struct ReadOffset
155 {
156 size_t offset;
157 FrameCallback callback;
158 };
159 using ReadOffsetMap = std::map<std::string, ReadOffset>;
160 NON_COPYABLE(RingBuffer);
161
162 void putToBuffer(std::shared_ptr<AudioFrame>&& data);
163
164 bool hasNoReadOffsets() const;
165
169 size_t getSmallestReadOffset() const;
170
174 size_t getReadOffset(const std::string& ringbufferId) const;
175
179 void storeReadOffset(size_t offset, const std::string& ringbufferId);
180
184 bool hasThisReadOffset(const std::string& ringbufferId) const;
185
189 size_t discard(size_t toDiscard);
190
191 const std::string id;
192
194 size_t endPos_;
195
197 AudioFormat format_ {AudioFormat::DEFAULT()};
198 std::vector<std::shared_ptr<AudioFrame>> buffer_ {16};
199
200 mutable std::mutex lock_;
201 mutable std::condition_variable not_empty_;
202 std::mutex writeLock_;
203
204 ReadOffsetMap readoffsets_;
205
206 Resampler resampler_;
207 AudioFrameResizer resizer_;
208
209 std::atomic_bool rmsSignal_ {false};
210 double rmsLevel_ {0};
211 int rmsFrameCount_ {0};
212};
213
214} // namespace jami
void setFrameSize(int frameSize)
void setFormat(const AudioFormat &format, int frameSize)
A ring buffer for mutichannel audio samples.
Definition ringbuffer.h:38
std::chrono::high_resolution_clock clock
Definition ringbuffer.h:40
std::function< void(const std::shared_ptr< AudioFrame > &)> FrameCallback
Definition ringbuffer.h:42
void createReadOffset(const std::string &ringbufferId, FrameCallback cb)
void debug()
Debug function print mEnd, mStart, mBufferSize.
void setFormat(const AudioFormat &format)
Definition ringbuffer.h:72
clock::time_point time_point
Definition ringbuffer.h:41
void removeReadOffset(const std::string &ringbufferId)
Remove a readoffset for this ringbuffer.
void flush(const std::string &ringbufferId)
Reset the counters to 0 for this read offset.
void createReadOffset(const std::string &ringbufferId)
Add a new readoffset for this ringbuffer.
size_t availableForGet(const std::string &ringbufferId) const
To get how much samples are available in the buffer to read in.
std::shared_ptr< AudioFrame > get(const std::string &ringbufferId)
Get data in the ring buffer.
size_t readOffsetCount() const
Definition ringbuffer.h:91
std::vector< std::string > getSubscribers()
Return the list of subscribers (Ring buffers Id that are reading this ring buffer).
bool isAudioMeterActive() const
Definition ringbuffer.h:150
bool isEmpty() const
Definition ringbuffer.h:129
size_t getLength(const std::string &ringbufferId) const
size_t discard(size_t toDiscard, const std::string &ringbufferId)
Discard data from the buffer.
void put(std::shared_ptr< AudioFrame > &&data)
Write data in the ring buffer.
const std::string & getId() const
Definition ringbuffer.h:55
void setAudioMeterState(bool state)
Definition ringbuffer.h:151
size_t putLength() const
Total length of the ring buffer which is available for "putting".
size_t waitForDataAvailable(const std::string &ringbufferId, const time_point &deadline=time_point::max()) const
Blocks until min_data_length samples of data is available, or until deadline has passed.
void setFrameSize(int nb_samples)
Definition ringbuffer.h:131
~RingBuffer()
Destructor.
bool isFull() const
Definition ringbuffer.h:127
AudioFormat getFormat() const
Definition ringbuffer.h:70
void emitSignal(Args... args)
Definition ring_signal.h:64
Simple macro to hide class' copy constructor and assignment operator.
#define NON_COPYABLE(ClassName)
Definition noncopyable.h:30
Structure to hold sample rate and channel number associated with audio data.
static const constexpr AudioFormat DEFAULT()
static const constexpr AudioFormat MONO()