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