537 lines
15 KiB
C
537 lines
15 KiB
C
|
#include "system/includes.h"
|
|||
|
#include "media/includes.h"
|
|||
|
#include "app_config.h"
|
|||
|
#include "app_online_cfg.h"
|
|||
|
/* #include "audio_drc.h" */
|
|||
|
/* #include "audio_reverb.h" */
|
|||
|
#include "clock_cfg.h"
|
|||
|
#include "audio_config.h"
|
|||
|
#include "storage_dev/storage_dev.h"
|
|||
|
#include "loud_speaker.h"
|
|||
|
#include "audio_dec.h"
|
|||
|
#include "audio_enc.h"
|
|||
|
#include "media/pcm_decoder.h"
|
|||
|
#include "media/audio_howling.h"
|
|||
|
#include "media/audio_voice_changer.h"
|
|||
|
#include "media/audio_echo_reverb.h"
|
|||
|
#define LOG_TAG "[APP-SPEAKER]"
|
|||
|
#define LOG_ERROR_ENABLE
|
|||
|
#define LOG_INFO_ENABLE
|
|||
|
#define LOG_DUMP_ENABLE
|
|||
|
#include "debug.h"
|
|||
|
|
|||
|
#define ECHO_ENABLE 0 //K歌混响
|
|||
|
#define HOWLING_ENABLE 0 //啸叫抑制
|
|||
|
#define PITCH_ENABLE 0 //变声
|
|||
|
|
|||
|
// mic 采样率 若存在与mic录音/usb mic 等同开情况 需保证采样率一致
|
|||
|
#define LOUND_SPEAKER_MIC_SAMPLE_RATE 44100
|
|||
|
|
|||
|
|
|||
|
//简易版扩音器功能 使用解码数据流程把mic数据接入mix,能把数据输出到DAC/FM/IIS等 (mic_effect.c里面的混响只能输出到DAC)
|
|||
|
// 可用于mic to dac的测试 /mic混响数据到fm/iis输出功能
|
|||
|
//
|
|||
|
#if 0
|
|||
|
|
|||
|
extern struct audio_adc_hdl adc_hdl;
|
|||
|
extern struct audio_decoder_task decode_task;
|
|||
|
extern struct audio_mixer mixer;
|
|||
|
|
|||
|
#define PCM_BUF_LEN (2*1024)
|
|||
|
enum {
|
|||
|
REVERB_STATUS_STOP = 0,
|
|||
|
REVERB_STATUS_START,
|
|||
|
REVERB_STATUS_PAUSE,
|
|||
|
};
|
|||
|
|
|||
|
struct s_speaker_hdl {
|
|||
|
struct audio_adc_output_hdl adc_output;
|
|||
|
struct adc_mic_ch mic_ch;
|
|||
|
|
|||
|
u32 process_len;
|
|||
|
struct audio_stream *stream; // 音频流
|
|||
|
int mic_gain;
|
|||
|
u16 mic_sr;
|
|||
|
u16 src_out_sr;
|
|||
|
u16 src_out_sr_n;
|
|||
|
int begin_size;
|
|||
|
int top_size;
|
|||
|
int bottom_size;
|
|||
|
u16 audio_new_rate;
|
|||
|
u16 audio_max_speed;
|
|||
|
u16 audio_min_speed;
|
|||
|
u8 sync_start;
|
|||
|
u8 pcm_buf[PCM_BUF_LEN ];
|
|||
|
cbuffer_t pcm_cbuf;
|
|||
|
u32 status : 2;
|
|||
|
u32 source_ch_num : 2;
|
|||
|
u32 reverb_en : 2;
|
|||
|
u32 howling_en : 2;
|
|||
|
u8 first_start;
|
|||
|
u8 speaker_pause;
|
|||
|
/* struct audio_decoder decoder; */
|
|||
|
struct audio_res_wait wait;
|
|||
|
struct audio_mixer_ch mix_ch;
|
|||
|
struct pcm_decoder pcm_dec; // pcm解码句柄
|
|||
|
|
|||
|
#if ECHO_ENABLE
|
|||
|
ECHO_API_STRUCT *p_echo_hdl;
|
|||
|
#endif
|
|||
|
#if HOWLING_ENABLE
|
|||
|
HOWLING_API_STRUCT *p_howling_hdl;
|
|||
|
#endif
|
|||
|
#if PITCH_ENABLE
|
|||
|
s_pitch_hdl *p_pitch_hdl;
|
|||
|
#endif
|
|||
|
struct channel_switch *channel_zoom;
|
|||
|
};
|
|||
|
static struct s_speaker_hdl *speaker_hdl = NULL;
|
|||
|
static u8 pcm_dec_maigc = 0;
|
|||
|
|
|||
|
//echo 参数
|
|||
|
EF_REVERB_FIX_PARM effect_echo_fix_parm = {
|
|||
|
.wetgain = 2048, ////湿声增益:[0:4096]
|
|||
|
.drygain = 4096, ////干声增益: [0:4096]
|
|||
|
.sr = LOUND_SPEAKER_MIC_SAMPLE_RATE, ////采样率
|
|||
|
.max_ms = 200, ////所需要的最大延时,影响 need_buf 大小
|
|||
|
|
|||
|
};
|
|||
|
|
|||
|
ECHO_PARM_SET effect_echo_parm = {
|
|||
|
.delay = 200, //回声的延时时间 0-300ms
|
|||
|
.decayval = 50, // 0-70%
|
|||
|
.direct_sound_enable = 1, //直达声使能 0/1
|
|||
|
.filt_enable = 0, //发散滤波器使能
|
|||
|
};
|
|||
|
|
|||
|
static void adc_output_to_buf(void *priv, s16 *data, int len)
|
|||
|
{
|
|||
|
if ((!speaker_hdl) || (speaker_hdl->status != REVERB_STATUS_START)) {
|
|||
|
return;
|
|||
|
}
|
|||
|
if (speaker_hdl->speaker_pause) {
|
|||
|
return;
|
|||
|
}
|
|||
|
int wlen = cbuf_write(&speaker_hdl->pcm_cbuf, data, len);
|
|||
|
if (!wlen) {
|
|||
|
putchar('W');
|
|||
|
}
|
|||
|
audio_decoder_resume(&speaker_hdl->pcm_dec.decoder);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
static void pcm_dec_relaese()
|
|||
|
{
|
|||
|
audio_decoder_task_del_wait(&decode_task, &speaker_hdl->wait);
|
|||
|
}
|
|||
|
|
|||
|
static void pcm_dec_close(void)
|
|||
|
{
|
|||
|
audio_decoder_close(&speaker_hdl->pcm_dec.decoder);
|
|||
|
audio_mixer_ch_close(&speaker_hdl->mix_ch);
|
|||
|
if (speaker_hdl->stream) {
|
|||
|
audio_stream_close(speaker_hdl->stream);
|
|||
|
speaker_hdl->stream = NULL;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
static int pcm_fread(void *hdl, void *buf, int len)
|
|||
|
{
|
|||
|
struct s_speaker_hdl *dec = (struct s_speaker_hdl *)hdl;
|
|||
|
int rlen = cbuf_read(&dec->pcm_cbuf, buf, len);
|
|||
|
/* printf("rlen %d",rlen); */
|
|||
|
return rlen;
|
|||
|
}
|
|||
|
|
|||
|
static void pcm_dec_event_handler(struct audio_decoder *decoder, int argc, int *argv)
|
|||
|
{
|
|||
|
switch (argv[0]) {
|
|||
|
case AUDIO_DEC_EVENT_END:
|
|||
|
if ((u8)argv[1] != (u8)(pcm_dec_maigc - 1)) {
|
|||
|
log_i("maigc err, %s\n", __FUNCTION__);
|
|||
|
break;
|
|||
|
}
|
|||
|
/* pcm_dec_close(); */
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/*----------------------------------------------------------------------------*/
|
|||
|
/**@brief pcm解码数据输出
|
|||
|
@param *entry: 音频流句柄
|
|||
|
@param *in: 输入信息
|
|||
|
@param *out: 输出信息
|
|||
|
@return 输出长度
|
|||
|
@note *out未使用
|
|||
|
*/
|
|||
|
/*----------------------------------------------------------------------------*/
|
|||
|
static int pcm_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 s_speaker_hdl *dec = container_of(pcm_dec, struct s_speaker_hdl, pcm_dec);
|
|||
|
audio_stream_run(&decoder->entry, in);
|
|||
|
return decoder->process_len;
|
|||
|
}
|
|||
|
/*----------------------------------------------------------------------------*/
|
|||
|
/**@brief pcm解码数据流激活
|
|||
|
@param *p: 私有句柄
|
|||
|
@return
|
|||
|
@note
|
|||
|
*/
|
|||
|
/*----------------------------------------------------------------------------*/
|
|||
|
static void dec_out_stream_resume(void *p)
|
|||
|
{
|
|||
|
struct s_speaker_hdl *dec = (struct s_speaker_hdl *)p;
|
|||
|
|
|||
|
audio_decoder_resume(&dec->pcm_dec.decoder);
|
|||
|
}
|
|||
|
|
|||
|
static int pcm_dec_start(void)
|
|||
|
{
|
|||
|
int err;
|
|||
|
struct audio_fmt f;
|
|||
|
struct s_speaker_hdl *dec = speaker_hdl;
|
|||
|
|
|||
|
log_i("\n--func=%s\n", __FUNCTION__);
|
|||
|
err = pcm_decoder_open(&dec->pcm_dec, &decode_task);
|
|||
|
if (err) {
|
|||
|
goto __err1;
|
|||
|
}
|
|||
|
|
|||
|
pcm_decoder_set_event_handler(&dec->pcm_dec, pcm_dec_event_handler, 0);
|
|||
|
pcm_decoder_set_read_data(&dec->pcm_dec, pcm_fread, dec);
|
|||
|
pcm_decoder_set_data_handler(&dec->pcm_dec, pcm_dec_data_handler);
|
|||
|
|
|||
|
audio_mixer_ch_open(&dec->mix_ch, &mixer);
|
|||
|
audio_mixer_ch_set_src(&dec->mix_ch, 1, 1);
|
|||
|
/* audio_mixer_ch_set_no_wait(&dec->mix_ch, 1, 10); // 超时自动丢数 */
|
|||
|
|
|||
|
|
|||
|
// 数据流串联
|
|||
|
struct audio_stream_entry *entries[8] = {NULL};
|
|||
|
u8 entry_cnt = 0;
|
|||
|
entries[entry_cnt++] = &dec->pcm_dec.decoder.entry;
|
|||
|
#if HOWLING_ENABLE
|
|||
|
entries[entry_cnt++] = &dec->p_howling_hdl->entry;
|
|||
|
#endif
|
|||
|
|
|||
|
#if ECHO_ENABLE
|
|||
|
entries[entry_cnt++] = &dec->p_echo_hdl->entry;
|
|||
|
#endif
|
|||
|
#if PITCH_ENABLE
|
|||
|
entries[entry_cnt++] = &dec->p_pitch_hdl->entry;
|
|||
|
//for test pitch
|
|||
|
loundspeaker_set_pitch_para(66, LOUND_SPEAKER_MIC_SAMPLE_RATE, EFFECT_VOICECHANGE_KIN0, 150);
|
|||
|
#endif
|
|||
|
if (dec->channel_zoom) {
|
|||
|
entries[entry_cnt++] = &dec->channel_zoom->entry;
|
|||
|
}
|
|||
|
|
|||
|
entries[entry_cnt++] = &dec->mix_ch.entry;
|
|||
|
dec->stream = audio_stream_open(dec, dec_out_stream_resume);
|
|||
|
audio_stream_add_list(dec->stream, entries, entry_cnt);
|
|||
|
|
|||
|
|
|||
|
audio_output_set_start_volume(APP_AUDIO_STATE_MUSIC);
|
|||
|
|
|||
|
/* audio_adc_mic_start(&dec->mic_ch); */
|
|||
|
log_i("\n\n audio decoder start \n");
|
|||
|
dec->status = REVERB_STATUS_START;
|
|||
|
err = audio_decoder_start(&dec->pcm_dec.decoder);
|
|||
|
if (err) {
|
|||
|
goto __err3;
|
|||
|
}
|
|||
|
log_i("\n\n audio mic start 1 \n");
|
|||
|
return 0;
|
|||
|
__err3:
|
|||
|
|
|||
|
dec->status = 0;
|
|||
|
audio_mic_close(&dec->mic_ch, &dec->adc_output);
|
|||
|
__err2:
|
|||
|
if (dec->stream) {
|
|||
|
audio_stream_close(dec->stream);
|
|||
|
dec->stream = NULL;
|
|||
|
}
|
|||
|
|
|||
|
pcm_decoder_close(&dec->pcm_dec);
|
|||
|
__err1:
|
|||
|
audio_decoder_task_del_wait(&decode_task, &dec->wait);
|
|||
|
return err;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
static int pcmdec_wait_res_handler(struct audio_res_wait *wait, int event)
|
|||
|
{
|
|||
|
int err = 0;
|
|||
|
if (!speaker_hdl) {
|
|||
|
log_e("speaker_hdl err \n");
|
|||
|
return -1;
|
|||
|
}
|
|||
|
log_i("pcmdec_wait_res_handler, event:%d;status:%d; \n", event, speaker_hdl->status);
|
|||
|
if (event == AUDIO_RES_GET) {
|
|||
|
if (speaker_hdl->status == REVERB_STATUS_STOP) {
|
|||
|
err = pcm_dec_start();
|
|||
|
} else if (speaker_hdl->status == REVERB_STATUS_PAUSE) {
|
|||
|
speaker_hdl->status = REVERB_STATUS_START;
|
|||
|
}
|
|||
|
} else if (event == AUDIO_RES_PUT) {
|
|||
|
if (speaker_hdl->status == REVERB_STATUS_START) {
|
|||
|
/* reverb_hdl->status = REVERB_STATUS_PAUSE; */
|
|||
|
}
|
|||
|
}
|
|||
|
return err;
|
|||
|
}
|
|||
|
//************************* MIC to DAC API *****************************//
|
|||
|
void stop_loud_speaker(void)
|
|||
|
{
|
|||
|
if (!speaker_hdl) {
|
|||
|
return;
|
|||
|
}
|
|||
|
log_i("\n--func=%s\n", __FUNCTION__);
|
|||
|
|
|||
|
speaker_hdl->status = REVERB_STATUS_STOP;
|
|||
|
|
|||
|
audio_mic_close(&speaker_hdl->mic_ch, &speaker_hdl->adc_output);
|
|||
|
pcm_dec_close();
|
|||
|
|
|||
|
#if ECHO_ENABLE
|
|||
|
close_echo(speaker_hdl->p_echo_hdl);
|
|||
|
#endif
|
|||
|
#if HOWLING_ENABLE
|
|||
|
close_howling(speaker_hdl->p_howling_hdl);
|
|||
|
#endif
|
|||
|
#if PITCH_ENABLE
|
|||
|
close_pitch(speaker_hdl->p_pitch_hdl);
|
|||
|
#endif
|
|||
|
if (speaker_hdl->channel_zoom) {
|
|||
|
channel_switch_close(&speaker_hdl->channel_zoom);
|
|||
|
}
|
|||
|
pcm_dec_relaese();
|
|||
|
|
|||
|
free(speaker_hdl);
|
|||
|
speaker_hdl = NULL;
|
|||
|
clock_remove_set(REVERB_CLK);
|
|||
|
}
|
|||
|
|
|||
|
void start_loud_speaker(struct audio_fmt *fmt)
|
|||
|
{
|
|||
|
struct s_speaker_hdl *reverb = NULL;
|
|||
|
int err;
|
|||
|
if (speaker_hdl) {
|
|||
|
stop_loud_speaker();
|
|||
|
}
|
|||
|
clock_add_set(REVERB_CLK);
|
|||
|
reverb = zalloc(sizeof(struct s_speaker_hdl));
|
|||
|
log_i("speaker hdl:%lu", sizeof(struct s_speaker_hdl));
|
|||
|
ASSERT(reverb);
|
|||
|
|
|||
|
struct audio_fmt f = {0};
|
|||
|
if (fmt) {
|
|||
|
f.sample_rate = fmt->sample_rate;
|
|||
|
}
|
|||
|
if (f.sample_rate == 0) {
|
|||
|
f.sample_rate = LOUND_SPEAKER_MIC_SAMPLE_RATE;
|
|||
|
}
|
|||
|
f.channel = 1;
|
|||
|
|
|||
|
reverb->source_ch_num = f.channel;
|
|||
|
reverb->mic_sr = f.sample_rate;
|
|||
|
reverb->mic_gain = 2;
|
|||
|
|
|||
|
|
|||
|
#if ECHO_ENABLE
|
|||
|
reverb->p_echo_hdl = open_echo(&effect_echo_parm, &effect_echo_fix_parm);
|
|||
|
ASSERT(reverb->p_echo_hdl);
|
|||
|
#endif
|
|||
|
#if HOWLING_ENABLE
|
|||
|
reverb->p_howling_hdl = open_howling(NULL, f.sample_rate, audio_output_channel_num(), 1);
|
|||
|
#endif
|
|||
|
|
|||
|
#if PITCH_ENABLE
|
|||
|
reverb->p_pitch_hdl = open_pitch(NULL);
|
|||
|
/* pause_pitch(reverb->p_pitch_hdl, 1); */
|
|||
|
#endif
|
|||
|
|
|||
|
if (audio_output_channel_num() != 1) {
|
|||
|
reverb->channel_zoom = channel_switch_open(audio_output_channel_type(), 1024);
|
|||
|
}
|
|||
|
#if 1
|
|||
|
cbuf_init(&reverb->pcm_cbuf, reverb->pcm_buf, sizeof(reverb->pcm_buf));
|
|||
|
if (audio_mic_open(&reverb->mic_ch, f.sample_rate, reverb->mic_gain) == 0) {
|
|||
|
reverb->adc_output.handler = adc_output_to_buf;
|
|||
|
audio_mic_add_output(&reverb->adc_output);
|
|||
|
audio_mic_start(&reverb->mic_ch);
|
|||
|
}
|
|||
|
#endif
|
|||
|
reverb->pcm_dec.ch_num = 1;
|
|||
|
reverb->pcm_dec.output_ch_num = 1;//audio_output_channel_num(); echo/pitch 只能处理单声道数据
|
|||
|
reverb->pcm_dec.output_ch_type = audio_output_channel_type();
|
|||
|
reverb->pcm_dec.sample_rate = reverb->mic_sr;
|
|||
|
|
|||
|
reverb->wait.priority = 0;
|
|||
|
reverb->wait.preemption = 0;
|
|||
|
reverb->wait.protect = 1;
|
|||
|
reverb->wait.handler = pcmdec_wait_res_handler;
|
|||
|
speaker_hdl = reverb;
|
|||
|
err = audio_decoder_task_add_wait(&decode_task, &reverb->wait);
|
|||
|
if (err == 0) {
|
|||
|
return ;
|
|||
|
}
|
|||
|
|
|||
|
log_e("audio decoder task add wait err \n");
|
|||
|
audio_mic_close(&reverb->mic_ch, &reverb->adc_output);
|
|||
|
|
|||
|
#if ECHO_ENABLE
|
|||
|
close_echo(reverb->p_echo_hdl);
|
|||
|
#endif
|
|||
|
#if HOWLING_ENABLE
|
|||
|
close_howling(reverb->p_howling_hdl);
|
|||
|
#endif
|
|||
|
#if PITCH_ENABLE
|
|||
|
close_pitch(reverb->p_pitch_hdl);
|
|||
|
#endif
|
|||
|
if (speaker_hdl->channel_zoom) {
|
|||
|
channel_switch_close(&speaker_hdl->channel_zoom);
|
|||
|
}
|
|||
|
clock_remove_set(REVERB_CLK);
|
|||
|
}
|
|||
|
/***************************************************************/
|
|||
|
int speaker_if_working(void)
|
|||
|
{
|
|||
|
if (speaker_hdl && (speaker_hdl->status == REVERB_STATUS_START)) {
|
|||
|
return 1;
|
|||
|
}
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
void loud_speaker_pause(void)
|
|||
|
{
|
|||
|
if (speaker_hdl) {
|
|||
|
speaker_hdl->speaker_pause = 1;
|
|||
|
audio_mixer_ch_pause(&speaker_hdl->mix_ch, 1);
|
|||
|
printf("speaker_pause [%d]", speaker_hdl->speaker_pause);
|
|||
|
}
|
|||
|
}
|
|||
|
void loud_speaker_resume(void)
|
|||
|
{
|
|||
|
if (speaker_hdl) {
|
|||
|
audio_mixer_ch_pause(&speaker_hdl->mix_ch, 0);
|
|||
|
speaker_hdl->speaker_pause = 0;
|
|||
|
printf("speaker_pause [%d]", speaker_hdl->speaker_pause);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/****************************效果设置接口***********************************/
|
|||
|
|
|||
|
void switch_holwing_en(void)
|
|||
|
{
|
|||
|
if (speaker_hdl) {
|
|||
|
speaker_hdl->howling_en ^= 1;
|
|||
|
#if HOWLING_ENABLE
|
|||
|
if (speaker_hdl->p_howling_hdl) {
|
|||
|
pause_howling(speaker_hdl->p_howling_hdl, speaker_hdl->howling_en);
|
|||
|
printf("howling_en [%d]", speaker_hdl->howling_en);
|
|||
|
}
|
|||
|
#endif
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
void switch_echo_en(void)
|
|||
|
{
|
|||
|
if (speaker_hdl) {
|
|||
|
speaker_hdl->reverb_en ^= 1;
|
|||
|
printf("reverb_en [%d]", speaker_hdl->reverb_en);
|
|||
|
#if ECHO_ENABLE
|
|||
|
if (speaker_hdl->reverb_en) {
|
|||
|
pause_echo(speaker_hdl->p_echo_hdl, speaker_hdl->reverb_en);
|
|||
|
}
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
/*----------------------------------------------------------------------------*/
|
|||
|
/**@brief loundspeaker echo 回声延时调节接口
|
|||
|
@param
|
|||
|
@return
|
|||
|
@note
|
|||
|
*/
|
|||
|
/*----------------------------------------------------------------------------*/
|
|||
|
void loundspeaker_set_echo_delay(u32 delay)
|
|||
|
{
|
|||
|
#if ECHO_ENABLE
|
|||
|
if (speaker_hdl == NULL || speaker_hdl->p_echo_hdl == NULL) {
|
|||
|
return ;
|
|||
|
}
|
|||
|
effect_echo_parm.delay = delay;
|
|||
|
update_echo_parm(speaker_hdl->p_echo_hdl, &effect_echo_parm);
|
|||
|
#endif
|
|||
|
}
|
|||
|
u32 loundspeaker_get_echo_delay(void)
|
|||
|
{
|
|||
|
#if ECHO_ENABLE
|
|||
|
if (speaker_hdl && speaker_hdl->p_echo_hdl) {
|
|||
|
return effect_echo_parm.delay;
|
|||
|
}
|
|||
|
#endif
|
|||
|
return 0;
|
|||
|
}
|
|||
|
/*----------------------------------------------------------------------------*/
|
|||
|
/**@brief loundspeaker echo 回声衰减系数调节接口
|
|||
|
@param
|
|||
|
@return
|
|||
|
@note
|
|||
|
*/
|
|||
|
/*----------------------------------------------------------------------------*/
|
|||
|
void loundspeaker_set_echo_decay(u32 decay)
|
|||
|
{
|
|||
|
#if ECHO_ENABLE
|
|||
|
if (speaker_hdl == NULL || speaker_hdl->p_echo_hdl == NULL) {
|
|||
|
return ;
|
|||
|
}
|
|||
|
effect_echo_parm.decayval = decay;
|
|||
|
update_echo_parm(speaker_hdl->p_echo_hdl, &effect_echo_parm);
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
u32 loundspeaker_get_echo_decay(void)
|
|||
|
{
|
|||
|
#if ECHO_ENABLE
|
|||
|
if (speaker_hdl && speaker_hdl->p_echo_hdl) {
|
|||
|
return effect_echo_parm.decayval;
|
|||
|
}
|
|||
|
#endif
|
|||
|
return 0;
|
|||
|
}
|
|||
|
/*----------------------------------------------------------------------------*/
|
|||
|
/**@brief loundspeaker 变声参数设置
|
|||
|
@param
|
|||
|
@return
|
|||
|
@note
|
|||
|
*/
|
|||
|
/*----------------------------------------------------------------------------*/
|
|||
|
void loundspeaker_set_pitch_para(u32 shiftv, u32 sr, u8 effect, u32 formant_shift)
|
|||
|
{
|
|||
|
#if PITCH_ENABLE
|
|||
|
if (speaker_hdl == NULL || speaker_hdl->p_pitch_hdl == NULL) {
|
|||
|
return ;
|
|||
|
}
|
|||
|
PITCH_SHIFT_PARM p_pitch_parm = {0};//get_pitch_parm();
|
|||
|
|
|||
|
p_pitch_parm.sr = sr;
|
|||
|
p_pitch_parm.shiftv = shiftv;
|
|||
|
p_pitch_parm.effect_v = effect;
|
|||
|
p_pitch_parm.formant_shift = formant_shift;
|
|||
|
|
|||
|
printf("\n\n\nshiftv[%d],sr[%d],effect[%d],formant_shift[%d] \n\n", p_pitch_parm.shiftv, p_pitch_parm.sr, p_pitch_parm.effect_v, p_pitch_parm.formant_shift);
|
|||
|
update_picth_parm(speaker_hdl->p_pitch_hdl, &p_pitch_parm);
|
|||
|
#endif
|
|||
|
}
|
|||
|
#endif /*TCFG_LOUDSPEAKER_ENABLE*/
|
|||
|
|