/*
 * Copyright (c) 2024 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @addtogroup HdiAudio
 *
 * @brief Provides unified APIs for audio services to access audio drivers.
 *
 * An audio service can obtain an audio driver object or agent and then call APIs provided by this object or agent to
 * access different types of audio devices based on the audio IDs, thereby obtaining audio information,
 * subscribing to or unsubscribing from audio data, enabling or disabling an audio,
 * setting the audio data reporting mode, and setting audio options such as the accuracy and measurement range.
 *
 * @since 4.1
 * @version 4.0
 */

package ohos.hdi.audio.v4_0;

import ohos.hdi.audio.v4_0.AudioTypes;
import ohos.hdi.audio.v4_0.IAudioCallback;

/**
 * @brief Provides capabilities for audio rendering, including controlling the rendering, setting audio attributes,
 * scenes, and volume, obtaining hardware latency, and rendering audio frames.
 *
 * @since 4.1
 * @version 2.0
 */
interface IAudioRender {
    /**
     * @brief Obtains the estimated latency of the audio device driver.
     *
     * @param render Indicates the pointer to the <b>IAudioRender</b> object to operate.
     * @param ms Indicates the pointer to the latency (in milliseconds) to be obtained.
     * @return Returns <b>0</b> if the latency is obtained; returns a negative value otherwise.
     *
     * @since 4.1
     * @version 2.0
     */
    GetLatency([out] unsigned int ms);

    /**
     * @brief Writes a frame of output data (downlink data) into the audio driver for rendering.
     *
     * @param render Indicates the pointer to the <b>IAudioRender</b> object to operate.
     * @param frame Indicates the pointer to the frame to write.
     * @param requestBytes Indicates the size of the frame, in bytes.
     * @param replyBytes Indicates the pointer to the actual length (in bytes) of the audio data to write.
     * @return Returns <b>0</b> if the data is written successfully; returns a negative value otherwise.
     *
     * @since 4.1
     * @version 2.0
     */
    RenderFrame([in] byte[] frame, [out] unsigned long replyBytes);

    /**
     * @brief Obtains the last number of output audio frames.
     *
     * @param render Indicates the pointer to the <b>IAudioRender</b> object to operate.
     * @param frames Indicates the pointer to the last number of output audio frames.
     * @param time Indicates the pointer to the timestamp associated with the frame.
     * @return Returns <b>0</b> if the last number is obtained; returns a negative value otherwise.
     * @see RenderFrame
     *
     * @since 4.1
     * @version 2.0
     */
    GetRenderPosition([out] unsigned long frames, [out] struct AudioTimeStamp time);

    /**
     * @brief Sets the audio rendering speed.
     *
     * @param render Indicates the pointer to the <b>IAudioRender</b> object to operate.
     * @param speed Indicates the rendering speed to set.
     * @return Returns <b>0</b> if the setting is successful; returns a negative value otherwise.
     * @see GetRenderSpeed
     *
     * @since 4.1
     * @version 2.0
     */
    SetRenderSpeed([in] float speed);

    /**
     * @brief Obtains the current audio rendering speed.
     *
     * @param render Indicates the pointer to the <b>IAudioRender</b> object to operate.
     * @param speed Indicates the pointer to the current rendering speed to obtain.
     * @return Returns <b>0</b> if the speed is successfully obtained; returns a negative value otherwise.
     * @see SetRenderSpeed
     *
     * @since 4.1
     * @version 2.0
     */
    GetRenderSpeed([out] float speed);

    /**
     * @brief Sets the channel mode for audio rendering.
     *
     * @param render Indicates the pointer to the <b>IAudioRender</b> object to operate.
     * @param mode Indicates the channel mode to set.
     * @return Returns <b>0</b> if the setting is successful; returns a negative value otherwise.
     * @see GetChannelMode
     *
     * @since 4.1
     * @version 2.0
     */
    SetChannelMode([in] enum AudioChannelMode mode);

    /**
     * @brief Obtains the current channel mode for audio rendering.
     *
     * @param render Indicates the pointer to the <b>IAudioRender</b> object to operate.
     * @param mode Indicates the pointer to the channel mode to obtain.
     * @return Returns <b>0</b> if the mode is successfully obtained; returns a negative value otherwise.
     * @see SetChannelMode
     *
     * @since 4.1
     * @version 2.0
     */
    GetChannelMode([out] enum AudioChannelMode mode);

    /**
     * @brief Registers an audio callback that will be invoked during playback when buffer data writing or
     * buffer drain is complete.
     *
     * @param render Indicates the pointer to the <b>IAudioRender</b> object to operate.
     * @param callback Indicates the callback to register.
     * @param cookie Indicates the pointer to the callback parameters.
     * @return Returns <b>0</b> if the operation is successful; returns a negative value otherwise.
     * @see RegCallback
     *
     * @since 4.1
     * @version 2.0
     */
    RegCallback([in] IAudioCallback audioCallback, [in] byte cookie);

    /**
     * @brief Drains the buffer.
     *
     * @param render Indicates the pointer to the <b>IAudioRender</b> object to operate.
     * @param type Indicates the pointer to the execution type of this function. For details,
     * see {@link AudioDrainNotifyType}.
     * @return Returns <b>0</b> if the operation is successful; returns a negative value otherwise.
     * @see RegCallback
     *
     * @since 4.1
     * @version 2.0
     */
    DrainBuffer([out] enum AudioDrainNotifyType type);

    /**
     * @brief query whether the vendor supports draining buffer
     *
     * @param render Indicates the pointer to the <b>IAudioRender</b> object to operate.
     * @param support indicates the state whether the vendor supports draining buffer. Value <b>true</b> means that
     * the vendor supports, and <b>false</b> means the opposite.
     * @return Returns <b>0</b> if the operation is successful; returns a negative value otherwise.
     * @see IsSupportsDrain
     *
     * @since 4.1
     * @version 2.0
     */
    IsSupportsDrain([out] boolean support);

    /**
     * @brief Checks whether the configuration of an audio scene is supported.
     *
     * @param handle Indicates the audio handle.
     * @param scene Indicates the pointer to the descriptor of the audio scene.
     * @param supported Indicates the pointer to the variable specifying whether the configuration is supported.
     * Value <b>true</b> means that the configuration is supported, and <b>false</b> means the opposite.
     * @return Returns <b>0</b> if the result is obtained; returns a negative value otherwise.
     * @see SelectScene
     *
     * @since 4.1
     * @version 2.0
     */
    CheckSceneCapability([in] struct AudioSceneDescriptor scene, [out] boolean supported);

    /**
     * @brief Selects an audio scene.
     *
     * <ul>
     *   <li>To select a specific audio scene, you need to specify both the application scenario and output device.
     *     For example, to select a scene using a smartphone speaker as the output device, set <b>scene</b> according
     *     to the scenarios where the speaker is used. For example:</li>
     *     <ul>
     *       <li>For media playback, set the value to <b>media_speaker</b>.</li>
     *       <li>For a voice call, set the value to <b>voice_speaker</b>.</li>
     *     </ul>
     *   <li>To select only the application scenario, such as media playback, movie, or gaming, you can set
     *     <b>scene</b> to <b>media</b>, <b>movie</b>, or <b>game</b>, respectively.</li>
     *   <li>To select only the output device, such as media receiver, speaker, or headset, you can set
     *     <b>scene</b> to <b>receiver</b>, <b>speaker</b>, or <b>headset</b>, respectively.</li>
     * </ul>
     * @param handle Indicates the audio handle.
     * @param scene Indicates the pointer to the descriptor of the audio scene to select.
     * @return Returns <b>0</b> if the scene is selected successfully; returns a negative value otherwise.
     * @see CheckSceneCapability
     *
     * @since 4.1
     * @version 2.0
     */
    SelectScene([in] struct AudioSceneDescriptor scene);

    /**
     * @brief Sets the mute operation for the audio.
     *
     * @param handle Indicates the audio handle.
     * @param mute Specifies whether to mute the audio. Value <b>true</b> means to mute the audio,
     * and <b>false</b> means the opposite.
     * @return Returns <b>0</b> if the setting is successful; returns a negative value otherwise.
     * @see GetMute
     *
     * @since 4.1
     * @version 2.0
     */
    SetMute([in] boolean mute);

    /**
     * @brief Obtains the mute operation set for the audio.
     *
     * @param handle Indicates the audio handle.
     * @param mute Indicates the pointer to the mute operation set for the audio. Value <b>true</b> means that
     * the audio is muted, and <b>false</b> means the opposite.
     * @return Returns <b>0</b> if the mute operation is obtained; returns a negative value otherwise.
     * @see SetMute
     *
     * @since 4.1
     * @version 2.0
     */
    GetMute([out] boolean mute);

    /**
     * @brief Sets the audio volume.
     *
     * The volume ranges from 0.0 to 1.0. If the volume level in an audio service ranges from 0 to 15,
     * <b>0.0</b> indicates that the audio is muted, and <b>1.0</b> indicates the maximum volume level (15).
     *
     * @param handle Indicates the audio handle.
     * @param volume Indicates the volume to set. The value ranges from 0.0 to 1.0.
     * @return Returns <b>0</b> if the setting is successful; returns a negative value otherwise.
     * @see GetVolume
     *
     * @since 4.1
     * @version 2.0
     */
    SetVolume([in] float volume);

    /**
     * @brief Obtains the audio volume.
     *
     * @param handle Indicates the audio handle.
     * @param volume Indicates the pointer to the volume to obtain. The value ranges from 0.0 to 1.0.
     * @return Returns <b>0</b> if the volume is obtained; returns a negative value otherwise.
     * @see SetVolume
     *
     * @since 4.1
     * @version 2.0
     */
    GetVolume([out] float volume);

    /**
     * @brief Obtains the range of the audio gain.
     *
     * The audio gain can be expressed in one of the following two ways (depending on the chip platform),
     * corresponding to two types of value ranges:
     * <ul>
     *   <li>Actual audio gain values, for example, ranging from -50 to 6 dB</li>
     *   <li>Float numbers ranging from 0.0 to 1.0, where <b>0.0</b> means to mute the audio,
     *     and <b>1.0</b> means the maximum gain value, for example, 6 dB</li>
     * </ul>
     * @param handle Indicates the audio handle.
     * @param min Indicates the pointer to the minimum value of the range.
     * @param max Indicates the pointer to the maximum value of the range.
     * @return Returns <b>0</b> if the range is obtained; returns a negative value otherwise.
     * @see GetGain
     * @see SetGain
     *
     * @since 4.1
     * @version 2.0
     */
    GetGainThreshold([out] float min, [out] float max);

    /**
     * @brief Obtains the audio gain.
     *
     * @param handle Indicates the audio handle.
     * @param gain Indicates the pointer to the audio gain.
     * @return Returns <b>0</b> if the audio gain is obtained; returns a negative value otherwise.
     * @see GetGainThreshold
     * @see SetGain
     *
     * @since 4.1
     * @version 2.0
     */
    GetGain([out] float gain);

    /**
     * @brief Sets the audio gain.
     *
     * @param handle Indicates the audio handle.
     * @param gain Indicates the audio gain to set.
     * @return Returns <b>0</b> if the setting is successful; returns a negative value otherwise.
     * @see GetGainThreshold
     * @see GetGain
     *
     * @since 4.1
     * @version 2.0
     */
    SetGain([in] float gain);

    /**
     * @brief Obtains the audio frame size, that is, the length (in bytes) of a frame.
     *
     * @param handle Indicates the audio handle.
     * @param size Indicates the pointer to the audio frame size (in bytes).
     * @return Returns <b>0</b> if the audio frame size is obtained; returns a negative value otherwise.
     *
     * @since 4.1
     * @version 2.0
     */
    GetFrameSize([out] unsigned long size);

    /**
     * @brief Obtains the number of audio frames in the audio buffer.
     *
     * @param handle Indicates the audio handle.
     * @param count Indicates the pointer to the number of audio frames in the audio buffer.
     * @return Returns <b>0</b> if the number of audio frames is obtained; returns a negative value otherwise.
     *
     * @since 4.1
     * @version 2.0
     */
    GetFrameCount([out] unsigned long count);

    /**
     * @brief Sets audio sampling attributes.
     *
     * @param handle Indicates the audio handle.
     * @param attrs Indicates the pointer to the audio sampling attributes to set, such as the sampling rate,
     * sampling precision, and channel.
     * @return Returns <b>0</b> if the setting is successful; returns a negative value otherwise.
     * @see GetSampleAttributes
     *
     * @since 4.1
     * @version 2.0
     */
    SetSampleAttributes([in] struct AudioSampleAttributes attrs);

    /**
     * @brief Obtains audio sampling attributes.
     *
     * @param handle Indicates the audio handle.
     * @param attrs Indicates the pointer to the audio sampling attributes, such as the sampling rate,
     * sampling precision, and channel.
     * @return Returns <b>0</b> if audio sampling attributes are obtained; returns a negative value otherwise.
     * @see SetSampleAttributes
     *
     * @since 4.1
     * @version 2.0
     */
    GetSampleAttributes([out] struct AudioSampleAttributes attrs);

    /**
     * @brief Obtains the data channel ID of the audio.
     *
     * @param handle Indicates the audio handle.
     * @param channelId Indicates the pointer to the data channel ID.
     * @return Returns <b>0</b> if the data channel ID is obtained; returns a negative value otherwise.
     *
     * @since 4.1
     * @version 2.0
     */
    GetCurrentChannelId([out] unsigned int channelId);

    /**
     * @brief Sets extra audio parameters.
     *
     * @param handle Indicates the audio handle.
     * @param keyValueList Indicates the pointer to the key-value list of the extra audio parameters.
     * The format is <i>key=value</i>. Separate multiple key-value pairs by semicolons (;).
     * @return Returns <b>0</b> if the operation is successful; returns a negative value otherwise.
     *
     * @since 4.1
     * @version 2.0
     */
    SetExtraParams([in] String keyValueList);

    /**
     * @brief Obtains extra audio parameters.
     *
     * @param handle Indicates the audio handle.
     * @param keyValueList Indicates the pointer to the key-value list of the extra audio parameters.
     * The format is <i>key=value</i>. Separate multiple key-value pairs by semicolons (;).
     * @return Returns <b>0</b> if the operation is successful; returns a negative value otherwise.
     *
     * @since 4.1
     * @version 2.0
     */
    GetExtraParams([out] String keyValueList);

    /**
     * @brief Requests a mmap buffer.
     *
     * @param handle Indicates the audio handle.
     * @param reqSize Indicates the size of the request mmap buffer.
     * @param desc Indicates the pointer to the mmap buffer descriptor.
     * @return Returns <b>0</b> if the operation is successful; returns a negative value otherwise.
     *
     * @since 4.1
     * @version 2.0
     */
    ReqMmapBuffer([in] int reqSize, [out] struct AudioMmapBufferDescriptor desc);

    /**
     * @brief Obtains the read/write position of the current mmap buffer.
     *
     * @param handle Indicates the audio handle.
     * @param frames Indicates the pointer to the frame where the read/write starts.
     * @param time Indicates the pointer to the timestamp associated with the frame where the read/write starts.
     * @return Returns <b>0</b> if the operation is successful; returns a negative value otherwise.
     *
     * @since 4.1
     * @version 2.0
     */
    GetMmapPosition([out] unsigned long frames, [out] struct AudioTimeStamp time);

    /**
     * @brief Add the audio effect which the effectid indicated.
     *
     * @param handle Indicates the audio handle.
     * @param effectid Indicates the audio effect instance identifier which is going to be added.
     * @return Returns <b>0</b> if the audio effect were added succesffully; returns a negative value otherwise.
     *
     * @since 4.1
     * @version 2.0
     */
    AddAudioEffect([in] unsigned long effectid);

    /**
     * @brief Remove the audio effect which the effectid indicated.
     *
     * @param handle Indicates the audio handle.
     * @param effectid Indicates the audio effect which is going to be removed.
     * @return Returns <b>0</b> if the audio effect were removed succesffully; returns a negative value otherwise.
     *
     * @since 4.1
     * @version 2.0
     */
    RemoveAudioEffect([in] unsigned long effectid);

    /**
     * @brief Get the buffer size of render or capturer
     *
     * @param handle Indicates the audio handle.
     * @param bufferSize Indicates the buffer size (in bytes) queried from the vendor
     * @return Returns <b>0</b> if the operation is successful; returns a negative value otherwise.
     *
     * @since 4.1
     * @version 2.0
     */
    GetFrameBufferSize([out] unsigned long bufferSize);

    /**
     * @brief Starts audio rendering or capturing.
     *
     * @param handle Indicates the audio handle.
     * @return Returns <b>0</b> if the rendering or capturing is successfully started;
     * returns a negative value otherwise.
     * @see Stop
     *
     * @since 4.1
     * @version 2.0
     */
    Start();

    /**
     * @brief Stops audio rendering or capturing.
     *
     * @param handle Indicates the audio handle.
     * @return Returns <b>0</b> if the rendering or capturing is successfully stopped;
     * returns a negative value otherwise.
     * @see Start
     *
     * @since 4.1
     * @version 2.0
     */
    Stop();

    /**
     * @brief Pauses audio rendering or capturing.
     *
     * @param handle Indicates the audio handle.
     * @return Returns <b>0</b> if the rendering or capturing is successfully paused;
     * returns a negative value otherwise.
     * @see Resume
     *
     * @since 4.1
     * @version 2.0
     */
    Pause();

    /**
     * @brief Resumes audio rendering or capturing.
     *
     * @param handle Indicates the audio handle.
     * @return Returns <b>0</b> if the rendering or capturing is successfully resumed;
     * returns a negative value otherwise.
     * @see Pause
     *
     * @since 4.1
     * @version 2.0
     */
    Resume();

    /**
     * @brief Flushes data in the audio buffer.
     *
     * @param handle Indicates the audio handle.
     * @return Returns <b>0</b> if the flush is successful; returns a negative value otherwise.
     *
     * @since 4.1
     * @version 2.0
     */
    Flush();

    /**
     * @brief Sets or cancels the standby mode of the audio device.
     *
     * @param handle Indicates the audio handle.
     * @return Returns <b>0</b> if the device is set to standby mode; returns a positive value if the standby mode is
     * canceled; returns a negative value if the setting fails.
     *
     * @since 4.1
     * @version 2.0
     */
    TurnStandbyMode();

    /**
     * @brief Dumps information about the audio device.
     *
     * @param handle Indicates the audio handle.
     * @param range Indicates the range of the device information to dump, which can be brief or full information.
     * @param fd Indicates the file to which the device information will be dumped.
     * @return Returns <b>0</b> if the operation is successful; returns a negative value otherwise.
     *
     * @since 4.1
     * @version 2.0
     */
    AudioDevDump([in] int range, [in] int fd);

    /**
     * @brief Query whether the vendor support pause and resume.
     *
     * @param handle Indicates the audio handle.
     * @param supportPause Indicates the state whether the vendor supports pausing. Value <b>true</b> means that
     * the vendor supports, and <b>false</b> means the opposite.
     * @param supportResume Indicates the state whether the vendor supports resuming. Value <b>true</b> means that
     * the vendor supports, and <b>false</b> means the opposite.
     * @return Returns <b>0</b> if the operation is successful; returns a negative value otherwise.
     * @see IsSupportsPauseAndResume
     *
     * @since 4.1
     * @version 2.0
     */
    IsSupportsPauseAndResume([out] boolean supportPause, [out] boolean supportResume);

    /**
     * @brief Set offload buffer size.
     *
     * @param handle Indicates the audio handle.
     * @param size Indicates the buffer size which contains the audio data.
     * @return Returns <b>0</b> if the operation is successful; returns a negative value otherwise.
     *
     * @since 4.1
     * @version 2.0
     */
    SetBufferSize([in] unsigned int size);
}