1849 lines
58 KiB
C
1849 lines
58 KiB
C
#include "audio_splicing.h"
|
||
#include "application/audio_bfilt.h"
|
||
#include "media/audio_eq_drc_apply.h"
|
||
#include "application/audio_echo_src.h"
|
||
#include "application/audio_energy_detect.h"
|
||
#include "clock_cfg.h"
|
||
#include "media/audio_stream.h"
|
||
#include "media/includes.h"
|
||
#include "mic_effect.h"
|
||
#include "asm/dac.h"
|
||
#include "audio_enc/audio_enc.h"
|
||
#include "audio_dec.h"
|
||
#include "stream_entry.h"
|
||
#include "effect_linein.h"
|
||
#include "audio_recorder_mix.h"
|
||
#include "app_task.h"
|
||
#include "vollevel_detect.h"
|
||
#include "media/effects_adj.h"
|
||
#include "audio_effect/audio_eff_default_parm.h"
|
||
#include "audio_effect/audio_autotune_demo.h"
|
||
#include "media/convert_data.h"
|
||
#include "simpleAGC.h"
|
||
|
||
#define LOG_TAG "[APP-REVERB]"
|
||
#define LOG_ERROR_ENABLE
|
||
#define LOG_INFO_ENABLE
|
||
#define LOG_DUMP_ENABLE
|
||
#define LOG_DEBUG_ENABLE
|
||
#include "debug.h"
|
||
|
||
#ifdef SUPPORT_MS_EXTENSIONS
|
||
//#pragma bss_seg(".audio_mic_stream_bss")
|
||
//#pragma data_seg(".audio_mic_stream_data")
|
||
#pragma const_seg(".audio_mic_effect_const")
|
||
#pragma code_seg(".audio_mic_effect_code")
|
||
#endif
|
||
|
||
#if defined(TCFG_MIC_EFFECT_ENABLE) && TCFG_MIC_EFFECT_ENABLE
|
||
|
||
#define LOUDNESS_DEBUG_ENABLE 0//分贝指示器
|
||
|
||
// 混响不叠加播U/SD的情况下可以使能,否则可能会出现某些高码率歌曲会卡顿的问题
|
||
#ifdef CONFIG_BOARD_AC696X_MEGAPHONE
|
||
#define ENABLE_BYPASS_CH_AND_EQ2 1//使能bypass ch and EQ2
|
||
#else
|
||
#define ENABLE_BYPASS_CH_AND_EQ2 0//使能bypass ch and EQ2
|
||
#endif
|
||
|
||
|
||
extern struct audio_dac_hdl dac_hdl;
|
||
struct aud_reverb_process {
|
||
struct audio_stream_entry entry; // 音频流入口
|
||
s16 *tmpbuf[3];
|
||
void *eff;//struct __mic_effect
|
||
s16 *out_buf;
|
||
u8 bit_wide;//eq是否输出32bit位宽
|
||
u8 in_ch;
|
||
u8 divide;//左右声道是否需要独立的gain
|
||
};
|
||
|
||
struct __mic_effect {
|
||
OS_MUTEX mutex;
|
||
struct __mic_effect_parm parm;
|
||
mic_stream *mic;
|
||
struct audio_eq *mic_eq0; //eq 句柄
|
||
struct audio_drc *mic_drc0; //eq 句柄
|
||
struct convert_data *convert0;//32-》16
|
||
#if TCFG_EQ_ENABLE && TCFG_MIC_TUNNING_EQ_ENABLE
|
||
struct audio_eq *mic_tunning_eq; //eq 句柄
|
||
#endif
|
||
|
||
|
||
struct audio_eq *mic_eq4; //eq drc句柄
|
||
struct audio_drc *mic_drc4; //eq drc句柄
|
||
struct convert_data *convert4;//32-》16
|
||
/* struct aud_gain_process *gain;//最后一级 的增益调节 */
|
||
|
||
struct audio_stream *stream; // 音频流
|
||
struct audio_stream_entry entry; // effect 音频入口
|
||
int out_len;
|
||
int process_len;
|
||
u8 input_ch_num; //mic输入给混响数据流的源声道数
|
||
|
||
NOISEGATE_API_STRUCT *noisegate;
|
||
void *d_vol;
|
||
HOWLING_API_STRUCT *howling_ps;
|
||
HOWLING_API_STRUCT *notch_howling;
|
||
voice_changer_hdl *voice_changer;
|
||
|
||
#if defined(TCFG_MIC_AUTOTUNE_ENABLE) && TCFG_MIC_AUTOTUNE_ENABLE
|
||
autotune_hdl *autotune;
|
||
#endif
|
||
|
||
struct channel_switch *channel_zoom;
|
||
struct audio_dac_channel *dac;
|
||
#if (RECORDER_MIX_EN)
|
||
struct __stream_entry *rec_hdl;
|
||
#endif
|
||
#if (TCFG_USB_MIC_DATA_FROM_MICEFFECT||TCFG_USB_MIC_DATA_FROM_DAC)
|
||
struct __stream_entry *usbmic_hdl;
|
||
u8 usbmic_start;
|
||
#endif
|
||
void *energy_hdl; //能量检测的hdl
|
||
u8 dodge_en; //能量检测运行过程闪避是否使能
|
||
|
||
struct __effect_linein *linein;
|
||
struct audio_drc *drc;
|
||
|
||
|
||
u8 pause_mark;
|
||
LOUDNESS_M_STRUCT loudness_adc;
|
||
LOUDNESS_M_STRUCT loudness_drc_out;
|
||
struct __stream_entry *loudness_debug_hdl;
|
||
|
||
struct audio_src_handle *src_hdl;
|
||
|
||
struct audio_eq *mic_eq3; //eq drc句柄
|
||
struct audio_drc *mic_drc3; //eq drc句柄
|
||
|
||
u8 main_pause;
|
||
//分支0节点
|
||
PLATE_REVERB_API_STRUCT *sub_0_plate_reverb_hdl;
|
||
struct audio_eq *mic_eq1; //eq drc句柄
|
||
struct audio_drc *mic_drc1; //eq drc句柄
|
||
|
||
//分支1节点
|
||
ECHO_API_STRUCT *sub_1_echo_hdl;
|
||
struct audio_eq *mic_eq2; //eq drc句柄
|
||
struct audio_drc *mic_drc2; //eq drc句柄
|
||
|
||
|
||
//分支1 2 3的总处理
|
||
struct aud_reverb_process *aud_reverb;
|
||
};
|
||
|
||
struct __mic_stream_parm *g_mic_parm = NULL;
|
||
static struct __mic_effect *p_effect = NULL;
|
||
#define __this p_effect
|
||
#define R_ALIN(var,al) ((((var)+(al)-1)/(al))*(al))
|
||
|
||
void *mic_tunning_eq_open(u32 sample_rate, u8 ch_num);
|
||
void mic_tunning_eq_close(void *eq);
|
||
void *mic_eq_open(u32 sample_rate, u8 ch_num, u8 eq_name);
|
||
void *mic_drc_open(u32 sample_rate, u8 ch_num, u8 drc_name, u8 _32bit);
|
||
void mic_eq_close(void *eq);
|
||
void mic_drc_close(void *drc);
|
||
void mic_effect_echo_parm_parintf(ECHO_PARM_SET *parm);
|
||
void *mic_energy_detect_open(u32 sr, u8 ch_num);
|
||
void mic_energy_detect_close(void *hdl);
|
||
void mic_voicechange_switch(u8 eff_mode);
|
||
|
||
|
||
|
||
s16 *aud_reverb_process_run(struct aud_reverb_process *hdl, s16 *data, int len);
|
||
static void audio_reverb_process_output_data_process_len(struct audio_stream_entry *entry, int len)
|
||
{
|
||
struct aud_reverb_process *hdl = container_of(entry, struct aud_reverb_process, entry);
|
||
}
|
||
static int audio_reverb_process_data_handler(struct audio_stream_entry *entry,
|
||
struct audio_data_frame *in,
|
||
struct audio_data_frame *out)
|
||
{
|
||
struct aud_reverb_process *hdl = container_of(entry, struct aud_reverb_process, entry);
|
||
/* if (in->data_len != 304) { */
|
||
/* printf("in->data_len %d\n", in->data_len); */
|
||
/* } */
|
||
|
||
out->data_sync = in->data_sync;
|
||
|
||
struct __mic_effect *eff = hdl->eff;
|
||
if (eff->sub_0_plate_reverb_hdl) {
|
||
out->channel = 2;//in->channel;
|
||
} else {
|
||
out->channel = in->channel;
|
||
}
|
||
out->data_len = out->channel * in->data_len;
|
||
hdl->in_ch = in->channel;
|
||
out->data = aud_reverb_process_run(hdl, (short *)((int)in->data + in->offset), (in->data_len - in->offset)); //默认输出2ch
|
||
if (out->channel == 1) {
|
||
pcm_dual_to_single(out->data, out->data, in->data_len * 2);
|
||
}
|
||
return in->data_len;
|
||
}
|
||
|
||
|
||
struct aud_reverb_process *aud_reverb_open(struct __mic_effect *eff, u8 bit_wide)
|
||
{
|
||
struct aud_reverb_process *hdl = zalloc(sizeof(struct aud_reverb_process));
|
||
hdl->eff = eff;
|
||
hdl->bit_wide = bit_wide;
|
||
hdl->entry.data_process_len = audio_reverb_process_output_data_process_len;
|
||
hdl->entry.data_handler = audio_reverb_process_data_handler;
|
||
|
||
return hdl;
|
||
}
|
||
|
||
void aud_reverb_close(struct aud_reverb_process *hdl)
|
||
{
|
||
if (!hdl) {
|
||
return;
|
||
}
|
||
local_irq_disable();
|
||
audio_stream_del_entry(&hdl->entry);
|
||
local_irq_enable();
|
||
for (int i = 0; i < 3; i++) {
|
||
if (hdl->tmpbuf[i]) {
|
||
free(hdl->tmpbuf[i]);
|
||
hdl->tmpbuf[i] = NULL;
|
||
}
|
||
}
|
||
free(hdl);
|
||
hdl = NULL;
|
||
}
|
||
|
||
void pcm_single_to_dual_32bit(void *out, void *in, u16 len)
|
||
{
|
||
s32 *outbuf = out;
|
||
s32 *inbuf = in;
|
||
len >>= 2;
|
||
while (len--) {
|
||
*outbuf++ = *inbuf;
|
||
*outbuf++ = *inbuf;
|
||
inbuf++;
|
||
}
|
||
}
|
||
|
||
s16 *aud_reverb_process_run(struct aud_reverb_process *hdl, s16 *data, int len)
|
||
{
|
||
struct __mic_effect *eff = hdl->eff;
|
||
u8 ch_num = eff->input_ch_num;
|
||
if (eff->sub_0_plate_reverb_hdl) {
|
||
//ch0
|
||
if (hdl->in_ch == 2) {
|
||
if (!hdl->tmpbuf[0]) {
|
||
hdl->tmpbuf[0] = malloc(len);//2ch 16 bit buf
|
||
}
|
||
u8 *tmp = hdl->tmpbuf[0];
|
||
pcm_dual_to_single(&tmp[len / 2], data, len);
|
||
run_plate_reverb(eff->sub_0_plate_reverb_hdl, &tmp[len / 2], hdl->tmpbuf[0], len / 2); //内部单变双
|
||
} else {
|
||
if (!hdl->bit_wide) { //16 bit
|
||
if (!hdl->tmpbuf[0]) {
|
||
hdl->tmpbuf[0] = malloc(len * 2);//2ch 16 bit buf
|
||
}
|
||
run_plate_reverb(eff->sub_0_plate_reverb_hdl, data, hdl->tmpbuf[0], len); //16bit 内部单变双
|
||
audio_dec_eq_run(eff->mic_eq1, hdl->tmpbuf[0], hdl->tmpbuf[0], len * 2);// 16bit 2ch
|
||
audio_dec_drc_run(eff->mic_drc1, hdl->tmpbuf[0], len * 2); //16bit 2ch
|
||
} else {
|
||
if (!hdl->tmpbuf[0]) {
|
||
hdl->tmpbuf[0] = malloc(len * 2 * 2);//2ch 32 bit buf
|
||
}
|
||
u8 *tmp = hdl->tmpbuf[0];
|
||
u8 *tar = &tmp[len * 2 * 2 - 2 * len]; //放在最后 16bit 2ch
|
||
run_plate_reverb(eff->sub_0_plate_reverb_hdl, data, tar, len); //16 bit 内部单变双
|
||
audio_dec_eq_run(eff->mic_eq1, tar, hdl->tmpbuf[0], len * 2);// 32bit 2ch out
|
||
audio_dec_drc_run(eff->mic_drc1, hdl->tmpbuf[0], len * 2 * 2); //32bit 2ch
|
||
}
|
||
}
|
||
}
|
||
|
||
//ch1
|
||
u32 points = 0;
|
||
if (hdl->in_ch == 1) {
|
||
if (!hdl->bit_wide) { //16 bit
|
||
|
||
u8 *tmp = NULL;
|
||
u8 *tar = NULL;
|
||
if (eff->sub_1_echo_hdl) {
|
||
if (!hdl->tmpbuf[1]) {
|
||
hdl->tmpbuf[1] = malloc(len * 2);//2ch 16 bit buf
|
||
}
|
||
//ch1
|
||
tmp = hdl->tmpbuf[1];
|
||
tar = &tmp[len];
|
||
if ((TCFG_MIC_EFFECT_SEL & MIC_EFFECT_MEGAPHONE)) {
|
||
memcpy(tar, data, len);
|
||
} else {
|
||
run_echo(eff->sub_1_echo_hdl, data, tar, len);
|
||
}
|
||
audio_dec_eq_run(eff->mic_eq2, tar, NULL, len); //1ch
|
||
audio_dec_drc_run(eff->mic_drc2, tar, len); //16bit 1ch
|
||
pcm_single_to_dual(hdl->tmpbuf[1], tar, len);//16bit 2ch
|
||
}
|
||
#if ENABLE_BYPASS_CH_AND_EQ2
|
||
if (!hdl->tmpbuf[2]) {
|
||
hdl->tmpbuf[2] = malloc(len * 2);//2ch 16 bit buf
|
||
}
|
||
//ch2
|
||
audio_dec_eq_run(eff->mic_eq3, data, NULL, len);//1ch
|
||
audio_dec_drc_run(eff->mic_drc3, data, len); //16bit 1ch
|
||
pcm_single_to_dual(hdl->tmpbuf[2], data, len);//16bit 2ch
|
||
#endif
|
||
points = (len * 2) / 2;
|
||
} else {
|
||
u8 *tmp = NULL;
|
||
u8 *tar = NULL;
|
||
if (eff->sub_1_echo_hdl) {
|
||
if (!hdl->tmpbuf[1]) {
|
||
hdl->tmpbuf[1] = malloc(len * 2 * 2); //2ch 32 bit buf
|
||
}
|
||
//ch1
|
||
tmp = hdl->tmpbuf[1];
|
||
tar = &tmp[len * 2 * 2 - len]; //放在最后 16bit 1ch
|
||
u8 *tar2 = &tmp[len * 2]; //buf中间位置
|
||
run_echo(eff->sub_1_echo_hdl, data, tar, len);
|
||
audio_dec_eq_run(eff->mic_eq2, tar, tar2, len); //16 ->32 1ch
|
||
audio_dec_drc_run(eff->mic_drc2, tar2, len * 2); //32bit 1ch
|
||
pcm_single_to_dual_32bit(hdl->tmpbuf[1], tar2, len * 2); //32bit 2ch out
|
||
}
|
||
|
||
//ch2
|
||
if (!hdl->tmpbuf[2]) {
|
||
hdl->tmpbuf[2] = malloc(len * 2 * 2); //2ch 32 bit buf
|
||
}
|
||
tmp = hdl->tmpbuf[2];
|
||
tar = &tmp[len * 2]; //buf中间位置
|
||
audio_dec_eq_run(eff->mic_eq3, data, tar, len);//16->32bit 1ch
|
||
audio_dec_drc_run(eff->mic_drc3, tar, len * 2); //32bit 1ch
|
||
pcm_single_to_dual_32bit(hdl->tmpbuf[2], tar, len * 2); //32bit 2ch
|
||
|
||
points = (len * 2 * 2) / 4;
|
||
}
|
||
} else {
|
||
if (!hdl->bit_wide) { //16 bit
|
||
|
||
u8 *tmp = NULL;
|
||
u8 *tar = NULL;
|
||
if (eff->sub_1_echo_hdl) {
|
||
if (!hdl->tmpbuf[1]) {
|
||
hdl->tmpbuf[1] = malloc(len);//2ch 16 bit buf
|
||
}
|
||
tmp = hdl->tmpbuf[1];
|
||
tar = &tmp[len / 2];
|
||
pcm_dual_to_single(tar, data, len);
|
||
run_echo(eff->sub_1_echo_hdl, tar, tar, len / 2);
|
||
pcm_single_to_dual(tmp, tar, len / 2);
|
||
audio_dec_eq_run(eff->mic_eq2, tmp, hdl->tmpbuf[1], len); //立体声处理2ch
|
||
audio_dec_drc_run(eff->mic_drc2, hdl->tmpbuf[1], len); //16bit 2ch
|
||
}
|
||
|
||
//ch2
|
||
if (!hdl->tmpbuf[2]) {
|
||
hdl->tmpbuf[2] = malloc(len);//2ch 16bit buf
|
||
}
|
||
audio_dec_eq_run(eff->mic_eq3, data, hdl->tmpbuf[2], len);
|
||
audio_dec_drc_run(eff->mic_drc3, hdl->tmpbuf[2], len); //16bit 2ch
|
||
points = len / 2;
|
||
} else {
|
||
|
||
u8 *tmp = NULL;
|
||
u8 *tar = NULL;
|
||
if (eff->sub_1_echo_hdl) {
|
||
if (!hdl->tmpbuf[1]) {
|
||
hdl->tmpbuf[1] = malloc(len * 2); //2ch 32 bit buf
|
||
}
|
||
//ch1
|
||
tmp = hdl->tmpbuf[1];
|
||
tar = &tmp[len * 2 - len / 2];
|
||
pcm_dual_to_single(tar, data, len);
|
||
run_echo(eff->sub_1_echo_hdl, tar, tar, len / 2);
|
||
pcm_single_to_dual(tmp, tar, len / 2);
|
||
audio_dec_eq_run(eff->mic_eq2, tmp, hdl->tmpbuf[1], len); //立体声处理2ch
|
||
audio_dec_drc_run(eff->mic_drc2, hdl->tmpbuf[1], len * 2); //32bit 2ch
|
||
}
|
||
|
||
//ch2
|
||
if (!hdl->tmpbuf[2]) {
|
||
hdl->tmpbuf[2] = malloc(len * 2 * 2); //2ch 32 bit buf
|
||
}
|
||
audio_dec_eq_run(eff->mic_eq3, data, hdl->tmpbuf[2], len);
|
||
audio_dec_drc_run(eff->mic_drc3, hdl->tmpbuf[2], len * 2); //32bit 2ch
|
||
points = (len * 2) / 4;
|
||
}
|
||
}
|
||
MixParam mix0 = {0};
|
||
MixParam mix1 = {0};
|
||
MixParam mix2 = {0};
|
||
|
||
u8 mode = get_mic_eff_mode();
|
||
Mix_TOOL_SET *mix_gain = &eff_mode[mode].mix_gain;
|
||
mix0.data = hdl->tmpbuf[0];
|
||
mix0.gain = mix_gain->gain1;
|
||
mix1.data = hdl->tmpbuf[1];
|
||
mix1.gain = mix_gain->gain2;
|
||
mix2.data = hdl->tmpbuf[2];
|
||
mix2.gain = mix_gain->gain3;
|
||
u8 out_ch_num = 2;
|
||
if (!hdl->bit_wide) { //16 bit
|
||
if (eff->sub_1_echo_hdl && eff->sub_0_plate_reverb_hdl) {
|
||
Mix16to16(&mix0, &mix1, &mix2, hdl->tmpbuf[0], out_ch_num, 3, points / out_ch_num);
|
||
} else if (eff->sub_0_plate_reverb_hdl) {
|
||
Mix16to16(&mix0, &mix2, NULL, hdl->tmpbuf[0], out_ch_num, 2, points / out_ch_num);
|
||
} else {
|
||
#if ENABLE_BYPASS_CH_AND_EQ2
|
||
Mix16to16(&mix1, &mix2, NULL, hdl->tmpbuf[1], out_ch_num, 2, points / out_ch_num);
|
||
#endif
|
||
return hdl->tmpbuf[1];
|
||
}
|
||
return hdl->tmpbuf[0];
|
||
} else {
|
||
if (eff->sub_1_echo_hdl && eff->sub_0_plate_reverb_hdl) {
|
||
Mix32to16(&mix0, &mix1, &mix2, hdl->tmpbuf[0], out_ch_num, 3, points / out_ch_num);
|
||
} else if (eff->sub_0_plate_reverb_hdl) {
|
||
Mix32to16(&mix0, &mix2, NULL, hdl->tmpbuf[0], out_ch_num, 2, points / out_ch_num);
|
||
} else {
|
||
Mix32to16(&mix1, &mix2, NULL, hdl->tmpbuf[1], out_ch_num, 2, points / out_ch_num);
|
||
return hdl->tmpbuf[1];
|
||
}
|
||
}
|
||
return hdl->tmpbuf[0];
|
||
}
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/**@brief mic数据流串接入口
|
||
@param
|
||
@return
|
||
@note
|
||
*/
|
||
/*----------------------------------------------------------------------------*/
|
||
static u32 mic_effect_effect_run(void *priv, void *in, void *out, u32 inlen, u32 outlen)
|
||
{
|
||
struct __mic_effect *effect = (struct __mic_effect *)priv;
|
||
if (effect == NULL) {
|
||
return 0;
|
||
}
|
||
struct audio_data_frame frame = {0};
|
||
frame.channel = effect->input_ch_num;
|
||
frame.sample_rate = effect->parm.sample_rate;
|
||
frame.data_len = inlen;
|
||
frame.data = in;
|
||
effect->out_len = 0;
|
||
effect->process_len = inlen;
|
||
|
||
if (effect->pause_mark) {
|
||
memset(in, 0, inlen);
|
||
return inlen;
|
||
} else {
|
||
|
||
}
|
||
#if LOUDNESS_DEBUG_ENABLE
|
||
loudness_meter_short(&effect->loudness_adc, in, inlen / 2);
|
||
#endif
|
||
while (1) {
|
||
audio_stream_run(&effect->entry, &frame);
|
||
if (effect->out_len >= effect->process_len) {
|
||
break;
|
||
}
|
||
frame.data = (s16 *)((u8 *)in + effect->out_len);
|
||
frame.data_len = inlen - effect->out_len;
|
||
}
|
||
return outlen;
|
||
}
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/**@brief 释放mic数据流资源
|
||
@param
|
||
@return
|
||
@note
|
||
*/
|
||
/*----------------------------------------------------------------------------*/
|
||
static void mic_effect_destroy(struct __mic_effect **hdl)
|
||
{
|
||
if (hdl == NULL || *hdl == NULL) {
|
||
return ;
|
||
}
|
||
struct __mic_effect *effect = *hdl;
|
||
if (effect->mic) {
|
||
log_i("mic_stream_destroy\n\n\n");
|
||
mic_stream_destroy(&effect->mic);
|
||
}
|
||
|
||
#if TCFG_MIC_DODGE_EN
|
||
if (effect->energy_hdl) {
|
||
mic_energy_detect_close(effect->energy_hdl);
|
||
}
|
||
#endif
|
||
|
||
if (effect->noisegate) {
|
||
log_i("close_noisegate\n\n\n");
|
||
audio_noisegate_close(effect->noisegate);
|
||
}
|
||
|
||
|
||
if (effect->howling_ps) {
|
||
log_i("close_howling\n\n\n");
|
||
close_howling(effect->howling_ps);
|
||
}
|
||
if (effect->notch_howling) {
|
||
log_i("close_howling\n\n\n");
|
||
close_howling(effect->notch_howling);
|
||
}
|
||
#if defined(TCFG_MIC_VOICE_CHANGER_ENABLE) && TCFG_MIC_VOICE_CHANGER_ENABLE
|
||
if (effect->voice_changer) {
|
||
audio_voice_changer_close_demo(effect->voice_changer);
|
||
}
|
||
#endif
|
||
#if defined(TCFG_MIC_AUTOTUNE_ENABLE) && TCFG_MIC_AUTOTUNE_ENABLE
|
||
if (effect->autotune) {
|
||
audio_autotune_close_demo(effect->autotune);
|
||
}
|
||
#endif
|
||
#if TCFG_EQ_ENABLE && TCFG_MIC_TUNNING_EQ_ENABLE
|
||
if (effect->mic_tunning_eq) {
|
||
mic_tunning_eq_close(effect->mic_tunning_eq);
|
||
}
|
||
#endif
|
||
if (effect->mic_eq0) {
|
||
log_i("mic_eq0_close\n\n\n");
|
||
mic_eq_close(effect->mic_eq0);
|
||
}
|
||
if (effect->mic_drc0) {
|
||
log_i("mic_drc0_close\n\n\n");
|
||
mic_drc_close(effect->mic_drc0);
|
||
}
|
||
if (effect->convert0) {
|
||
log_i("convet0_data_close\n\n\n");
|
||
convet_data_close(effect->convert0);
|
||
}
|
||
|
||
if (effect->mic_eq1) {
|
||
log_i("mic_eq1_close\n\n\n");
|
||
mic_eq_close(effect->mic_eq1);
|
||
}
|
||
if (effect->mic_drc1) {
|
||
log_i("mic_drc1_close\n\n\n");
|
||
mic_drc_close(effect->mic_drc1);
|
||
}
|
||
|
||
if (effect->mic_eq2) {
|
||
log_i("mic_eq2_close\n\n\n");
|
||
mic_eq_close(effect->mic_eq2);
|
||
}
|
||
if (effect->mic_drc2) {
|
||
log_i("mic_drc2_close\n\n\n");
|
||
mic_drc_close(effect->mic_drc2);
|
||
}
|
||
|
||
if (effect->mic_eq3) {
|
||
log_i("mic_eq3_close\n\n\n");
|
||
mic_eq_close(effect->mic_eq3);
|
||
}
|
||
if (effect->mic_drc3) {
|
||
log_i("mic_drc3_close\n\n\n");
|
||
mic_drc_close(effect->mic_drc3);
|
||
}
|
||
|
||
if (effect->mic_eq4) {
|
||
log_i("mic_eq4_close\n\n\n");
|
||
mic_eq_close(effect->mic_eq4);
|
||
}
|
||
if (effect->mic_drc4) {
|
||
log_i("mic_drc4_close\n\n\n");
|
||
mic_drc_close(effect->mic_drc4);
|
||
}
|
||
|
||
if (effect->convert4) {
|
||
log_i("convet4_data_close\n\n\n");
|
||
convet_data_close(effect->convert4);
|
||
}
|
||
/* if (effect->gain) { */
|
||
/* log_i("audio_gain_close_demo\n\n\n"); */
|
||
/* audio_gain_close_demo(effect->gain); */
|
||
/* effect->gain = NULL; */
|
||
/* } */
|
||
if (effect->sub_1_echo_hdl) {
|
||
close_echo(effect->sub_1_echo_hdl);
|
||
}
|
||
if (effect->sub_0_plate_reverb_hdl) {
|
||
close_plate_reverb(effect->sub_0_plate_reverb_hdl);
|
||
}
|
||
if (effect->d_vol) {
|
||
audio_stream_del_entry(audio_dig_vol_entry_get(effect->d_vol));
|
||
#if SYS_DIGVOL_GROUP_EN
|
||
sys_digvol_group_ch_close("mic_mic");
|
||
#else
|
||
audio_dig_vol_close(effect->d_vol);
|
||
#endif/*SYS_DIGVOL_GROUP_EN*/
|
||
}
|
||
/* if (effect->linein) { */
|
||
/* effect_linein_close(&effect->linein); */
|
||
/* } */
|
||
|
||
if (effect->src_hdl) {
|
||
audio_stream_del_entry(&effect->src_hdl->entry);
|
||
audio_hw_src_stop(effect->src_hdl);
|
||
audio_hw_src_close(effect->src_hdl);
|
||
free(effect->src_hdl);
|
||
effect->src_hdl = NULL;
|
||
}
|
||
if (effect->channel_zoom) {
|
||
channel_switch_close(&effect->channel_zoom);
|
||
/*effect->channel_zoom = NULL;*/
|
||
}
|
||
if (effect->loudness_debug_hdl) {
|
||
stream_entry_close(&effect->loudness_debug_hdl);
|
||
}
|
||
if (effect->dac) {
|
||
audio_stream_del_entry(&effect->dac->entry);
|
||
audio_dac_free_channel(effect->dac);
|
||
free(effect->dac);
|
||
effect->dac = NULL;
|
||
}
|
||
|
||
#if (RECORDER_MIX_EN)
|
||
if (effect->rec_hdl) {
|
||
stream_entry_close(&effect->rec_hdl);
|
||
}
|
||
#endif
|
||
#if (TCFG_USB_MIC_DATA_FROM_MICEFFECT||TCFG_USB_MIC_DATA_FROM_DAC)
|
||
if (effect->usbmic_hdl) {
|
||
stream_entry_close(&effect->usbmic_hdl);
|
||
}
|
||
#endif
|
||
if (effect->aud_reverb) {
|
||
aud_reverb_close(effect->aud_reverb);
|
||
}
|
||
|
||
if (effect->stream) {
|
||
audio_stream_close(effect->stream);
|
||
}
|
||
local_irq_disable();
|
||
free(effect);
|
||
*hdl = NULL;
|
||
local_irq_enable();
|
||
|
||
mem_stats();
|
||
clock_remove_set(REVERB_CLK);
|
||
}
|
||
/*----------------------------------------------------------------------------*/
|
||
/**@brief 串流唤醒
|
||
@param
|
||
@return
|
||
@note 暂未使用
|
||
*/
|
||
/*----------------------------------------------------------------------------*/
|
||
static void mic_stream_resume(void *p)
|
||
{
|
||
struct __mic_effect *effect = (struct __mic_effect *)p;
|
||
/* audio_decoder_resume_all(&decode_task); */
|
||
}
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/**@brief 串流数据处理长度回调
|
||
@param
|
||
@return
|
||
@note
|
||
*/
|
||
/*----------------------------------------------------------------------------*/
|
||
static void mic_effect_data_process_len(struct audio_stream_entry *entry, int len)
|
||
{
|
||
|
||
struct __mic_effect *effect = container_of(entry, struct __mic_effect, entry);
|
||
effect->out_len += len;
|
||
/* printf("out len[%d]",effect->out_len); */
|
||
}
|
||
|
||
static int mic_effect_record_stream_callback(void *priv, struct audio_data_frame *in)
|
||
{
|
||
struct __mic_effect *effect = (struct __mic_effect *)priv;
|
||
|
||
s16 *data = in->data;
|
||
u32 len = in->data_len;
|
||
|
||
return recorder_mix_pcm_write((u8 *)data, len);
|
||
}
|
||
extern int usb_audio_mic_write_do(void *data, u16 len);
|
||
static int mic_effect_otherout_stream_callback(void *priv, struct audio_data_frame *in)
|
||
{
|
||
struct __mic_effect *effect = (struct __mic_effect *)priv;
|
||
s16 *data = in->data;
|
||
u32 len = in->data_len;
|
||
|
||
#if ((TCFG_USB_MIC_DATA_FROM_MICEFFECT||TCFG_USB_MIC_DATA_FROM_DAC))
|
||
if (effect->usbmic_start) {
|
||
if (len) {
|
||
usb_audio_mic_write_do(data, len);
|
||
}
|
||
} else {
|
||
}
|
||
#endif
|
||
return len;
|
||
}
|
||
|
||
void mic_effect_to_usbmic_onoff(u8 mark)
|
||
{
|
||
#if (TCFG_USB_MIC_DATA_FROM_MICEFFECT||TCFG_USB_MIC_DATA_FROM_DAC)
|
||
if (__this) {
|
||
__this->usbmic_start = mark ? 1 : 0;
|
||
}
|
||
#endif
|
||
}
|
||
|
||
static void inline rl_rr_mix_to_rl_rr(short *data, int len)
|
||
{
|
||
s32 tmp32_1;
|
||
s32 tmp32_2;
|
||
s16 *inbuf = data;
|
||
inbuf = inbuf + 2; //定位到第三通道
|
||
len >>= 3;
|
||
__asm__ volatile(
|
||
"1: \n\t"
|
||
"rep %0 { \n\t"
|
||
" %2 = h[%1 ++= 2](s) \n\t" //取第三通道值,并地址偏移两个字节指向第四通道数据
|
||
" %3 = h[%1 ++= -2](s) \n\t" //取第四通道值,并地址偏移两个字节指向第三通道数据
|
||
" %2 = %2 + %3 \n\t"
|
||
" %2 = sat16(%2)(s) \n\t" //饱和处理
|
||
" h[%1 ++= 2] = %2 \n\t" //存取第三通道数据,并地址偏移两个字节指向第四通道数据
|
||
" h[%1 ++= 6] = %2 \n\t" //存取第四通道数据,并地址偏移六个字节指向第三通道相邻的数据
|
||
"} \n\t"
|
||
"if(%0 != 0) goto 1b \n\t"
|
||
:
|
||
"=&r"(len),
|
||
"=&r"(inbuf),
|
||
"=&r"(tmp32_1),
|
||
"=&r"(tmp32_2)
|
||
:
|
||
"0"(len),
|
||
"1"(inbuf),
|
||
"2"(tmp32_1),
|
||
"3"(tmp32_2)
|
||
:
|
||
);
|
||
}
|
||
static int effect_to_dac_data_pro_handle(struct audio_stream_entry *entry, struct audio_data_frame *in)
|
||
{
|
||
#if (SOUNDCARD_ENABLE)
|
||
if (in->data_len == 0) {
|
||
return 0;
|
||
}
|
||
#if 1
|
||
rl_rr_mix_to_rl_rr(in->data, in->data_len);//汇编加速
|
||
#else
|
||
s16 *outbuf = in->data;
|
||
s16 *inbuf = in->data;
|
||
s32 tmp32;
|
||
u16 len = in->data_len;
|
||
len >>= 3;
|
||
while (len--) {
|
||
*outbuf++ = inbuf[0];
|
||
*outbuf++ = inbuf[1];
|
||
tmp32 = (inbuf[2] + inbuf[3]);
|
||
if (tmp32 < -32768) {
|
||
tmp32 = -32768;
|
||
} else if (tmp32 > 32767) {
|
||
tmp32 = 32767;
|
||
}
|
||
*outbuf++ = tmp32;
|
||
*outbuf++ = tmp32;
|
||
inbuf += 4;
|
||
}
|
||
#endif
|
||
#endif
|
||
return 0;
|
||
}
|
||
|
||
#if TCFG_APP_RECORD_EN
|
||
static int prob_handler_to_record(struct audio_stream_entry *entry, struct audio_data_frame *in)
|
||
{
|
||
if (app_get_curr_task() != APP_RECORD_TASK) {
|
||
return 0;
|
||
}
|
||
if (in->data_len == 0) {
|
||
return 0;
|
||
}
|
||
if (recorder_is_encoding() == 0) {
|
||
return 0;
|
||
}
|
||
int wlen = recorder_userdata_to_enc(in->data, in->data_len);
|
||
if (wlen != in->data_len) {
|
||
putchar('N');
|
||
}
|
||
return 0;
|
||
}
|
||
#endif
|
||
|
||
int audio_data_check_cb(struct audio_stream_entry *entry, struct audio_data_frame *data_buf)
|
||
{
|
||
|
||
if (__this) {
|
||
loudness_meter_short(&__this->loudness_drc_out, data_buf->data, data_buf->data_len / 2);
|
||
}
|
||
return data_buf->data_len;
|
||
}
|
||
|
||
#if (TCFG_AUDIO_DAC_CONNECT_MODE == DAC_OUTPUT_LR || TCFG_AUDIO_DAC_CONNECT_MODE == DAC_OUTPUT_DUAL_LR_DIFF)
|
||
#define DAC_OUTPUT_CHANNELS 2
|
||
#elif (TCFG_AUDIO_DAC_CONNECT_MODE == DAC_OUTPUT_MONO_R || TCFG_AUDIO_DAC_CONNECT_MODE == DAC_OUTPUT_MONO_R || TCFG_AUDIO_DAC_CONNECT_MODE == DAC_OUTPUT_MONO_LR_DIFF)
|
||
#define DAC_OUTPUT_CHANNELS 1
|
||
#elif (TCFG_AUDIO_DAC_CONNECT_MODE == DAC_OUTPUT_FRONT_LR_REAR_LR)
|
||
#define DAC_OUTPUT_CHANNELS 4
|
||
#else
|
||
#define DAC_OUTPUT_CHANNELS 3
|
||
#endif
|
||
|
||
static u8 reverb_mode = 0;
|
||
static u8 voicechange_mode = 0;
|
||
void switch_mic_effect_mode(void)
|
||
{
|
||
reverb_mode++;
|
||
if (reverb_mode > 2) {
|
||
reverb_mode = 0;
|
||
}
|
||
printf("\n--func=%s [%d] \n", __FUNCTION__, reverb_mode);
|
||
|
||
set_mic_reverb_mode_by_id(reverb_mode);
|
||
}
|
||
/*----------------------------------------------------------------------------*/
|
||
/**@brief (mic数据流)混响打开接口
|
||
@param
|
||
@return
|
||
@note
|
||
*/
|
||
/*----------------------------------------------------------------------------*/
|
||
bool mic_effect_start(void)
|
||
{
|
||
bool ret = false;
|
||
mem_stats();
|
||
printf("\n--func=%s\n", __FUNCTION__);
|
||
if (__this) {
|
||
log_e("reverb is already start \n");
|
||
return ret;
|
||
}
|
||
struct __mic_effect *effect = (struct __mic_effect *)zalloc(sizeof(struct __mic_effect));
|
||
if (effect == NULL) {
|
||
return false;
|
||
}
|
||
u8 mode = get_mic_eff_mode();
|
||
struct eff_parm *mic_eff = &eff_mode[mode];
|
||
|
||
clock_add_set(REVERB_CLK);
|
||
os_mutex_create(&effect->mutex);
|
||
memcpy(&effect->parm, &effect_parm_default, sizeof(struct __mic_effect_parm));
|
||
struct __mic_stream_parm *mic_parm = (struct __mic_stream_parm *)&effect_mic_stream_parm_default;
|
||
if (g_mic_parm) {
|
||
mic_parm = g_mic_parm;
|
||
}
|
||
|
||
#if LOUDNESS_DEBUG_ENABLE
|
||
loudness_meter_init(&effect->loudness_adc, effect_mic_stream_parm_default.sample_rate, 50, 1);
|
||
loudness_meter_init(&effect->loudness_drc_out, effect_mic_stream_parm_default.sample_rate, 50, 2);
|
||
effect->loudness_debug_hdl = stream_entry_open(effect, audio_data_check_cb, 0);// 能量计算及打印节点
|
||
#endif
|
||
if ((TCFG_MIC_EFFECT_SEL & MIC_EFFECT_ECHO)
|
||
&& (TCFG_MIC_EFFECT_SEL & MIC_EFFECT_REVERB)) {
|
||
log_e("effect config err ?? !!!, cann't support echo && reverb at the same time\n");
|
||
mic_effect_destroy(&effect);
|
||
return false;
|
||
}
|
||
u16 irq_points = mic_parm->point_unit;
|
||
u8 ch_num = 1; //??
|
||
effect->input_ch_num = ch_num;
|
||
#if TCFG_MIC_DODGE_EN
|
||
if (effect->parm.effect_config & BIT(MIC_EFFECT_CONFIG_ENERGY_DETECT)) {
|
||
effect->energy_hdl = mic_energy_detect_open(effect->parm.sample_rate, ch_num);
|
||
effect->dodge_en = 0;//默认关闭, 需要通过按键触发打开
|
||
}
|
||
#endif
|
||
///声音门限初始化
|
||
if (effect->parm.effect_config & BIT(MIC_EFFECT_CONFIG_NOISEGATE)) {
|
||
effect->noisegate = audio_noisegate_open_demo(AEID_MIC_NS_GATE, MIC_EFFECT_SAMPLERATE, ch_num);
|
||
}
|
||
|
||
///啸叫抑制初始化
|
||
if (effect->parm.effect_config & BIT(MIC_EFFECT_CONFIG_HOWLING)) {
|
||
log_i("open_howling\n\n\n");
|
||
effect->howling_ps = open_howling(NULL, effect->parm.sample_rate, 0, 1);//以频
|
||
}
|
||
|
||
if (effect->parm.effect_config & BIT(MIC_EFFECT_CONFIG_HOWLING_TRAP)) {
|
||
log_i("open_howling\n\n\n");
|
||
|
||
HOWLING_PARM_SET howling_param = {
|
||
.threshold = mic_eff->notchhowling_parm.parm.threshold,
|
||
.fade_time = mic_eff->notchhowling_parm.parm.fade_n,
|
||
.notch_Q = mic_eff->notchhowling_parm.parm.Q,
|
||
.notch_gain = mic_eff->notchhowling_parm.parm.gain,
|
||
.sample_rate = MIC_EFFECT_SAMPLERATE,
|
||
.channel = 1,
|
||
|
||
};
|
||
#if (TCFG_USER_TWS_ENABLE == 0)
|
||
effect->notch_howling = open_howling(&howling_param, effect->parm.sample_rate, 0, 0);//陷波
|
||
#endif
|
||
}
|
||
|
||
#if defined(TCFG_MIC_VOICE_CHANGER_ENABLE) && TCFG_MIC_VOICE_CHANGER_ENABLE
|
||
effect->voice_changer = audio_voice_changer_open_demo(AEID_MIC_VOICE_CHANGER, effect->parm.sample_rate);
|
||
#endif
|
||
#if defined(TCFG_MIC_AUTOTUNE_ENABLE) && TCFG_MIC_AUTOTUNE_ENABLE
|
||
effect->autotune = audio_autotune_open_demo(AEID_MIC_AUTOTUNE, effect->parm.sample_rate);
|
||
#endif
|
||
log_i("effect->parm.sample_rate %d\n", effect->parm.sample_rate);
|
||
#if TCFG_EQ_ENABLE && TCFG_MIC_TUNNING_EQ_ENABLE
|
||
effect->mic_tunning_eq = mic_tunning_eq_open(effect->parm.sample_rate, ch_num);
|
||
#endif
|
||
|
||
if (effect->parm.effect_config & BIT(MIC_EFFECT_CONFIG_EQ0)) {
|
||
effect->mic_eq0 = mic_eq_open(effect->parm.sample_rate, ch_num, AEID_MIC_EQ0);
|
||
if (effect->mic_eq0 && effect->mic_eq0->out_32bit) {
|
||
effect->mic_drc0 = mic_drc_open(effect->parm.sample_rate, ch_num, AEID_MIC_DRC0, 1);
|
||
effect->convert0 = convet_data_open(0, (irq_points << 1) * ch_num);
|
||
} else {
|
||
#if ENABLE_BYPASS_CH_AND_EQ2
|
||
effect->mic_drc0 = mic_drc_open(effect->parm.sample_rate, ch_num, AEID_MIC_DRC0, 0);
|
||
#endif
|
||
}
|
||
}
|
||
|
||
#if ENABLE_BYPASS_CH_AND_EQ2
|
||
effect->mic_eq3 = mic_eq_open(effect->parm.sample_rate, ch_num, AEID_MIC_EQ3);
|
||
#endif
|
||
if (effect->mic_eq3 && effect->mic_eq3->out_32bit) {
|
||
effect->mic_drc3 = mic_drc_open(effect->parm.sample_rate, ch_num, AEID_MIC_DRC3, 1);
|
||
}
|
||
|
||
// sub 0 分流节点
|
||
if ((TCFG_MIC_EFFECT_SEL & MIC_EFFECT_ECHO) || (TCFG_MIC_EFFECT_SEL & MIC_EFFECT_MEGAPHONE)) {
|
||
effect->sub_1_echo_hdl = open_echo((ECHO_PARM_SET *)&mic_eff->echo_parm.parm, (EF_REVERB_FIX_PARM *)&effect_echo_fix_parm_default);
|
||
|
||
if (effect->sub_1_echo_hdl) {
|
||
#if ENABLE_BYPASS_CH_AND_EQ2
|
||
effect->mic_eq2 = mic_eq_open(effect->parm.sample_rate, ch_num, AEID_MIC_EQ2);
|
||
#endif
|
||
if (effect->mic_eq2 && effect->mic_eq2->out_32bit) {
|
||
effect->mic_drc2 = mic_drc_open(effect->parm.sample_rate, ch_num, AEID_MIC_DRC2, 1);
|
||
}
|
||
}
|
||
}
|
||
|
||
if (TCFG_MIC_EFFECT_SEL & MIC_EFFECT_REVERB) {
|
||
effect->sub_0_plate_reverb_hdl = open_plate_reverb((Plate_reverb_parm *)&mic_eff->plate_reverb_parm.parm, effect->parm.sample_rate);
|
||
if (effect->sub_0_plate_reverb_hdl) {
|
||
ch_num = 2;
|
||
}
|
||
|
||
effect->mic_eq1 = mic_eq_open(effect->parm.sample_rate, ch_num, AEID_MIC_EQ1);
|
||
if (effect->mic_eq1 && effect->mic_eq1->out_32bit) {
|
||
effect->mic_drc1 = mic_drc_open(effect->parm.sample_rate, ch_num, AEID_MIC_DRC1, 1);
|
||
}
|
||
}
|
||
|
||
//多路混合后 EQ drc
|
||
#if TCFG_AUDIO_MIC_EFFECT_POST_EQ_ENABLE
|
||
effect->mic_eq4 = mic_eq_open(effect->parm.sample_rate, ch_num, AEID_MIC_EQ4);
|
||
if (effect->mic_eq4 && effect->mic_eq4->out_32bit) {
|
||
effect->mic_drc4 = mic_drc_open(effect->parm.sample_rate, ch_num, AEID_MIC_DRC4, 1);
|
||
effect->convert4 = convet_data_open(0, (irq_points << 1) * ch_num);
|
||
}
|
||
#endif/*TCFG_AUDIO_MIC_EFFECT_POST_EQ_ENABLE*/
|
||
|
||
/* effect->gain = audio_gain_open_demo(AEID_MIC_GAIN, ch_num); */
|
||
|
||
///初始化数字音量
|
||
struct audio_stream_entry *dvol_entry;
|
||
if (effect->parm.effect_config & BIT(MIC_EFFECT_CONFIG_DVOL)) {
|
||
effect_dvol_default_parm.ch_total = ch_num;
|
||
#if SYS_DIGVOL_GROUP_EN
|
||
dvol_entry = sys_digvol_group_ch_open("mic_mic", -1, &effect_dvol_default_parm);
|
||
effect->d_vol = audio_dig_vol_group_hdl_get(sys_digvol_group, "mic_mic");
|
||
#else
|
||
effect->d_vol = audio_dig_vol_open((audio_dig_vol_param *)&effect_dvol_default_parm);
|
||
dvol_entry = audio_dig_vol_entry_get(effect->d_vol);
|
||
#endif /*SYS_DIGVOL_GROUP_EN*/
|
||
}
|
||
|
||
//打开混响变采样
|
||
if (effect->parm.effect_config & BIT(MIC_EFFECT_CONFIG_SOFT_SRC)) {
|
||
u32 out_sr = audio_output_nor_rate();
|
||
|
||
effect->src_hdl = zalloc(sizeof(struct audio_src_handle));
|
||
audio_hw_src_open(effect->src_hdl, ch_num, SRC_TYPE_RESAMPLE);
|
||
audio_hw_src_set_rate(effect->src_hdl, effect->parm.sample_rate, out_sr);
|
||
}
|
||
|
||
//混响通路混合linein
|
||
/* if (effect->parm.effect_config & BIT(MIC_EFFECT_CONFIG_LINEIN)) { */
|
||
/* effect->linein = effect_linein_open(); */
|
||
/* } */
|
||
|
||
u8 output_channels = DAC_OUTPUT_CHANNELS;
|
||
if (output_channels != ch_num) {
|
||
u32 points_num = REVERB_LADC_IRQ_POINTS * 4;
|
||
effect->channel_zoom = channel_switch_open(output_channels == 2 ? AUDIO_CH_LR : (output_channels == 4 ? AUDIO_CH_QUAD : AUDIO_CH_DIFF), output_channels == 4 ? (points_num * 2 + 128) : 1024);
|
||
//effect->channel_zoom = channel_switch_open(AUDIO_CH_LR, 1024);
|
||
}
|
||
|
||
effect->dac = (struct audio_dac_channel *)zalloc(sizeof(struct audio_dac_channel));
|
||
if (effect->dac) {
|
||
audio_dac_new_channel(&dac_hdl, effect->dac);
|
||
struct audio_dac_channel_attr attr;
|
||
audio_dac_channel_get_attr(effect->dac, &attr);
|
||
attr.delay_time = mic_parm->dac_delay;
|
||
attr.write_mode = WRITE_MODE_FORCE;
|
||
audio_dac_channel_set_attr(effect->dac, &attr);
|
||
effect->dac->entry.prob_handler = effect_to_dac_data_pro_handle;
|
||
/* audio_dac_channel_set_pause(effect->dac,1); */
|
||
}
|
||
|
||
effect->entry.data_process_len = mic_effect_data_process_len;
|
||
|
||
#if (RECORDER_MIX_EN)
|
||
///送录音数据流
|
||
effect->rec_hdl = stream_entry_open(effect, mic_effect_record_stream_callback, 1);
|
||
#endif
|
||
#if (TCFG_USB_MIC_DATA_FROM_MICEFFECT||TCFG_USB_MIC_DATA_FROM_DAC)
|
||
effect->usbmic_hdl = stream_entry_open(effect, mic_effect_otherout_stream_callback, 1);
|
||
#endif
|
||
|
||
u8 bit_wide = 0;
|
||
if (effect->mic_eq1 && effect->mic_eq1->out_32bit) {
|
||
bit_wide = 1;
|
||
}
|
||
|
||
effect->aud_reverb = aud_reverb_open(effect, bit_wide);
|
||
|
||
// 数据流串联
|
||
struct audio_stream_entry *entries[25] = {NULL};
|
||
u8 entry_cnt = 0;
|
||
entries[entry_cnt++] = &effect->entry;
|
||
|
||
#if TCFG_MIC_DODGE_EN
|
||
if (effect->energy_hdl) {
|
||
entries[entry_cnt++] = audio_energy_detect_entry_get(effect->energy_hdl);
|
||
}
|
||
#endif
|
||
if (effect->noisegate) {
|
||
entries[entry_cnt++] = &effect->noisegate->entry;
|
||
}
|
||
|
||
#if TCFG_EQ_ENABLE && TCFG_MIC_TUNNING_EQ_ENABLE
|
||
if (effect->mic_tunning_eq) {
|
||
entries[entry_cnt++] = &effect->mic_tunning_eq->entry;
|
||
}
|
||
#endif
|
||
if (effect->mic_eq0) {
|
||
entries[entry_cnt++] = &effect->mic_eq0->entry;
|
||
}
|
||
if (effect->mic_drc0) {
|
||
entries[entry_cnt++] = &effect->mic_drc0->entry;
|
||
}
|
||
|
||
if (effect->mic_eq0 && effect->mic_eq0->out_32bit) {
|
||
if (effect->convert0) {
|
||
entries[entry_cnt++] = &effect->convert0->entry;
|
||
}
|
||
}
|
||
|
||
if (effect->howling_ps) {
|
||
entries[entry_cnt++] = &effect->howling_ps->entry;
|
||
}
|
||
if (effect->notch_howling) {
|
||
entries[entry_cnt++] = &effect->notch_howling->entry;
|
||
}
|
||
if (effect->voice_changer) {
|
||
entries[entry_cnt++] = &effect->voice_changer->entry;
|
||
}
|
||
#if defined(TCFG_MIC_AUTOTUNE_ENABLE) && TCFG_MIC_AUTOTUNE_ENABLE
|
||
if (effect->autotune) {
|
||
entries[entry_cnt++] = &effect->autotune->entry;
|
||
}
|
||
#endif
|
||
if (effect->aud_reverb) {
|
||
entries[entry_cnt++] = &effect->aud_reverb->entry;
|
||
}
|
||
|
||
if (effect->d_vol) {
|
||
entries[entry_cnt++] = dvol_entry;
|
||
}
|
||
if (effect->mic_eq4) {
|
||
entries[entry_cnt++] = &effect->mic_eq4->entry;
|
||
if (effect->mic_eq4->out_32bit) {
|
||
if (effect->mic_drc4) {
|
||
entries[entry_cnt++] = &effect->mic_drc4->entry;
|
||
}
|
||
if (effect->convert4) {
|
||
entries[entry_cnt++] = &effect->convert4->entry;
|
||
}
|
||
}
|
||
}
|
||
/* if (effect->gain) { */
|
||
/* entries[entry_cnt++] = &effect->gain->entry; */
|
||
/* } */
|
||
if (effect->loudness_debug_hdl) {
|
||
entries[entry_cnt++] = &effect->loudness_debug_hdl->entry;
|
||
}
|
||
|
||
if (effect->channel_zoom) {
|
||
entries[entry_cnt++] = &effect->channel_zoom->entry;
|
||
}
|
||
if (effect->dac) {
|
||
entries[entry_cnt++] = &effect->dac->entry;
|
||
#if (TCFG_USB_MIC_DATA_FROM_DAC)
|
||
if (effect->usbmic_hdl) {
|
||
entries[entry_cnt++] = &effect->usbmic_hdl->entry;
|
||
}
|
||
#endif
|
||
}
|
||
|
||
effect->stream = audio_stream_open(effect, mic_stream_resume);
|
||
audio_stream_add_list(effect->stream, entries, entry_cnt);
|
||
|
||
/* effect->main_pause = 2; */
|
||
///mic 数据流初始化
|
||
effect->mic = mic_stream_creat(mic_parm);
|
||
if (effect->mic == NULL) {
|
||
mic_effect_destroy(&effect);
|
||
return false;
|
||
}
|
||
mic_stream_set_output(effect->mic, (void *)effect, mic_effect_effect_run);
|
||
mic_stream_start(effect->mic);
|
||
#if (RECORDER_MIX_EN)
|
||
recorder_mix_pcm_stream_open(effect->parm.sample_rate, ch_num);
|
||
#endif
|
||
|
||
clock_set_cur();
|
||
__this = effect;
|
||
|
||
|
||
log_info("--------------------------effect start ok\n");
|
||
mem_stats();
|
||
|
||
mic_effect_change_mode(mode);
|
||
|
||
return true;
|
||
}
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/**@brief mic增益调节
|
||
@param
|
||
@return
|
||
@note
|
||
*/
|
||
/*----------------------------------------------------------------------------*/
|
||
/* void mic_effect_mic_gain_parm_fill(EFFECTS_MIC_GAIN_PARM *parm, u8 fade, u8 online) */
|
||
/* { */
|
||
/* if (__this == NULL || parm == NULL) { */
|
||
/* return ; */
|
||
/* } */
|
||
/* audio_mic_set_gain(parm->gain); */
|
||
/* } */
|
||
/*----------------------------------------------------------------------------*/
|
||
/**@brief mic效果模式切换(数据流音效组合切换)
|
||
@param
|
||
@return
|
||
@note 使用效果配置文件时生效
|
||
*/
|
||
/*----------------------------------------------------------------------------*/
|
||
void mic_effect_change_mode(u16 mode)
|
||
{
|
||
set_mic_reverb_mode_by_id(mode);
|
||
}
|
||
/*----------------------------------------------------------------------------*/
|
||
/**@brief 获取mic效果模式(数据流音效组合)
|
||
@param
|
||
@return
|
||
@note 使用效果配置文件时生效
|
||
*/
|
||
/*----------------------------------------------------------------------------*/
|
||
u16 mic_effect_get_cur_mode(void)
|
||
{
|
||
return get_mic_eff_mode();
|
||
}
|
||
|
||
void *mic_eq_open(u32 sample_rate, u8 ch_num, u8 eq_name)
|
||
{
|
||
#if TCFG_EQ_ENABLE
|
||
|
||
#if(TCFG_MIC_EFFECT_SEL == MIC_EFFECT_MEGAPHONE)
|
||
if ((eq_name == AEID_MIC_EQ1)) {
|
||
return NULL;
|
||
}
|
||
#endif
|
||
|
||
|
||
u8 mode = get_mic_eff_mode();
|
||
|
||
struct audio_eq_param parm = {0};
|
||
parm.channels = ch_num;
|
||
if ((eq_name == AEID_MIC_EQ0) || (eq_name == AEID_MIC_EQ4)) {
|
||
/* parm.out_32bit = 1;//32bit位宽输出 */ //696默认使用16bitEQ
|
||
}
|
||
parm.no_wait = 0;//同步方式
|
||
parm.cb = eq_get_filter_info;
|
||
parm.sr = sample_rate;
|
||
parm.eq_name = eq_name;
|
||
|
||
u8 index = get_eq_module_index(eq_name);
|
||
log_d("index %d\n", index);
|
||
parm.max_nsection = eff_mode[mode].eq_parm[index].seg_num;
|
||
parm.nsection = eff_mode[mode].eq_parm[index].seg_num;
|
||
parm.seg = eff_mode[mode].eq_parm[index].seg;
|
||
parm.global_gain = eff_mode[mode].eq_parm[index].global_gain;
|
||
log_d("=====mic eq_name %d\n", eq_name);
|
||
struct audio_eq *eq = audio_dec_eq_open(&parm);
|
||
return eq;
|
||
|
||
#else
|
||
return NULL;
|
||
#endif//TCFG_EQ_ENABLE
|
||
}
|
||
|
||
void *mic_drc_open(u32 sample_rate, u8 ch_num, u8 drc_name, u8 _32bit)
|
||
{
|
||
#if TCFG_DRC_ENABLE
|
||
u8 mode = get_mic_eff_mode();
|
||
log_i("sample_rate %d %d\n", sample_rate, ch_num);
|
||
struct audio_drc_param parm = {0};
|
||
parm.channels = ch_num;
|
||
parm.sr = sample_rate;
|
||
parm.out_32bit = _32bit;
|
||
parm.cb = drc_get_filter_info;
|
||
parm.drc_name = drc_name;
|
||
u8 index = get_drc_module_index(drc_name);
|
||
parm.wdrc = &eff_mode[mode].drc_parm[index];
|
||
log_d("=====drc_name %d\n", drc_name);
|
||
struct audio_drc *drc = audio_dec_drc_open(&parm);
|
||
clock_add(EQ_CLK);
|
||
return drc;
|
||
#else
|
||
return NULL;
|
||
#endif//TCFG_DRC_ENABLE
|
||
|
||
}
|
||
|
||
void mic_eq_close(void *eq)
|
||
{
|
||
#if TCFG_EQ_ENABLE
|
||
if (eq) {
|
||
audio_dec_eq_close(eq);
|
||
clock_remove(EQ_CLK);
|
||
}
|
||
#endif
|
||
return;
|
||
}
|
||
|
||
void mic_drc_close(void *drc)
|
||
{
|
||
#if TCFG_DRC_ENABLE
|
||
if (drc) {
|
||
audio_dec_drc_close(drc);
|
||
drc = NULL;
|
||
clock_remove(EQ_CLK);
|
||
}
|
||
#endif
|
||
return;
|
||
}
|
||
|
||
#if TCFG_EQ_ENABLE && TCFG_MIC_TUNNING_EQ_ENABLE
|
||
struct eq_seg_info mic_high_bass_eq_seg[] = {
|
||
{0, EQ_IIR_TYPE_BAND_PASS, 100, 0, 0.7f},
|
||
{1, EQ_IIR_TYPE_BAND_PASS, 1000, 0, 0.7f},
|
||
};
|
||
|
||
struct eq_tool mic_tunning_eq_parm = {0};
|
||
/*
|
||
*混响mic tunning_eq 打开
|
||
* */
|
||
void *mic_tunning_eq_open(u32 sample_rate, u8 ch_num)
|
||
{
|
||
u8 seg_num = ARRAY_SIZE(mic_high_bass_eq_seg);
|
||
mic_tunning_eq_parm.seg_num = seg_num;
|
||
mic_tunning_eq_parm.global_gain = 0;
|
||
memcpy(&mic_tunning_eq_parm.seg, mic_high_bass_eq_seg, sizeof(mic_high_bass_eq_seg));
|
||
|
||
struct audio_eq_param parm = {0};
|
||
parm.channels = ch_num;
|
||
parm.cb = eq_get_filter_info;
|
||
parm.sr = sample_rate;
|
||
parm.eq_name = AEID_MIC_TUNNING_EQ;
|
||
parm.max_nsection = mic_tunning_eq_parm.seg_num;
|
||
parm.nsection = mic_tunning_eq_parm.seg_num;
|
||
parm.seg = mic_tunning_eq_parm.seg;
|
||
parm.global_gain = mic_tunning_eq_parm.global_gain;
|
||
|
||
parm.fade = 1;//高低音增益更新差异大,会引入哒哒音,此处使能系数淡入
|
||
parm.fade_step = 0.4f;//淡入步进(0.1f~1.0f)
|
||
|
||
log_d("=====mic tunning eq_name %d\n", parm.eq_name);
|
||
struct audio_eq *eq = audio_dec_eq_open(&parm);
|
||
return eq;
|
||
}
|
||
|
||
|
||
/*
|
||
*混响mic tunning_eq 关闭
|
||
* */
|
||
void mic_tunning_eq_close(void *eq)
|
||
{
|
||
if (eq) {
|
||
audio_dec_eq_close(eq);
|
||
}
|
||
}
|
||
|
||
|
||
/*
|
||
*index:0 low, 1 high
|
||
*gain:增益(-12~0)dB
|
||
* */
|
||
void mic_tunning_eq_update(u8 index, float gain)
|
||
{
|
||
if (gain > 0) {
|
||
gain = 0;
|
||
} else if (gain < -12) {
|
||
gain = -12;
|
||
}
|
||
mic_tunning_eq_parm.seg[index].gain = gain;
|
||
/* log_d("mic tunning eq index %d, %d\n", index, (int)gain); */
|
||
struct audio_eq *hdl = get_cur_eq_hdl_by_name(AEID_MIC_TUNNING_EQ);
|
||
if (hdl) {
|
||
cur_eq_set_update(AEID_MIC_TUNNING_EQ, &mic_tunning_eq_parm.seg[index], mic_tunning_eq_parm.seg_num, 1);
|
||
}
|
||
|
||
}
|
||
/*
|
||
*混响切换模式时更新高低音参数
|
||
*/
|
||
void mic_tunning_eq_update_parm(u8 mode)
|
||
{
|
||
#if 0
|
||
u8 seg_num = ARRAY_SIZE(mic_high_bass_eq_seg);
|
||
struct audio_eq *hdl = get_cur_eq_hdl_by_name(AEID_MIC_TUNNING_EQ);
|
||
for (int i = 0; i < seg_num; i++) {
|
||
if (hdl) {
|
||
cur_eq_set_update(AEID_MIC_TUNNING_EQ, &mic_tunning_eq_parm.seg[i], mic_tunning_eq_parm.seg_num, 1);
|
||
}
|
||
}
|
||
#endif
|
||
}
|
||
#endif/*TCFG_EQ_ENABLE && TCFG_MIC_TUNNING_EQ_ENABLE*/
|
||
|
||
|
||
#if TCFG_MIC_DODGE_EN
|
||
void mic_e_det_handler(u8 event, u8 ch)
|
||
{
|
||
//printf(">>>> ch:%d %s\n", ch, event ? ("MUTE") : ("UNMUTE"));
|
||
struct __mic_effect *effect = (struct __mic_effect *)__this;
|
||
#if SYS_DIGVOL_GROUP_EN
|
||
//printf("effect_dvol_default_parm.ch_total %d effect->dodge_en %d\n", effect_dvol_default_parm.ch_total, effect->dodge_en);
|
||
if (ch == effect_dvol_default_parm.ch_total) {
|
||
if (effect->dodge_en) {
|
||
if (effect && effect->d_vol) {
|
||
if (event) { //推出闪避
|
||
audio_dig_vol_group_dodge(sys_digvol_group, "mic_mic", 100, 100);
|
||
} else { //启动闪避
|
||
audio_dig_vol_group_dodge(sys_digvol_group, "mic_mic", 100, 0);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
#endif
|
||
}
|
||
/*----------------------------------------------------------------------------*/
|
||
/**@brief 打开mic 能量检测
|
||
@param
|
||
@return
|
||
@note
|
||
*/
|
||
/*----------------------------------------------------------------------------*/
|
||
void *mic_energy_detect_open(u32 sr, u8 ch_num)
|
||
{
|
||
audio_energy_detect_param e_det_param = {0};
|
||
e_det_param.mute_energy = dodge_parm.dodge_out_thread;//人声能量小于mute_energy 退出闪避
|
||
e_det_param.unmute_energy = dodge_parm.dodge_in_thread;//人声能量大于 100触发闪避
|
||
e_det_param.mute_time_ms = dodge_parm.dodge_out_time_ms;
|
||
e_det_param.unmute_time_ms = dodge_parm.dodge_in_time_ms;
|
||
e_det_param.count_cycle_ms = 2;
|
||
e_det_param.sample_rate = sr;
|
||
e_det_param.event_handler = mic_e_det_handler;
|
||
e_det_param.ch_total = ch_num;
|
||
e_det_param.dcc = 1;
|
||
void *audio_e_det_hdl = audio_energy_detect_open(&e_det_param);
|
||
return audio_e_det_hdl;
|
||
}
|
||
/*----------------------------------------------------------------------------*/
|
||
/**@brief 关闭mic 能量检测
|
||
@param
|
||
@return
|
||
@note
|
||
*/
|
||
/*----------------------------------------------------------------------------*/
|
||
void mic_energy_detect_close(void *hdl)
|
||
{
|
||
if (hdl) {
|
||
audio_stream_del_entry(audio_energy_detect_entry_get(hdl));
|
||
#if SYS_DIGVOL_GROUP_EN
|
||
struct __mic_effect *effect = (struct __mic_effect *)__this;
|
||
if (effect->d_vol) {
|
||
audio_dig_vol_group_dodge(sys_digvol_group, "mic_mic", 100, 100); // undodge
|
||
}
|
||
#endif
|
||
|
||
audio_energy_detect_close(hdl);
|
||
}
|
||
}
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/**@brief 能量检测运行过程,是否触发闪避
|
||
@param
|
||
@return
|
||
@note
|
||
*/
|
||
/*----------------------------------------------------------------------------*/
|
||
void mic_dodge_ctr(void)
|
||
{
|
||
struct __mic_effect *effect = (struct __mic_effect *)__this;
|
||
if (effect) {
|
||
effect->dodge_en = !effect->dodge_en;
|
||
}
|
||
}
|
||
u8 mic_dodge_get_status(void)
|
||
{
|
||
struct __mic_effect *effect = (struct __mic_effect *)__this;
|
||
if (effect) {
|
||
return effect->dodge_en;
|
||
}
|
||
return 0;
|
||
}
|
||
#endif
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/**@brief (mic数据流)混响关闭接口
|
||
@param
|
||
@return
|
||
@note
|
||
*/
|
||
/*----------------------------------------------------------------------------*/
|
||
void mic_effect_stop(void)
|
||
{
|
||
mic_effect_destroy(&__this);
|
||
}
|
||
/*----------------------------------------------------------------------------*/
|
||
/**@brief (mic数据流)混响暂停接口(整个数据流不运行)
|
||
@param
|
||
@return
|
||
@note
|
||
*/
|
||
/*----------------------------------------------------------------------------*/
|
||
void mic_effect_pause(u8 mark)
|
||
{
|
||
if (__this) {
|
||
__this->pause_mark = mark ? 1 : 0;
|
||
}
|
||
}
|
||
/*----------------------------------------------------------------------------*/
|
||
/**@brief (mic数据流)混响暂停输出到DAC(数据流后级不写入DAC)
|
||
@param
|
||
@return
|
||
@note
|
||
*/
|
||
/*----------------------------------------------------------------------------*/
|
||
void mic_effect_dac_pause(u8 mark)
|
||
{
|
||
if (__this && __this->dac) {
|
||
audio_dac_channel_set_pause(__this->dac, mark);
|
||
}
|
||
}
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/**@brief (mic数据流)混响状态获取接口
|
||
@param
|
||
@return
|
||
@note
|
||
*/
|
||
/*----------------------------------------------------------------------------*/
|
||
u8 mic_effect_get_status(void)
|
||
{
|
||
return ((__this) ? 1 : 0);
|
||
}
|
||
/*----------------------------------------------------------------------------*/
|
||
/**@brief 数字音量调节接口
|
||
@param
|
||
@return
|
||
@note
|
||
*/
|
||
/*----------------------------------------------------------------------------*/
|
||
void mic_effect_set_dvol(u8 vol)
|
||
{
|
||
if (__this && __this->d_vol) {
|
||
audio_dig_vol_set(__this->d_vol, 3, vol);
|
||
}
|
||
}
|
||
u8 mic_effect_get_dvol(void)
|
||
{
|
||
if (__this && __this->d_vol) {
|
||
return audio_dig_vol_get(__this->d_vol, 1);
|
||
}
|
||
return 0;
|
||
}
|
||
/*----------------------------------------------------------------------------*/
|
||
/**@brief 获取mic增益接口
|
||
@param
|
||
@return
|
||
@note
|
||
*/
|
||
/*----------------------------------------------------------------------------*/
|
||
u8 mic_effect_get_micgain(void)
|
||
{
|
||
//动态调的需实时记录
|
||
return effect_mic_stream_parm_default.mic_gain;
|
||
}
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/**@brief reverb 效果声增益调节接口
|
||
@param wet增益系数%[0,300];dry增益系数%[0,200]
|
||
@return
|
||
@note
|
||
*/
|
||
/*----------------------------------------------------------------------------*/
|
||
void mic_effect_set_reverb_wet(int wet)
|
||
{
|
||
if (__this == NULL || __this->sub_0_plate_reverb_hdl == NULL) {
|
||
return ;
|
||
}
|
||
os_mutex_pend(&__this->mutex, 0);
|
||
Plate_reverb_parm parm;
|
||
memcpy(&parm, & __this->sub_0_plate_reverb_hdl->reverb_parm_obj, sizeof(Plate_reverb_parm));
|
||
parm.wet = wet;
|
||
update_plate_reverb_parm(__this->sub_0_plate_reverb_hdl, &parm);
|
||
os_mutex_post(&__this->mutex);
|
||
}
|
||
|
||
int mic_effect_get_reverb_wet(void)
|
||
{
|
||
if (__this && __this->sub_0_plate_reverb_hdl) {
|
||
return __this->sub_0_plate_reverb_hdl->reverb_parm_obj.wet;
|
||
}
|
||
return 0;
|
||
}
|
||
void mic_effect_set_reverb_dry(int dry)
|
||
{
|
||
if (__this == NULL || __this->sub_0_plate_reverb_hdl == NULL) {
|
||
return ;
|
||
}
|
||
os_mutex_pend(&__this->mutex, 0);
|
||
Plate_reverb_parm parm;
|
||
memcpy(&parm, & __this->sub_0_plate_reverb_hdl->reverb_parm_obj, sizeof(Plate_reverb_parm));
|
||
parm.dry = dry;
|
||
update_plate_reverb_parm(__this->sub_0_plate_reverb_hdl, &parm);
|
||
os_mutex_post(&__this->mutex);
|
||
}
|
||
|
||
int mic_effect_get_reverb_dry(void)
|
||
{
|
||
if (__this && __this->sub_0_plate_reverb_hdl) {
|
||
return __this->sub_0_plate_reverb_hdl->reverb_parm_obj.dry;
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/**@brief echo 回声延时调节接口
|
||
@param delay 回声延时[0,max_ms]
|
||
@return
|
||
@note
|
||
*/
|
||
/*----------------------------------------------------------------------------*/
|
||
void mic_effect_set_echo_delay(u32 delay)
|
||
{
|
||
if (__this == NULL || __this->sub_1_echo_hdl == NULL) {
|
||
return ;
|
||
}
|
||
os_mutex_pend(&__this->mutex, 0);
|
||
ECHO_PARM_SET parm;
|
||
memcpy(&parm, &__this->sub_1_echo_hdl->echo_parm_obj, sizeof(ECHO_PARM_SET));
|
||
parm.delay = delay;
|
||
update_echo_parm(__this->sub_1_echo_hdl, &parm);
|
||
os_mutex_post(&__this->mutex);
|
||
}
|
||
u32 mic_effect_get_echo_delay(void)
|
||
{
|
||
if (__this && __this->sub_1_echo_hdl) {
|
||
return __this->sub_1_echo_hdl->echo_parm_obj.delay;
|
||
}
|
||
return 0;
|
||
}
|
||
/*----------------------------------------------------------------------------*/
|
||
/**@brief echo 回声衰减系数调节接口
|
||
@param decay 衰减系数值%[0,90]
|
||
@return
|
||
@note
|
||
*/
|
||
/*----------------------------------------------------------------------------*/
|
||
void mic_effect_set_echo_decay(u32 decay)
|
||
{
|
||
if (__this == NULL || __this->sub_1_echo_hdl == NULL) {
|
||
return ;
|
||
}
|
||
os_mutex_pend(&__this->mutex, 0);
|
||
ECHO_PARM_SET parm;
|
||
memcpy(&parm, &__this->sub_1_echo_hdl->echo_parm_obj, sizeof(ECHO_PARM_SET));
|
||
parm.decayval = decay;
|
||
update_echo_parm(__this->sub_1_echo_hdl, &parm);
|
||
os_mutex_post(&__this->mutex);
|
||
}
|
||
|
||
u32 mic_effect_get_echo_decay(void)
|
||
{
|
||
if (__this && __this->sub_1_echo_hdl) {
|
||
return __this->sub_1_echo_hdl->echo_parm_obj.decayval;
|
||
}
|
||
return 0;
|
||
}
|
||
/*----------------------------------------------------------------------------*/
|
||
/**@brief echo 回声wetgain调节接口
|
||
@param wetgain 湿声增益系数%[0,200]
|
||
@return
|
||
@note
|
||
*/
|
||
/*----------------------------------------------------------------------------*/
|
||
void mic_effect_set_echo_wetgain(u32 wetgain)
|
||
{
|
||
if (__this == NULL || __this->sub_1_echo_hdl == NULL) {
|
||
return ;
|
||
}
|
||
os_mutex_pend(&__this->mutex, 0);
|
||
ECHO_PARM_SET parm;
|
||
memcpy(&parm, &__this->sub_1_echo_hdl->echo_parm_obj, sizeof(ECHO_PARM_SET));
|
||
parm.wetgain = wetgain;
|
||
update_echo_parm(__this->sub_1_echo_hdl, &parm);
|
||
os_mutex_post(&__this->mutex);
|
||
}
|
||
|
||
u32 mic_effect_get_echo_wetgain(void)
|
||
{
|
||
if (__this && __this->sub_1_echo_hdl) {
|
||
return __this->sub_1_echo_hdl->echo_parm_obj.wetgain;
|
||
}
|
||
return 0;
|
||
}
|
||
/*----------------------------------------------------------------------------*/
|
||
/**@brief echo 回声drygain调节接口
|
||
@param 干声增益系数%[0,100]
|
||
@return
|
||
@note
|
||
*/
|
||
/*----------------------------------------------------------------------------*/
|
||
void mic_effect_set_echo_drygain(u32 drygain)
|
||
{
|
||
if (__this == NULL || __this->sub_1_echo_hdl == NULL) {
|
||
return ;
|
||
}
|
||
os_mutex_pend(&__this->mutex, 0);
|
||
ECHO_PARM_SET parm;
|
||
memcpy(&parm, &__this->sub_1_echo_hdl->echo_parm_obj, sizeof(ECHO_PARM_SET));
|
||
parm.drygain = drygain;
|
||
update_echo_parm(__this->sub_1_echo_hdl, &parm);
|
||
os_mutex_post(&__this->mutex);
|
||
}
|
||
|
||
u32 mic_effect_get_echo_drygain(void)
|
||
{
|
||
if (__this && __this->sub_1_echo_hdl) {
|
||
return __this->sub_1_echo_hdl->echo_parm_obj.drygain;
|
||
}
|
||
return 0;
|
||
}
|
||
//*********************变声音效切换例程**********************************//
|
||
|
||
/* VOICE_CHANGER_NONE,//原声 */
|
||
/* VOICE_CHANGER_UNCLE,//大叔 */
|
||
/* VOICE_CHANGER_GODDESS,//女神 */
|
||
/* VOICE_CHANGER_BABY,//娃娃音 */
|
||
/* VOICE_CHANGER_MAGIC,//魔音女声 */
|
||
/* VOICE_CHANGER_MONSTER,//怪兽音 */
|
||
/* VOICE_CHANGER_DONALD_DUCK,//唐老鸭 */
|
||
/* VOICE_CHANGER_MINIONS,//小黄人 */
|
||
/* VOICE_CHANGER_ROBOT,//机器音 */
|
||
/* VOICE_CHANGER_WHISPER,//气音 */
|
||
/* VOICE_CHANGER_MELODY,//固定旋律音 */
|
||
/* VOICE_CHANGER_FEEDBACK,//调制音 */
|
||
|
||
|
||
|
||
VOICECHANGER_PARM parm = {
|
||
.shiftv = 100,//[50-200];越尖锐,越大声音越沉;100就是原声
|
||
.formant_shift = 100,
|
||
.effect_v = EFFECT_VOICECHANGE_PITCHSHIFT,
|
||
};
|
||
/*----------------------------------------------------------------------------*/
|
||
/**@brief 变声音调重置为原声音调
|
||
@param NULL
|
||
@return
|
||
@note
|
||
*/
|
||
/*----------------------------------------------------------------------------*/
|
||
void mic_pitchv_reset_parm(void)
|
||
{
|
||
#if defined(TCFG_MIC_VOICE_CHANGER_ENABLE) && TCFG_MIC_VOICE_CHANGER_ENABLE
|
||
parm.shiftv = 100;
|
||
audio_voice_changer_update_parm(AEID_MIC_VOICE_CHANGER, &parm);
|
||
#endif
|
||
}
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/**@brief 变声音调递增
|
||
@param NULL
|
||
@return
|
||
@note
|
||
*/
|
||
/*----------------------------------------------------------------------------*/
|
||
void mic_pitchv_up(void)
|
||
{
|
||
#if defined(TCFG_MIC_VOICE_CHANGER_ENABLE) && TCFG_MIC_VOICE_CHANGER_ENABLE
|
||
if (parm.shiftv < 190) {
|
||
parm.shiftv += 10;
|
||
audio_voice_changer_update_parm(AEID_MIC_VOICE_CHANGER, &parm);
|
||
}
|
||
#endif
|
||
}
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/**@brief 变声音调递减
|
||
@param NULL
|
||
@return
|
||
@note
|
||
*/
|
||
/*----------------------------------------------------------------------------*/
|
||
void mic_pitchv_down(void)
|
||
{
|
||
#if defined(TCFG_MIC_VOICE_CHANGER_ENABLE) && TCFG_MIC_VOICE_CHANGER_ENABLE
|
||
if (parm.shiftv > 60) {
|
||
parm.shiftv -= 10;
|
||
audio_voice_changer_update_parm(AEID_MIC_VOICE_CHANGER, &parm);
|
||
}
|
||
#endif
|
||
}
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/**@brief 变声音效循环切换
|
||
@param NULL
|
||
@return
|
||
@note
|
||
*/
|
||
/*----------------------------------------------------------------------------*/
|
||
void mic_voicechange_loop(void)
|
||
{
|
||
voicechange_mode++;
|
||
if (voicechange_mode >= VOICE_CHANGER_MAX) {
|
||
voicechange_mode = VOICE_CHANGER_NONE;
|
||
}
|
||
mic_voicechange_switch(voicechange_mode);
|
||
}
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/**@brief 变声音效指定模式切换
|
||
@param eff_mode 模式索引
|
||
@return
|
||
@note
|
||
*/
|
||
/*----------------------------------------------------------------------------*/
|
||
void mic_voicechange_switch(u8 eff_mode)
|
||
{
|
||
#if defined(TCFG_MIC_VOICE_CHANGER_ENABLE) && TCFG_MIC_VOICE_CHANGER_ENABLE
|
||
if (!mic_effect_get_status()) {
|
||
mic_effect_start();
|
||
/* return; */
|
||
}
|
||
switch (eff_mode) {
|
||
case VOICE_CHANGER_NONE://原声,录音棚
|
||
/* tone_play_index(IDEX_TONE_MIC_OST, 1); */
|
||
break;
|
||
case VOICE_CHANGER_UNCLE://大叔
|
||
/* tone_play_index(IDEX_TONE_UNCLE, 1); */
|
||
break;
|
||
case VOICE_CHANGER_GODDESS://女神
|
||
/* tone_play_index(IDEX_TONE_GODNESS, 1); */
|
||
break;
|
||
case VOICE_CHANGER_BABY://娃娃音
|
||
/* tone_play_index(IDEX_TONE_BABY, 1); */
|
||
break;
|
||
case VOICE_CHANGER_MAGIC://魔音女声
|
||
/* tone_play_index(IDEX_TONE_BABY, 1); */
|
||
break;
|
||
case VOICE_CHANGER_MONSTER://怪兽音
|
||
/* tone_play_index(IDEX_TONE_BABY, 1); */
|
||
break;
|
||
case VOICE_CHANGER_DONALD_DUCK://唐老鸭
|
||
/* tone_play_index(IDEX_TONE_BABY, 1); */
|
||
break;
|
||
case VOICE_CHANGER_MINIONS://小黄人
|
||
/* tone_play_index(IDEX_TONE_BABY, 1); */
|
||
break;
|
||
case VOICE_CHANGER_ROBOT://机器音
|
||
/* tone_play_index(IDEX_TONE_BABY, 1); */
|
||
break;
|
||
case VOICE_CHANGER_WHISPER://气音
|
||
/* tone_play_index(IDEX_TONE_BABY, 1); */
|
||
break;
|
||
case VOICE_CHANGER_MELODY://固定旋律音
|
||
/* tone_play_index(IDEX_TONE_BABY, 1); */
|
||
break;
|
||
case VOICE_CHANGER_FEEDBACK://调制音
|
||
/* tone_play_index(IDEX_TONE_BABY, 1); */
|
||
break;
|
||
default:
|
||
puts("mic_ERROR\n");
|
||
/* mic_effect_stop(); */
|
||
break;
|
||
}
|
||
audio_voice_changer_mode_switch(AEID_MIC_VOICE_CHANGER, eff_mode);
|
||
#endif//TCFG_MIC_VOICE_CHANGER_ENABLE
|
||
}
|
||
|
||
/**************************各个音效模块参数设置接口(调试工具/模式切换会使用勿修改)************************************/
|
||
void plate_reverb_update_parm(void *parm, int bypass)
|
||
{
|
||
if (__this && __this->sub_0_plate_reverb_hdl) {
|
||
update_plate_reverb_parm(__this->sub_0_plate_reverb_hdl, parm);
|
||
plate_reverb_update_bypass(__this->sub_0_plate_reverb_hdl, bypass);
|
||
}
|
||
}
|
||
|
||
void echo_updata_parm(void *parm, int bypass)
|
||
{
|
||
if (__this && __this->sub_1_echo_hdl) {
|
||
update_echo_parm(__this->sub_1_echo_hdl, parm);
|
||
echo_update_bypass(__this->sub_1_echo_hdl, bypass);
|
||
}
|
||
}
|
||
|
||
void noisegate_update_parm(void *parm, int bypass)
|
||
{
|
||
audio_noisegate_update(AEID_MIC_NS_GATE, parm);
|
||
audio_noisegate_bypass(AEID_MIC_NS_GATE, bypass);
|
||
}
|
||
|
||
void howling_pitch_shift_update_parm(void *parm, int bypass)
|
||
{
|
||
if (__this && __this->howling_ps) {
|
||
update_howling_parm(__this->howling_ps, parm);
|
||
howling_update_bypass(__this->howling_ps, bypass);
|
||
}
|
||
}
|
||
|
||
void notchhowline_update_parm(void *parm, int bypass)
|
||
{
|
||
if (__this && __this->notch_howling) {
|
||
update_howling_parm(__this->notch_howling, parm);
|
||
howling_update_bypass(__this->notch_howling, bypass);
|
||
}
|
||
|
||
}
|
||
|
||
/**************************各个音效模块参数设置接口 END************************************/
|
||
#endif
|