blob: 1539e8013cde592f69fe19a84d62f0280bd82017 [file] [log] [blame]
// 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(fxbug.dev/64877): Complete parameters and types for processing elements.
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;
type ElementType = flexible enum {
/// Vendor Specific. A type of processing element not covered by any subsequent type definition.
VENDOR_SPECIFIC = 1;
/// Define pipelines start/end.
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;
};
/// 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;
};
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 uint64;
/// Processing element type. Required.
2: type ElementType;
/// If included, type specific parameters for the processing element.
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.
4: can_disable bool;
/// If included, a textual description of the processing element.
5: description string:MAX_STRING_SIZE;
};
/// 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;
};
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, for instance if a `SetElementState` enables a
/// disabled processing element providing a `TypeSpecificElementState`, then any previous
/// informational `TypeSpecificElementState` is superceded.
1: type_specific TypeSpecificElementState;
/// Process element enable/disable state. Optional. 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.
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.
3: latency Latency;
};
/// Edge pairs between processing elements used to define ordering in processing elements
/// arrangements.
type EdgePair = struct {
processing_element_id_from uint64;
processing_element_id_to uint64;
};
/// 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 uint64;
/// 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).
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.
SetElementState(struct {
processing_element_id uint64;
state ElementState;
}) -> (struct {}) error zx.status;
/// Sets the topology to be used using an id to the vector returned by `GetTopologies`.
/// If `GetTopologies` returns more than one `Topology`, `SetTopology` must be called to put the
/// driver in an initialized state. 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.
SetTopology(struct {
topology_id uint64;
}) -> (struct {}) error zx.status;
};
/// For an overview see
/// [[Signal Processing Interface]](https://fuchsia.dev/fuchsia-src/concepts/drivers/driver_architectures/audio_drivers/audio_signal_processing).
protocol Reader {
/// Returns a vector of supported processing elements.
/// Must return one or more processing elements, or ZX_ERR_NOT_SUPORTED.
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 `WatchElement` sent by the client.
/// The driver will not respond to subsequent client `WatchElement` 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`.
WatchElementState(struct {
processing_element_id uint64;
}) -> (struct {
state ElementState;
});
/// Returns a vector of supported topologies.
/// Must return one or more topologies, or ZX_ERR_NOT_SUPORTED.
/// 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.
GetTopologies() -> (struct {
topologies vector<Topology>:MAX_COUNT_TOPOLOGIES;
}) error zx.status;
};