/**************************************************************************
 * Copyright (C) 2012-2021  Unisound
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 **************************************************************************
 *
 * Description : uni_audio_out_v2.h
 * Author      : yzs.unisound.com
 * Date        : 2021.03.01
 *
 **************************************************************************/
#ifndef _UNI_AUDIO_OUT_V2_H__
#define _UNI_AUDIO_OUT_V2_H__

typedef void (*UNI_AUDIO_OUT_FRAME_CB)(unsigned int saddr, unsigned int eaddr);
typedef void (*UNI_AUDIO_OUT_FRAME_OVER_CB)(void);

/**
 * @brief 左右通道的起始地址和通道大小
 */
typedef struct {
	unsigned char *buffer0; ///< 左声道起始地址 8字节对齐
	unsigned char *buffer1; ///< 右声道起始地址 8字节对齐
	unsigned int   size;    ///< 通路buffer大小,同时对左右声道buffer起作用 128字节对齐
} UNI_AUDIO_OUT_BUFFER;

/**
 * @brief PCM参数配置
 */
typedef struct {
	unsigned int  sample_rate; ///< PCM采样率
	unsigned char channels;   ///< PCM通道数
	unsigned char bits;       ///< PCM位深16/32bit
	unsigned char interlace;  ///< PCM交织:1 非交织:0
	unsigned char endian;     ///< PCM大小端0:小端,1:大端
} UNI_AUDIO_OUT_PCM;

/**
 * @brief 回调函数
 */
typedef struct {
	UNI_AUDIO_OUT_FRAME_CB      new_frame_callback; ///< 回调,该函数实现不能阻塞
	UNI_AUDIO_OUT_FRAME_OVER_CB frame_over_callback; ///< 帧数据全部消耗完回调,该函数实现不能阻塞
} UNI_AUDIO_OUT_CALLBACK;

/**
 * @brief 播放帧配置
 */
typedef struct {
	unsigned int  saddr;       ///< 帧起始地址
	unsigned int  eaddr;       ///< 帧结束地址
} UNI_AUDIO_OUT_FRAME;

/**
 * @brief 播放通道的选择
 */
typedef enum {
	UNI_AUDIO_OUT_STEREO_C = 0,///< 双声道立体声,左声道选0th,右声道选1th,不混合
	UNI_AUDIO_OUT_LEFT_C,     ///< 左声道,左声道选0th,右声道选0th,不混合
	UNI_AUDIO_OUT_RIGHT_C,    ///< 右声道,左声道选1th,右声道选1th,不混合
	UNI_AUDIO_OUT_MONO_C,     ///< mono,左声道选0th,右声道选1th,混合
} UNI_AUDIO_OUT_CHANNEL;

/**
 * @brief 播放 需要在初始化后调用
 *
 * @param route 选择播放的通路,为0即可
 * @return int  是否初始化成功
 * @retval handle 成功
 * @retval -1 失败
 */
int uni_audio_out_alloc_playback(unsigned char route);

/**
 * @brief 播放结束后,释放空间
 *
 * @param handle  播放操作句柄
 * @return int    是否释放成功
 * @retval 0 成功
 * @retval -1 失败
 */
int uni_audio_out_free(int handle);

/**
 * @brief 配置通路左右声道的buffer
 *
 * @param handle  播放操作句柄
 * @param conf    配置buffer
 * @return int    是否配置成功
 * @retval 0 成功
 * @retval -1 失败
 */
int uni_audio_out_config_buffer(int handle, UNI_AUDIO_OUT_BUFFER *conf);

/**
 * @brief 配置通路pcm的参数
 *
 * @param handle  播放操作句柄
 * @param conf    pcm参数
 * @return int    是否配置成功
 * @retval 0 成功
 * @retval -1 失败
 */
int uni_audio_out_config_pcm(int handle, UNI_AUDIO_OUT_PCM *conf);

/**
 * @brief 配置播放中断回调
 *
 * @param handle  播放操作句柄
 * @param cb      回调
 * @return int    是否配置成功
 * @retval 0 成功
 * @retval -1 失败
 */
int uni_audio_out_config_cb(int handle, UNI_AUDIO_OUT_CALLBACK *cb);

/**
 * @brief 播放一帧数据
 *
 * @param handle  播放操作句柄
 * @param frame    数据帧参数
 * @return int    是否push成功
 * @retval 0 成功
 * @retval -1 失败
 */
int uni_audio_out_push_frame(int handle, UNI_AUDIO_OUT_FRAME *frame);

/**
 * @brief 等待帧数据全部消耗完
 *
 * @param handle  播放操作句柄
 * @return int    是否消耗完
 * @retval 0 消耗完成
 * @retval -1  push失败
 */
int uni_audio_out_drain_frame(int handle);

/**
 * @brief 设置db -25到18db
 *
 * @param handle  播放操作句柄
 * @param db      设置的db
 * @return int    设置是否成功
 * @retval 0  成功
 * @retval -1  失败
 */
int uni_audio_out_set_db(int handle, short db);

/**
 * @brief 获取当前db -25到18db
 *
 * @param handle  播放操作句柄
 * @param db      传出db值
 * @return int 获取当前db
 * @retval db  获取的db
 * @retval -1  失败
 */
int uni_audio_out_get_db(int handle, short *db);

/**
 * @brief 设置静音
 *
 * @param handle  播放操作句柄
 * @param mute    1:静音 0:取消静音
 * @return int    设置是否成功
 * @retval 0  成功
 * @retval -1  失败
 */
int uni_audio_out_set_mute(int handle, int mute);

/**
 * @brief 获取是否静音
 *
 * @param handle  播放操作句柄
 * @return int    是否静音
 * @retval 0  不静音
 * @retval 1  静音
 * @retval -1  失败
 */
int uni_audio_out_get_mute(int handle);

/**
 * @brief 设置左右声道通道的选择
 *
 * @param handle  播放操作句柄
 * @param channel  选择的模式
 * @return int    是否成功
 * @retval 0  成功
 * @retval -1  失败
 */
int uni_audio_out_set_channel(int handle, UNI_AUDIO_OUT_CHANNEL channel);

/**
 * @brief 初始化播放
 *
 * @param aout_mode audio play 模式 0:master 1:slave
 * @return int  是否初始化成功
 * @retval handle 成功
 * @retval -1 失败
 */
int uni_audio_out_init(int aout_mode);

/**
 * @brief audio out 退出
 *
 * @return int 退出是否成功
 * @retval 0 成功
 * @retval -1 失败
 */
int uni_audio_out_exit(void);

/**
 * @brief audio out 挂起
 *
 * @param handle  播放操作句柄
 * @return int 挂起是否成功
 * @retval 0 成功
 * @retval -1 失败
 */
int uni_audio_out_suspend(int handle);

/**
 * @brief audio out 恢复
 *
 * @return int 恢复是否成功
 * @retval 0 成功
 * @retval -1 失败
 */
int uni_audio_out_resume(int handle);
#endif
