JUCE  v6.1.6 (6.0.8-1114)
JUCE API
Looking for a senior C++ dev?
I'm looking for work. Hire me!
juce::AbstractFifo Class Reference

Encapsulates the logic required to implement a lock-free FIFO. More...

#include <juce_AbstractFifo.h>

Collaboration diagram for juce::AbstractFifo:

Classes

class  ScopedReadWrite
 Class for a scoped reader/writer. More...
 

Public Types

using ScopedRead = ScopedReadWrite< ReadOrWrite::read >
 
using ScopedWrite = ScopedReadWrite< ReadOrWrite::write >
 

Public Member Functions

 AbstractFifo (int capacity) noexcept
 Creates a FIFO to manage a buffer with the specified capacity. More...
 
void finishedRead (int numRead) noexcept
 Called after reading from the FIFO, to indicate that this many items have now been consumed. More...
 
void finishedWrite (int numWritten) noexcept
 Called after writing from the FIFO, to indicate that this many items have been added. More...
 
int getFreeSpace () const noexcept
 Returns the number of items that can currently be added to the buffer without it overflowing. More...
 
int getNumReady () const noexcept
 Returns the number of items that can currently be read from the buffer. More...
 
int getTotalSize () const noexcept
 Returns the total size of the buffer being managed. More...
 
void prepareToRead (int numWanted, int &startIndex1, int &blockSize1, int &startIndex2, int &blockSize2) const noexcept
 Returns the location within the buffer from which the next block of data should be read. More...
 
void prepareToWrite (int numToWrite, int &startIndex1, int &blockSize1, int &startIndex2, int &blockSize2) const noexcept
 Returns the location within the buffer at which an incoming block of data should be written. More...
 
ScopedRead read (int numToRead) noexcept
 Replaces prepareToRead/finishedRead with a single function. More...
 
void reset () noexcept
 Clears the buffer positions, so that it appears empty. More...
 
void setTotalSize (int newSize) noexcept
 Changes the buffer's total size. More...
 
ScopedWrite write (int numToWrite) noexcept
 Replaces prepareToWrite/finishedWrite with a single function. More...
 

Private Types

enum  ReadOrWrite {
  ReadOrWrite::read,
  ReadOrWrite::write
}
 

Private Attributes

int bufferSize
 
Atomic< intvalidEnd
 
Atomic< intvalidStart
 

Detailed Description

Encapsulates the logic required to implement a lock-free FIFO.

This class handles the logic needed when building a single-reader, single-writer FIFO.

It doesn't actually hold any data itself, but your FIFO class can use one of these to manage its position and status when reading or writing to it.

To use it, you can call prepareToWrite() to determine the position within your own buffer that an incoming block of data should be stored, and prepareToRead() to find out when the next outgoing block should be read from.

e.g.

struct MyFifo
{
void addToFifo (const int* someData, int numItems)
{
const auto scope = abstractFifo.write (numItems);
if (scope.blockSize1 > 0)
copySomeData (myBuffer + scope.startIndex1, someData, scope.blockSize1);
if (scope.blockSize2 > 0)
copySomeData (myBuffer + scope.startIndex2, someData, scope.blockSize2);
}
void readFromFifo (int* someData, int numItems)
{
const auto scope = abstractFifo.read (numItems);
if (scope.blockSize1 > 0)
copySomeData (someData, myBuffer + scope.startIndex1, scope.blockSize1);
if (scope.blockSize2 > 0)
copySomeData (someData + scope.blockSize1, myBuffer + scope.startIndex2, scope.blockSize2);
}
AbstractFifo abstractFifo { 1024 };
int myBuffer[1024];
};

@tags{Core}

Member Typedef Documentation

◆ ScopedRead

◆ ScopedWrite

Member Enumeration Documentation

◆ ReadOrWrite

enum juce::AbstractFifo::ReadOrWrite
strongprivate
Enumerator
read 
write 

Constructor & Destructor Documentation

◆ AbstractFifo()

juce::AbstractFifo::AbstractFifo ( int  capacity)
noexcept

Creates a FIFO to manage a buffer with the specified capacity.

Member Function Documentation

◆ finishedRead()

void juce::AbstractFifo::finishedRead ( int  numRead)
noexcept

Called after reading from the FIFO, to indicate that this many items have now been consumed.

See also
prepareToRead

◆ finishedWrite()

void juce::AbstractFifo::finishedWrite ( int  numWritten)
noexcept

Called after writing from the FIFO, to indicate that this many items have been added.

See also
prepareToWrite

◆ getFreeSpace()

int juce::AbstractFifo::getFreeSpace ( ) const
noexcept

Returns the number of items that can currently be added to the buffer without it overflowing.

◆ getNumReady()

int juce::AbstractFifo::getNumReady ( ) const
noexcept

Returns the number of items that can currently be read from the buffer.

◆ getTotalSize()

int juce::AbstractFifo::getTotalSize ( ) const
noexcept

Returns the total size of the buffer being managed.

◆ prepareToRead()

void juce::AbstractFifo::prepareToRead ( int  numWanted,
int startIndex1,
int blockSize1,
int startIndex2,
int blockSize2 
) const
noexcept

Returns the location within the buffer from which the next block of data should be read.

Because the section of data that you want to read from the buffer may overlap the end and wrap around to the start, two blocks within your buffer are returned, and you should read from both of them.

If the number of items you ask for is greater than the amount of data available, then blockSize1 + blockSize2 may add up to a lower value than numWanted. If this happens, you may decide to keep waiting and re-trying the method until there's enough data available.

After calling this method, if you choose to read the data, you must call finishedRead() to tell the FIFO how much data you have consumed.

e.g.

void readFromFifo (int* someData, int numItems)
{
int start1, size1, start2, size2;
prepareToRead (numSamples, start1, size1, start2, size2);
if (size1 > 0)
copySomeData (someData, myBuffer + start1, size1);
if (size2 > 0)
copySomeData (someData + size1, myBuffer + start2, size2);
finishedRead (size1 + size2);
}
Parameters
numWantedindicates how many items you'd like to add to the buffer
startIndex1on exit, this will contain the start index in your buffer at which your data should be written
blockSize1on exit, this indicates how many items can be written to the block starting at startIndex1
startIndex2on exit, this will contain the start index in your buffer at which any data that didn't fit into the first block should be written
blockSize2on exit, this indicates how many items can be written to the block starting at startIndex2
See also
finishedRead

◆ prepareToWrite()

void juce::AbstractFifo::prepareToWrite ( int  numToWrite,
int startIndex1,
int blockSize1,
int startIndex2,
int blockSize2 
) const
noexcept

Returns the location within the buffer at which an incoming block of data should be written.

Because the section of data that you want to add to the buffer may overlap the end and wrap around to the start, two blocks within your buffer are returned, and you should copy your data into the first one, with any remaining data spilling over into the second.

If the number of items you ask for is too large to fit within the buffer's free space, then blockSize1 + blockSize2 may add up to a lower value than numToWrite. If this happens, you may decide to keep waiting and re-trying the method until there's enough space available.

After calling this method, if you choose to write your data into the blocks returned, you must call finishedWrite() to tell the FIFO how much data you actually added.

e.g.

void addToFifo (const int* someData, int numItems)
{
int start1, size1, start2, size2;
prepareToWrite (numItems, start1, size1, start2, size2);
if (size1 > 0)
copySomeData (myBuffer + start1, someData, size1);
if (size2 > 0)
copySomeData (myBuffer + start2, someData + size1, size2);
finishedWrite (size1 + size2);
}
Parameters
numToWriteindicates how many items you'd like to add to the buffer
startIndex1on exit, this will contain the start index in your buffer at which your data should be written
blockSize1on exit, this indicates how many items can be written to the block starting at startIndex1
startIndex2on exit, this will contain the start index in your buffer at which any data that didn't fit into the first block should be written
blockSize2on exit, this indicates how many items can be written to the block starting at startIndex2
See also
finishedWrite

◆ read()

ScopedRead juce::AbstractFifo::read ( int  numToRead)
noexcept

Replaces prepareToRead/finishedRead with a single function.

This function returns an object which contains the start indices and block sizes, and also automatically finishes the read operation when it goes out of scope.

{
auto readHandle = fifo.read (4);
for (auto i = 0; i != readHandle.blockSize1; ++i)
{
// read the item at index readHandle.startIndex1 + i
}
for (auto i = 0; i != readHandle.blockSize2; ++i)
{
// read the item at index readHandle.startIndex2 + i
}
} // readHandle goes out of scope here, finishing the read operation

◆ reset()

void juce::AbstractFifo::reset ( )
noexcept

Clears the buffer positions, so that it appears empty.

◆ setTotalSize()

void juce::AbstractFifo::setTotalSize ( int  newSize)
noexcept

Changes the buffer's total size.

Note that this isn't thread-safe, so don't call it if there's any danger that it might overlap with a call to any other method in this class!

◆ write()

ScopedWrite juce::AbstractFifo::write ( int  numToWrite)
noexcept

Replaces prepareToWrite/finishedWrite with a single function.

This function returns an object which contains the start indices and block sizes, and also automatically finishes the write operation when it goes out of scope.

{
auto writeHandle = fifo.write (5);
for (auto i = 0; i != writeHandle.blockSize1; ++i)
{
// write the item at index writeHandle.startIndex1 + i
}
for (auto i = 0; i != writeHandle.blockSize2; ++i)
{
// write the item at index writeHandle.startIndex2 + i
}
} // writeHandle goes out of scope here, finishing the write operation

Member Data Documentation

◆ bufferSize

int juce::AbstractFifo::bufferSize
private

◆ validEnd

Atomic<int> juce::AbstractFifo::validEnd
private

◆ validStart

Atomic<int> juce::AbstractFifo::validStart
private

The documentation for this class was generated from the following file:
juce::AbstractFifo::finishedRead
void finishedRead(int numRead) noexcept
Called after reading from the FIFO, to indicate that this many items have now been consumed.
juce::AbstractFifo::prepareToRead
void prepareToRead(int numWanted, int &startIndex1, int &blockSize1, int &startIndex2, int &blockSize2) const noexcept
Returns the location within the buffer from which the next block of data should be read.
juce::AbstractFifo::finishedWrite
void finishedWrite(int numWritten) noexcept
Called after writing from the FIFO, to indicate that this many items have been added.
juce::AbstractFifo::prepareToWrite
void prepareToWrite(int numToWrite, int &startIndex1, int &blockSize1, int &startIndex2, int &blockSize2) const noexcept
Returns the location within the buffer at which an incoming block of data should be written.
juce::AbstractFifo::AbstractFifo
AbstractFifo(int capacity) noexcept
Creates a FIFO to manage a buffer with the specified capacity.