// 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;

const uint32 UNIQUE_ID_SIZE = 16;
const uint32 MAX_UI_STRING_SIZE = 256;
const uint32 MAX_COUNT_CHANNELS_TO_USE = 64;
const uint32 MAX_COUNT_SUPPORTED_NUMBER_OF_CHANNELS = 64;
const uint32 MAX_COUNT_SUPPORTED_SAMPLE_FORMATS = 3;
const uint32 MAX_COUNT_SUPPORTED_RATES = 64;
const uint32 MAX_COUNT_SUPPORTED_BYTES_PER_SAMPLE = 8;
const uint32 MAX_COUNT_SUPPORTED_VALID_BITS_PER_SAMPLE = 8;
const uint32 MAX_COUNT_FORMATS = 64;

alias clock_domain = uint32;
const clock_domain CLOCK_DOMAIN_MONOTONIC = 0x00000000;
const clock_domain CLOCK_DOMAIN_EXTERNAL = 0xFFFFFFFF;

enum SampleFormat : 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;
};

table SupportedFormats {
    /// Supported formats for non-compressed PCM samples.
    1: PcmSupportedFormats pcm_supported_formats;
};

/// 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 //docs/concepts/drivers/driver_interfaces/audio_streaming.md.
struct PcmSupportedFormats {
    /// Vector of possible number of channels supported in ascending order.
    vector<uint8>:MAX_COUNT_SUPPORTED_NUMBER_OF_CHANNELS number_of_channels;

    /// Vector of possible `SampleFormat`s supported.
    vector<SampleFormat>:MAX_COUNT_SUPPORTED_SAMPLE_FORMATS 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.
    vector<uint8>:MAX_COUNT_SUPPORTED_BYTES_PER_SAMPLE 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.
    vector<uint8>:MAX_COUNT_SUPPORTED_VALID_BITS_PER_SAMPLE valid_bits_per_sample;

    /// Vector of possible frame rates supported in ascending order.
    vector<uint32>:MAX_COUNT_SUPPORTED_RATES frame_rates;
};

table Format {
    /// Format supporting non-compressed PCM samples.
    1: PcmFormat pcm_format;
};

/// 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
/// //docs/concepts/drivers/driver_interfaces/audio_streaming.md.
struct PcmFormat {
    /// Number of channels.
    uint8 number_of_channels;

    /// Which channels to use as a bitmask. Channels not set in the bitmask are ignored.
    /// The least significant bit corresponds to index 0.
    uint64 channels_to_use_bitmask;

    /// The format of all samples.
    SampleFormat sample_format;

    /// Bytes allocated to hold a sample, equal or bigger than the valid sample size in
    /// `valid_bits_per_sample`.
    uint8 bytes_per_sample;

    /// 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.
    uint8 valid_bits_per_sample;

    /// The frame rate for all samples.
    uint32 frame_rate;
};

/// Gain state requested by the client or returned by the driver.
table GainState {
    /// Current mute state. If not included, the state is unmuted.
    1: bool muted;

    /// Current Automatic Gain Control (AGC) state. If not included, AGC is disabled.
    2: bool agc_enabled;

    /// Current gain in decibels. Must be included.
    3: float32 gain_db;
};

/// Plug state as returned by the driver.
table PlugState {
    /// Stream is currently plugged in. Must be included.
    1: bool plugged;

    /// Timestamps the information provided in the rest of the fields of this struct.
    /// Must be included.
    2: zx.time plug_state_time;
};

enum PlugDetectCapabilities {
    /// Stream is hardwired (will always be plugged in).
    HARDWIRED = 0;

    /// Stream is able to asynchronously notify of plug state changes.
    CAN_ASYNC_NOTIFY = 1;
};

table StreamProperties {
    /// A unique identifier. If not included, there is no unique id for the StreamConfig.
    1: array<uint8>:UNIQUE_ID_SIZE unique_id;

    /// Stream type is input or output. Must be included.
    2: bool is_input;

    /// Gain mute capability. If not included, the StreamConfig can't mute.
    3: bool can_mute;

    /// Automatic Gain Control (AGC) capability. If not included, the StreamConfig can't AGC.
    4: bool can_agc;

    /// Minimum gain in decibels. Must be included.
    5: float32 min_gain_db;

    /// Maximum gain in decibels. Must be included.
    6: float32 max_gain_db;

    /// 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`.
    /// Must be included.
    7: float32 gain_step_db;

    /// Plug Detect Capabilities. Must be included.
    8: PlugDetectCapabilities plug_detect_capabilities;

    /// UI string for the manufacturer name. If not included, the manufacturer is unspecified.
    9: string:MAX_UI_STRING_SIZE manufacturer;

    /// UI string for the product name. If not included, the product name is unspecified.
    10: string:MAX_UI_STRING_SIZE product;

    /// An identifier for the clock domain in which this hardware operates. If the hardware is
    /// operating in CLOCK_DOMAIN_MONOTONIC, its nominal rate is locked to that of the
    /// ZX_CLOCK_MONOTONIC time reference. Given the start time, and a nominal rate, the position
    /// of the playback/capture pointer may always be calculated using a clock monotonic timestamp
    /// as the pointer's movement is locked to that of ZX_CLOCK_MONOTONIC.
    ///
    /// Other values indicate that playback/capture is not locked to ZX_CLOCK_MONOTONIC, and moves
    /// at its own rate depending on a number of factors. Client will need to make use of the
    /// timing information present in the position notification updates in order to recover the
    /// clock of the audio stream. The clock_domain comes from an system wide entity (or instance a
    /// platform bus or clock tree/global driver). Audio drivers retrieve clock_domain from such
    /// system wide entity. Must be included.
    11: clock_domain clock_domain;
};

/// For an overview see
/// [Audio Driver Streaming Interface](//docs/concepts/drivers/driver_interfaces/audio_streaming.md)
protocol StreamConfig {
    /// Retrieves top level static properties.
    GetProperties() -> (StreamProperties properties);

    /// 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() -> (vector<SupportedFormats>:MAX_COUNT_FORMATS supported_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(Format format, request<RingBuffer> ring_buffer);

    /// 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() -> (GainState gain_state);

    /// Client update of the gain state.
    SetGain(GainState target_state);

    /// 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() -> (PlugState plug_state);
};
