// Copyright (c) 2023, NVIDIA CORPORATION. All rights reserved.
//
// NVIDIA CORPORATION and its licensors retain all intellectual property
// and proprietary rights in and to this software, related documentation
// and any modifications thereto. Any use, reproduction, disclosure or
// distribution of this software and related documentation without an express
// license agreement from NVIDIA CORPORATION is strictly prohibited.
//
// --------- Warning: This is a build system generated file. ----------
//

//! @file
//!
//! @brief This file was generated by <i>omni.bind</i>.

#include <omni/core/OmniAttr.h>
#include <omni/core/Interface.h>
#include <omni/core/ResultError.h>

#include <functional>
#include <utility>
#include <type_traits>

#ifndef OMNI_BIND_INCLUDE_INTERFACE_IMPL


/** An individual audio capture stream. */
template <>
class omni::core::Generated<omni::audio::experimental::ICaptureStream_abi>
    : public omni::audio::experimental::ICaptureStream_abi
{
public:
    OMNI_PLUGIN_INTERFACE("omni::audio::experimental::ICaptureStream")

    /** Starts capturing audio data from the stream.
     *
     *  @param[in] flags Flags to alter the recording behavior.
     *
     *  @returns @ref carb::audio::AudioResult::eOk if the capture is successfully started.
     *  @returns An @ref AudioResult error code if the stream could not be started.
     *
     *  @remarks Audio streams are in a stopped state when they're created.
     *           You must call start() to start recording audio.
     *
     *  @remarks Without @ref fCaptureStreamStartFlagOneShot, the stream will
     *           perform looping capture. This means that once the ring buffer
     *           has been filled, audio will start being recorded from the start
     *           of the buffer again.
     *
     *  @remarks Looping audio will not overwrite unread parts of the ring buffer.
     *           Only parts of the buffer that have been unlocked can be overwritten
     *           by the audio system.
     *           Data written into the ring buffer must be unlocked periodically
     *           when using looping capture or the ring buffer will fill up and
     *           the device will overrun.
     *
     *  @thread_safety Calls to this function cannot occur concurrently with
     *                 other calls to @ref ICaptureStream_abi::start_abi() or @ref ICaptureStream_abi::stop_abi().
     */
    omni::audio::experimental::AudioResult start(omni::audio::experimental::CaptureStreamStartFlags flags) noexcept;

    /** Stop capturing audio data from the stream.
     *
     *  @param[in] flags Flags to alter the stopping behavior.
     *
     *  @returns @ref carb::audio::AudioResult::eOk if the capture was successfully stopped.
     *  @returns @ref carb::audio::AudioResult::eNotAllowed if the stream was already stopped.
     *  @returns An @ref AudioResult error code if something else went wrong.
     *           The stream is likely broken in this case.
     *
     *  @remarks This will stop capturing audio. Any audio data that would have
     *           been captured between this point and the next call to @ref ICaptureStream_abi::start_abi()
     *           will be lost.
     *
     *  @remarks If there is unread data in the buffer, that data can still be
     *           read with lock() after the stream is stopped.
     *
     *  @note If fCaptureStreamStopFlagSync was not specified, the stop call will not sync with the
     *        device so you could still receive callbacks after.
     *
     *  @note CC-1180: You cannot use fCaptureStreamStopFlagSync from a callback.
     *
     *  @thread_safety Calls to this function cannot occur concurrently with
     *                 other calls to @ref ICaptureStream_abi::start_abi() or @ref ICaptureStream_abi::stop_abi().
     */
    omni::audio::experimental::AudioResult stop(omni::audio::experimental::CaptureStreamStopFlags flags) noexcept;

    /** Check if the stream is still capturing data.
     *  @returns `true` if the stream is still capturing.
     *  @returns `false` if the stream is stopped.
     *           Callbacks will no longer be sent if `false` was returned unless the strema was
     *           stoped with @ref ICaptureStream_abi::stop_abi() was called without fCaptureStreamStopFlagSync.
     */
    bool isCapturing() noexcept;

    /** Get the available number of frames to be read.
     *
     *  @param[out] available The number of frames that can be read from the buffer.
     *
     *  @returns @ref carb::audio::AudioResult::eOk if the frame count was retrieved successfully.
     *  @returns @ref carb::audio::AudioResult::eOverrun if data has not been read fast enough and
     *           the buffer filled up.
     *  @returns @ref carb::audio::AudioResult::eNotAllowed if callback recording is being used.
     *  @returns An @ref AudioResult error code if the operation fails for any other reason.
     *
     *  @remarks This will check how much data is available to be read from the buffer.
     *           This call is only valid when polling style recording is in use.
     */
    omni::audio::experimental::AudioResult getAvailableFrames(size_t* available) noexcept;

    /** Lock the next chunk of the buffer to be read.
     *
     *  @param[in]  request  The length of the buffer to lock, in frames.
     *                       This may be 0 to lock as much data as possible.
     *                       This does not need to be a multiple of the fragment
     *                       length.
     *                       If you need to convert bytes to frames, you can use
     *                       @ref carb::audio::convertUnits() or
     *                       @ref carb::audio::framesToBytes() (note that this is
     *                       slow due to requiring a division).
     *  @param[out] region   Receives the audio data.
     *                       This can be `nullptr` to query the available data
     *                       in the buffer, rather than locking it.
     *                       This buffer can be held until unlock() is called;
     *                       after unlock is called, the stream can start writing
     *                       into this buffer.
     *  @param[out] received The length of data available in @p buffer, in frames.
     *                       This will not exceed @p request.
     *                       Due to the fact that a ring buffer is used, you may
     *                       have more data in the buffer than is returned in one
     *                       call; a second call would be needed to read the full
     *                       buffer.
     *                       If you need to convert this to bytes, you can use
     *                       @ref carb::audio::convertUnits() or
     *                       @ref carb::audio::framesToBytes().
     *
     *  @returns @ref carb::audio::AudioResult::eOk if the requested region is successfully locked.
     *  @returns @ref carb::audio::AudioResult::eOutOfMemory if there is no audio data available
     *           in the buffer yet.
     *  @returns @ref carb::audio::AudioResult::eNotAllowed if a region is already locked
     *           and needs to be unlocked.
     *  @returns @ref carb::audio::AudioResult::eNotAllowed if the stream is using callback
     *           style recording.
     *  @returns @ref carb::audio::AudioResult::eOverrun if data has not been read fast
     *           enough and the underlying device has overrun.
     *           This will happen on some audio systems (e.g. ALSA) if the
     *           capture buffer fills up.
     *           This can also happen on some audio systems sporadically if the
     *           device's timing characteristics are too aggressive.
     *  @returns an carb::audio::AudioResult::e* error code if the region could not be locked.
     *
     *  @remarks This is used to get data from the capture stream when polling
     *           style recording is being used (ie: there is no data callback).
     *           When using this style of recording, portions of the buffer must
     *           be periodically locked and unlocked.
     *
     *  @remarks This retrieves the next portion of the buffer.
     *           This portion of the buffer is considered to be locked until
     *           @ref ICaptureStream_abi::unlock_abi() is called.
     *           Only one region of the buffer can be locked at a time.
     *           When using a looping capture, the caller should ensure that data
     *           is unlocked before the buffer fills up or overruns may occur.
     */
    omni::audio::experimental::AudioResult lock(size_t request, const void** region, size_t* received) noexcept;

    /** Unlocks a previously locked region of the buffer.
     *
     *  @param[in] consumed The number of frames in the previous buffer that were consumed.
     *                      Any frames that were not consumed will be returned in future
     *                      @ref ICaptureStream_abi::lock_abi() calls.
     *                      0 is valid here if you want to have the same locked region
     *                      returned on the next lock() call.
     *
     *  @returns @ref carb::audio::AudioResult::eOk if the region is successfully unlocked.
     *  @returns @ref carb::audio::AudioResult::eOutOfRange if @p consumed was larger than
     *           the locked region.
     *  @returns @ref carb::audio::AudioResult::eNotAllowed if no region is currently locked.
     *  @returns an carb::audio::AudioResult::e* error code if the region could not be unlocked.
     *
     *  @remarks This unlocks a region of the buffer that was locked with a
     *           previous call to ICaptureStream_abi::lock_abi().
     *           Now that this region is unlocked, the device can start writing to it,
     *           so the caller should no longer access that region.
     *           Once the buffer is unlocked, a new region may be locked with ICaptureStream_abi::lock_abi().
     *
     *  @note If the locked region is not fully unlocked, the part of the region that
     *        was not unlocked will be returned on the next call to ICaptureStream_abi::lock_abi().
     *        A second call to unlock cannot be made in this situation, it will fail.
     */
    omni::audio::experimental::AudioResult unlock(size_t consumed) noexcept;

    /** Retrieve the size of the capture buffer.
     *
     *  @returns The size of the capture buffer, in frames.
     *           You can use @ref ICaptureStream_abi::getSoundFormat_abi() and @ref carb::audio::convertUnits()
     *           to convert to bytes or other units.
     *
     *  @remarks If your code is dependent on the buffer's actual size, it is
     *           better to retrieve it with this function since the buffer size
     *           used with device creation can be adjusted.
     */
    size_t getBufferSize() noexcept;

    /** Retrieve the number of fragments used in this stream.
     *
     *  @returns The number of buffer fragments.
     *           This is the number of regions the recording buffer is divided
     *           into.
     */
    size_t getFragmentCount() noexcept;

    /** Retrieve the format of the audio being captured.
     *
     *  @param[out] format The format of the audio being captured.
     *                     This may not be `nullptr`.
     */
    void getSoundFormat(omni::audio::experimental::SoundFormat* format) noexcept;

    /** Clear any data that is currently in the recording buffer.
     *
     *  @returns @ref carb::audio::AudioResult::eOk if the buffer was successfully cleared.
     *  @returns an carb::audio::AudioResult::e* error code if the buffer could not be cleared.
     *
     *  @remarks This is a quick way to get rid of any data that is left in the
     *           buffer.
     *           This will also reset the write position on the buffer back to
     *           0, so the next lock call will return the start of the buffer
     *           (this can be useful if you want to do a one shot capture of the
     *           entire buffer).
     *
     *  @note If this is called while the capture stream is recording, the stream
     *        will be paused before it is reset.
     */
    omni::audio::experimental::AudioResult reset() noexcept;
};

#endif

#ifndef OMNI_BIND_INCLUDE_INTERFACE_DECL

inline omni::audio::experimental::AudioResult omni::core::Generated<omni::audio::experimental::ICaptureStream_abi>::start(
    omni::audio::experimental::CaptureStreamStartFlags flags) noexcept
{
    return start_abi(flags);
}

inline omni::audio::experimental::AudioResult omni::core::Generated<omni::audio::experimental::ICaptureStream_abi>::stop(
    omni::audio::experimental::CaptureStreamStopFlags flags) noexcept
{
    return stop_abi(flags);
}

inline bool omni::core::Generated<omni::audio::experimental::ICaptureStream_abi>::isCapturing() noexcept
{
    return isCapturing_abi();
}

inline omni::audio::experimental::AudioResult omni::core::Generated<
    omni::audio::experimental::ICaptureStream_abi>::getAvailableFrames(size_t* available) noexcept
{
    return getAvailableFrames_abi(available);
}

inline omni::audio::experimental::AudioResult omni::core::Generated<omni::audio::experimental::ICaptureStream_abi>::lock(
    size_t request, const void** region, size_t* received) noexcept
{
    return lock_abi(request, region, received);
}

inline omni::audio::experimental::AudioResult omni::core::Generated<omni::audio::experimental::ICaptureStream_abi>::unlock(
    size_t consumed) noexcept
{
    return unlock_abi(consumed);
}

inline size_t omni::core::Generated<omni::audio::experimental::ICaptureStream_abi>::getBufferSize() noexcept
{
    return getBufferSize_abi();
}

inline size_t omni::core::Generated<omni::audio::experimental::ICaptureStream_abi>::getFragmentCount() noexcept
{
    return getFragmentCount_abi();
}

inline void omni::core::Generated<omni::audio::experimental::ICaptureStream_abi>::getSoundFormat(
    omni::audio::experimental::SoundFormat* format) noexcept
{
    getSoundFormat_abi(format);
}

inline omni::audio::experimental::AudioResult omni::core::Generated<omni::audio::experimental::ICaptureStream_abi>::reset() noexcept
{
    return reset_abi();
}

#endif

#undef OMNI_BIND_INCLUDE_INTERFACE_DECL
#undef OMNI_BIND_INCLUDE_INTERFACE_IMPL
static_assert(std::is_standard_layout<omni::audio::experimental::Format>::value,
              "omni::audio::experimental::Format must be standard layout to be used in ONI ABI");
static_assert(std::is_standard_layout<omni::audio::experimental::CaptureDeviceDesc>::value,
              "omni::audio::experimental::CaptureDeviceDesc must be standard layout to be used in ONI ABI");
static_assert(std::is_standard_layout<omni::audio::experimental::CaptureInfoData>::value,
              "omni::audio::experimental::CaptureInfoData must be standard layout to be used in ONI ABI");
static_assert(std::is_standard_layout<omni::audio::experimental::CaptureStreamDesc>::value,
              "omni::audio::experimental::CaptureStreamDesc must be standard layout to be used in ONI ABI");
