// 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.media.sounds;

using fuchsia.io;
using fuchsia.media;
using fuchsia.mem;
using zx;

/// Allows clients to play fire-and-forget sounds.
[Discoverable]
protocol Player {
    /// Adds a sound to the collection maintained for the client, reading the sound from a file.
    /// If `id` identifies an existing sound in the collection, the service will close the
    /// connection. Returns the duration of the sound or an error status returned from an I/O
    /// operation.
    ///
    /// Currently, only PCM WAV files and Ogg/Opus files are supported.
    AddSoundFromFile(uint32 id, fuchsia.io.File file) -> (zx.duration duration) error zx.status;

    /// Adds a sound, in the form of a buffer containing raw PCM samples, to the collection
    /// maintained for the client. The service will retain a handle to the buffer's VMO until the
    /// sound is removed and is no longer playing or until the connection is closed.
    ///
    /// If `id` identifies an existing sound in the collection, the service will close the
    /// connection.
    AddSoundBuffer(uint32 id, fuchsia.mem.Buffer buffer, fuchsia.media.AudioStreamType stream_type);

    /// Removes a sound from the collection maintained for the client. A sound can be removed even
    /// if a `PlaySound` method is pending for that sound.
    ///
    /// If `id` doesn't identify an existing sound in the collection, the service will do nothing.
    /// This is tolerated so that clients don't have to wait for the response from
    /// `AddSoundFromFile` before playing and removing the sound.
    ///
    /// Removing an unneeded sound frees the resources associated with that sound, principally
    /// the VMO required to store the uncompressed sound.
    RemoveSound(uint32 id);

    /// Plays the existing sound identified by `id` using a renderer with usage `usage`. The
    /// sound is played as soon as possible. The reply is sent when the sound is finished playing.
    /// If `id` doesn't identify an existing sound in the collection, the method returns
    /// `PlaySoundError.NO_SUCH_SOUND`. The most recent `PlaySound` call for a given valid id can
    /// be stopped using `StopPlayingSound`, in which case, this method returns
    /// `PlaySoundError.STOPPED`.
    PlaySound(uint32 id, fuchsia.media.AudioRenderUsage usage) -> () error PlaySoundError;

    /// Stops playback of the sound identified by `id` invoked by the the most recent call to
    /// `PlaySound` for that sound. If `id` doesn't identify an existing sound in the collection
    /// or if the sound is not currently playing, this method does nothing. If more than one
    /// `PlaySound` method is currently pending for that sound, only the most recent is stopped.
    [Transitional]
    StopPlayingSound(uint32 id);
};

/// Error type for `Player.PlaySound`.
enum PlaySoundError {
    /// The `id` passed to `PlaySound` is not recognized.
    NO_SUCH_SOUND = 1;

    /// Underlying audio renderer failed.
    RENDERER_FAILED = 2;

    /// Playback of the sound was interrupted by a |StopPlayingSound| method call.
    STOPPED = 3;
};
