LMMS
Loading...
Searching...
No Matches
juce_AbstractFifo.cpp
Go to the documentation of this file.
1/*
2 ==============================================================================
3
4 This file is part of the JUCE library.
5 Copyright (c) 2022 - Raw Material Software Limited
6
7 JUCE is an open source library subject to commercial or open-source
8 licensing.
9
10 The code included in this file is provided under the terms of the ISC license
11 http://www.isc.org/downloads/software-support-policy/isc-license. Permission
12 To use, copy, modify, and/or distribute this software for any purpose with or
13 without fee is hereby granted provided that the above copyright notice and
14 this permission notice appear in all copies.
15
16 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
17 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
18 DISCLAIMED.
19
20 ==============================================================================
21*/
22
23namespace juce
24{
25
27{
28 jassert (bufferSize > 0);
29}
30
33
35{
36 auto vs = validStart.get();
37 auto ve = validEnd.get();
38 return ve >= vs ? (ve - vs) : (bufferSize - (vs - ve));
39}
40
42{
43 validEnd = 0;
44 validStart = 0;
45}
46
47void AbstractFifo::setTotalSize (int newSize) noexcept
48{
49 jassert (newSize > 0);
50 reset();
51 bufferSize = newSize;
52}
53
54//==============================================================================
55void AbstractFifo::prepareToWrite (int numToWrite, int& startIndex1, int& blockSize1,
56 int& startIndex2, int& blockSize2) const noexcept
57{
58 auto vs = validStart.get();
59 auto ve = validEnd.get();
60
61 auto freeSpace = ve >= vs ? (bufferSize - (ve - vs)) : (vs - ve);
62 numToWrite = jmin (numToWrite, freeSpace - 1);
63
64 if (numToWrite <= 0)
65 {
66 startIndex1 = 0;
67 startIndex2 = 0;
68 blockSize1 = 0;
69 blockSize2 = 0;
70 }
71 else
72 {
73 startIndex1 = ve;
74 startIndex2 = 0;
75 blockSize1 = jmin (bufferSize - ve, numToWrite);
76 numToWrite -= blockSize1;
77 blockSize2 = numToWrite <= 0 ? 0 : jmin (numToWrite, vs);
78 }
79}
80
81void AbstractFifo::finishedWrite (int numWritten) noexcept
82{
83 jassert (numWritten >= 0 && numWritten < bufferSize);
84
85 auto newEnd = validEnd.get() + numWritten;
86
87 if (newEnd >= bufferSize)
88 newEnd -= bufferSize;
89
90 validEnd = newEnd;
91}
92
93void AbstractFifo::prepareToRead (int numWanted, int& startIndex1, int& blockSize1,
94 int& startIndex2, int& blockSize2) const noexcept
95{
96 auto vs = validStart.get();
97 auto ve = validEnd.get();
98
99 auto numReady = ve >= vs ? (ve - vs) : (bufferSize - (vs - ve));
100 numWanted = jmin (numWanted, numReady);
101
102 if (numWanted <= 0)
103 {
104 startIndex1 = 0;
105 startIndex2 = 0;
106 blockSize1 = 0;
107 blockSize2 = 0;
108 }
109 else
110 {
111 startIndex1 = vs;
112 startIndex2 = 0;
113 blockSize1 = jmin (bufferSize - vs, numWanted);
114 numWanted -= blockSize1;
115 blockSize2 = numWanted <= 0 ? 0 : jmin (numWanted, ve);
116 }
117}
118
119void AbstractFifo::finishedRead (int numRead) noexcept
120{
121 jassert (numRead >= 0 && numRead <= bufferSize);
122
123 auto newStart = validStart.get() + numRead;
124
125 if (newStart >= bufferSize)
126 newStart -= bufferSize;
127
128 validStart = newStart;
129}
130
131//==============================================================================
132template <AbstractFifo::ReadOrWrite mode>
134 : startIndex1 (other.startIndex1),
135 blockSize1 (other.blockSize1),
136 startIndex2 (other.startIndex2),
137 blockSize2 (other.blockSize2)
138{
139 swap (other);
140}
141
142template <AbstractFifo::ReadOrWrite mode>
145{
146 swap (other);
147 return *this;
148}
149
150template <AbstractFifo::ReadOrWrite mode>
152{
153 std::swap (other.fifo, fifo);
154 std::swap (other.startIndex1, startIndex1);
155 std::swap (other.blockSize1, blockSize1);
156 std::swap (other.startIndex2, startIndex2);
157 std::swap (other.blockSize2, blockSize2);
158}
159
162
163AbstractFifo::ScopedRead AbstractFifo::read (int numToRead) noexcept { return { *this, numToRead }; }
164AbstractFifo::ScopedWrite AbstractFifo::write (int numToWrite) noexcept { return { *this, numToWrite }; }
165
166
167//==============================================================================
168//==============================================================================
169#if JUCE_UNIT_TESTS
170
171class AbstractFifoTests : public UnitTest
172{
173public:
174 AbstractFifoTests()
175 : UnitTest ("Abstract Fifo", UnitTestCategories::containers)
176 {}
177
178 struct WriteThread : public Thread
179 {
180 WriteThread (AbstractFifo& f, int* b, Random rng)
181 : Thread ("fifo writer"), fifo (f), buffer (b), random (rng)
182 {
183 startThread();
184 }
185
186 ~WriteThread()
187 {
188 stopThread (5000);
189 }
190
191 void run()
192 {
193 int n = 0;
194
195 while (! threadShouldExit())
196 {
197 int num = random.nextInt (2000) + 1;
198
199 auto writer = fifo.write (num);
200
201 jassert (writer.blockSize1 >= 0 && writer.blockSize2 >= 0);
202 jassert (writer.blockSize1 == 0
203 || (writer.startIndex1 >= 0 && writer.startIndex1 < fifo.getTotalSize()));
204 jassert (writer.blockSize2 == 0
205 || (writer.startIndex2 >= 0 && writer.startIndex2 < fifo.getTotalSize()));
206
207 writer.forEach ([this, &n] (int index) { this->buffer[index] = n++; });
208 }
209 }
210
211 AbstractFifo& fifo;
212 int* buffer;
213 Random random;
214 };
215
217
218 void runTest() override
219 {
220 beginTest ("AbstractFifo");
221
222 int buffer[5000];
223 AbstractFifo fifo (numElementsInArray (buffer));
224
225 WriteThread writer (fifo, buffer, getRandom());
226
227 int n = 0;
228 Random r = getRandom();
229 r.combineSeed (12345);
230
231 for (int count = 100000; --count >= 0;)
232 {
233 int num = r.nextInt (6000) + 1;
234
235 auto reader = fifo.read (num);
236
237 if (! (reader.blockSize1 >= 0 && reader.blockSize2 >= 0)
238 && (reader.blockSize1 == 0
239 || (reader.startIndex1 >= 0 && reader.startIndex1 < fifo.getTotalSize()))
240 && (reader.blockSize2 == 0
241 || (reader.startIndex2 >= 0 && reader.startIndex2 < fifo.getTotalSize())))
242 {
243 expect (false, "prepareToRead returned -ve values");
244 break;
245 }
246
247 bool failed = false;
248
249 reader.forEach ([&failed, &buffer, &n] (int index)
250 {
251 failed = (buffer[index] != n++) || failed;
252 });
253
254 if (failed)
255 {
256 expect (false, "read values were incorrect");
257 break;
258 }
259 }
260 }
261
263};
264
265static AbstractFifoTests fifoUnitTests;
266
267#endif
268
269} // namespace juce
Type jmin(const Type a, const Type b)
Definition MathsFunctions.h:60
#define noexcept
Definition DistrhoDefines.h:72
static void run(LV2_Handle instance, uint32_t n_samples)
Definition bindings_test_plugin.c:112
Definition juce_AbstractFifo.h:203
void swap(ScopedReadWrite &) noexcept
Definition juce_AbstractFifo.cpp:151
AbstractFifo * fifo
Definition juce_AbstractFifo.h:250
int startIndex1
Definition juce_AbstractFifo.h:243
int blockSize2
Definition juce_AbstractFifo.h:243
int blockSize1
Definition juce_AbstractFifo.h:243
int startIndex2
Definition juce_AbstractFifo.h:243
void reset() noexcept
Definition juce_AbstractFifo.cpp:41
void prepareToWrite(int numToWrite, int &startIndex1, int &blockSize1, int &startIndex2, int &blockSize2) const noexcept
Definition juce_AbstractFifo.cpp:55
Atomic< int > validEnd
Definition juce_AbstractFifo.h:303
ScopedReadWrite< ReadOrWrite::read > ScopedRead
Definition juce_AbstractFifo.h:253
int getTotalSize() const noexcept
Definition juce_AbstractFifo.cpp:31
ScopedRead read(int numToRead) noexcept
Definition juce_AbstractFifo.cpp:163
void prepareToRead(int numWanted, int &startIndex1, int &blockSize1, int &startIndex2, int &blockSize2) const noexcept
Definition juce_AbstractFifo.cpp:93
AbstractFifo(int capacity) noexcept
Definition juce_AbstractFifo.cpp:26
void finishedRead(int numRead) noexcept
Definition juce_AbstractFifo.cpp:119
int getFreeSpace() const noexcept
Definition juce_AbstractFifo.cpp:32
Atomic< int > validStart
Definition juce_AbstractFifo.h:303
void finishedWrite(int numWritten) noexcept
Definition juce_AbstractFifo.cpp:81
ScopedWrite write(int numToWrite) noexcept
Definition juce_AbstractFifo.cpp:164
ScopedReadWrite< ReadOrWrite::write > ScopedWrite
Definition juce_AbstractFifo.h:254
int getNumReady() const noexcept
Definition juce_AbstractFifo.cpp:34
int bufferSize
Definition juce_AbstractFifo.h:302
void setTotalSize(int newSize) noexcept
Definition juce_AbstractFifo.cpp:47
Definition juce_UnitTest.h:70
unsigned f
Definition inflate.c:1572
#define JUCE_BEGIN_IGNORE_WARNINGS_MSVC(warnings)
Definition juce_CompilerWarnings.h:198
#define JUCE_END_IGNORE_WARNINGS_MSVC
Definition juce_CompilerWarnings.h:199
#define jassert(expression)
Definition juce_UnitTestCategories.h:27
JOCTET * buffer
Definition juce_JPEGLoader.cpp:302
Definition carla_juce.cpp:31
int n
Definition crypt.c:458
int r
Definition crypt.c:458
b
Definition crypt.c:628
#define void
Definition unzip.h:396
_WDL_CSTRING_PREFIX void INT_PTR count
Definition wdlcstring.h:263
#define const
Definition zconf.h:137