fuchsia.audio

Added: HEAD

PROTOCOLS

DelayWatcher

Defined in fuchsia.audio/delay.fidl

Watches for a delay to change.

WatchDelay

The first call returns immediately with the current delay, if known. Subsequent calls block until the delay changes. There can be at most one outstanding call, otherwise the channel may be closed.

Request

NameType
payload DelayWatcherWatchDelayRequest

Response

NameType
payload DelayWatcherWatchDelayResponse

GainControl

Defined in fuchsia.audio/gain.fidl

Enables control and monitoring of audio gain. This interface is typically a tear-off of other interfaces.

Knobs

This interface exposes two orthogonal knobs:

  • The gain knob controls a single value in "relative decibels". A value of 0 applies no gain, positive values increase gain, and negative values decrease gain. Depending on context, gain may be applied relative to an input stream or relative to some absolute reference point, such as the maximum loudness of a speaker.

    This knob has no defined maximum or minimum value. Individual implementations may clamp to an implementation-defined maximum value or treat all values below an implementation-defined minimum value equivalent to "muted", but this behavior is not required.

  • The mute knob controls a single boolean value. When true, the GainControl is muted and the effective gain is negative infinity. When false, gain is controlled by the gain knob.

Scheduling

Changes to the gain and mute knobs can be scheduled for a time in the future. Scheduling happens on timestamps relative to a reference clock which must be established when this protocol is created.

TODO(https://fxbug.dev/42176154): scheduling semantics are subject to change

SetGain

Sets the gain knob.

Request

NameType
payload GainControlSetGainRequest

Response

NameType
payload GainControl_SetGain_Result

SetMute

Set the mute knob.

Request

NameType
payload GainControlSetMuteRequest

Response

NameType
payload GainControl_SetMute_Result

StreamSink

Defined in fuchsia.audio/stream_sink.fidl

A packet sink for cross-process audio stream transport, implemented by audio consumers and used by audio producers.

End

Indicates that the end of the stream has been reached. Consumers such as audio renderers signal their clients when the last packet before end-of-stream has been rendered, so the client knows when to, for example, change the UI state of a player to let the user know the content is done playing. This method is logically scoped to the current segment. A SetSegment request and (typically) more packets may follow this request.

Request

<EMPTY>

OnWillClose

Sent immediately before the consumer closes to indicate why the consumer is closing the connection. After sending this event, the consumer must refrain from sending any more messages and close the connection promptly.

Response

NameType
payload StreamSinkOnWillCloseRequest

PutPacket

Puts a packet to the sink.

Request

NameType
payload StreamSinkPutPacketRequest

StartSegment

Starts a new segment. Packets following this request and preceding the next such request are assigned to the segment.

Request

NameType
payload StreamSinkStartSegmentRequest

WillClose

Sent immediately before the producer closes to indicate why the producer is closing the connection. After sending this request, the producer must refrain from sending any more messages and close the connection promptly.

Request

NameType
payload StreamSinkWillCloseRequest

STRUCTS

UnspecifiedBestEffort

Defined in fuchsia.audio/stream_sink.fidl

<EMPTY>

UnspecifiedContinuous

Defined in fuchsia.audio/stream_sink.fidl

<EMPTY>

ENUMS

ChannelConfig flexible

Type: uint32

Defined in fuchsia.audio/format.fidl

Spatial assignment of channels.

NameValueDescription
1

Front.C (CENTER)

2

Front.L (LEFT) | Front.R (RIGHT)

3

Front.L | Front.R | Back.L | Back.R, aka “Four corners”

4

Front.L | Front.R | Back.C, aka “LRS”

5

Front.L | Front.R | Front.C | Back.C, aka “LRCS”

6

Front.L | Front.R | Front.C | LFE | Side.L | Side.R

CompressionType flexible

Type: uint32

Defined in fuchsia.audio/compression.fidl

NameValueDescription
0
1
2
3
4
5
6
7
8
9
10
11
12
13

GainError flexible

Type: uint32

Defined in fuchsia.audio/gain.fidl

Type of errors returned by GainControl.

NameValueDescription
1

A required field was not provided.

2

A flexible field had an unsupported option. This can happen when a client built with API version X+1 talks to a server built with API version X.

SampleType flexible

Type: uint32

Defined in fuchsia.audio/format.fidl

Expresses the type of individual audio samples.

NameValueDescription
1
2
3
4
5

TABLES

Compression

Defined in fuchsia.audio/compression.fidl

Describes the compression applied to a stream.

OrdinalFieldTypeDescription
type CompressionType

The type of compression applied to the stream.

oob_parameters vector<uint8>:32768

Opaque ‘out-of-band’ parameters describing the compression of the stream. The format of this field is a function of the CompressionType. It communicates to decoders parameters that are required to decompress the described stream. Many compression types do not require this field.

DelayWatcherWatchDelayRequest

Defined in fuchsia.audio/delay.fidl

OrdinalFieldTypeDescription

DelayWatcherWatchDelayResponse

Defined in fuchsia.audio/delay.fidl

OrdinalFieldTypeDescription
delay zx/Duration

Optional. If not specified, the delay is unknown.

Format

Defined in fuchsia.audio/format.fidl

Describes a format used for audio streams without reference to compression. Where compression is supported, this type should be combined with fuchsia.media2.Compression. An uncompressed audio stream uses LPCM encoding.

OrdinalFieldTypeDescription
sample_type SampleType

The type of individual samples.

channel_count uint32

The number of samples per frame.

frames_per_second uint32

The number of frames per second.

channel_layout ChannelLayout

The spatial assignment of each channel.

GainControlSetGainRequest

Defined in fuchsia.audio/gain.fidl

OrdinalFieldTypeDescription
how GainUpdateMethod

How to update the gain knob.

Required.

when fuchsia.media2/RealTime

When to apply this update.

Required.

GainControlSetMuteRequest

Defined in fuchsia.audio/gain.fidl

OrdinalFieldTypeDescription
muted bool

New value of the mute knob.

Required.

when fuchsia.media2/RealTime

When to apply this update.

Required.

GainControl_SetGain_Response

Defined in fuchsia.audio/gain.fidl

OrdinalFieldTypeDescription

GainControl_SetMute_Response

Defined in fuchsia.audio/gain.fidl

OrdinalFieldTypeDescription

Packet

Defined in fuchsia.audio/stream_sink.fidl

Describes a packet delivered via StreamSink.

OrdinalFieldTypeDescription
payload fuchsia.media2/PayloadRange

Location of the payload for this packet. This field is required.

timestamp Timestamp

Timestamp indicating when this packet should be presented. Omitting this field implies an unspecified_best_effort timestamp.

capture_timestamp zx/Time

Capture time for this packet as a system monotonic time value. This field is optional and may be set by capturers to indicate when this packet was captured.

flags PacketFlags

Flags describing the packet. Omitting this field implies all flags are clear.

front_frames_to_drop uint32

Indicates how many frames should be dropped from the front of the output packet produced by a decoder from this input packet. This value should only be provided for compressed streams. If this field is omitted, no front frames should be dropped.

back_frames_to_drop uint32

Indicates how many frames should be dropped from the back of the output packet produced by a decoder from this input packet. This value should only be provided for compressed streams. If this field is omitted, no back frames should be dropped.

encryption_properties fuchsia.drm/PacketEncryptionProperties

Describes the encryption applied to this packet. Omitting this field implies the packet is not encrypted.

RampFunctionLinearSlope

Defined in fuchsia.audio/gain.fidl

Gain follows a linear slope over a linear domain.

For example, a ramp from gain -2.3dB to -1.6dB is a ramp in the linear domain from 0.1 to 0.5. If this is applied over 4ms, then the sequence of gain updates is:

  • At 0ms, gain = 0.1 = -2.3dB
  • At 1ms, gain = 0.2 = -2.0dB
  • At 2ms, gain = 0.3 = -1.8dB
  • At 3ms, gain = 0.4 = -1.7dB
  • At 4ms, gain = 0.5 = -1.6dB

Note that the changes in dB follow a logarithmic (not linear) curve.

OrdinalFieldTypeDescription

RampedGain

Defined in fuchsia.audio/gain.fidl

Describes a ramped gain command. When this command is applied, gain is ramped from its current value to the target value, over the specified duration, using the specified function.

OrdinalFieldTypeDescription
target_gain_db float32
duration zx/Duration
function RampFunction

RingBuffer resource

Defined in fuchsia.audio/ring_buffer.fidl

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 DpFrameRate 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) + DpFrameRate. The producer writes DpFrameRate frames from the position onwards. This entire region, from SafeWritePos(T) through 2DpFrameRate must be allocated to the producer at time T. Making a similar argument for consumers, we arrive at the following constraints:

P >= 2DpFrameRate
C >= 2Dc*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.

OrdinalFieldTypeDescription
buffer fuchsia.mem/Buffer

The actual ring buffer. The sum of producer_bytes and consumer_bytes must be <= buffer.size.

Required.

format Format

Encoding of audio data in the buffer. Required.

producer_bytes uint64

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.

consumer_bytes uint64

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.

reference_clock handle<clock>

Reference clock for the ring buffer.

Required.

reference_clock_domain uint32

Domain of reference_clock. See fuchsia.hardware.audio.ClockDomain. TODO(https://fxbug.dev/42066209): If fuchsia.hardware.audio doesn't need to import fuchsia.audio, we can use that type directly below.

Optional. If not specified, defaults to CLOCK_DOMAIN_EXTERNAL.

StreamSinkOnWillCloseRequest

Defined in fuchsia.audio/stream_sink.fidl

OrdinalFieldTypeDescription
reason fuchsia.media2/ConsumerClosedReason

Reason the connection will close.

StreamSinkPutPacketRequest resource

Defined in fuchsia.audio/stream_sink.fidl

OrdinalFieldTypeDescription
packet Packet

Describes the packet. This field is required.

release_fence handle<eventpair>

Eventpair closed when the consumer is done with the packet and the buffer region associated with the packet may be reused. Packets may be released in any order. The release fence may be duplicated by the service, so it must be sent with right ZX_RIGHT_DUPLICATE. This field is optional.

StreamSinkStartSegmentRequest

Defined in fuchsia.audio/stream_sink.fidl

OrdinalFieldTypeDescription
segment_id int64

Identifies the segment. New segment IDs for a given connection must always be strictly increasing. This field is required.

StreamSinkWillCloseRequest

Defined in fuchsia.audio/stream_sink.fidl

OrdinalFieldTypeDescription
reason fuchsia.media2/ProducerClosedReason

Reason the connection will close.

UNIONS

ChannelLayout flexible

Defined in fuchsia.audio/format.fidl

Expresses the intended assignment of channels in an audio elementary stream.

OrdinalVariantTypeDescription
config ChannelConfig

This value describes the assignment of every channel. Channel configuration must agree with channel_count.

GainControl_SetGain_Result strict

Defined in fuchsia.audio/gain.fidl

OrdinalVariantTypeDescription
response GainControl_SetGain_Response
err GainError

GainControl_SetMute_Result strict

Defined in fuchsia.audio/gain.fidl

OrdinalVariantTypeDescription
response GainControl_SetMute_Response
err GainError

GainUpdateMethod flexible

Defined in fuchsia.audio/gain.fidl

Supported types of gain updates.

OrdinalVariantTypeDescription
gain_db float32

Immediately set the gain to this value.

ramped RampedGain

Change the gain gradually using a ramp.

RampFunction flexible

Defined in fuchsia.audio/gain.fidl

Supported types of ramping functions.

OrdinalVariantTypeDescription
linear_slope RampFunctionLinearSlope

Timestamp flexible

Defined in fuchsia.audio/stream_sink.fidl

Indicates the position of an audio packet in the stream timeline.

OrdinalVariantTypeDescription
specified int64

Specific time in the stream timeline. Units vary and are provided when the connection is established.

unspecified_continuous UnspecifiedContinuous

Indicates the packet should be presented immediately after the previous packet, if there is a previous packet. If there is no previous packet, this option is equivalent to a specified value of 0.

This option implies that the stream timeline should not ‘slip’ even if the packet arrives late. The packet is intended to be presented immediately after the previous packet, and the resulting timing is to be maintained regardless of the arrival time of the packet.

unspecified_best_effort UnspecifiedBestEffort

Indicates the packet should be presented as soon as possible after the previous packet, if there is one, as soon as possible if not.

This option implies that the stream time should ‘slip’ if the packet arrives too late to be rendered immediately after the previous packet. This option is often used when a gap occurs in an un-timestamped stream, perhaps due to a lossy upstream source.

BITS

PacketFlags flexible

Type: uint32

Defined in fuchsia.audio/stream_sink.fidl

Flags describing a packet.

NameValueDescription
1

Indicates that this packet is provided only so that later packets can be interpreted. A decoder should drop the decompressed packets generated from this packet.

CONSTANTS

NameValueTypeDescription
MAX_COMPRESSION_PARAMETERS_SIZE 32768 uint64

The maximum size of Compression.parameters.