tracktion-engine 3.0-10-g034fdde4aa5
Tracktion Engine — High level data model for audio applications

« « « Anklang Documentation
Loading...
Searching...
No Matches
tracktion_AudioBufferPool.h
Go to the documentation of this file.
1 /*
2 ,--. ,--. ,--. ,--.
3 ,-' '-.,--.--.,--,--.,---.| |,-.,-' '-.`--' ,---. ,--,--, Copyright 2024
4 '-. .-'| .--' ,-. | .--'| /'-. .-',--.| .-. || \ Tracktion Software
5 | | | | \ '-' \ `--.| \ \ | | | |' '-' '| || | Corporation
6 `---' `--' `--`--'`---'`--'`--' `---' `--' `---' `--''--' www.tracktion.com
7
8 Tracktion Engine uses a GPL/commercial licence - see LICENCE.md for details.
9*/
10
11
12namespace tracktion { inline namespace graph
13{
14#include "../3rd_party/farbot/include/farbot/fifo.hpp"
15}}
16
17namespace tracktion { inline namespace graph
18{
19
20//==============================================================================
34{
35public:
41 AudioBufferPool() = default;
42
46 AudioBufferPool (size_t maxCapacity);
47
62 choc::buffer::ChannelArrayBuffer<float> allocate (choc::buffer::Size);
63
70 bool release (choc::buffer::ChannelArrayBuffer<float>&&);
71
72 //==============================================================================
74 void reset();
75
77 void setCapacity (size_t);
78
80 size_t getCapacity() const { return capacity; }
81
83 void reserve (size_t numBuffers, choc::buffer::Size);
84
85 //==============================================================================
89 size_t getNumBuffers();
90
95 size_t getAllocatedSize();
96
97private:
99 size_t capacity = 0;
100};
101
102
103//==============================================================================
104// _ _ _ _
105// __| | ___ | |_ __ _ (_)| | ___
106// / _` | / _ \| __| / _` || || |/ __|
107// | (_| || __/| |_ | (_| || || |\__ \ _ _ _
108// \__,_| \___| \__| \__,_||_||_||___/(_)(_)(_)
109//
110// Code beyond this point is implementation detail...
111//
112//==============================================================================
113inline AudioBufferPool::AudioBufferPool (size_t maxCapacity)
114{
115 setCapacity (maxCapacity);
116}
117
118inline choc::buffer::ChannelArrayBuffer<float> AudioBufferPool::allocate (choc::buffer::Size size)
119{
120 choc::buffer::ChannelArrayBuffer<float> buffer;
121
122 if (fifo->pop (buffer))
123 {
124 if (auto bufferSize = buffer.getSize();
125 bufferSize.numChannels < size.numChannels
126 || bufferSize.numFrames < size.numFrames)
127 {
128 buffer.resize (size);
129 }
130 }
131 else
132 {
133 buffer.resize (size);
134 }
135
136 return buffer;
137}
138
139inline bool AudioBufferPool::release (choc::buffer::ChannelArrayBuffer<float>&& buffer)
140{
141 return fifo->push (std::move (buffer));
142}
143
144//==============================================================================
145inline void AudioBufferPool::setCapacity (size_t maxCapacity)
146{
147 maxCapacity = (size_t) juce::nextPowerOfTwo ((int) maxCapacity);
148
149 if (maxCapacity <= capacity)
150 return;
151
153 capacity = maxCapacity;
154}
155
156inline void AudioBufferPool::reserve (size_t numBuffers, choc::buffer::Size size)
157{
159
160 // Remove all the buffers
161 for (;;)
162 {
163 choc::buffer::ChannelArrayBuffer<float> tempBuffer;
164
165 if (! fifo->pop (tempBuffer))
166 break;
167
168 buffers.emplace_back (std::move (tempBuffer));
169 }
170
171 // Ensure their size is as big as required
172 for (auto& b : buffers)
173 {
174 if (auto bufferSize = b.getSize();
175 bufferSize.numChannels < size.numChannels
176 || bufferSize.numFrames < size.numFrames)
177 {
178 b.resize (size);
179 }
180 }
181
182 // Reset the fifo storage to hold the new number of buffers
183 const int numToAdd = static_cast<int> (numBuffers) - static_cast<int> (buffers.size());
184
185 // Push the temp buffers back
186 for (auto& b : buffers)
187 {
188 [[ maybe_unused ]] bool succeeded = release (std::move (b));
189 assert (succeeded); // Capacity too small?
190 }
191
192 // Push any additional buffers
193 for (int i = 0; i < numToAdd; ++i)
194 {
195 [[ maybe_unused ]] bool succeeded = release (choc::buffer::ChannelArrayBuffer<float> (size));
196 assert (succeeded); // Capacity too small?
197 }
198}
199
201{
203
204 // Remove all the buffers
205 for (;;)
206 {
207 choc::buffer::ChannelArrayBuffer<float> tempBuffer;
208
209 if (! fifo->pop (tempBuffer))
210 break;
211
212 buffers.emplace_back (std::move (tempBuffer));
213 }
214
215 const auto numBuffers = buffers.size();
216
217 // Push the temp buffers back
218 for (auto& b : buffers)
219 {
220 [[ maybe_unused ]] bool succeeded = release (std::move (b));
221 assert (succeeded);
222 }
223
224 return numBuffers;
225}
226
228{
229 size_t size = 0;
231
232 // Remove all the buffers
233 for (;;)
234 {
235 choc::buffer::ChannelArrayBuffer<float> tempBuffer;
236
237 if (! fifo->pop (tempBuffer))
238 break;
239
240 buffers.emplace_back (std::move (tempBuffer));
241 }
242
243 // Calculate the size of them
244 for (auto& b : buffers)
245 size += b.getView().data.getBytesNeeded (b.getSize());
246
247 // Then put them back in the fifo
248 for (auto& b : buffers)
249 fifo->push (std::move (b));
250
251 return size;
252}
253
254}} // namespace tracktion
assert
A lock-free pool of audio buffers.
choc::buffer::ChannelArrayBuffer< float > allocate(choc::buffer::Size)
Returns an allocated buffer for a given size from the pool.
bool release(choc::buffer::ChannelArrayBuffer< float > &&)
Releases an allocated buffer back to the pool.
void reset()
Releases all the internal allocated storage.
size_t getAllocatedSize()
Returns the currently allocated size of all the buffers in bytes.
AudioBufferPool()=default
Create an empty pool.
size_t getCapacity() const
Returns the current maximum number of buffers this can store.
void reserve(size_t numBuffers, choc::buffer::Size)
Reserves a number of buffers of a given size, preallocating them.
void setCapacity(size_t)
Sets the maximum number of buffers this can store.
size_t getNumBuffers()
Returns the current number of buffers in the pool.
T emplace_back(T... args)
T is_pointer_v
typedef int
int nextPowerOfTwo(int n) noexcept
T size(T... args)
typedef size_t