// Copyright 2016 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;

@discoverable
closed protocol Audio {
    strict CreateAudioRenderer(resource struct {
        audio_renderer_request server_end:AudioRenderer;
    });

    /// Creates an AudioCapturer which either captures from the current default
    /// audio input device, or loops-back from the current default audio output
    /// device based on value passed for the loopback flag.
    ///
    // TODO(mpuryear): Get rid of the loopback flag ASAP. Routing decisions (and
    // security surrounding routing decisions) should be much more sophisticated
    // than this. This is just a placeholder until we have a design in place.
    // Eventually, I suspect that all of this will move up into the audio policy
    // manager and application clients will obtain AudioCapturers from and control
    // through the policy manager.
    strict CreateAudioCapturer(resource struct {
        audio_capturer_request server_end:AudioCapturer;
        loopback bool;
    });

    // TODO(fxbug.dev/38104): Remove these methods.
    @transitional
    @deprecated
    strict SetSystemMute(struct {
        muted bool;
    });
    @transitional
    @deprecated
    strict SetSystemGain(struct {
        gain_db float32;
    });
    @transitional
    @deprecated
    strict -> SystemGainMuteChanged(struct {
        gain_db float32;
        muted bool;
    });
};

/// Permitted ranges for AudioRenderer and AudioCapturer
const MIN_PCM_CHANNEL_COUNT uint32 = 1;
const MAX_PCM_CHANNEL_COUNT uint32 = 8;
const MIN_PCM_FRAMES_PER_SECOND uint32 = 1000;
const MAX_PCM_FRAMES_PER_SECOND uint32 = 192000;
