Files
99_7018_lmx/cpu/br28/sound_device.c
2025-10-29 13:10:02 +08:00

387 lines
9.5 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*****************************************************************
>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;
}
}