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

using zx;

// fuchsia.virtualaudio.Forwarder
//

/// Using this Simple Layout (C-bound) protocol, an intermediary (such as the
/// virtual audio service) forwards FIDL protocol requests to the virtual audio
/// driver, which enables clients to use more full-featured (C++ based) bindings
/// with this driver -- specifically the Control, Input and Output protocols.
[Layout = "Simple"]
protocol Forwarder {
    SendControl(request<Control> control);
    SendInput(request<Input> input);
    SendOutput(request<Output> output);
};

// fuchsia.virtualaudio.Control
//

/// This protocol provides the caller a high-level ON/OFF switch for overall
/// virtual audio functionality at the system level. When virtualaudio is
/// disabled, device configurations can be created and changed, but no devices
/// can be added. When virtualaudio is enabled, device configurations can again
/// be converted into devices by calling `Add()`.
[Discoverable]
protocol Control {
    /// Allow inputs and outputs to be activated, but do not automatically
    /// reactivate those previously deactivated by `Disable()`. Does not affect
    /// existing Configs. By default, virtualaudio is enabled on system startup.
    /// This method's callback can be used as a mechanism to synchronize with
    /// other asynchronous in-flight virtualaudio FIDL operations.
    Enable() -> ();

    /// Deactivate all active inputs/outputs; disallow subsequent activations.
    /// This method's callback can be used as a mechanism to synchronize with
    /// other asynchronous in-flight virtualaudio FIDL operations.
    Disable() -> ();
};

///
/// The Input and Output protocols closely correspond to the capabilities
/// exposed by the Audio Driver Streaming Interface, fully documented at
/// driver-interfaces/audio.md and declared at device/audio.h.
///

// fuchsia.virtualaudio.Input
//
/// This protocol represents an active virtual audio input device. It inherits
/// the parent protocols Device and Configuration. This protocol, as well as the
/// contents of Device, represent actions that can be taken by an active input
/// device -- actions that should be immediately detected and reacted upon by
/// the audio subsystem.
[Discoverable]
protocol Input {
    compose Device;

    // TODO(mpuryear): `SetCaptureSignal()` -- indicate what to "capture".
    // E.g. sinusoid, constant, square, ramp, saw, noise. Can differ by channel.

    // TODO(mpuryear): `PairWithOutput()` -- client passes an output (server)
    // binding; input device returns as captured data the streamed output data.
};

// fuchsia.virtualaudio.Output
//

/// This protocol represents an active virtual audio output device. It inherits
/// the parent protocols Device and Configuration. This protocol, as well as the
/// contents of Device, represent actions that can be taken by an active output
/// device -- actions that should be immediately detected and reacted upon by
/// the audio subsystem.
[Discoverable]
protocol Output {
    compose Device;

    // TODO(mpuryear): any render-specific configuration or runtime triggers.
};

/// This protocol represents the base functionality of active Input and Output
/// audio devices -- methods that are common to both protocols. This protocol,
/// as well as the contents of Output and Input, represent actions that can be
/// taken by an active device -- actions that should be immediately detected and
/// reacted upon by the audio subsystem.
[FragileBase]
protocol Device {
    compose Configuration;

    /// Activate (`DdkAdd`) the virtual audio device as currently configured. A
    /// device node will be published and detected by the AudioDeviceManager,
    /// and a driver for the virtual device will be loaded and queried. Device
    /// arrivals are exposed to clients by the
    /// `fuchsia.media.AudioDeviceEnumerator` protocol, in `GetDevices()` and
    /// the `->OnDeviceAdded()` event.
    Add();

    /// Deactivate (`DdkRemove`) the active virtual audio device, but retain its
    /// configuration for future activation. The driver for the virtual device
    /// will be unloaded, and the device node closed. Device removals are
    /// exposed to clients by `fuchsia.media.AudioDeviceEnumerator`, in
    /// `GetDevices()` and `->OnDeviceRemoved()`.
    Remove();

    /// Return the format selected by the client, when that client issued an
    /// `AUDIO_STREAM_CMD_SET_FORMAT` command. This can only occur after a
    /// device has been added, and is only allowed to occur before the device's
    /// ring buffer has been returned (i.e., before an
    /// `AUDIO_RB_CMD_GET_BUFFER` command).
    GetFormat() -> (uint32 frames_per_second, uint32 sample_format,
                    uint32 num_channels, zx.duration external_delay);

    /// Notify all subscribed listeners when the above format is set or changed.
    -> OnSetFormat(uint32 frames_per_second, uint32 sample_format,
                   uint32 num_channels, zx.duration external_delay);

    /// Return the current gain state for this device. After a device has been
    /// added, a client can call this at any time -- even before the ring buffer
    /// has been established, or before the format has been set.
    GetGain() -> (bool current_mute, bool current_agc, float32 current_gain_db);

    /// Notify all subscribed listeners when the above gain is set or changed.
    -> OnSetGain(bool current_mute, bool current_agc, float32 current_gain_db);

    /// Return details about the ring buffer that was established in response
    /// to a client `AUDIO_RB_CMD_GET_BUFFER` command. This will only occur
    /// after the client sets the format and retrieves other driver information.
    GetBuffer() -> (handle<vmo> ring_buffer, uint32 num_ring_buffer_frames,
                    uint32 notifications_per_ring);

    /// Notify all subscribed listeners when the above buffer has been created.
    -> OnBufferCreated(handle<vmo> ring_buffer, uint32 num_ring_buffer_frames,
                       uint32 notifications_per_ring);

    /// Override the position notification frequency set by AudioCore for this
    /// stream, with the given value. Although this method can be called at any
    /// time (including before this Input|Output is added, or after it is
    /// started), logically it makes most sense to call this immediately after
    /// receiving details about the just-created ring buffer, via `GetBuffer` or
    /// the `->OnBufferCreated` event.
    SetNotificationFrequency(uint32 notifications_per_ring);

    /// Notify all subscribed listeners when the device is commanded to Start
    /// streaming. This can only occur after a device is fully configured
    /// (format is set; ring buffer is established and fetched).
    -> OnStart(zx.time start_time);

    /// Notify all subscribed listeners when the device is commanded to Stop
    /// streaming. This can only occur when the device is already Started. Stop
    /// returns the device to a fully-configured state. Upon this command, the
    /// already-set format and ring buffer are retained without change, but
    /// position will re-begin at 0, if the device is again Started.
    -> OnStop(zx.time stop_time, uint32 ring_position);

    /// Return the current position (in bytes) within the ring buffer. This can
    /// only be called after the ring buffer is established. If the device has
    /// not yet Started streaming, then zero will always be returned.
    GetPosition() -> (uint32 ring_position, zx.time clock_time);

    /// Notify all subscribed listeners, when any `AUDIO_RB_POSITION_NOTIFY`
    /// position notification is issued by the driver. The frequency of these
    /// per-stream notifications is set by AudioCore, reported to VAD clients
    /// via `GetBuffer` or the `->OnBufferCreated` event. VirtualAudioDevice
    /// clients can enable an alternate notification frequency for a given
    /// stream by calling `SetNotificationFrequency`.
    -> OnPositionNotify(uint32 ring_position, zx.time clock_time);

    /// Hot-plug or hot-unplug an active virtual device, at the specified time.
    /// For devices marked as capable of asynchronously notifying the system of
    /// plug changes, the driver will now send the values using
    /// `AUDIO_STREAM_PLUG_DETECT_NOTIFY`. Else, values will be reflected when
    /// the driver is next sent an `AUDIO_STREAM_CMD_PLUG_DETECT` command. This
    /// information is used by the system when determining which device is
    /// default. This, in turn, is exposed to clients by the
    /// `fuchsia.media.AudioDeviceEnumerator` protocol: in `GetDevices()`,
    /// `GetDefaultInputDevice()`/`GetDefaultOutputDevice()` and the
    /// `->OnDefaultDeviceChanged()` event.
    ChangePlugState(zx.time plug_change_time, bool plugged);

    // TODO(mpuryear): `TweakClockRate(uint64 numerator, uint64 denominator)` --
    // emulating a device clock, advance position at given ratio of MONOTONIC.
};

/// This protocol is conceptually a base protocol to Device. It exposes the
/// methods used to specify the properties of a virtual audio device (its
/// configuration), before the virtual device is instantiated by the call to
/// `Add()`. Although the non-Add methods on this protocol can be called after
/// calling `Add()` (i.e., after Configuration has been converted into active
/// Device), this only changes how future Devices will be created; it has no
/// effect on already-created Devices.
[FragileBase]
protocol Configuration {
    /// Set the virtual audio device's name. This corresponds to the value
    /// associated with the device node for this virtual device. This must be
    /// called before calling `Add()`, or after `Remove()`.
    SetDeviceName(string device_name);

    /// Set the virtual audio device's manufacturer name. This must be called
    /// before calling `Add()`, or after `Remove()`. Once a device is activated,
    /// this value is returned by the driver in response to an
    /// `AUDIO_STREAM_CMD_GET_STRING` command of string ID
    /// `AUDIO_STREAM_STR_ID_MANUFACTURER`. This information is exposed to
    /// clients by the `fuchsia.media.AudioDeviceEnumerator` protocol: returned
    /// in an `AudioDeviceInfo` struct by `GetDevices()` and the
    /// `->OnDeviceAdded()` event.
    SetManufacturer(string manufacturer_name);

    /// Set the virtual audio device's product name. This must be called before
    /// calling `Add()`, or after `Remove()`. Once the device is activated, this
    /// value is returned by the driver in response to an
    /// `AUDIO_STREAM_CMD_GET_STRING` command of string ID
    /// `AUDIO_STREAM_STR_ID_PRODUCT`. This information is exposed to clients by
    /// the `fuchsia.media.AudioDeviceEnumerator` protocol: returned in an
    /// `AudioDeviceInfo` struct by `GetDevices()` and the `->OnDeviceAdded()`
    /// event.
    SetProduct(string product_name);

    /// Set the virtual audio device's unique ID, a 16-character string. This
    /// must be called before calling `Add()`, or after `Remove()`. Once the
    /// device is activated, this value is returned by the driver in response
    /// to an `AUDIO_STREAM_CMD_GET_UNIQUE_ID` command. This value is exposed
    /// to clients by the `fuchsia.media.AudioDeviceEnumerator` protocol:
    /// returned in an `AudioDeviceInfo` struct by `GetDevices()` or
    /// `->OnDeviceAdded()`.
    SetUniqueId(array<uint8>:16 unique_id);

    /// Add a supported format range for this audio device. This must be called
    /// before calling `Add()`, or after `Remove()`. Once the device is
    /// activated, format ranges are returned by the driver in response to an
    /// `AUDIO_STREAM_CMD_GET_FORMATS` command. sample_format_flags is of type
    /// audio_sample_format_t, and rate_family_flags is a bit field of possible
    /// constants beginning with ASF_RANGE_FLAG_FPS_. See audio.h for details.
    AddFormatRange(uint32 sample_format_flags, uint32 min_frame_rate,
                   uint32 max_frame_rate, uint8 min_channels,
                   uint8 max_channels, uint16 rate_family_flags);

    /// Remove the minimal format range that is added by default to all
    /// configurations. As with `AddFormatRange()`, this method must be called
    /// before calling `Add()`, or after `Remove()`.
    ClearFormatRanges();

    /// Set the virtual audio device's fifo depth, in bytes. This must be called
    /// before calling `Add()`, or after `Remove()`. Once the device is
    /// activated, the depth of its FIFO is returned by the driver in response
    /// to an `AUDIO_RB_CMD_GET_FIFO_DEPTH` command on the ring buffer channel.
    SetFifoDepth(uint32 fifo_depth_bytes);

    /// Set the virtual audio device's external delay, in nanoseconds. This must
    /// be called before calling `Add()`, or after `Remove()`. Once the device
    /// is activated, this value is returned by the driver in response to an
    /// `AUDIO_STREAM_CMD_SET_FORMAT` command.
    //
    // Treating this as a static property is inadequate, considering that the
    // delay is intended to be calculated from the format that was just set.
    SetExternalDelay(zx.duration external_delay);

    /// Set restrictions for the device ring buffer. This must be called before
    /// calling `Add()`, or after `Remove()`. Once the device is activated, the
    /// ring buffer and its size are returned by the driver in response to an
    /// `AUDIO_RB_CMD_GET_BUFFER` command on the ring buffer channel.
    /// Note: both min_frames and max_frames must be multiples of modulo_frames.
    SetRingBufferRestrictions(uint32 min_frames, uint32 max_frames,
                              uint32 modulo_frames);

    /// Set gain properties for this virtual device. This must be called before
    /// calling `Add()`, or after `Remove()`. Once the device is activated, gain
    /// information is returned by the driver in an
    /// `audio_stream_cmd_get_gain_resp` struct, in response to an
    /// `AUDIO_STREAM_CMD_GET_GAIN` command. This information is exposed to
    /// clients by the `fuchsia.media.AudioDeviceEnumerator` protocol: returned
    /// in an `AudioGainInfo` struct by `GetDeviceGain()` and the
    /// `->OnDeviceGainChanged()` event.
    SetGainProperties(float32 min_gain_db, float32 max_gain_db,
                      float32 gain_step_db, float32 current_gain_db,
                      bool can_mute, bool current_mute,
                      bool can_agc, bool current_agc);

    /// Set plug properties for this virtual device. This must be called before
    /// calling `Add()`, or after `Remove()`. Once the device is activated, plug
    /// information is returned by the driver in response to an
    /// `AUDIO_STREAM_CMD_PLUG_DETECT `command. This information is used by the
    /// system when determining which device is default. This in turn is exposed
    /// to clients by the `fuchsia.media.AudioDeviceEnumerator` protocol: in
    /// `GetDevices()`, `GetDefaultInputDevice()`/`GetDefaultOutputDevice()` and
    /// the `->OnDefaultDeviceChanged()` event.
    SetPlugProperties(zx.time plug_change_time, bool plugged, bool hardwired,
                      bool can_notify);

    /// Return a configuration to its default settings. This call has no effect
    /// on active devices. In other words, it must be called before calling
    /// `Add()`, or after `Remove()`.
    ResetConfiguration();
};
