fix macOS build (following Projucer changes made in Windows, which removed /Applications/JUCE/modules from its headers). move JUCE headers under source control, so that Windows and macOS can both build against same version of JUCE. remove AUv3 target (I think it's an iOS thing, so it will never work with this macOS fluidsynth dylib).
This commit is contained in:
296
modules/juce_core/containers/juce_AbstractFifo.cpp
Normal file
296
modules/juce_core/containers/juce_AbstractFifo.cpp
Normal file
@ -0,0 +1,296 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2017 - ROLI Ltd.
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
The code included in this file is provided under the terms of the ISC license
|
||||
http://www.isc.org/downloads/software-support-policy/isc-license. Permission
|
||||
To use, copy, modify, and/or distribute this software for any purpose with or
|
||||
without fee is hereby granted provided that the above copyright notice and
|
||||
this permission notice appear in all copies.
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
AbstractFifo::AbstractFifo (int capacity) noexcept : bufferSize (capacity)
|
||||
{
|
||||
jassert (bufferSize > 0);
|
||||
}
|
||||
|
||||
AbstractFifo::~AbstractFifo() {}
|
||||
|
||||
int AbstractFifo::getTotalSize() const noexcept { return bufferSize; }
|
||||
int AbstractFifo::getFreeSpace() const noexcept { return bufferSize - getNumReady() - 1; }
|
||||
|
||||
int AbstractFifo::getNumReady() const noexcept
|
||||
{
|
||||
auto vs = validStart.get();
|
||||
auto ve = validEnd.get();
|
||||
return ve >= vs ? (ve - vs) : (bufferSize - (vs - ve));
|
||||
}
|
||||
|
||||
void AbstractFifo::reset() noexcept
|
||||
{
|
||||
validEnd = 0;
|
||||
validStart = 0;
|
||||
}
|
||||
|
||||
void AbstractFifo::setTotalSize (int newSize) noexcept
|
||||
{
|
||||
jassert (newSize > 0);
|
||||
reset();
|
||||
bufferSize = newSize;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void AbstractFifo::prepareToWrite (int numToWrite, int& startIndex1, int& blockSize1, int& startIndex2, int& blockSize2) const noexcept
|
||||
{
|
||||
auto vs = validStart.get();
|
||||
auto ve = validEnd.get();
|
||||
|
||||
auto freeSpace = ve >= vs ? (bufferSize - (ve - vs)) : (vs - ve);
|
||||
numToWrite = jmin (numToWrite, freeSpace - 1);
|
||||
|
||||
if (numToWrite <= 0)
|
||||
{
|
||||
startIndex1 = 0;
|
||||
startIndex2 = 0;
|
||||
blockSize1 = 0;
|
||||
blockSize2 = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
startIndex1 = ve;
|
||||
startIndex2 = 0;
|
||||
blockSize1 = jmin (bufferSize - ve, numToWrite);
|
||||
numToWrite -= blockSize1;
|
||||
blockSize2 = numToWrite <= 0 ? 0 : jmin (numToWrite, vs);
|
||||
}
|
||||
}
|
||||
|
||||
void AbstractFifo::finishedWrite (int numWritten) noexcept
|
||||
{
|
||||
jassert (numWritten >= 0 && numWritten < bufferSize);
|
||||
|
||||
auto newEnd = validEnd.get() + numWritten;
|
||||
|
||||
if (newEnd >= bufferSize)
|
||||
newEnd -= bufferSize;
|
||||
|
||||
validEnd = newEnd;
|
||||
}
|
||||
|
||||
void AbstractFifo::prepareToRead (int numWanted, int& startIndex1, int& blockSize1, int& startIndex2, int& blockSize2) const noexcept
|
||||
{
|
||||
auto vs = validStart.get();
|
||||
auto ve = validEnd.get();
|
||||
|
||||
auto numReady = ve >= vs ? (ve - vs) : (bufferSize - (vs - ve));
|
||||
numWanted = jmin (numWanted, numReady);
|
||||
|
||||
if (numWanted <= 0)
|
||||
{
|
||||
startIndex1 = 0;
|
||||
startIndex2 = 0;
|
||||
blockSize1 = 0;
|
||||
blockSize2 = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
startIndex1 = vs;
|
||||
startIndex2 = 0;
|
||||
blockSize1 = jmin (bufferSize - vs, numWanted);
|
||||
numWanted -= blockSize1;
|
||||
blockSize2 = numWanted <= 0 ? 0 : jmin (numWanted, ve);
|
||||
}
|
||||
}
|
||||
|
||||
void AbstractFifo::finishedRead (int numRead) noexcept
|
||||
{
|
||||
jassert (numRead >= 0 && numRead <= bufferSize);
|
||||
|
||||
auto newStart = validStart.get() + numRead;
|
||||
|
||||
if (newStart >= bufferSize)
|
||||
newStart -= bufferSize;
|
||||
|
||||
validStart = newStart;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
template <AbstractFifo::ReadOrWrite mode>
|
||||
AbstractFifo::ScopedReadWrite<mode>::ScopedReadWrite (AbstractFifo& f, int num) noexcept
|
||||
: fifo (&f)
|
||||
{
|
||||
prepare (*fifo, num);
|
||||
}
|
||||
|
||||
template <AbstractFifo::ReadOrWrite mode>
|
||||
AbstractFifo::ScopedReadWrite<mode>::ScopedReadWrite (ScopedReadWrite&& other) noexcept
|
||||
: startIndex1 (other.startIndex1),
|
||||
blockSize1 (other.blockSize1),
|
||||
startIndex2 (other.startIndex2),
|
||||
blockSize2 (other.blockSize2)
|
||||
{
|
||||
swap (other);
|
||||
}
|
||||
|
||||
template <AbstractFifo::ReadOrWrite mode>
|
||||
AbstractFifo::ScopedReadWrite<mode>&
|
||||
AbstractFifo::ScopedReadWrite<mode>::operator= (ScopedReadWrite&& other) noexcept
|
||||
{
|
||||
swap (other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <AbstractFifo::ReadOrWrite mode>
|
||||
AbstractFifo::ScopedReadWrite<mode>::~ScopedReadWrite() noexcept
|
||||
{
|
||||
if (fifo != nullptr)
|
||||
finish (*fifo, blockSize1 + blockSize2);
|
||||
}
|
||||
|
||||
template <AbstractFifo::ReadOrWrite mode>
|
||||
void AbstractFifo::ScopedReadWrite<mode>::swap (ScopedReadWrite& other) noexcept
|
||||
{
|
||||
std::swap (other.fifo, fifo);
|
||||
std::swap (other.startIndex1, startIndex1);
|
||||
std::swap (other.blockSize1, blockSize1);
|
||||
std::swap (other.startIndex2, startIndex2);
|
||||
std::swap (other.blockSize2, blockSize2);
|
||||
}
|
||||
|
||||
template<>
|
||||
void AbstractFifo::ScopedReadWrite<AbstractFifo::ReadOrWrite::read>::prepare (AbstractFifo& f, int num) noexcept
|
||||
{
|
||||
f.prepareToRead (num, startIndex1, blockSize1, startIndex2, blockSize2);
|
||||
}
|
||||
|
||||
template<>
|
||||
void AbstractFifo::ScopedReadWrite<AbstractFifo::ReadOrWrite::write>::prepare (AbstractFifo& f, int num) noexcept
|
||||
{
|
||||
f.prepareToWrite (num, startIndex1, blockSize1, startIndex2, blockSize2);
|
||||
}
|
||||
|
||||
template<>
|
||||
void AbstractFifo::ScopedReadWrite<AbstractFifo::ReadOrWrite::read>::finish (AbstractFifo& f, int num) noexcept
|
||||
{
|
||||
f.finishedRead (num);
|
||||
}
|
||||
|
||||
template<>
|
||||
void AbstractFifo::ScopedReadWrite<AbstractFifo::ReadOrWrite::write>::finish (AbstractFifo& f, int num) noexcept
|
||||
{
|
||||
f.finishedWrite (num);
|
||||
}
|
||||
|
||||
template class AbstractFifo::ScopedReadWrite<AbstractFifo::ReadOrWrite::read>;
|
||||
template class AbstractFifo::ScopedReadWrite<AbstractFifo::ReadOrWrite::write>;
|
||||
|
||||
//==============================================================================
|
||||
#if JUCE_UNIT_TESTS
|
||||
|
||||
class AbstractFifoTests : public UnitTest
|
||||
{
|
||||
public:
|
||||
AbstractFifoTests() : UnitTest ("Abstract Fifo", "Containers") {}
|
||||
|
||||
struct WriteThread : public Thread
|
||||
{
|
||||
WriteThread (AbstractFifo& f, int* b, Random rng)
|
||||
: Thread ("fifo writer"), fifo (f), buffer (b), random (rng)
|
||||
{
|
||||
startThread();
|
||||
}
|
||||
|
||||
~WriteThread()
|
||||
{
|
||||
stopThread (5000);
|
||||
}
|
||||
|
||||
void run()
|
||||
{
|
||||
int n = 0;
|
||||
|
||||
while (! threadShouldExit())
|
||||
{
|
||||
int num = random.nextInt (2000) + 1;
|
||||
|
||||
auto writer = fifo.write (num);
|
||||
|
||||
jassert (writer.blockSize1 >= 0 && writer.blockSize2 >= 0);
|
||||
jassert (writer.blockSize1 == 0
|
||||
|| (writer.startIndex1 >= 0 && writer.startIndex1 < fifo.getTotalSize()));
|
||||
jassert (writer.blockSize2 == 0
|
||||
|| (writer.startIndex2 >= 0 && writer.startIndex2 < fifo.getTotalSize()));
|
||||
|
||||
writer.forEach ([this, &n] (int index) { this->buffer[index] = n++; });
|
||||
}
|
||||
}
|
||||
|
||||
AbstractFifo& fifo;
|
||||
int* buffer;
|
||||
Random random;
|
||||
};
|
||||
|
||||
void runTest() override
|
||||
{
|
||||
beginTest ("AbstractFifo");
|
||||
|
||||
int buffer[5000];
|
||||
AbstractFifo fifo (numElementsInArray (buffer));
|
||||
|
||||
WriteThread writer (fifo, buffer, getRandom());
|
||||
|
||||
int n = 0;
|
||||
Random r = getRandom();
|
||||
r.combineSeed (12345);
|
||||
|
||||
for (int count = 100000; --count >= 0;)
|
||||
{
|
||||
int num = r.nextInt (6000) + 1;
|
||||
|
||||
auto reader = fifo.read (num);
|
||||
|
||||
if (! (reader.blockSize1 >= 0 && reader.blockSize2 >= 0)
|
||||
&& (reader.blockSize1 == 0
|
||||
|| (reader.startIndex1 >= 0 && reader.startIndex1 < fifo.getTotalSize()))
|
||||
&& (reader.blockSize2 == 0
|
||||
|| (reader.startIndex2 >= 0 && reader.startIndex2 < fifo.getTotalSize())))
|
||||
{
|
||||
expect (false, "prepareToRead returned -ve values");
|
||||
break;
|
||||
}
|
||||
|
||||
bool failed = false;
|
||||
|
||||
reader.forEach ([&failed, &buffer, &n] (int index)
|
||||
{
|
||||
failed = (buffer[index] != n++) || failed;
|
||||
});
|
||||
|
||||
if (failed)
|
||||
{
|
||||
expect (false, "read values were incorrect");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static AbstractFifoTests fifoUnitTests;
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace juce
|
Reference in New Issue
Block a user