KT24-1110_65E-HA-651B/cpu/br25/audio_dec/audio_dec_linein.c

819 lines
25 KiB
C
Raw Normal View History

2024-11-10 10:44:17 +00:00
/*
****************************************************************
*File : audio_dc_linein.c
*Note :
*
****************************************************************
*/
#include "asm/includes.h"
#include "media/includes.h"
#include "media/pcm_decoder.h"
#include "system/includes.h"
#include "effectrs_sync.h"
#include "app_config.h"
#include "audio_config.h"
#include "audio_dec.h"
#include "app_config.h"
#include "app_main.h"
#include "audio_enc.h"
#include "clock_cfg.h"
#include "dev_manager.h"
#include "media/convert_data.h"
#include "audio_effect/audio_dynamic_eq_demo.h"
#include "media/effects_adj.h"
#include "audio_effect/audio_eff_default_parm.h"
#if TCFG_PCM_ENC2TWS_ENABLE
#include "bt_tws.h"
#endif
#if (TCFG_LINEIN_ENABLE || TCFG_FM_ENABLE)//外部收音走linein
//////////////////////////////////////////////////////////////////////////////
struct linein_dec_hdl {
struct audio_stream *stream; // 音频流
struct pcm_decoder pcm_dec; // pcm解码句柄
struct audio_res_wait wait; // 资源等待句柄
struct audio_mixer_ch mix_ch; // 叠加句柄
#if AUDIO_SURROUND_CONFIG
surround_hdl *surround; //环绕音效句柄
#endif
#if AUDIO_VBASS_CONFIG
struct aud_gain_process *vbass_prev_gain;
NOISEGATE_API_STRUCT *ns_gate;
vbass_hdl *vbass; //虚拟低音句柄
#endif
#if TCFG_EQ_ENABLE && TCFG_AUDIO_OUT_EQ_ENABLE
struct audio_eq *high_bass;
struct audio_drc *hb_drc;//高低音后的drc
#if defined(TCFG_DRC_ENABLE) && TCFG_DRC_ENABLE
struct convert_data *hb_convert;
#endif
#endif
struct audio_eq *eq; //eq drc句柄
struct audio_drc *drc; // drc句柄
#if defined(TCFG_DRC_ENABLE) && TCFG_DRC_ENABLE
struct convert_data *convert;
#endif
#if defined(MUSIC_EXT_EQ_AFTER_DRC) && MUSIC_EXT_EQ_AFTER_DRC
struct audio_eq *ext_eq; //eq drc句柄 扩展eq
#endif
#if defined(TCFG_DYNAMIC_EQ_ENABLE) && TCFG_DYNAMIC_EQ_ENABLE
struct audio_eq *eq2; //eq drc句柄
struct dynamic_eq_hdl *dy_eq;
struct convert_data *convert2;
#endif
#if defined(TCFG_PHASER_GAIN_AND_CH_SWAP_ENABLE) && TCFG_PHASER_GAIN_AND_CH_SWAP_ENABLE
struct aud_gain_process *gain;
#endif
u32 id; // 唯一标识符,随机值
u32 start : 1; // 正在解码
u32 source : 8; // linein音频源
void *linein; // 底层驱动句柄
};
//////////////////////////////////////////////////////////////////////////////
struct linein_dec_hdl *linein_dec = NULL; // linein解码句柄
//////////////////////////////////////////////////////////////////////////////
int linein_sample_size(void *hdl);
int linein_sample_total(void *hdl);
//////////////////////////////////////////////////////////////////////////////
/*----------------------------------------------------------------------------*/
/**@brief linein解码释放
@param
@return
@note
*/
/*----------------------------------------------------------------------------*/
void linein_dec_relaese()
{
if (linein_dec) {
audio_decoder_task_del_wait(&decode_task, &linein_dec->wait);
clock_remove(AUDIO_CODING_PCM);
local_irq_disable();
free(linein_dec);
linein_dec = NULL;
local_irq_enable();
}
}
/*----------------------------------------------------------------------------*/
/**@brief linein解码事件处理
@param *decoder:
@param argc:
@param *argv:
@return
@note
*/
/*----------------------------------------------------------------------------*/
static void linein_dec_event_handler(struct audio_decoder *decoder, int argc, int *argv)
{
switch (argv[0]) {
case AUDIO_DEC_EVENT_END:
if (!linein_dec) {
log_i("linein_dec handle err ");
break;
}
if (linein_dec->id != argv[1]) {
log_w("linein_dec id err : 0x%x, 0x%x \n", linein_dec->id, argv[1]);
break;
}
linein_dec_close();
//audio_decoder_resume_all(&decode_task);
break;
}
}
/*----------------------------------------------------------------------------*/
/**@brief linein解码数据输出
@param *entry:
@param *in:
@param *out:
@return
@note *out未使用
*/
/*----------------------------------------------------------------------------*/
static int linein_dec_data_handler(struct audio_stream_entry *entry,
struct audio_data_frame *in,
struct audio_data_frame *out)
{
struct audio_decoder *decoder = container_of(entry, struct audio_decoder, entry);
struct pcm_decoder *pcm_dec = container_of(decoder, struct pcm_decoder, decoder);
struct linein_dec_hdl *dec = container_of(pcm_dec, struct linein_dec_hdl, pcm_dec);
if (!dec->start) {
return 0;
}
audio_stream_run(&decoder->entry, in);
return decoder->process_len;
}
/*----------------------------------------------------------------------------*/
/**@brief linein解码数据流激活
@param *p:
@return
@note
*/
/*----------------------------------------------------------------------------*/
static void linein_dec_out_stream_resume(void *p)
{
struct linein_dec_hdl *dec = p;
audio_decoder_resume(&dec->pcm_dec.decoder);
}
/*----------------------------------------------------------------------------*/
/**@brief linein解码激活
@param
@return
@note
*/
/*----------------------------------------------------------------------------*/
static void linein_dec_resume(void)
{
if (linein_dec) {
audio_decoder_resume(&linein_dec->pcm_dec.decoder);
}
}
/*----------------------------------------------------------------------------*/
/**@brief 计算linein输入采样率
@param
@return
@note
*/
/*----------------------------------------------------------------------------*/
static int audio_linein_input_sample_rate(void *priv)
{
struct linein_dec_hdl *dec = (struct linein_dec_hdl *)priv;
int sample_rate = linein_stream_sample_rate(dec->linein);
int buf_size = linein_sample_size(dec->linein);
#if TCFG_PCM_ENC2TWS_ENABLE
if (dec->pcm_dec.dec_no_out_sound) {
/*TWS的上限在linein输入buffer下限在tws push buffer*/
if (buf_size >= linein_sample_total(dec->linein) / 2) {
sample_rate += (sample_rate * 1 / 10000);
} else if (tws_api_local_media_trans_check_ready_total() < 1024) {
sample_rate -= (sample_rate * 1 / 10000);
}
return sample_rate;
}
#endif
/* if (dec->pcm_dec.sample_rate == 44100 && audio_mixer_get_sample_rate(&mixer) == 44100) { */
if ((dec->pcm_dec.sample_rate == 44100) && (audio_mixer_get_original_sample_rate_by_type(&mixer, MIXER_SR_SPEC) == 44100)) {
sample_rate = 44100 + (sample_rate - 44118);
}
if (buf_size >= (linein_sample_total(dec->linein) * 3 / 4)) {
sample_rate += (sample_rate * 1 / 10000);
}
if (buf_size <= (linein_sample_total(dec->linein) / 2)) {
sample_rate -= (sample_rate * 1 / 10000);
}
return sample_rate;
}
/*----------------------------------------------------------------------------*/
/**@brief linein解码开始
@param
@return 0
@return 0
@note
*/
/*----------------------------------------------------------------------------*/
int linein_dec_start()
{
int err;
struct linein_dec_hdl *dec = linein_dec;
struct audio_mixer *p_mixer = &mixer;
if (!linein_dec) {
return -EINVAL;
}
err = pcm_decoder_open(&dec->pcm_dec, &decode_task);
if (err) {
goto __err1;
}
// 打开linein驱动
dec->linein = linein_sample_open(dec->source, dec->pcm_dec.sample_rate);
linein_sample_set_resume_handler(dec->linein, linein_dec_resume);
pcm_decoder_set_event_handler(&dec->pcm_dec, linein_dec_event_handler, dec->id);
pcm_decoder_set_read_data(&dec->pcm_dec, linein_sample_read, dec->linein);
pcm_decoder_set_data_handler(&dec->pcm_dec, linein_dec_data_handler);
#if TCFG_PCM_ENC2TWS_ENABLE
{
// localtws使用sbc等编码转发
struct audio_fmt enc_f;
memcpy(&enc_f, &dec->pcm_dec.decoder.fmt, sizeof(struct audio_fmt));
enc_f.coding_type = AUDIO_CODING_SBC;
if (dec->pcm_dec.ch_num == 2) { // 如果是双声道数据localtws在解码时才变成对应声道
enc_f.channel = 2;
}
int ret = localtws_enc_api_open(&enc_f, LOCALTWS_ENC_FLAG_STREAM);
if (ret == true) {
dec->pcm_dec.dec_no_out_sound = 1;
// 重定向mixer
p_mixer = &g_localtws.mixer;
// 关闭资源等待。最终会在localtws解码处等待
audio_decoder_task_del_wait(&decode_task, &dec->wait);
if (dec->pcm_dec.output_ch_num != enc_f.channel) {
dec->pcm_dec.output_ch_num = dec->pcm_dec.decoder.fmt.channel = enc_f.channel;
if (enc_f.channel == 2) {
dec->pcm_dec.output_ch_type = AUDIO_CH_LR;
} else {
dec->pcm_dec.output_ch_type = AUDIO_CH_DIFF;
}
}
}
}
#endif
if (!dec->pcm_dec.dec_no_out_sound) {
audio_mode_main_dec_open(AUDIO_MODE_MAIN_STATE_DEC_LINEIN);
}
// 设置叠加功能
audio_mixer_ch_open_head(&dec->mix_ch, p_mixer);
audio_mixer_ch_set_no_wait(&dec->mix_ch, 1, 10); // 超时自动丢数
audio_mixer_ch_set_sample_rate(&dec->mix_ch, dec->pcm_dec.sample_rate);
if ((dec->pcm_dec.sample_rate == audio_mixer_get_sample_rate(p_mixer)) && (AUDIO_OUTPUT_WAY == AUDIO_OUTPUT_WAY_DAC)) {
} else {
audio_mixer_ch_follow_resample_enable(&dec->mix_ch, dec, audio_linein_input_sample_rate);
}
#if AUDIO_SURROUND_CONFIG
//环绕音效
#if defined(LINEIN_MODE_SOLE_EQ_EN) && LINEIN_MODE_SOLE_EQ_EN
dec->surround = surround_open_demo(AEID_AUX_SURROUND, dec->pcm_dec.output_ch_type);
#else
dec->surround = surround_open_demo(AEID_MUSIC_SURROUND, dec->pcm_dec.output_ch_type);
#endif
#endif
#if AUDIO_VBASS_CONFIG
#if defined(LINEIN_MODE_SOLE_EQ_EN) && LINEIN_MODE_SOLE_EQ_EN
dec->vbass_prev_gain = audio_gain_open_demo(AEID_AUX_VBASS_PREV_GAIN, dec->pcm_dec.output_ch_num);
dec->ns_gate = audio_noisegate_open_demo(AEID_AUX_NS_GATE, dec->pcm_dec.sample_rate, dec->pcm_dec.output_ch_num);
//虚拟低音
dec->vbass = audio_vbass_open_demo(AEID_AUX_VBASS, dec->pcm_dec.sample_rate, dec->pcm_dec.output_ch_num);
#else
dec->vbass_prev_gain = audio_gain_open_demo(AEID_MUSIC_VBASS_PREV_GAIN, dec->pcm_dec.output_ch_num);
dec->ns_gate = audio_noisegate_open_demo(AEID_MUSIC_NS_GATE, dec->pcm_dec.sample_rate, dec->pcm_dec.output_ch_num);
//虚拟低音
dec->vbass = audio_vbass_open_demo(AEID_MUSIC_VBASS, dec->pcm_dec.sample_rate, dec->pcm_dec.output_ch_num);
#endif
#endif
#if TCFG_EQ_ENABLE && TCFG_AUDIO_OUT_EQ_ENABLE
#if defined(LINEIN_MODE_SOLE_EQ_EN) && LINEIN_MODE_SOLE_EQ_EN
dec->high_bass = high_bass_aux_eq_open(dec->pcm_dec.sample_rate, dec->pcm_dec.output_ch_num);
dec->hb_drc = high_bass_aux_drc_open(dec->pcm_dec.sample_rate, dec->pcm_dec.output_ch_num);
#else
dec->high_bass = high_bass_eq_open(dec->pcm_dec.sample_rate, dec->pcm_dec.output_ch_num);
dec->hb_drc = high_bass_drc_open(dec->pcm_dec.sample_rate, dec->pcm_dec.output_ch_num);
#endif
#if defined(TCFG_DRC_ENABLE) && TCFG_DRC_ENABLE
if (dec->hb_drc && dec->hb_drc->run32bit) {
dec->hb_convert = convet_data_open(0, 512);
}
#endif
#endif
#if TCFG_EQ_ENABLE && TCFG_LINEIN_MODE_EQ_ENABLE
#if defined(LINEIN_MODE_SOLE_EQ_EN) && LINEIN_MODE_SOLE_EQ_EN
dec->eq = linein_eq_open(dec->pcm_dec.sample_rate, dec->pcm_dec.output_ch_num);// eq
#else
dec->eq = music_eq_open(dec->pcm_dec.sample_rate, dec->pcm_dec.output_ch_num);// eq
#endif
#if TCFG_DRC_ENABLE && TCFG_LINEIN_MODE_DRC_ENABLE
#if defined(LINEIN_MODE_SOLE_EQ_EN) && LINEIN_MODE_SOLE_EQ_EN
dec->drc = linein_drc_open(dec->pcm_dec.sample_rate, dec->pcm_dec.output_ch_num);//drc
#else
dec->drc = music_drc_open(dec->pcm_dec.sample_rate, dec->pcm_dec.output_ch_num);//drc
#endif
#endif/*TCFG_LINEIN_MODE_DRC_ENABLE*/
#if defined(TCFG_DRC_ENABLE) && TCFG_DRC_ENABLE
if (dec->eq && dec->eq->out_32bit) {
dec->convert = convet_data_open(0, 512);
}
#endif
#if defined(MUSIC_EXT_EQ_AFTER_DRC) && MUSIC_EXT_EQ_AFTER_DRC
#if defined(LINEIN_MODE_SOLE_EQ_EN) && LINEIN_MODE_SOLE_EQ_EN
dec->ext_eq = aux_ext_eq_open(dec->pcm_dec.sample_rate, dec->pcm_dec.output_ch_num);
#else
dec->ext_eq = music_ext_eq_open(dec->pcm_dec.sample_rate, dec->pcm_dec.output_ch_num);
#endif
#endif
#if defined(TCFG_DYNAMIC_EQ_ENABLE) && TCFG_DYNAMIC_EQ_ENABLE
#if defined(LINEIN_MODE_SOLE_EQ_EN) && LINEIN_MODE_SOLE_EQ_EN
dec->eq2 = linein_eq2_open(dec->pcm_dec.sample_rate, dec->pcm_dec.output_ch_num);// eq
dec->dy_eq = audio_dynamic_eq_ctrl_open(AEID_AUX_DYNAMIC_EQ, dec->pcm_dec.sample_rate, dec->pcm_dec.output_ch_num);//动态eq
#else
dec->eq2 = music_eq2_open(dec->pcm_dec.sample_rate, dec->pcm_dec.output_ch_num);// eq
dec->dy_eq = audio_dynamic_eq_ctrl_open(AEID_MUSIC_DYNAMIC_EQ, dec->pcm_dec.sample_rate, dec->pcm_dec.output_ch_num);//动态eq
#endif
dec->convert2 = convet_data_open(0, 512);
#endif/*TCFG_DYNAMIC_EQ_ENABLE*/
u16 gain_name = AEID_MUSIC_GAIN;
u16 swap_name = AEID_MUSIC_CH_SWAP;
#if defined(LINEIN_MODE_SOLE_EQ_EN) && LINEIN_MODE_SOLE_EQ_EN
gain_name = AEID_AUX_GAIN;
swap_name = AEID_AUX_CH_SWAP;
#endif
#if defined(TCFG_PHASER_GAIN_AND_CH_SWAP_ENABLE) && TCFG_PHASER_GAIN_AND_CH_SWAP_ENABLE
dec->gain = audio_gain_open_demo(gain_name, dec->pcm_dec.output_ch_num);
#endif
#endif/*TCFG_LINEIN_MODE_EQ_ENABLE*/
struct audio_stream_entry *entries[16] = {NULL};
u8 entry_cnt = 0;
u8 rl_rr_entry_start = 0;
entries[entry_cnt++] = &dec->pcm_dec.decoder.entry;
#if SYS_DIGVOL_GROUP_EN
void *dvol_entry = sys_digvol_group_ch_open("music_linein", -1, NULL);
entries[entry_cnt++] = dvol_entry;
#endif // SYS_DIGVOL_GROUP_EN
#if AUDIO_VBASS_CONFIG
if (dec->vbass_prev_gain) {
entries[entry_cnt++] = &dec->vbass_prev_gain->entry;
}
if (dec->ns_gate) {
entries[entry_cnt++] = &dec->ns_gate->entry;
}
if (dec->vbass) {
entries[entry_cnt++] = &dec->vbass->entry;
}
#endif
#if TCFG_EQ_ENABLE && TCFG_AUDIO_OUT_EQ_ENABLE
if (dec->high_bass) { //高低音
entries[entry_cnt++] = &dec->high_bass->entry;
}
if (dec->hb_drc) { //高低音后drc
entries[entry_cnt++] = &dec->hb_drc->entry;
#if defined(TCFG_DRC_ENABLE) && TCFG_DRC_ENABLE
if (dec->hb_convert) {
entries[entry_cnt++] = &dec->hb_convert->entry;
}
#endif
}
#endif
rl_rr_entry_start = entry_cnt - 1;//记录eq的上一个节点
#if defined(TCFG_PHASER_GAIN_AND_CH_SWAP_ENABLE) && TCFG_PHASER_GAIN_AND_CH_SWAP_ENABLE
if (dec->gain) {
entries[entry_cnt++] = &dec->gain->entry;
}
#endif
#if AUDIO_SURROUND_CONFIG
if (dec->surround) {
entries[entry_cnt++] = &dec->surround->entry;
}
#endif
#if TCFG_EQ_ENABLE && TCFG_LINEIN_MODE_EQ_ENABLE
if (dec->eq) {
entries[entry_cnt++] = &dec->eq->entry;
if (dec->drc) {
entries[entry_cnt++] = &dec->drc->entry;
}
#if defined(TCFG_DRC_ENABLE) && TCFG_DRC_ENABLE
if (dec->convert) {
entries[entry_cnt++] = &dec->convert->entry;
}
#endif
#if defined(MUSIC_EXT_EQ_AFTER_DRC) && MUSIC_EXT_EQ_AFTER_DRC
if (dec->ext_eq) {
entries[entry_cnt++] = &dec->ext_eq->entry;
}
#endif
#if defined(TCFG_DYNAMIC_EQ_ENABLE) && TCFG_DYNAMIC_EQ_ENABLE
if (dec->eq2) {
entries[entry_cnt++] = &dec->eq2->entry;
}
if (dec->dy_eq && dec->dy_eq->dy_eq) {
entries[entry_cnt++] = &dec->dy_eq->dy_eq->entry;
}
if (dec->convert2) {
entries[entry_cnt++] = &dec->convert2->entry;
}
#endif
}
#endif
entries[entry_cnt++] = &dec->mix_ch.entry;
// 创建数据流,把所有节点连接起来
dec->stream = audio_stream_open(dec, linein_dec_out_stream_resume);
audio_stream_add_list(dec->stream, entries, entry_cnt);
// 设置音频输出音量
audio_output_set_start_volume(APP_AUDIO_STATE_MUSIC);
// 开始解码
dec->start = 1;
err = audio_decoder_start(&dec->pcm_dec.decoder);
if (err) {
goto __err3;
}
clock_set_cur();
return 0;
__err3:
dec->start = 0;
#if AUDIO_SURROUND_CONFIG
surround_close_demo(dec->surround);
#endif
#if AUDIO_VBASS_CONFIG
audio_gain_close_demo(dec->vbass_prev_gain);
audio_noisegate_close_demo(dec->ns_gate);
audio_vbass_close_demo(dec->vbass);
#endif
#if TCFG_EQ_ENABLE && TCFG_AUDIO_OUT_EQ_ENABLE
high_bass_eq_close(dec->high_bass);
high_bass_drc_close(dec->hb_drc);
#if defined(TCFG_DRC_ENABLE) && TCFG_DRC_ENABLE
convet_data_close(dec->hb_convert);
#endif
#endif
#if TCFG_EQ_ENABLE && TCFG_LINEIN_MODE_EQ_ENABLE
#if defined(LINEIN_MODE_SOLE_EQ_EN) && LINEIN_MODE_SOLE_EQ_EN
linein_eq_close(dec->eq);
#else
music_eq_close(dec->eq);
#endif
#if TCFG_DRC_ENABLE && TCFG_LINEIN_MODE_DRC_ENABLE
#if defined(LINEIN_MODE_SOLE_EQ_EN) && LINEIN_MODE_SOLE_EQ_EN
linein_drc_close(dec->drc);
#else
music_drc_close(dec->drc);
#endif
#endif
#if defined(TCFG_DRC_ENABLE) && TCFG_DRC_ENABLE
convet_data_close(dec->convert);
#endif
#if defined(MUSIC_EXT_EQ_AFTER_DRC) && MUSIC_EXT_EQ_AFTER_DRC
#if defined(LINEIN_MODE_SOLE_EQ_EN) && LINEIN_MODE_SOLE_EQ_EN
aux_ext_eq_close(dec->ext_eq);
#else
music_ext_eq_close(dec->ext_eq);
#endif
#endif
#if defined(TCFG_DYNAMIC_EQ_ENABLE) && TCFG_DYNAMIC_EQ_ENABLE
music_eq2_close(dec->eq2);
audio_dynamic_eq_ctrl_close(dec->dy_eq);
convet_data_close(dec->convert2);
#endif
#if defined(TCFG_PHASER_GAIN_AND_CH_SWAP_ENABLE) && TCFG_PHASER_GAIN_AND_CH_SWAP_ENABLE
audio_gain_close_demo(dec->gain);
#endif
#endif
if (dec->linein) {
linein_sample_close(dec->linein);
dec->linein = NULL;
}
audio_mixer_ch_close(&dec->mix_ch);
#if TCFG_PCM_ENC2TWS_ENABLE
if (linein_dec->pcm_dec.dec_no_out_sound) {
linein_dec->pcm_dec.dec_no_out_sound = 0;
localtws_enc_api_close();
}
#endif
#if SYS_DIGVOL_GROUP_EN
sys_digvol_group_ch_close("music_linein");
#endif // SYS_DIGVOL_GROUP_EN
if (dec->stream) {
audio_stream_close(dec->stream);
dec->stream = NULL;
}
pcm_decoder_close(&dec->pcm_dec);
__err1:
linein_dec_relaese();
return err;
}
/*----------------------------------------------------------------------------*/
/**@brief fm解码关闭
@param
@return
@note
*/
/*----------------------------------------------------------------------------*/
static void __linein_dec_close(void)
{
if (linein_dec && linein_dec->start) {
linein_dec->start = 0;
pcm_decoder_close(&linein_dec->pcm_dec);
linein_sample_close(linein_dec->linein);
linein_dec->linein = NULL;
#if AUDIO_SURROUND_CONFIG
surround_close_demo(linein_dec->surround);
#endif
#if AUDIO_VBASS_CONFIG
audio_gain_close_demo(linein_dec->vbass_prev_gain);
audio_noisegate_close_demo(linein_dec->ns_gate);
audio_vbass_close_demo(linein_dec->vbass);
#endif
#if TCFG_EQ_ENABLE && TCFG_AUDIO_OUT_EQ_ENABLE
high_bass_eq_close(linein_dec->high_bass);
high_bass_drc_close(linein_dec->hb_drc);
#if defined(TCFG_DRC_ENABLE) && TCFG_DRC_ENABLE
convet_data_close(linein_dec->hb_convert);
#endif
#endif
#if TCFG_EQ_ENABLE && TCFG_LINEIN_MODE_EQ_ENABLE
#if defined(LINEIN_MODE_SOLE_EQ_EN) && LINEIN_MODE_SOLE_EQ_EN
linein_eq_close(linein_dec->eq);
#else
music_eq_close(linein_dec->eq);
#endif
#if TCFG_DRC_ENABLE && TCFG_LINEIN_MODE_DRC_ENABLE
#if defined(LINEIN_MODE_SOLE_EQ_EN) && LINEIN_MODE_SOLE_EQ_EN
linein_drc_close(linein_dec->drc);
#else
music_drc_close(linein_dec->drc);
#endif
#endif
#if defined(TCFG_DRC_ENABLE) && TCFG_DRC_ENABLE
convet_data_close(linein_dec->convert);
#endif
#if defined(MUSIC_EXT_EQ_AFTER_DRC) && MUSIC_EXT_EQ_AFTER_DRC
#if defined(LINEIN_MODE_SOLE_EQ_EN) && LINEIN_MODE_SOLE_EQ_EN
aux_ext_eq_close(linein_dec->ext_eq);
#else
music_ext_eq_close(linein_dec->ext_eq);
#endif
#endif
#if defined(TCFG_DYNAMIC_EQ_ENABLE) && TCFG_DYNAMIC_EQ_ENABLE
music_eq2_close(linein_dec->eq2);
audio_dynamic_eq_ctrl_close(linein_dec->dy_eq);
convet_data_close(linein_dec->convert2);
#endif
#if defined(TCFG_PHASER_GAIN_AND_CH_SWAP_ENABLE) && TCFG_PHASER_GAIN_AND_CH_SWAP_ENABLE
audio_gain_close_demo(linein_dec->gain);
#endif
#endif
audio_mixer_ch_close(&linein_dec->mix_ch);
#if TCFG_PCM_ENC2TWS_ENABLE
if (linein_dec->pcm_dec.dec_no_out_sound) {
linein_dec->pcm_dec.dec_no_out_sound = 0;
localtws_enc_api_close();
}
#endif
#if SYS_DIGVOL_GROUP_EN
sys_digvol_group_ch_close("music_linein");
#endif // SYS_DIGVOL_GROUP_EN
// 先关闭各个节点最后才close数据流
if (linein_dec->stream) {
audio_stream_close(linein_dec->stream);
linein_dec->stream = NULL;
}
}
}
/*----------------------------------------------------------------------------*/
/**@brief linein解码资源等待
@param *wait:
@param event:
@return 0
@note
*/
/*----------------------------------------------------------------------------*/
static int linein_wait_res_handler(struct audio_res_wait *wait, int event)
{
int err = 0;
log_i("linein_wait_res_handler, event:%d\n", event);
if (event == AUDIO_RES_GET) {
// 启动解码
err = linein_dec_start();
} else if (event == AUDIO_RES_PUT) {
// 被打断
__linein_dec_close();
}
return err;
}
/*----------------------------------------------------------------------------*/
/**@brief 打开linein解码
@param source:
@param sample_rate:
@return 0
@return 0
@note
*/
/*----------------------------------------------------------------------------*/
int linein_dec_open(u8 source, u32 sample_rate)
{
int err;
struct linein_dec_hdl *dec;
dec = zalloc(sizeof(*dec));
if (!dec) {
return -ENOMEM;
}
linein_dec = dec;
dec->id = rand32();
switch (source) {
case BIT(0):
case BIT(1):
dec->pcm_dec.ch_num = 1;
break;
case BIT(2):
case BIT(3):
dec->pcm_dec.ch_num = 1;
break;
default:
if (audio_adc_support_linein_combined()) {
/*F版支持一路adc采样linein左右声道混合输入*/
dec->pcm_dec.ch_num = 1;
} else {
log_e("Linein can only select a single channel\n");
ASSERT(0, "err\n");
}
break;
}
dec->source = source;
dec->pcm_dec.output_ch_num = audio_output_channel_num();
dec->pcm_dec.output_ch_type = audio_output_channel_type();
#if TCFG_MIC_EFFECT_ENABLE
dec->pcm_dec.sample_rate = MIC_EFFECT_SAMPLERATE;
#else
dec->pcm_dec.sample_rate = sample_rate;
#endif
dec->wait.priority = 2;
dec->wait.preemption = 0;
dec->wait.snatch_same_prio = 1;
dec->wait.handler = linein_wait_res_handler;
clock_add(AUDIO_CODING_PCM);
#if TCFG_DEC2TWS_ENABLE
// 设置localtws重播接口
localtws_globle_set_dec_restart(linein_dec_push_restart);
#endif
err = audio_decoder_task_add_wait(&decode_task, &dec->wait);
return err;
}
/*----------------------------------------------------------------------------*/
/**@brief 关闭linein解码
@param
@return
@note
*/
/*----------------------------------------------------------------------------*/
void linein_dec_close(void)
{
if (!linein_dec) {
return;
}
__linein_dec_close();
linein_dec_relaese();
clock_set_cur();
log_i("linein dec close \n\n ");
}
/*----------------------------------------------------------------------------*/
/**@brief linein解码重新开始
@param id: id
@return 0
@return 0
@note
*/
/*----------------------------------------------------------------------------*/
int linein_dec_restart(int id)
{
if ((!linein_dec) || (id != linein_dec->id)) {
return -1;
}
u8 source = linein_dec->source;
u32 sample_rate = linein_dec->pcm_dec.sample_rate;
linein_dec_close();
int err = linein_dec_open(source, sample_rate);
return err;
}
/*----------------------------------------------------------------------------*/
/**@brief 推送linein解码重新开始命令
@param
@return true
@return false
@note
*/
/*----------------------------------------------------------------------------*/
int linein_dec_push_restart(void)
{
if (!linein_dec) {
return false;
}
int argv[3];
argv[0] = (int)linein_dec_restart;
argv[1] = 1;
argv[2] = (int)linein_dec->id;
os_taskq_post_type(os_current_task(), Q_CALLBACK, ARRAY_SIZE(argv), argv);
return true;
}
#endif