| // Copyright 2022 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| library fuchsia.audio.device; |
| |
| using fuchsia.hardware.audio; |
| using fuchsia.hardware.audio.signalprocessing; |
| using zx; |
| |
| /// The length of the device's unique ID, in bytes. |
| const UNIQUE_INSTANCE_ID_SIZE uint32 = fuchsia.hardware.audio.UNIQUE_ID_SIZE; |
| |
| /// When a device is detected (or added via `Provider/AddDevice`), it is |
| /// queried for its properties and capabilities. Once this enumeration process |
| /// completes, it is announced to clients that are watching for device arrivals |
| /// via `Registry/WatchDevicesAdded`. |
| /// |
| /// An `Info` table is returned for each audio device that has been added. |
| type Info = table { |
| /// A device identifier that is guaranteed unique for this boot session, but |
| /// may change across reboots. |
| /// |
| /// Required for all device types. |
| 1: token_id TokenId; |
| |
| /// The protocol used by the driver, and (if StreamConfig) its directionality. |
| /// |
| /// Required for all device types. |
| 2: device_type DeviceType; |
| |
| /// The device's high-level name, as received from devfs or the |
| /// `Provider/AddDevice` caller. |
| /// |
| /// Required for all device types. |
| 3: device_name string:MAX_STRING_SIZE; |
| |
| /// The name of the device's manufacturer. |
| /// |
| /// Optional for all device types. |
| 4: manufacturer string:MAX_STRING_SIZE; |
| |
| /// The device's high-level product name. |
| /// |
| /// Optional for all device types. |
| 5: product string:MAX_STRING_SIZE; |
| |
| /// A 16-character ID provided by the driver that (if present) can be used |
| /// to differentiate instances of the same device. This value should not |
| /// change across system reboots. |
| /// |
| /// Optional for all device types. |
| 6: unique_instance_id array<uint8, UNIQUE_INSTANCE_ID_SIZE>; |
| |
| /// Whether the device is a source (is_input TRUE) or destination (is_input FALSE) of audio. |
| /// |
| /// Required for StreamConfig; optional for Codec; absent for Composite. |
| 7: is_input bool; |
| |
| /// The union of all formats the device can support, across all combinations of device |
| /// configuration settings. |
| /// If the device exposes one or more RingBuffer ENDPOINT elements, this field must be present |
| /// and its vector must contain exactly one entry for each relevant ENDPOINT element. |
| /// If the device exposes NO RingBuffer ENDPOINT elements, this field must be omitted (entirely |
| /// absent, rather than populated with an empty vector). |
| /// |
| /// Required for StreamConfig; optional for Composite; absent for Codec. |
| 8: ring_buffer_format_sets vector<ElementRingBufferFormatSet>:MAX_COUNT_PROCESSING_ELEMENTS; |
| |
| /// The union of all DAI formats the device can support, across all combinations |
| /// of device configuration settings. |
| /// If the device exposes one or more Dai ENDPOINT elements, this field must be present and its |
| /// vector must contain exactly one entry for each relevant ENDPOINT element. |
| /// If the device exposes NO Dai ENDPOINT elements, this field must be omitted (entirely absent, |
| /// rather than populated with an empty vector). |
| /// |
| /// Required for Codec; optional for Composite; absent for StreamConfig. |
| 9: dai_format_sets vector<ElementDaiFormatSet>:MAX_COUNT_PROCESSING_ELEMENTS; |
| |
| /// The device's gain/mute capabilities. |
| /// |
| /// Required for StreamConfig; absent for Codec and Composite. |
| // |
| // TODO(https://fxbug.dev/42052918): Remove legacy gain aspects once driver API does. |
| // Going forward, gain will be handled by `SignalProcessing`. |
| 10: gain_caps GainCapabilities; |
| |
| /// The device's hot-plug capabilities. |
| /// |
| /// Required for Codec and StreamConfig; absent for Composite. |
| 11: plug_detect_caps PlugDetectCapabilities; |
| |
| /// An identifier for the clock domain in which the device's clock hardware |
| /// operates. Devices in the same clock domain remain perfectly |
| /// synchronized. They may drift relative to some other clock domain, but |
| /// all clocks in that domain will do so perfectly _together_. Although |
| /// their clocks have the same rate, their positions may be offset by an |
| /// arbitrary, fixed amount. |
| /// |
| /// There are two special values for clock domain: |
| /// |
| /// * `CLOCK_DOMAIN_MONOTONIC` means the hardware is driven by the system |
| /// montonic clock and will always be synchronized with that timeline. |
| /// |
| /// * `CLOCK_DOMAIN_EXTERNAL` means the hardware is not synchronized with any |
| /// other known clocks (even any other clocks in `CLOCK_DOMAIN_EXTERNAL`). |
| /// |
| /// Required for Composite and StreamConfig; absent for Codec. |
| 12: clock_domain ClockDomain; |
| |
| /// The vector of supported signal-processing elements. |
| /// If present, must contain at least one element. |
| /// |
| /// Required for Composite; optional for Codec and StreamConfig. |
| 13: signal_processing_elements |
| vector<fuchsia.hardware.audio.signalprocessing.Element>:fuchsia.hardware.audio.signalprocessing.MAX_COUNT_PROCESSING_ELEMENTS; |
| |
| /// The vector of supported signal-processing topologies. |
| /// If present, must contain at least one element. |
| /// |
| /// Required for Composite; optional for Codec and StreamConfig. |
| 14: signal_processing_topologies |
| vector<fuchsia.hardware.audio.signalprocessing.Topology>:fuchsia.hardware.audio.signalprocessing.MAX_COUNT_TOPOLOGIES; |
| }; |
| |
| /// The device's overall gain capabilities. |
| // |
| // TODO(https://fxbug.dev/42052918): Remove legacy gain aspects once driver API does. |
| // Going forward, gain will be handled by `SignalProcessing`. |
| type GainCapabilities = table { |
| /// The device's minimum gain, in decibels. |
| /// |
| /// Required. |
| 1: min_gain_db float32; |
| |
| /// The device's maximum gain, in decibels. |
| /// |
| /// Required. |
| 2: max_gain_db float32; |
| |
| /// The precision of each gain-change step, in decibels. |
| /// |
| /// Required. |
| 3: gain_step_db float32; |
| |
| /// If true, the device contains a distinct MUTE control. If false or |
| /// absent, it does not. |
| /// |
| /// Optional. |
| 4: can_mute bool; |
| |
| /// Automatic Gain Control. If absent, this hardware does not support AGC. |
| /// |
| /// Optional. |
| 5: can_agc bool; |
| }; |
| |
| /// The device's hot-plug capabilities. |
| type PlugDetectCapabilities = flexible enum { |
| /// Device is always plugged in. Plug state cannot change. |
| HARDWIRED = 0; |
| |
| /// Device can be un/plugged and can asynchronously notify of changes. |
| PLUGGABLE = 1; |
| }; |
| |
| /// The current plugged-in state for the device. |
| type PlugState = flexible enum { |
| /// Connected and available for audio streaming. |
| PLUGGED = 1; |
| |
| /// Not connected; unavailable for audio streaming. |
| UNPLUGGED = 2; |
| }; |
| |
| /// `Registry` instances notify clients as devices arrive and depart, and they |
| /// create observers (see `Observer`) that notify of more detailed state changes. |
| @discoverable |
| closed protocol Registry { |
| /// Register for notification when one or more devices are added. |
| /// The `devices` vector will always contain at least one `Info` entry. |
| strict WatchDevicesAdded() -> (table { |
| /// Devices added since `WatchDevicesAdded` was last called. This method |
| /// returns all audio devices when called for the first time. |
| 1: devices vector<Info>:MAX_COUNT_DEVICES; |
| }) error RegistryWatchDevicesAddedError; |
| |
| /// Register for notification when an (active, added) device is removed. |
| /// Because the method only notifies of one removal, upon completion it |
| /// should immediately be re-called, in case other removals have occurred. |
| strict WatchDeviceRemoved() -> (table { |
| /// The token of the device least-recently removed. |
| 1: token_id TokenId; |
| }) error RegistryWatchDeviceRemovedError; |
| |
| /// Request an `Observer` for the specified device. |
| strict CreateObserver(resource table { |
| /// The token of the device to be observed. |
| /// |
| /// Required. |
| 1: token_id TokenId; |
| |
| /// The server end of the `Observer` that will be created. |
| /// |
| /// Required. |
| 2: observer_server server_end:Observer; |
| }) -> (table {}) error RegistryCreateObserverError; |
| }; |
| |
| /// Errors returned by `Registry/WatchDevicesAdded`. |
| type RegistryWatchDevicesAddedError = flexible enum { |
| /// The previous `WatchDevicesAdded` call has not yet completed. |
| ALREADY_PENDING = 1; |
| }; |
| |
| /// Errors returned by `Registry/WatchDeviceRemoved`. |
| type RegistryWatchDeviceRemovedError = flexible enum { |
| /// The previous `WatchDeviceRemoved` call has not yet completed. |
| ALREADY_PENDING = 1; |
| }; |
| |
| /// Errors returned by `Registry/CreateObserver`. |
| type RegistryCreateObserverError = flexible enum { |
| /// The required `token_id` is missing. |
| INVALID_TOKEN_ID = 1; |
| |
| /// The required `observer_server` is missing. |
| INVALID_OBSERVER = 2; |
| |
| /// No device with `token_id` was found. Either this token has never been |
| /// used, or the device with `token_id` has been removed. |
| DEVICE_NOT_FOUND = 3; |
| |
| /// The device with `token_id` has encountered an error and can no longer be observed. |
| DEVICE_ERROR = 4; |
| }; |
| |
| /// `Observer` instances are used to learn the capabilities and state of an |
| /// audio device, and to stay informed as its state changes over time. Each |
| /// `Observer` is associated with an initialized audio device. An audio device |
| /// may be observed by multiple `Observer` instances. |
| closed protocol Observer { |
| /// Query the device's available processing topologies and individual |
| /// elements, and watch for changes to those elements. |
| /// |
| /// These methods must be supported by Composite devices, |
| /// but are optional for Codec and StreamConfig devices. |
| compose fuchsia.hardware.audio.signalprocessing.Reader; |
| |
| /// Request notification of any change to the device's gain state. |
| /// |
| /// Note: this only notifies of changes to controls described in the |
| /// device's`Info` table (`GainCapabilities` specifically). Use |
| /// `WatchElementState` for gain processing exposed as `SignalProcessing` |
| /// (`GetTopologies`, `GetElements`). |
| /// |
| /// Should only be called for StreamConfig devices. |
| // |
| // TODO(https://fxbug.dev/42052918): Remove legacy gain aspects once driver API does. |
| // Going forward, gain will be handled by `SignalProcessing`. |
| strict WatchGainState() -> (table { |
| /// The device's most recent gain state. |
| 1: state GainState; |
| }) error ObserverWatchGainStateError; |
| |
| /// Request notification of any change to the device's plug state. When |
| /// called for the first time, it will return immediately. |
| /// |
| /// Should only be called for Codec or StreamConfig devices. |
| strict WatchPlugState() -> (table { |
| /// The device's current plug state. |
| 1: state PlugState; |
| |
| /// The time (in CLOCK_MONOTONIC) of the most-recent change in plug state. |
| 2: plug_time zx.Time; |
| }) error ObserverWatchPlugStateError; |
| |
| /// Retrieve the device's reference clock. |
| /// |
| /// This clock will be in the domain specified in the device's `Info` table. |
| /// |
| /// Should only be called for Composite or StreamConfig devices. |
| strict GetReferenceClock() -> (resource table { |
| /// The device's reference clock. |
| 1: reference_clock zx.Handle:CLOCK; |
| }) error ObserverGetReferenceClockError; |
| }; |
| |
| /// Errors returned by `Observer/WatchGainState`. |
| type ObserverWatchGainStateError = flexible enum { |
| /// This device has encountered an error and can no longer be observed. |
| DEVICE_ERROR = 1; |
| |
| /// This device type does not support the method that was called. |
| WRONG_DEVICE_TYPE = 2; |
| |
| /// The previous `WatchGainState` call has not yet completed. |
| ALREADY_PENDING = 3; |
| }; |
| |
| /// Errors returned by `Observer/WatchPlugState`. |
| type ObserverWatchPlugStateError = flexible enum { |
| /// This device has encountered an error and can no longer be observed. |
| DEVICE_ERROR = 1; |
| |
| /// This device type does not support the method that was called. |
| WRONG_DEVICE_TYPE = 2; |
| |
| /// The previous `WatchPlugState` call has not yet completed. |
| ALREADY_PENDING = 3; |
| }; |
| |
| /// Errors returned by `Observer/GetReferenceClock`. |
| type ObserverGetReferenceClockError = flexible enum { |
| /// This device has encountered an error and can no longer be observed. |
| DEVICE_ERROR = 1; |
| |
| /// This device type does not support the method that was called. |
| WRONG_DEVICE_TYPE = 2; |
| |
| /// The device's reference clock could not be returned. |
| DEVICE_CLOCK_UNAVAILABLE = 3; |
| }; |