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

    /// Return the number of active input and output virtual devices.
    /// This method's callback can be used as a mechanism to synchronize with
    /// other asynchronous in-flight virtualaudio FIDL operations.
    GetNumDevices() -> (uint32 num_input_devices,
                        uint32 num_output_devices);
};

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