class RingBuffer
Defined at line 968 of file fidling/gen/sdk/fidl/fuchsia.audio/fuchsia.audio/cpp/fidl/fuchsia.audio/cpp/natural_types.h
A ring buffer of audio data.
Each ring buffer has a producer (who writes to the buffer) and a consumer
(who reads from the buffer). Additionally, each ring buffer is associated
with a reference clock that keeps time for the buffer.
## PCM Data
A ring buffer of PCM audio is a window into a potentially-infinite sequence
of frames. Each frame is assigned a "frame number" where the first frame in
the infinite sequence is numbered 0. Frame `X` can be found at ring buffer
offset `(X % RingBufferFrames) * BytesPerFrame`, where `RingBufferFrames` is
the size of the ring buffer in frames and `BytesPerFrame` is the size of a
single frame.
## Concurrency Protocol
Each ring buffer has a single producer and a single consumer which are
synchronized by time. At each point in time T according to the ring buffer's
reference clock, we define two functions:
* `SafeWritePos(T)` is the lowest (oldest) frame number the producer is
allowed to write. The producer can write to this frame or to any
higher-numbered frame.
* `SafeReadPos(T)` is the highest (youngest) frame number the consumer is
allowed to read. The consumer can read this frame or any lower-numbered
frame.
To prevent conflicts, we define these to be offset by one:
```
SafeWritePos(T) = SafeReadPos(T) + 1
```
To avoid races, there must be a single producer, but there may be multiple
consumers. Additionally, since the producer and consumer(s) are synchronized
by *time*, we require explicit fences to ensure cache coherency: the
producer must insert an appropriate fence after each write (to flush CPU
caches and prevent compiler reordering of stores) and the consumer(s) must
insert an appropriate fence before each read (to invalidate CPU caches and
prevent compiler reordering of loads).
Since the buffer has finite size, the producer/consumer cannot write/read
infinitely in the future/past. We allocate `P` frames to the producer and
`C` frames to the consumer(s), where `P + C
<
= RingBufferFrames` and `P` and
`C` are both chosen by whoever creates the ring buffer.
## Deciding on `P` and `C`
In practice, producers/consumers typically write/read batches of frames
on regular periods. For example, a producer might wake every `Dp`
milliseconds to write `Dp*FrameRate` frames, where `FrameRate` is the PCM
stream's frame rate. If a producer wakes at time T, it will spend up to the
next `Dp` period writing those frames. This means the lowest frame number it
can safely write to is `SafeWritePos(T+Dp)`, which is equivalent to
`SafeWritePos(T) + Dp*FrameRate`. The producer writes `Dp*FrameRate` frames
from the position onwards. This entire region, from `SafeWritePos(T)`
through `2*Dp*FrameRate` must be allocated to the producer at time T. Making
a similar argument for consumers, we arrive at the following constraints:
```
P >= 2*Dp*FrameRate
C >= 2*Dc*FrameRate
RingBufferFrames >= P + C
```
Hence, in practice, `P` and `C` can be derived from the batch sizes used by
the producer and consumer, where the maximum batch sizes are limited by the
ring buffer size.
## Defining `SafeWritePos`
The definition of `SafeWritePos` (and, implicitly, `SafeReadPos`) must be
provided out-of-band.
## Non-PCM Data
Non-PCM data is handled similarly to PCM data, except positions are
expressed as "byte offsets" instead of "frame numbers", where the infinite
sequence starts at byte offset 0.
Public Methods
void RingBuffer (Storage_ storage)
bool IsEmpty ()
void RingBuffer ()
Defined at line 974 of file fidling/gen/sdk/fidl/fuchsia.audio/fuchsia.audio/cpp/fidl/fuchsia.audio/cpp/natural_types.h
void RingBuffer (RingBuffer && )
Defined at line 975 of file fidling/gen/sdk/fidl/fuchsia.audio/fuchsia.audio/cpp/fidl/fuchsia.audio/cpp/natural_types.h
const std::optional< ::fuchsia_mem::Buffer> & buffer ()
The actual ring buffer. The sum of `producer_bytes` and `consumer_bytes`
must be
<
= `buffer.size`.
Required.
::std::optional< ::fuchsia_mem::Buffer> & buffer ()
The actual ring buffer. The sum of `producer_bytes` and `consumer_bytes`
must be
<
= `buffer.size`.
Required.
RingBuffer & buffer (std::optional< ::fuchsia_mem::Buffer> value)
The actual ring buffer. The sum of `producer_bytes` and `consumer_bytes`
must be
<
= `buffer.size`.
Required.
const std::optional< ::fuchsia_audio::Format> & format ()
Encoding of audio data in the buffer.
Required.
::std::optional< ::fuchsia_audio::Format> & format ()
Encoding of audio data in the buffer.
Required.
RingBuffer & format (std::optional< ::fuchsia_audio::Format> value)
Encoding of audio data in the buffer.
Required.
RingBuffer & operator= (RingBuffer && )
Defined at line 976 of file fidling/gen/sdk/fidl/fuchsia.audio/fuchsia.audio/cpp/fidl/fuchsia.audio/cpp/natural_types.h
const std::optional<uint64_t> & producer_bytes ()
The number of bytes allocated to the producer.
For PCM encodings, `P = producer_bytes / BytesPerFrame(format)`, where P
must be integral.
For non-PCM encodings, there are no constraints, however individual encodings
may impose stricter requirements.
Required.
::std::optional<uint64_t> & producer_bytes ()
The number of bytes allocated to the producer.
For PCM encodings, `P = producer_bytes / BytesPerFrame(format)`, where P
must be integral.
For non-PCM encodings, there are no constraints, however individual encodings
may impose stricter requirements.
Required.
RingBuffer & producer_bytes (std::optional<uint64_t> value)
The number of bytes allocated to the producer.
For PCM encodings, `P = producer_bytes / BytesPerFrame(format)`, where P
must be integral.
For non-PCM encodings, there are no constraints, however individual encodings
may impose stricter requirements.
Required.
const std::optional<uint64_t> & consumer_bytes ()
The number of bytes allocated to the consumer.
For PCM encodings, `C = consumer_bytes / BytesPerFrame(format)`, where C
must be integral.
For non-PCM encodings, there are no constraints, however individual encodings
may impose stricter requirements.
Required.
::std::optional<uint64_t> & consumer_bytes ()
The number of bytes allocated to the consumer.
For PCM encodings, `C = consumer_bytes / BytesPerFrame(format)`, where C
must be integral.
For non-PCM encodings, there are no constraints, however individual encodings
may impose stricter requirements.
Required.
RingBuffer & consumer_bytes (std::optional<uint64_t> value)
The number of bytes allocated to the consumer.
For PCM encodings, `C = consumer_bytes / BytesPerFrame(format)`, where C
must be integral.
For non-PCM encodings, there are no constraints, however individual encodings
may impose stricter requirements.
Required.
const std::optional< ::zx::clock> & reference_clock ()
Reference clock for the ring buffer.
Required.
::std::optional< ::zx::clock> & reference_clock ()
Reference clock for the ring buffer.
Required.
RingBuffer & reference_clock (std::optional< ::zx::clock> value)
Reference clock for the ring buffer.
Required.
const std::optional<uint32_t> & reference_clock_domain ()
Domain of `reference_clock`. See `fuchsia.hardware.audio.ClockDomain`.
Optional. If not specified, defaults to `CLOCK_DOMAIN_EXTERNAL`.
::std::optional<uint32_t> & reference_clock_domain ()
Domain of `reference_clock`. See `fuchsia.hardware.audio.ClockDomain`.
Optional. If not specified, defaults to `CLOCK_DOMAIN_EXTERNAL`.
RingBuffer & reference_clock_domain (std::optional<uint32_t> value)
Domain of `reference_clock`. See `fuchsia.hardware.audio.ClockDomain`.
Optional. If not specified, defaults to `CLOCK_DOMAIN_EXTERNAL`.
void RingBuffer (::fidl::internal::DefaultConstructPossiblyInvalidObjectTag )
Friends
class MemberVisitor
class NaturalTableCodingTraits