| 
																	
																	
																	
																 | 
																@@ -0,0 +1,758 @@ | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																/* | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																 * DISTRHO Plugin Framework (DPF) | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																 * Copyright (C) 2012-2021 Filipe Coelho <falktx@falktx.com> | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																 * | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																 * 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. | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																 * | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																 * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																 */ | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																#ifndef DISTRHO_RING_BUFFER_HPP_INCLUDED | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																#define DISTRHO_RING_BUFFER_HPP_INCLUDED | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																#include "../DistrhoUtils.hpp" | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																START_NAMESPACE_DISTRHO | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																// ----------------------------------------------------------------------- | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																// Buffer structs | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																/** | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																   Base structure for all RingBuffer containers. | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																   This struct details the data model used in DPF's RingBuffer class. | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																   DPF RingBuffer uses a struct just like this one to store positions, buffer data, size, etc. | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																   The RingBuffer itself takes ownership of this struct and uses it to store any needed data. | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																   This allows to dynamically change the way its ring buffer is allocated, simply by changing the template type. | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																   For example, `RingBufferControl<HeapBuffer>` will create a ring buffer with heap memory, which can be of any size. | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																   In the same vein, `RingBufferControl<SmallStackBuffer>` will create a ring buffer with stack memory, | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																   directly tied to the RingBufferControl it belongs to. | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																   The main idea behind this model is to allow RingBufferControl over memory created elsewhere, | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																   for example shared memory area. | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																   One can create/place the Buffer struct in shared memory, and point RingBufferControl to it, | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																   thus avoiding the pitfalls of sharing access to a non trivially-copyable/POD C++ class. | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																   Unlike other ring buffers, an extra variable is used to track pending writes. | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																   This is so we can write a few bytes at a time and later mark the whole operation as complete, | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																   thus avoiding the issue of reading data too early from the other side. | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																   For example, write the size of some data first, and then the actual data. | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																   The reading side will only see data available once size + data is completely written and "committed". | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																 */ | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																struct HeapBuffer { | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																   /** | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																      Size of the buffer, allocated in @a buf. | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																      If the size is fixed (stack buffer), this variable can be static. | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    */ | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    uint32_t size; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																   /** | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																      Current writing position, headmost position of the buffer. | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																      Increments when writing. | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    */ | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    uint32_t head; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																   /** | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																      Current reading position, last used position of the buffer. | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																      Increments when reading. | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																      head == tail means empty buffer. | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    */ | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    uint32_t tail; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																   /** | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																      Temporary position of head until a commitWrite() is called. | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																      If buffer writing fails, wrtn will be back to head position thus ignoring the last operation(s). | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																      If buffer writing succeeds, head will be set to this variable. | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    */ | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    uint32_t wrtn; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																   /** | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																      Boolean used to check if a write operation failed. | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																      This ensures we don't get incomplete writes. | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    */ | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    bool invalidateCommit; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																   /** | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																      Pointer to buffer data. | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																      This can be either stack or heap data, depending on the usecase. | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    */ | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    uint8_t* buf; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																}; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																/** | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																   RingBufferControl compatible struct with a relatively small stack size (4k bytes). | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																   @see HeapBuffer | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																*/ | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																struct SmallStackBuffer { | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    static const uint32_t size = 4096; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    uint32_t head, tail, wrtn; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    bool     invalidateCommit; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    uint8_t  buf[size]; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																}; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																/** | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																   RingBufferControl compatible struct with a relatively big stack size (16k bytes). | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																   @see HeapBuffer | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																*/ | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																struct BigStackBuffer { | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    static const uint32_t size = 16384; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    uint32_t head, tail, wrtn; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    bool     invalidateCommit; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    uint8_t  buf[size]; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																}; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																/** | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																   RingBufferControl compatible struct with a huge stack size (64k bytes). | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																   @see HeapBuffer | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																*/ | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																struct HugeStackBuffer { | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    static const uint32_t size = 65536; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    uint32_t head, tail, wrtn; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    bool     invalidateCommit; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    uint8_t  buf[size]; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																}; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																// ----------------------------------------------------------------------- | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																// RingBufferControl templated class | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																/** | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																   DPF built-in RingBuffer class. | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																   RingBufferControl takes one buffer struct to take control over, and operates over it. | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																   This is meant for single-writer, single-reader type of control. | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																   Writing and reading is wait and lock-free. | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																   Typically usage involves: | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																   ``` | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																   // definition | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																   RingBufferControl<HeapBuffer> myHeapBuffer; // or HeapRingBuffer class directly | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																   // construction, only needed for heap buffers | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																   myHeapBuffer.createBuffer(8192); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																   // writing data | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																   myHeapBuffer.writeUInt(size); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																   myHeapBuffer.writeCustomData(someOtherData, size); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																   myHeapBuffer.commitWrite(); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																   // reading data | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																   if (myHeapBuffer.isDataAvailableForReading()) | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																   { | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																      uint32_t size; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																      if (myHeapBuffer.readUInt(size) && readCustomData(&anotherData, size)) | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																      { | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																          // do something with "anotherData" | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																      } | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																   } | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																   ``` | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																   @see HeapBuffer | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																 */ | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																template <class BufferStruct> | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																class RingBufferControl | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																{ | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																public: | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    /* | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																     * Constructor for unitialized ring buffer. | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																     * A call to setRingBuffer is required to tied this control to a ring buffer struct; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																     * | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																     */ | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    RingBufferControl() noexcept | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        : buffer(nullptr), | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																          errorReading(false), | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																          errorWriting(false) {} | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    /* | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																     * Destructor. | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																     */ | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    virtual ~RingBufferControl() noexcept {} | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    // ------------------------------------------------------------------- | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    // check operations | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    /* | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																     * Check if there is any data available for reading, regardless of size. | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																     */ | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    bool isDataAvailableForReading() const noexcept; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    /* | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																     * Check if ring buffer is empty (that is, there is nothing to read). | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																     */ | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    bool isEmpty() const noexcept | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    { | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        DISTRHO_SAFE_ASSERT_RETURN(buffer != nullptr, false); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        return (buffer->buf == nullptr || buffer->head == buffer->tail); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    } | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    /* | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																     * Get the size of the data available to read. | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																     */ | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    uint32_t getAvailableDataSize() const noexcept | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    { | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        DISTRHO_SAFE_ASSERT_RETURN(buffer != nullptr, 0); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        const uint32_t wrap((buffer->tail > buffer->wrtn) ? 0 : buffer->size); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        return wrap + buffer->tail - buffer->wrtn; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    } | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    // ------------------------------------------------------------------- | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    // clear/reset operations | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    /* | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																     * Clear the entire ring buffer data, marking the buffer as empty. | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																     * Requires a buffer struct tied to this class. | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																     */ | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    void clearData() noexcept | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    { | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        DISTRHO_SAFE_ASSERT_RETURN(buffer != nullptr,); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        buffer->head = 0; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        buffer->tail = 0; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        buffer->wrtn = 0; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        buffer->invalidateCommit = false; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        std::memset(buffer->buf, 0, buffer->size); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    } | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    // ------------------------------------------------------------------- | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    // read operations | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    /* | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																     * Read a single boolean value. | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																     * Returns false if reading fails. | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																     */ | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    bool readBool() noexcept | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    { | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        bool b = false; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        return tryRead(&b, sizeof(bool)) ? b : false; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    } | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    /* | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																     * Read a single 8-bit byte. | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																     * Returns 0 if reading fails. | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																     */ | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    uint8_t readByte() noexcept | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    { | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        uint8_t B = 0; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        return tryRead(&B, sizeof(uint8_t)) ? B : 0; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    } | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    /* | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																     * Read a short 16-bit integer. | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																     * Returns 0 if reading fails. | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																     */ | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    int16_t readShort() noexcept | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    { | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        int16_t s = 0; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        return tryRead(&s, sizeof(int16_t)) ? s : 0; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    } | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    /* | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																     * Read a short unsigned 16-bit integer. | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																     * Returns 0 if reading fails. | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																     */ | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    uint16_t readUShort() noexcept | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    { | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        uint16_t us = 0; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        return tryRead(&us, sizeof(uint16_t)) ? us : 0; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    } | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    /* | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																     * Read a regular 32-bit integer. | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																     * Returns 0 if reading fails. | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																     */ | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    int32_t readInt() noexcept | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    { | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        int32_t i = 0; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        return tryRead(&i, sizeof(int32_t)) ? i : 0; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    } | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    /* | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																     * Read an unsigned 32-bit integer. | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																     * Returns 0 if reading fails. | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																     */ | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    uint32_t readUInt() noexcept | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    { | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        uint32_t ui = 0; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        return tryRead(&ui, sizeof(int32_t)) ? ui : 0; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    } | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    /* | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																     * Read a long 64-bit integer. | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																     * Returns 0 if reading fails. | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																     */ | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    int64_t readLong() noexcept | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    { | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        int64_t l = 0; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        return tryRead(&l, sizeof(int64_t)) ? l : 0; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    } | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    /* | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																     * Read a long unsigned 64-bit integer. | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																     * Returns 0 if reading fails. | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																     */ | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    uint64_t readULong() noexcept | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    { | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        uint64_t ul = 0; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        return tryRead(&ul, sizeof(int64_t)) ? ul : 0; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    } | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    /* | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																     * Read a single-precision floating point number. | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																     * Returns 0 if reading fails. | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																     */ | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    float readFloat() noexcept | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    { | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        float f = 0.0f; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        return tryRead(&f, sizeof(float)) ? f : 0.0f; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    } | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    /* | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																     * Read a double-precision floating point number. | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																     * Returns 0 if reading fails. | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																     */ | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    double readDouble() noexcept | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    { | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        double d = 0.0; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        return tryRead(&d, sizeof(double)) ? d : 0.0; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    } | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    /*! | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																     * Read an arbitrary amount of data, specified by @a size. | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																     * data pointer must be non-null, and size > 0. | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																     * | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																     * Returns true if reading succeeds. | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																     * In case of failure, @a data pointer is automatically cleared by @a size bytes. | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																     */ | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    bool readCustomData(void* const data, const uint32_t size) noexcept | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    { | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        DISTRHO_SAFE_ASSERT_RETURN(data != nullptr, false); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        DISTRHO_SAFE_ASSERT_RETURN(size > 0, false); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        if (tryRead(data, size)) | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																            return true; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        std::memset(data, 0, size); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        return false; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    } | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    /*! | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																     * Read a custom data type specified by the template typename used, | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																     * with size being automatically deduced by the compiler (through the use of sizeof). | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																     * | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																     * Returns true if reading succeeds. | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																     * In case of failure, @a type value is automatically cleared by its deduced size. | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																     */ | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    template <typename T> | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    bool readCustomType(T& type) noexcept | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    { | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        if (tryRead(&type, sizeof(T))) | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																            return true; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        std::memset(&type, 0, sizeof(T)); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        return false; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    } | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    // ------------------------------------------------------------------- | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    // write operations | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    /* | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																     * Write a single boolean value. | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																     */ | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    bool writeBool(const bool value) noexcept | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    { | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        return tryWrite(&value, sizeof(bool)); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    } | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    /* | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																     * Write a single 8-bit byte. | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																     */ | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    bool writeByte(const uint8_t value) noexcept | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    { | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        return tryWrite(&value, sizeof(uint8_t)); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    } | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    /* | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																     * Write a short 16-bit integer. | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																     */ | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    bool writeShort(const int16_t value) noexcept | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    { | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        return tryWrite(&value, sizeof(int16_t)); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    } | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    /* | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																     * Write a short unsigned 16-bit integer. | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																     */ | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    bool writeUShort(const uint16_t value) noexcept | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    { | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        return tryWrite(&value, sizeof(uint16_t)); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    } | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    /* | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																     * Write a regular 32-bit integer. | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																     */ | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    bool writeInt(const int32_t value) noexcept | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    { | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        return tryWrite(&value, sizeof(int32_t)); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    } | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    /* | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																     * Write an unsigned 32-bit integer. | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																     */ | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    bool writeUInt(const uint32_t value) noexcept | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    { | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        return tryWrite(&value, sizeof(uint32_t)); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    } | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    /* | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																     * Write a long 64-bit integer. | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																     */ | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    bool writeLong(const int64_t value) noexcept | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    { | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        return tryWrite(&value, sizeof(int64_t)); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    } | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    /* | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																     * Write a long unsigned 64-bit integer. | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																     */ | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    bool writeULong(const uint64_t value) noexcept | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    { | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        return tryWrite(&value, sizeof(uint64_t)); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    } | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    /* | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																     * Write a single-precision floating point number. | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																     */ | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    bool writeFloat(const float value) noexcept | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    { | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        return tryWrite(&value, sizeof(float)); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    } | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    /* | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																     * Write a double-precision floating point number. | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																     */ | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    bool writeDouble(const double value) noexcept | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    { | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        return tryWrite(&value, sizeof(double)); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    } | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    /*! | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																     * Write an arbitrary amount of data, specified by @a size. | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																     * data pointer must be non-null, and size > 0. | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																     */ | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    bool writeCustomData(const void* const data, const uint32_t size) noexcept | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    { | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        DISTRHO_SAFE_ASSERT_RETURN(data != nullptr, false); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        DISTRHO_SAFE_ASSERT_RETURN(size > 0, false); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        return tryWrite(data, size); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    } | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    /*! | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																     * Write a custom data type specified by the template typename used, | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																     * with size being automatically deduced by the compiler (through the use of sizeof). | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																     */ | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    template <typename T> | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    bool writeCustomType(const T& type) noexcept | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    { | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        return tryWrite(&type, sizeof(T)); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    } | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    // ------------------------------------------------------------------- | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    /*! | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																     * Commit all previous write operations to the ringbuffer. | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																     * If a write operation has previously failed, this will reset/invalidate the previous write attempts. | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																     */ | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    bool commitWrite() noexcept | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    { | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        DISTRHO_SAFE_ASSERT_RETURN(buffer != nullptr, false); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        if (buffer->invalidateCommit) | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        { | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																            buffer->wrtn = buffer->head; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																            buffer->invalidateCommit = false; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																            return false; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        } | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        // nothing to commit? | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        DISTRHO_SAFE_ASSERT_RETURN(buffer->head != buffer->wrtn, false); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        // all ok | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        buffer->head = buffer->wrtn; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        errorWriting = false; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        return true; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    } | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    // ------------------------------------------------------------------- | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																protected: | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    /* | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																     * Tie this ring buffer control to a ring buffer struct, optionally clearing its data. | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																     */ | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    void setRingBuffer(BufferStruct* const ringBuf, const bool clearRingBufferData) noexcept | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    { | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        DISTRHO_SAFE_ASSERT_RETURN(buffer != ringBuf,); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        buffer = ringBuf; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        if (clearRingBufferData && ringBuf != nullptr) | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																            clearData(); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    } | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    // ------------------------------------------------------------------- | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    /** @internal try reading from the buffer, can fail. */ | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    bool tryRead(void* const buf, const uint32_t size) noexcept | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    { | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        DISTRHO_SAFE_ASSERT_RETURN(buffer != nullptr, false); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        #if defined(__clang__) | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        # pragma clang diagnostic push | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        # pragma clang diagnostic ignored "-Wtautological-pointer-compare" | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        #endif | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        DISTRHO_SAFE_ASSERT_RETURN(buffer->buf != nullptr, false); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        #if defined(__clang__) | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        # pragma clang diagnostic pop | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        #endif | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        DISTRHO_SAFE_ASSERT_RETURN(buf != nullptr, false); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        DISTRHO_SAFE_ASSERT_RETURN(size > 0, false); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        DISTRHO_SAFE_ASSERT_RETURN(size < buffer->size, false); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        // empty | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        if (buffer->head == buffer->tail) | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																            return false; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        uint8_t* const bytebuf(static_cast<uint8_t*>(buf)); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        const uint32_t head(buffer->head); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        const uint32_t tail(buffer->tail); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        const uint32_t wrap((head > tail) ? 0 : buffer->size); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        if (size > wrap + head - tail) | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        { | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																            if (! errorReading) | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																            { | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																                errorReading = true; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																                d_stderr2("RingBuffer::tryRead(%p, %lu): failed, not enough space", buf, (ulong)size); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																            } | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																            return false; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        } | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        uint32_t readto(tail + size); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        if (readto > buffer->size) | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        { | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																            readto -= buffer->size; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																            if (size == 1) | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																            { | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																                std::memcpy(bytebuf, buffer->buf + tail, 1); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																            } | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																            else | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																            { | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																                const uint32_t firstpart(buffer->size - tail); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																                std::memcpy(bytebuf, buffer->buf + tail, firstpart); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																                std::memcpy(bytebuf + firstpart, buffer->buf, readto); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																            } | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        } | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        else | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        { | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																            std::memcpy(bytebuf, buffer->buf + tail, size); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																            if (readto == buffer->size) | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																                readto = 0; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        } | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        buffer->tail = readto; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        errorReading = false; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        return true; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    } | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    /** @internal try writing to the buffer, can fail. */ | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    bool tryWrite(const void* const buf, const uint32_t size) noexcept | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    { | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        DISTRHO_SAFE_ASSERT_RETURN(buffer != nullptr, false); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        DISTRHO_SAFE_ASSERT_RETURN(buf != nullptr, false); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        DISTRHO_SAFE_ASSERT_RETURN(size > 0, false); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        CARLA_SAFE_ASSERT_UINT2_RETURN(size < buffer->size, size, buffer->size, false); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        const uint8_t* const bytebuf(static_cast<const uint8_t*>(buf)); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        const uint32_t tail(buffer->tail); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        const uint32_t wrtn(buffer->wrtn); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        const uint32_t wrap((tail > wrtn) ? 0 : buffer->size); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        if (size >= wrap + tail - wrtn) | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        { | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																            if (! errorWriting) | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																            { | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																                errorWriting = true; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																                d_stderr2("RingBuffer::tryWrite(%p, %lu): failed, not enough space", buf, (ulong)size); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																            } | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																            buffer->invalidateCommit = true; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																            return false; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        } | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        uint32_t writeto(wrtn + size); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        if (writeto > buffer->size) | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        { | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																            writeto -= buffer->size; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																            if (size == 1) | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																            { | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																                std::memcpy(buffer->buf, bytebuf, 1); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																            } | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																            else | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																            { | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																                const uint32_t firstpart(buffer->size - wrtn); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																                std::memcpy(buffer->buf + wrtn, bytebuf, firstpart); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																                std::memcpy(buffer->buf, bytebuf + firstpart, writeto); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																            } | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        } | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        else | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        { | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																            std::memcpy(buffer->buf + wrtn, bytebuf, size); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																            if (writeto == buffer->size) | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																                writeto = 0; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        } | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        buffer->wrtn = writeto; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        return true; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    } | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																private: | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    /** Buffer struct pointer. */ | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    BufferStruct* buffer; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    /** Whether read errors have been printed to terminal. */ | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    bool errorReading; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    /** Whether write errors have been printed to terminal. */ | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    bool errorWriting; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    DISTRHO_PREVENT_VIRTUAL_HEAP_ALLOCATION | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    DISTRHO_DECLARE_NON_COPYABLE(RingBufferControl) | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																}; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																template <class BufferStruct> | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																inline bool RingBufferControl<BufferStruct>::isDataAvailableForReading() const noexcept | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																{ | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    return (buffer != nullptr && buffer->head != buffer->tail); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																} | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																template <> | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																inline bool RingBufferControl<HeapBuffer>::isDataAvailableForReading() const noexcept | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																{ | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    return (buffer != nullptr && buffer->buf != nullptr && buffer->head != buffer->tail); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																} | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																// ----------------------------------------------------------------------- | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																// RingBuffer using heap space | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																/** | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																   RingBufferControl with a heap buffer. | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																   This is a convenience class that provides a method for creating and destroying the heap data. | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																   Requires the use of createBuffer(uint32_t) to make the ring buffer usable. | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																*/ | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																class HeapRingBuffer : public RingBufferControl<HeapBuffer> | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																{ | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																public: | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    /** Constructor. */ | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    HeapRingBuffer() noexcept | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        : heapBuffer({0, 0, 0, 0, false, nullptr}) | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    { | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																#ifndef DISTRHO_PROPER_CPP11_SUPPORT | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        std::memset(&heapBuffer, 0, sizeof(heapBuffer)); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																#endif | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    } | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    /** Destructor. */ | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    ~HeapRingBuffer() noexcept override | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    { | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        if (heapBuffer.buf == nullptr) | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																            return; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        delete[] heapBuffer.buf; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        heapBuffer.buf = nullptr; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    } | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    /** Create a buffer of the specified size. */ | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    bool createBuffer(const uint32_t size) noexcept | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    { | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        DISTRHO_SAFE_ASSERT_RETURN(heapBuffer.buf == nullptr, false); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        DISTRHO_SAFE_ASSERT_RETURN(size > 0,  false); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        const uint32_t p2size = d_nextPowerOf2(size); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        try { | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																            heapBuffer.buf = new uint8_t[p2size]; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        } DISTRHO_SAFE_EXCEPTION_RETURN("HeapRingBuffer::createBuffer", false); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        heapBuffer.size = p2size; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        setRingBuffer(&heapBuffer, true); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    } | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    /** Delete the previously allocated buffer. */ | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    void deleteBuffer() noexcept | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    { | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        DISTRHO_SAFE_ASSERT_RETURN(heapBuffer.buf != nullptr,); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        setRingBuffer(nullptr, false); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        delete[] heapBuffer.buf; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        heapBuffer.buf  = nullptr; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        heapBuffer.size = 0; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    } | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																private: | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    /** The heap buffer used for this class. */ | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    HeapBuffer heapBuffer; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    DISTRHO_PREVENT_VIRTUAL_HEAP_ALLOCATION | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    DISTRHO_DECLARE_NON_COPYABLE(HeapRingBuffer) | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																}; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																// ----------------------------------------------------------------------- | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																// RingBuffer using small stack space | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																/** | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																   RingBufferControl with an included small stack buffer. | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																   No setup is necessary, this class is usable as-is. | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																*/ | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																class SmallStackRingBuffer : public RingBufferControl<SmallStackBuffer> | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																{ | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																public: | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    /** Constructor. */ | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    SmallStackRingBuffer() noexcept | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        : stackBuffer({0, 0, 0, false, {0}}) | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    { | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																#ifndef DISTRHO_PROPER_CPP11_SUPPORT | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        std::memset(&stackBuffer, 0, sizeof(stackBuffer)); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																#endif | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        setRingBuffer(&stackBuffer, true); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    } | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																private: | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    /** The small stack buffer used for this class. */ | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    SmallStackBuffer stackBuffer; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    DISTRHO_PREVENT_VIRTUAL_HEAP_ALLOCATION | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    DISTRHO_DECLARE_NON_COPYABLE(SmallStackRingBuffer) | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																}; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																// ----------------------------------------------------------------------- | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																END_NAMESPACE_DISTRHO | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																#endif // DISTRHO_RING_BUFFER_HPP_INCLUDED |