| // Copyright 2019 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.hardware.audio; |
| |
| using zx; |
| using fuchsia.hardware.audio.signalprocessing; |
| |
| const UNIQUE_ID_SIZE uint32 = 16; |
| const MAX_UI_STRING_SIZE uint32 = 256; |
| const MAX_COUNT_CHANNELS_IN_RING_BUFFER uint32 = 64; |
| const MAX_COUNT_SUPPORTED_NUMBER_OF_CHANNELS uint32 = 64; |
| const MAX_COUNT_CHANNEL_SETS uint32 = 64; |
| const MAX_COUNT_SUPPORTED_SAMPLE_FORMATS uint32 = 3; |
| const MAX_COUNT_SUPPORTED_RATES uint32 = 64; |
| const MAX_COUNT_SUPPORTED_BYTES_PER_SAMPLE uint32 = 8; |
| const MAX_COUNT_SUPPORTED_VALID_BITS_PER_SAMPLE uint32 = 8; |
| const MAX_COUNT_FORMATS uint32 = 64; |
| |
| alias clock_domain = uint32; |
| const CLOCK_DOMAIN_MONOTONIC clock_domain = 0x00000000; |
| const CLOCK_DOMAIN_EXTERNAL clock_domain = 0xFFFFFFFF; |
| |
| type SampleFormat = strict enum : uint8 { |
| /// Signed Linear Pulse Code Modulation samples at the host endianness. |
| PCM_SIGNED = 1; |
| |
| /// Unsigned Linear Pulse Code Modulation samples at the host endianness. |
| PCM_UNSIGNED = 2; |
| |
| /// Floating point samples IEEE-754 encoded. |
| PCM_FLOAT = 3; |
| }; |
| |
| type ChannelAttributes = table { |
| /// Minimum frequency guaranteed to be emitted by (or captured in) this channel, in Hz. Optional. |
| /// If both `min_frequency` and `max_frequency` are not included, then this channel is assumed |
| /// to cover the full frequency range of this device. |
| /// TODO(fxbug.dev/81743): Define expectations beyond these min/max limits and enable drivers |
| /// to express tolerances related to this. |
| 1: min_frequency uint32; |
| |
| /// Maximum frequency guaranteed to be emitted by (or captured in) this channel, in Hz. Optional. |
| /// If both `min_frequency` and `max_frequency` are not included, then this channel is assumed |
| /// to cover the full frequency range of this device. |
| /// TODO(fxbug.dev/81743): Define expectations beyond these min/max limits and enable drivers |
| /// to express tolerances related to this. |
| 2: max_frequency uint32; |
| }; |
| |
| type ChannelSet = table { |
| /// Describes attributes for this channel set. Required. |
| /// The size of this vector defines the number of channels supported by this `ChannelSet`. |
| /// Each element of the vector defines attributes of a single channel. |
| 1: attributes vector<ChannelAttributes>:MAX_COUNT_CHANNELS_IN_RING_BUFFER; |
| }; |
| |
| type SupportedFormats = table { |
| /// Supported formats for non-compressed PCM samples with attributes. Required. |
| 1: pcm_supported_formats PcmSupportedFormats; |
| }; |
| |
| /// Format supporting non-compressed PCM audio. Frames are made up of number of channels samples |
| /// which have `valid_bits_per_sample` bits of left-justified data within `bytes_per_sample` |
| /// bytes. All values listed in each vector are supported. When not all combinations supported by |
| /// the driver can be described with one `SupportedFormats` (and hence one `PcmSupportedFormats`), |
| /// `GetSupportedFormats` returns more than one `SupportedFormats` in the returned vector. |
| /// For more detailed information see [Audio Driver Streaming Interface](https://fuchsia.dev/fuchsia-src/concepts/drivers/driver_architectures/audio_drivers/audio_streaming). |
| type PcmSupportedFormats = table { |
| /// Vector of possible `ChannelSets` supported. Required. |
| /// A `ChannelSet` defines a number of channels supported plus a number of optional |
| /// attributes for these channels. |
| /// Only one `ChannelSet` is allowed for each unique number of channels. |
| 1: channel_sets vector<ChannelSet>:MAX_COUNT_CHANNEL_SETS; |
| |
| /// Vector of possible `SampleFormat`s supported. Required. |
| 2: sample_formats vector<SampleFormat>:MAX_COUNT_SUPPORTED_SAMPLE_FORMATS; |
| |
| /// Vector of possible number of bits allocated to hold a sample, |
| /// equal or bigger than the actual sample size in `valid_bits_per_sample` in ascending order. |
| /// Required. |
| 3: bytes_per_sample vector<uint8>:MAX_COUNT_SUPPORTED_BYTES_PER_SAMPLE; |
| |
| /// Vector of possible number of bits in a sample in ascending order, must be equal or smaller |
| /// than `bytes_per_channel` for samples to fit. If smaller, bits are left justified, and any |
| /// additional bits will be ignored. Required. |
| 4: valid_bits_per_sample vector<uint8>:MAX_COUNT_SUPPORTED_VALID_BITS_PER_SAMPLE; |
| |
| /// Vector of possible frame rates supported in ascending order. Required. |
| 5: frame_rates vector<uint32>:MAX_COUNT_SUPPORTED_RATES; |
| }; |
| |
| type Format = table { |
| /// Format supporting non-compressed PCM samples. Required. |
| 1: pcm_format PcmFormat; |
| }; |
| |
| /// Format supporting non-compressed PCM audio. Frames are made up of `number_of_channels` samples |
| /// which have `valid_bits_per_sample` bits of left-justified data within `bytes_per_channel`. |
| /// bytes. For more detailed information see |
| /// [Audio Driver Streaming Interface](https://fuchsia.dev/fuchsia-src/concepts/drivers/driver_architectures/audio_drivers/audio_streaming). |
| type PcmFormat = struct { |
| /// Number of channels. |
| number_of_channels uint8; |
| |
| /// The format of all samples. |
| sample_format SampleFormat; |
| |
| /// Bytes allocated to hold a sample, equal or bigger than the valid sample size in |
| /// `valid_bits_per_sample`. |
| bytes_per_sample uint8; |
| |
| /// Number of valid bits in a sample, must be equal or smaller than bits in `bytes_per_sample`. |
| /// If smaller, bits are left justified, and any additional bits must be ignored by the |
| /// receiver. |
| valid_bits_per_sample uint8; |
| |
| /// The frame rate for all samples. |
| frame_rate uint32; |
| }; |
| |
| /// Gain state requested by the client or returned by the driver. |
| type GainState = table { |
| /// Current mute state. If not included, the state is unmuted. |
| 1: muted bool; |
| |
| /// Current Automatic Gain Control (AGC) state. If not included, AGC is disabled. |
| 2: agc_enabled bool; |
| |
| /// Current gain in decibels. Required. |
| 3: gain_db float32; |
| }; |
| |
| /// Plug state as returned by the driver. |
| /// If the driver reports a `plug_detect_capabilities` equal to HARDWIRED, then the driver should |
| /// respond to `WatchPlugState` only the first time it is called, with `plugged` set to true and |
| /// `plug_state_time` set to time '0'. |
| type PlugState = table { |
| /// Stream is currently plugged in. Required |
| 1: plugged bool; |
| |
| /// Timestamps the information provided in the rest of the fields of this struct. Required. |
| 2: plug_state_time zx.time; |
| }; |
| |
| type PlugDetectCapabilities = strict enum { |
| /// Stream is hardwired (will always be plugged in). |
| HARDWIRED = 0; |
| |
| /// Stream is able to asynchronously notify of plug state changes. |
| CAN_ASYNC_NOTIFY = 1; |
| }; |
| |
| type StreamProperties = table { |
| /// A unique identifier. If not included, there is no unique id for the StreamConfig. |
| 1: unique_id array<uint8, UNIQUE_ID_SIZE>; |
| |
| /// Stream type is input or output. Required. |
| 2: is_input bool; |
| |
| /// Gain mute capability. If not included, the StreamConfig can't mute. |
| 3: can_mute bool; |
| |
| /// Automatic Gain Control (AGC) capability. If not included, the StreamConfig can't AGC. |
| 4: can_agc bool; |
| |
| /// Minimum gain in decibels. Required. |
| 5: min_gain_db float32; |
| |
| /// Maximum gain in decibels. Required. |
| 6: max_gain_db float32; |
| |
| /// Gain step in decibels, this value must not be negative, but may be zero to convey an |
| /// effectively continuous range of values. Must not exceed `max_gain_db` - `min_gain_db`. |
| /// Required. |
| 7: gain_step_db float32; |
| |
| /// Plug Detect Capabilities. Required. |
| 8: plug_detect_capabilities PlugDetectCapabilities; |
| |
| /// UI string for the manufacturer name. If not included, the manufacturer is unspecified. |
| 9: manufacturer string:MAX_UI_STRING_SIZE; |
| |
| /// UI string for the product name. If not included, the product name is unspecified. |
| 10: product string:MAX_UI_STRING_SIZE; |
| |
| /// An identifier for the clock domain in which this hardware operates. If |
| /// two hardware devices have the same clock domain, their clock rates are |
| /// identical and perfectly synchronized. Although these two clocks have the |
| /// same rate, the clock positions may be offset from each other by an |
| /// arbitrary (but fixed) amount. The clock_domain typically comes from a |
| /// system wide entity, such as a platform bus or global clock tree. |
| /// |
| /// There are two special values: |
| /// |
| /// * CLOCK_DOMAIN_MONOTONIC means the hardware is operating at the same |
| /// rate as the system montonic clock. |
| /// |
| /// * CLOCK_DOMAIN_EXTERNAL means the hardware is operating at an unknown |
| /// rate and is not synchronized with any known clock, not even with |
| /// other clocks in domain CLOCK_DOMAIN_EXTERNAL. |
| /// |
| /// If the domain is not CLOCK_DOMAIN_MONOTONIC, client must use position |
| /// notification updates to recover the hardware's clock. |
| /// |
| /// Required. |
| 11: clock_domain clock_domain; |
| }; |
| |
| /// For an overview see |
| /// [Audio Driver Streaming Interface](https://fuchsia.dev/fuchsia-src/concepts/drivers/driver_architectures/audio_drivers/audio_streaming) |
| protocol StreamConfig { |
| /// Allows providing driver health state. |
| compose Health; |
| |
| /// Allows providing signal processing capabilities. |
| compose fuchsia.hardware.audio.signalprocessing.Connector; |
| |
| /// Retrieves top level static properties. |
| GetProperties() -> (struct { |
| properties StreamProperties; |
| }); |
| |
| /// Gets formats supported by a given driver. When not all combinations supported by the |
| /// driver can be described with one `SupportedFormats`, the driver returns more than one |
| /// `SupportedFormats` in the returned vector. For example, if one `SupportedFormats` allows |
| /// for 32 bits samples at 48KHz, and 16 bits samples at 96KHz, but not 32 bits samples at |
| /// 96KHz, then the driver replies with 2 `SupportedFormats`: <<32bits>,<48KHz>> and |
| /// <<16bits>,<96KHz>>. For simplicity, this example ignores parameters other than rate and |
| /// bits per sample. In the case where the driver supports either 16 or 32 bits samples at |
| /// either 48 or 96KHz, the driver would reply with 1 `SupportedFormats`: |
| /// <<16bits,32bits>,<48KHz,96KHz>>. |
| GetSupportedFormats() -> (struct { |
| supported_formats vector<SupportedFormats>:MAX_COUNT_FORMATS; |
| }); |
| |
| /// `CreateRingBuffer` is sent by clients to select a stream format based on information that |
| /// the driver provides in `GetSupportedFormats` what is supported by the client, and any other |
| /// requirement. The `ring_buffer` channel is used to control the audio buffer, if a previous |
| /// ring buffer channel had been established and was still active, the driver must close that |
| /// (ring buffer) channel and make every attempt to gracefully quiesce any on-going streaming |
| /// operations in the process. |
| CreateRingBuffer(resource struct { |
| format Format; |
| ring_buffer server_end:RingBuffer; |
| }); |
| |
| /// Get the gain state via a hanging get. The driver will reply to the first `WatchGainState` |
| /// sent by the client and this reply must include a `gain_db` set to 0dB or lower. The driver |
| /// will not respond to subsequent client `WatchGainState` calls until the gain state changes |
| /// from what was most recently reported. |
| WatchGainState() -> (struct { |
| gain_state GainState; |
| }); |
| |
| /// Client update of the gain state. |
| SetGain(struct { |
| target_state GainState; |
| }); |
| |
| /// Get the plug detect state via a hanging get. The driver will reply to the first |
| /// `WatchPlugState` sent by the client. The driver will not respond to subsequent client |
| /// `WatchPlugState` calls until the plug state changes from what was most recently reported. |
| WatchPlugState() -> (struct { |
| plug_state PlugState; |
| }); |
| }; |