// Copyright 2021 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.signalprocessing;

using zx;

// TODO(https://fxbug.dev/42143529): Complete parameters and types for processing elements.

alias ElementId = uint64;
alias TopologyId = uint64;

const MAX_COUNT_PROCESSING_ELEMENTS uint32 = 64;
const MAX_COUNT_TOPOLOGIES uint32 = 64;
const MAX_COUNT_PROCESSING_ELEMENTS_EDGE_PAIRS uint32 = 64;
const MAX_STRING_SIZE uint32 = 256;
@available(added=HEAD)
const MAX_BYTES_ELEMENT_VENDOR_SPECIFIC uint32 = 4096;

type ElementType = flexible enum {
    /// Vendor Specific. A type of processing element not covered by any subsequent type definition.
    VENDOR_SPECIFIC = 1;

    /// The start/end of a pipeline.
    @available(removed=12)
    END_POINT = 2;

    /// Controls pipelines channel mixing and routing.
    CONNECTION_POINT = 3;

    /// Gain control, a.k.a. Volume control.
    GAIN = 4;

    /// Automatic Gain Control.
    /// Automatically maintains a suitable signal level regardless of variation of its input.
    AUTOMATIC_GAIN_CONTROL = 5;

    /// Automatic Gain Limiter.
    /// Automatically maintains a signal level below a level specified.
    /// Input below the level is unaffected, and peaks above the level are attenuated.
    AUTOMATIC_GAIN_LIMITER = 6;

    /// Alters the dynamic range of the signal, e.g. dynamic range compression.
    DYNAMICS = 7;

    /// Mute.
    MUTE = 8;

    /// Delay.
    DELAY = 9;

    /// Equalizer.
    EQUALIZER = 10;

    /// Sample Rate Conversion.
    SAMPLE_RATE_CONVERSION = 11;

    /// The start/end of a pipeline.
    @available(added=12, removed=20)
    ENDPOINT = 12;

    /// Ring Buffer.
    /// This is the first of two types of elements that can start/end processing pipelines.
    @available(added=20)
    RING_BUFFER = 13;

    /// Digital Audio Interface Interconnect.
    /// This is the second of two types of elements that can start/end processing pipelines.
    @available(added=20)
    DAI_INTERCONNECT = 14;
};

/// Type-specific Parameters for an `Element`.
type TypeSpecificElement = flexible union {
    // See vendor_specific.fidl.
    1: vendor_specific VendorSpecific;

    // See gain.fidl.
    2: gain Gain;

    // See equalizer.fidl.
    3: equalizer Equalizer;

    // See dynamics.fidl.
    4: dynamics Dynamics;

    // See dai_interconnect.fidl.
    @available(added=12, removed=20)
    5: endpoint Endpoint;

    // See dai_interconnect.fidl.
    @available(added=20)
    6: dai_interconnect DaiInterconnect;
};

@available(removed=20)
type Latency = flexible union {
    /// Latency added to the pipeline as a zx.Duration.
    1: latency_time zx.Duration;

    /// Latency added to the pipeline as a number of frames.
    2: latency_frames uint32;
};

type Element = table {
    /// Unique ID for this element. The scope of this id is only within the `SignalProcessing`
    /// protocol lifespan, i.e. until the channel associated with the protocol is closed.
    ///
    /// Required.
    1: id ElementId;

    /// Processing element type.
    ///
    /// Required.
    2: type ElementType;

    /// If included, type-specific parameters for the processing element.
    ///
    /// Optional.
    3: type_specific TypeSpecificElement;

    /// If included and true, the processing element can be disabled via
    /// `ElementSetState`.
    /// If not included or false, the processing element is always enabled.
    ///
    /// Optional.
    ///
    /// # Deprecation
    ///
    /// Use `can_bypass` instead.
    @available(removed=20)
    4: can_disable bool;

    /// If included, a textual description of the processing element.
    ///
    /// Optional.
    5: description string:MAX_STRING_SIZE;

    /// If included and true, the processing element can be stopped via `ElementSetState`.
    /// If not included or false, the processing element is always started.
    ///
    /// Optional.
    @available(added=20)
    6: can_stop bool;

    /// If included and true, the processing element can be bypassed via `ElementSetState`.
    /// If not included or false, the processing element cannot be bypassed.
    ///
    /// Optional.
    @available(added=20)
    7: can_bypass bool;
};

/// Type-specific processing element state.
/// The type of processing element control is defined by the type of parameters provided in this
/// union. Must match the type returned in the corresponding `ElementType` entry in the
/// corresponding `Element`.
type TypeSpecificElementState = flexible union {
    // See vendor_specific.fidl.
    1: vendor_specific VendorSpecificState;

    // See gain.fidl.
    2: gain GainElementState;

    // See equalizer.fidl.
    3: equalizer EqualizerElementState;

    // See dynamics.fidl.
    4: dynamics DynamicsElementState;

    // See dai_interconnect.fidl.
    @available(added=12, removed=20)
    5: endpoint EndpointElementState;

    // See dai_interconnect.fidl.
    @available(added=20)
    6: dai_interconnect DaiInterconnectElementState;
};

/// The current state of an element, as returned from the driver. Note that this table contains
/// fields that are not present in `SettableElementState`, since they cannot be set by clients.
type ElementState = table {
    /// If included, type-specific state parameters for the processing element.
    ///
    /// If this processing element is disabled and its type-specific state is provided, then the
    /// type-specific state is only informational (e.g. the state of a stopped element, if it were
    /// to be re-started without also providing additional superceding state information).
    ///
    /// Optional.
    1: type_specific TypeSpecificElementState;

    /// Process element enable/disable state. By default processing elements are enabled.
    /// If the corresponding `Element` returned `can_disable` equals to `false`, then
    /// this field can't be set to `false`.
    /// If `enabled` is not included, then `state` must be included if and only if the processing
    /// element is currently enabled.
    ///
    /// Optional.
    ///
    /// # Deprecation
    ///
    /// Use `bypassed` instead.
    @available(removed=20)
    2: enabled bool;

    /// If included, how much latency is added to the pipeline if this processing element is
    /// enabled. This field must not be present in a `SetElementState` `state` since
    /// the latency can't be set by a client, it can only provided by the server in a
    /// `WatchElementState` reply.
    ///
    /// Optional.
    @available(removed=20)
    3: latency Latency;

    /// If included, an opaque object of octets for exchanging vendor specific information.
    ///
    /// Optional.
    @available(added=HEAD)
    4: vendor_specific_data vector<uint8>:MAX_BYTES_ELEMENT_VENDOR_SPECIFIC;

    /// The started/stopped state for this processing element.
    /// If true, the hardware associated with the element is started. If false, stopped.
    ///
    /// By default processing elements are started.
    ///
    /// A stopped processing element does not provide its abstracted functionality.
    /// Specifically, no audio data flows through a stopped element.
    ///
    /// Required.
    @available(added=20)
    5: started bool;

    /// The bypassed state for this processing element.
    /// If true, the hardware associated with the element is bypassed. If false, not bypassed.
    ///
    /// By default processing elements are not bypassed.
    /// If the corresponding `Element` returned `can_bypass` equals to `false`, then
    /// this field can't be set to `true`.
    ///
    /// A bypassed element does not affect the flow of audio through the topology.
    ///
    /// Optional.
    @available(added=20)
    6: bypassed bool;

    /// If included, the driver's best estimate of the amount of time it takes the element's
    /// hardware to enter a fully operational mode after `started` has changed from false to true.
    /// Hardware may require some duration to get into a fully operational mode after a change in
    /// power state, for example.
    ///
    /// If this delay is not taken into account, then the initial frames of an audio stream may be
    /// lost while an audio element is powering up.
    /// If not included, `turn_on_delay` is unknown.
    ///
    /// Optional.
    @available(added=20)
    7: turn_on_delay zx.Duration;

    /// If included, the driver's best estimate of the amount of time it takes the element's
    /// hardware to enter a fully disabled mode after  `started` has changed from true to false.
    /// Hardware may require some duration to get into a fully stopped state after a change in
    /// power state, for example.
    ///
    /// If this delay is not taken into account, more frames will be emitted/captured than a
    /// client may realize, specifically when elements are powering down.
    /// If not included, `turn_off_delay` is unknown.
    ///
    /// Optional.
    @available(added=20)
    8: turn_off_delay zx.Duration;

    /// If included, the driver's best estimate (as currently configured, including `bypassed`) of
    /// the delay added by this processing element.
    ///
    /// This value must be taken into account by clients when determining the requirements for
    /// minimum lead time (during playback) and minimum capture delay (during capture).
    ///
    /// For an element of type `RING_BUFFER`, this delay should not include the inherent delay
    /// added by the temporary buffering needed to copy data in and out of a ring buffer, which
    /// is contained in the `RingBufferProperties` field `driver_transfer_bytes`.
    ///
    /// Optional.
    @available(added=20)
    9: processing_delay zx.Duration;
};

/// Type-specific processing element state that can be set by clients.
/// The type of processing element control is defined by the type of parameters provided in this
/// union. Must match the type returned in the corresponding `ElementType` entry in the
/// corresponding `Element`.
@available(added=20)
type SettableTypeSpecificElementState = flexible union {
    // See vendor_specific.fidl.
    1: vendor_specific VendorSpecificState;

    // See gain.fidl.
    2: gain GainElementState;

    // See equalizer.fidl.
    3: equalizer EqualizerElementState;

    // See dynamics.fidl.
    4: dynamics DynamicsElementState;
};

/// Processing element state that can be set by clients.
@available(added=20)
type SettableElementState = table {

    /// Type-specific state parameters for the processing element.
    ///
    /// If this processing element is disabled and its type-specific state is provided, then the
    /// type-specific state is only informational, for instance if a `SetElementState` enables a
    /// disabled processing element providing a `SettableTypeSpecificElementState`, then any
    /// previous informational `SettableTypeSpecificElementState` is superceded.
    ///
    /// If not set, then the element's previous `type_specific` state will be unchanged.
    ///
    /// Optional for Dynamics, Equalizer, Gain and VendorSpecific types.
    /// Invalid if included for any other element type.
    1: type_specific SettableTypeSpecificElementState;

    /// If included, an opaque object of octets for exchanging vendor specific information.
    /// This can send vendor-specific data to any element, not just the VendorSpecific type.
    ///
    /// Optional.
    @available(added=HEAD)
    2: vendor_specific_data vector<uint8>:MAX_BYTES_ELEMENT_VENDOR_SPECIFIC;

    /// Whether to start this processing element (or to stop it, if false).
    /// A stopped processing element does not provide its abstracted functionality.
    /// Specifically, no audio data flows through a stopped element.
    ///
    /// If the corresponding `Element` returned `can_stop` equals to `false`, then this field
    /// must not be set to `false`.
    /// If not set, then the element's previous `started` state will be unchanged.
    ///
    /// Optional.
    3: started bool;

    /// Whether to bypass this processing element (or to enable/"unbypass" it, if false).
    /// A bypassed element does not affect the flow of audio through the topology.
    /// Specifically, audio flows through the element without any change.
    ///
    /// If the corresponding `Element` contains a `can_bypass` of `false`, then this field
    /// must not be set to `true`.
    /// If not set, then the element's previous `bypassed` state will be unchanged.
    ///
    /// Optional.
    4: bypassed bool;
};

/// Edge pairs between processing elements used to define ordering in processing elements
/// arrangements.
type EdgePair = struct {
    processing_element_id_from ElementId;
    processing_element_id_to ElementId;
};

/// A `Topology` specifies one way processing elements are arranged within the hardware.
type Topology = table {
    /// Unique ID for this topology. The scope of this id is only within the `SignalProcessing`
    /// protocol lifespan, i.e. until the channel associated with the protocol is closed.
    ///
    /// Required.
    1: id TopologyId;

    /// Vector of processing elements edge pairs in this order.
    /// The ordering of processing elements with edge pairs form pipelines.
    /// To define multiple possible pipelines, return more `Topology` entries in `GetTopologies`.
    ///
    /// Required.
    2: processing_elements_edge_pairs vector<EdgePair>:MAX_COUNT_PROCESSING_ELEMENTS_EDGE_PAIRS;
};

/// For an overview see
/// [[Signal Processing Interface]](https://fuchsia.dev/fuchsia-src/concepts/drivers/driver_architectures/audio_drivers/audio_signal_processing).
closed protocol SignalProcessing {
    /// Exposes read-only signal processing properties.
    compose Reader;

    /// Controls a processing element using a unique id returned by `GetElements`.
    /// Returns `ZX_ERR_INVALID_ARGS` if the `processing_element_id` does not match an id returned
    /// by `GetElements` or the type of `TypeSpecificElementState` does not
    /// match the `ElementType` of the processing element returned by
    /// `GetElements` for this id.
    /// The driver may return `ZX_ERR_INVALID_ARGS` if the `state` values are invalid, i.e. any
    /// of the values violates rules specified in this protocol, e.g. trying to change an
    /// `EQUALIZER` processing element's `EqualizerBandState` `frequency` when this processing
    /// element did not advertise `CAN_CONTROL_FREQUENCY` in its `supported_controls`.
    ///
    /// `SetElementState` may be called before or after non-`SignalProcessing` protocol
    /// calls. If called after non-`SignalProcessing` protocol calls then
    /// `SetElementState` may or may not require renegotiation of the driver state as
    /// reached with calls of the protocol composing `SignalProcessing`, e.g. `Dai`.
    /// For instance, `SetElementState` changing an `AGL` processing element's parameters
    /// may not require renegotiation of the `Dai` state because changing a gain parameter usually
    /// does not change the set of supported audio formats.
    /// By contrast, if `SetElementState` changes the parameters of a `CONNECTION_POINT`
    /// element, the change may require renegotiation because it may invalidate the set of
    /// supported formats returned in a previous `GetDaiFormats` `Dai` protocol call.
    ///
    /// It is the driver's job to determine when renegotiation is required. If renegotiation is
    /// required, then `SetElementState` must return `ZX_ERR_BAD_STATE` and the client must
    /// close the protocol channel such that the protocol negotiations are started over.
    /// The client then must make the `SetElementState` call that returned
    /// `ZX_ERR_BAD_STATE` before any non-`SignalProcessing` protocol calls.
    @available(replaced=20)
    strict SetElementState(struct {
        processing_element_id ElementId;
        state ElementState;
    }) -> () error zx.Status;

    /// Controls a processing element using a unique ElementId returned by `GetElements`.
    /// Note that `SettableElementState` is a subset of `ElementState`, because some fields returned
    /// from `WatchElementState` (e.g. `latency`) can only be observed (not set) by the client.
    ///
    /// Returns `ZX_ERR_INVALID_ARGS` if the `processing_element_id` does not match an id returned
    /// by `GetElements` or the type of `SettableTypeSpecificElementState` does not
    /// match the `ElementType` of the processing element returned by
    /// `GetElements` for this id.
    /// The driver may return `ZX_ERR_INVALID_ARGS` if the `state` values are invalid, i.e. any
    /// of the values violates rules specified in this protocol, e.g. trying to change an
    /// `EQUALIZER` processing element's `EqualizerBandState` `frequency` when this processing
    /// element did not advertise `CAN_CONTROL_FREQUENCY` in its `supported_controls`.
    ///
    /// `SetElementState` may be called before or after non-`SignalProcessing` protocol
    /// calls. If called after non-`SignalProcessing` protocol calls then
    /// `SetElementState` may or may not require renegotiation of the driver state as
    /// reached with calls of the protocol composing `SignalProcessing`, e.g. `Dai`.
    /// For instance, `SetElementState` changing an `AGL` processing element's parameters
    /// may not require renegotiation of the `Dai` state because changing a gain parameter usually
    /// does not change the set of supported audio formats.
    /// By contrast, if `SetElementState` changes the parameters of a `CONNECTION_POINT`
    /// element, the change may require renegotiation because it may invalidate the set of
    /// supported formats returned in a previous `GetDaiFormats` `Dai` protocol call.
    ///
    /// It is the driver's job to determine when renegotiation is required. If renegotiation is
    /// required, then `SetElementState` must return `ZX_ERR_BAD_STATE` and the client must
    /// close the protocol channel such that the protocol negotiations are started over.
    /// The client then must make the `SetElementState` call that returned
    /// `ZX_ERR_BAD_STATE` before any non-`SignalProcessing` protocol calls.
    @available(added=20)
    strict SetElementState(struct {
        processing_element_id ElementId;
        state SettableElementState;
    }) -> () error zx.Status;

    /// Sets the topology to be used using an id to the vector returned by `GetTopologies`.
    /// The current topology is communicated by `WatchTopology` responses. To change which topology
    /// is active, a client uses `SetTopology`.
    /// If the specified `topology_id` is not within the`topologies` returned by `GetTopologies`,
    /// this call will return `ZX_ERR_INVALID_ARGS`.
    /// If `GetTopologies` returns only one `Topology`, `SetTopology` is optional and has no effect.
    ///
    /// `SetTopology` may be called before or after non-`SignalProcessing` protocol calls.
    /// If called after non-`SignalProcessing` protocol calls, then `SetTopology` may return
    /// `ZX_ERR_BAD_STATE` to indicate that the operation can not proceed without renegotiation of
    /// the driver state. See `SetElementState` for further discussion.
    strict SetTopology(struct {
        topology_id TopologyId;
    }) -> () error zx.Status;
};

/// For an overview see
/// [[Signal Processing Interface]](https://fuchsia.dev/fuchsia-src/concepts/drivers/driver_architectures/audio_drivers/audio_signal_processing).
closed protocol Reader {
    /// Returns a vector of supported processing elements.
    /// Must return one or more processing elements, or `ZX_ERR_NOT_SUPPORTED`.
    strict GetElements() -> (struct {
        processing_elements vector<Element>:MAX_COUNT_PROCESSING_ELEMENTS;
    }) error zx.Status;

    /// Get the processing element state via a hanging get.
    /// For a given `processing_element_id`, the driver will reply to the first `WatchElementState`
    /// sent by the client. The driver will not respond to subsequent client `WatchElementState`
    /// calls for a given `processing_element_id` until any field of the `Element` table changes
    /// from what was most recently reported for that `processing_element_id`.
    ///
    /// The driver will close the protocol channel with an error of `ZX_ERR_BAD_STATE`, if this
    /// method is called again while there is already a pending `WatchElementState` for this client
    /// and processing_element_id.
    strict WatchElementState(struct {
        processing_element_id ElementId;
    }) -> (struct {
        state ElementState;
    });

    /// Returns a vector of supported topologies.
    /// Must return one or more topologies, or `ZX_ERR_NOT_SUPPORTED`.
    /// If more than one topology is returned, then the client may choose any of the topologies from
    /// the list with `SetTopology`.
    /// If only one topology is returned, then the topology definition is informational only since
    /// the one and only topology used can't be changed with `SetTopology`.
    /// If `GetElements` returns one or more elements, `GetTopologies` must return one or
    /// more topologies.
    strict GetTopologies() -> (struct {
        topologies vector<Topology>:MAX_COUNT_TOPOLOGIES;
    }) error zx.Status;

    /// Get the current topology via a hanging get.
    /// The driver will immediately reply to the first `WatchTopology` sent by each client. The
    /// driver will not respond to subsequent `WatchTopology` calls from that client until the
    /// signal-processing topology changes, which occurs as a result of a `SetTopology` call.
    /// The driver will close the protocol channel with an error of `ZX_ERR_BAD_STATE`, if this
    /// method is called again while there is already a pending `WatchTopology` for this client.
    @available(added=HEAD)
    strict WatchTopology() -> (struct {
        topology_id TopologyId;
    });
};
