387 lines
9.5 KiB
C
387 lines
9.5 KiB
C
/*****************************************************************
|
||
>file name : sound_device.c
|
||
>create time : Fri 25 Feb 2022 05:44:41 PM CST
|
||
*****************************************************************/
|
||
#include "app_config.h"
|
||
#include "media/includes.h"
|
||
#include "audio_iis.h"
|
||
#include "sound_device.h"
|
||
#include "audio_config.h"
|
||
#include "audio_syncts.h"
|
||
#include "audio_dvol.h"
|
||
#include "aec_user.h"
|
||
#if TCFG_AUDIO_DAC_ENABLE
|
||
#define SOUND_PCM_DAC_ENABLE 1
|
||
#else
|
||
#define SOUND_PCM_DAC_ENABLE 0
|
||
#endif
|
||
|
||
#if TCFG_AUDIO_OUTPUT_IIS
|
||
#define SOUND_PCM_IIS_ENABLE 1
|
||
|
||
#if !TCFG_AUDIO_OUTPUT_IIS_AND_DAC
|
||
/*暂时不支持iis和dac同时输出*/
|
||
#undef SOUND_PCM_DAC_ENABLE
|
||
#define SOUND_PCM_DAC_ENABLE 0
|
||
#endif
|
||
|
||
#else /*TCFG_AUDIO_OUTPUT_IIS == 0*/
|
||
#define SOUND_PCM_IIS_ENABLE 0
|
||
#endif /*end TCFG_AUDIO_OUTPUT_IIS*/
|
||
|
||
#define SOUND_PCM_DEV_NUM (SOUND_PCM_DAC_ENABLE + SOUND_PCM_IIS_ENABLE)
|
||
|
||
#if SOUND_PCM_DAC_ENABLE
|
||
#if (TCFG_AUDIO_DAC_CONNECT_MODE == DAC_OUTPUT_LR)||(TCFG_AUDIO_DAC_CONNECT_MODE == DAC_OUTPUT_MONO_R)
|
||
s16 dac_buff[4 * 1024 + 512];
|
||
#else
|
||
s16 dac_buff[2 * 1024 + 512];
|
||
#endif
|
||
#else
|
||
s16 dac_buff[0];
|
||
#endif
|
||
|
||
struct audio_dac_hdl dac_hdl;
|
||
struct audio_iis_hdl iis_hdl;
|
||
|
||
extern const int config_audio_dac_mix_enable;
|
||
extern struct dac_platform_data dac_data;
|
||
void audio_fade_in_fade_out(u8 left_vol, u8 right_vol);
|
||
|
||
int sound_pcm_dev_is_running(void)
|
||
{
|
||
if (SOUND_PCM_DAC_ENABLE) {
|
||
return audio_dac_is_working(&dac_hdl);
|
||
}
|
||
return 1;
|
||
}
|
||
|
||
void sound_pcm_dev_channel_mute(u8 ch, u8 mute)
|
||
{
|
||
if (SOUND_PCM_DAC_ENABLE) {
|
||
audio_dac_ch_mute(&dac_hdl, ch, mute);
|
||
}
|
||
}
|
||
|
||
|
||
int sound_pcm_trigger_resume(int time_ms, void *priv, void (*callback)(void *priv))
|
||
{
|
||
int err = 0;
|
||
|
||
if (SOUND_PCM_DAC_ENABLE) {
|
||
err = audio_dac_irq_enable(&dac_hdl, time_ms, priv, callback);
|
||
}
|
||
|
||
if (SOUND_PCM_DEV_NUM == 1) {
|
||
if (SOUND_PCM_IIS_ENABLE) {
|
||
err = audio_iis_trigger_interrupt(&iis_hdl, time_ms, priv, callback);
|
||
}
|
||
}
|
||
|
||
return err;
|
||
}
|
||
|
||
int sound_pcm_dev_set_delay_time(int prepared_time, int delay_time)
|
||
{
|
||
if (SOUND_PCM_DAC_ENABLE) {
|
||
audio_dac_set_delay_time(&dac_hdl, prepared_time, delay_time);
|
||
}
|
||
|
||
if (SOUND_PCM_IIS_ENABLE) {
|
||
audio_iis_set_delay_time(&iis_hdl, prepared_time, delay_time);
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
int sound_pcm_dev_start(void *private_data, int sample_rate, s16 volume)
|
||
{
|
||
if (SOUND_PCM_DAC_ENABLE) {
|
||
if (!audio_dac_is_working(&dac_hdl)) {
|
||
audio_dac_set_sample_rate(&dac_hdl, sample_rate);
|
||
audio_dac_set_volume(&dac_hdl, volume);
|
||
audio_dac_start(&dac_hdl);
|
||
}
|
||
audio_dac_channel_start(private_data);
|
||
}
|
||
|
||
if (SOUND_PCM_IIS_ENABLE) {
|
||
audio_iis_dma_start(&iis_hdl);
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
int sound_pcm_dev_stop(void *private_data)
|
||
{
|
||
if (SOUND_PCM_DAC_ENABLE) {
|
||
audio_dac_set_protect_time(&dac_hdl, 0, NULL, NULL);
|
||
audio_dac_channel_close(private_data);
|
||
audio_dac_stop(&dac_hdl);
|
||
#if (SYS_VOL_TYPE == VOL_TYPE_DIGITAL)
|
||
u8 dvol_idx = MUSIC_DVOL;
|
||
audio_digital_vol_set_no_fade(dvol_idx, 0); //更新当前数字音量为0
|
||
#endif/*SYS_VOL_TYPE == VOL_TYPE_DIGITAL*/
|
||
}
|
||
|
||
if (SOUND_PCM_IIS_ENABLE) {
|
||
audio_iis_dma_stop(&iis_hdl);
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
int sound_pcm_match_sample_rate(int sample_rate)
|
||
{
|
||
if (SOUND_PCM_IIS_ENABLE) {
|
||
return audio_iis_pcm_sample_rate(&iis_hdl);
|
||
}
|
||
|
||
return sample_rate;
|
||
}
|
||
|
||
int sound_pcm_dev_write(void *private_data, void *data, int len)
|
||
{
|
||
int wlen = len;
|
||
int wlen1 = 0;
|
||
if (SOUND_PCM_DEV_NUM == 1) {
|
||
if (SOUND_PCM_DAC_ENABLE) {
|
||
if (config_audio_dac_mix_enable) {
|
||
return audio_dac_channel_write(private_data, &dac_hdl, data, len);
|
||
} else {
|
||
return audio_dac_write(&dac_hdl, data, len);
|
||
}
|
||
}
|
||
|
||
if (SOUND_PCM_IIS_ENABLE) {
|
||
wlen1 = audio_iis_pcm_write(&iis_hdl, data, len);
|
||
return wlen1;
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
if (SOUND_PCM_DAC_ENABLE) {
|
||
if (config_audio_dac_mix_enable) {
|
||
wlen = audio_dac_channel_write(private_data, &dac_hdl, data, len);
|
||
} else {
|
||
wlen = audio_dac_write(&dac_hdl, data, len);
|
||
}
|
||
}
|
||
|
||
if (SOUND_PCM_IIS_ENABLE) {
|
||
wlen1 = audio_iis_pcm_write(&iis_hdl, data, wlen);
|
||
}
|
||
|
||
if (wlen != wlen1) {
|
||
printf("iis wlen1 %d != dac wlen %d\nl", wlen1, wlen);
|
||
/*
|
||
* TODO :
|
||
* 这个时候说明DAC与IIS的数据消耗不同步,需要启动同步处理机制
|
||
* */
|
||
}
|
||
|
||
return wlen;
|
||
}
|
||
|
||
void sound_pcm_dev_add_syncts(void *priv)
|
||
{
|
||
/*蓝牙音频同步仅能挂载到一个设备上,无法挂载多个*/
|
||
|
||
if (SOUND_PCM_DAC_ENABLE) {
|
||
audio_dac_add_syncts_handle(&dac_hdl, priv);
|
||
return;
|
||
}
|
||
|
||
if (SOUND_PCM_IIS_ENABLE) {
|
||
audio_iis_add_syncts_handle(&iis_hdl, priv);
|
||
}
|
||
}
|
||
|
||
void sound_pcm_dev_remove_syncts(void *handle)
|
||
{
|
||
if (SOUND_PCM_DAC_ENABLE) {
|
||
audio_dac_remove_syncts_handle(&dac_hdl, handle);
|
||
}
|
||
|
||
if (SOUND_PCM_IIS_ENABLE) {
|
||
audio_iis_remove_syncts_handle(&iis_hdl, handle);
|
||
}
|
||
}
|
||
|
||
int sound_pcm_dev_channel_mapping(int ch_num)
|
||
{
|
||
if (SOUND_PCM_DEV_NUM == 1) {
|
||
u8 ch_map = SOUND_CHMAP_MONO;
|
||
if (SOUND_PCM_DAC_ENABLE) {
|
||
ch_map = audio_dac_get_channel(&dac_hdl);
|
||
if (ch_map == DAC_OUTPUT_LR) {
|
||
return 2;
|
||
}
|
||
return 1;
|
||
}
|
||
|
||
if (SOUND_PCM_IIS_ENABLE) {
|
||
if (ch_num == 0) {
|
||
return audio_iis_pcm_channel_num(&iis_hdl);
|
||
}
|
||
|
||
if (ch_num == 1) {
|
||
ch_map = SOUND_CHMAP_MONO;
|
||
} else if (ch_num == 2) {
|
||
ch_map = SOUND_CHMAP_FL | SOUND_CHMAP_FR;
|
||
}
|
||
audio_iis_pcm_remapping(&iis_hdl, ch_map);
|
||
return audio_iis_pcm_channel_num(&iis_hdl);
|
||
}
|
||
} else {
|
||
u8 ch_map = SOUND_CHMAP_MONO;
|
||
if (SOUND_PCM_DAC_ENABLE) {
|
||
ch_map = audio_dac_get_channel(&dac_hdl);
|
||
ch_num = 1;
|
||
if (ch_map == DAC_OUTPUT_LR) {
|
||
ch_num = 2;
|
||
}
|
||
}
|
||
|
||
if (SOUND_PCM_IIS_ENABLE) {
|
||
if (ch_num == 0) {
|
||
return audio_iis_pcm_channel_num(&iis_hdl);
|
||
}
|
||
|
||
if (ch_num == 1) {
|
||
ch_map = SOUND_CHMAP_MONO;
|
||
} else if (ch_num == 2) {
|
||
ch_map = SOUND_CHMAP_FL | SOUND_CHMAP_FR;
|
||
}
|
||
audio_iis_pcm_remapping(&iis_hdl, ch_map);
|
||
return audio_iis_pcm_channel_num(&iis_hdl);
|
||
}
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
int sound_pcm_dev_buffered_frames(void)
|
||
{
|
||
if (SOUND_PCM_DAC_ENABLE) {
|
||
return audio_dac_buffered_frames(&dac_hdl);
|
||
}
|
||
|
||
if (SOUND_PCM_IIS_ENABLE) {
|
||
return audio_iis_buffered_frames(&iis_hdl);
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
int sound_pcm_dev_buffered_time(void)
|
||
{
|
||
if (SOUND_PCM_DAC_ENABLE) {
|
||
return audio_dac_data_time(&dac_hdl);
|
||
}
|
||
|
||
if (SOUND_PCM_IIS_ENABLE) {
|
||
return audio_iis_buffered_time(&iis_hdl);
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
void sound_pcm_set_underrun_params(int time_ms, void *priv, void (*callback)(void *))
|
||
{
|
||
if (SOUND_PCM_DAC_ENABLE) {
|
||
audio_dac_set_protect_time(&dac_hdl, time_ms, priv, callback);
|
||
}
|
||
|
||
if (SOUND_PCM_IIS_ENABLE) {
|
||
audio_iis_set_underrun_params(&iis_hdl, time_ms, priv, callback);
|
||
}
|
||
}
|
||
|
||
void sound_pcm_dev_try_power_on(void)
|
||
{
|
||
if (SOUND_PCM_DAC_ENABLE) {
|
||
if (!sound_pcm_dev_is_running()) {
|
||
audio_dac_try_power_on(&dac_hdl);
|
||
}
|
||
}
|
||
}
|
||
|
||
void sound_pcm_dev_set_analog_gain(s16 gain)
|
||
{
|
||
if (SOUND_PCM_DAC_ENABLE) {
|
||
audio_dac_set_analog_vol(&dac_hdl, gain);
|
||
}
|
||
}
|
||
|
||
static void sound_pcm_dac_driver_init(void)
|
||
{
|
||
if (!SOUND_PCM_DAC_ENABLE) {
|
||
return;
|
||
}
|
||
|
||
audio_dac_init(&dac_hdl, &dac_data);
|
||
|
||
/* u8 mode = TCFG_AUDIO_DAC_DEFAULT_VOL_MODE; */
|
||
/* if (1 != syscfg_read(CFG_VOLUME_ENHANCEMENT_MODE, &mode, 1)) { */
|
||
/* printf("vm no CFG_VOLUME_ENHANCEMENT_MODE !\n"); */
|
||
/* } */
|
||
/* app_audio_dac_vol_mode_set(mode); */
|
||
|
||
#if defined(TCFG_AUDIO_DAC_24BIT_MODE) && TCFG_AUDIO_DAC_24BIT_MODE
|
||
audio_dac_set_bit_mode(&dac_hdl, 1);
|
||
#endif/*TCFG_AUDIO_DAC_24BIT_MODE*/
|
||
|
||
//u32 dacr32 = read_capless_DTB();
|
||
//audio_dac_set_capless_DTB(&dac_hdl, dacr32);
|
||
audio_dac_set_buff(&dac_hdl, dac_buff, sizeof(dac_buff));
|
||
audio_dac_set_delay_time(&dac_hdl, 20, 30);
|
||
audio_dac_set_analog_vol(&dac_hdl, 0);
|
||
|
||
struct audio_dac_trim dac_trim = {0};
|
||
int len = syscfg_read(CFG_DAC_TRIM_INFO, (void *)&dac_trim, sizeof(dac_trim));
|
||
if (len != sizeof(dac_trim) || audio_dac_trim_value_check(&dac_trim)) {
|
||
audio_dac_do_trim(&dac_hdl, &dac_trim, 0);
|
||
syscfg_write(CFG_DAC_TRIM_INFO, (void *)&dac_trim, sizeof(dac_trim));
|
||
}
|
||
|
||
//mic_trim_run();
|
||
audio_dac_set_trim_value(&dac_hdl, &dac_trim);
|
||
audio_dac_set_fade_handler(&dac_hdl, NULL, audio_fade_in_fade_out);
|
||
}
|
||
|
||
static void sound_pcm_iis_driver_init(void)
|
||
{
|
||
audio_iis_pcm_tx_open(&iis_hdl, TCFG_IIS_OUTPUT_DATAPORT_SEL, TCFG_IIS_SR);
|
||
}
|
||
|
||
int sound_pcm_driver_init(void)
|
||
{
|
||
if (SOUND_PCM_DAC_ENABLE) {
|
||
sound_pcm_dac_driver_init();
|
||
} else if (TCFG_AUDIO_ADC_ENABLE) {
|
||
audio_dac_init(&dac_hdl, &dac_data);
|
||
}
|
||
|
||
if (SOUND_PCM_IIS_ENABLE) {
|
||
sound_pcm_iis_driver_init();
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
void *get_iis_alink_param(void)
|
||
{
|
||
return (void *)iis_hdl.alink0_param;
|
||
}
|
||
|
||
|
||
int sound_pcm_sync_device_select(void)
|
||
{
|
||
if (SOUND_PCM_DAC_ENABLE) {
|
||
return PCM_INSIDE_DAC;
|
||
}
|
||
|
||
if (SOUND_PCM_IIS_ENABLE) {
|
||
return PCM_OUTSIDE_DAC;
|
||
}
|
||
}
|