This commit is contained in:
huxi
2025-12-03 11:12:34 +08:00
parent c23ae4f24c
commit bc195654bf
8163 changed files with 3799544 additions and 92 deletions
+107
View File
@@ -0,0 +1,107 @@
#ifdef SUPPORT_MS_EXTENSIONS
#pragma bss_seg(".audio_dc_offset_remove.data.bss")
#pragma data_seg(".audio_dc_offset_remove.data")
#pragma const_seg(".audio_dc_offset_remove.text.const")
#pragma code_seg(".audio_dc_offset_remove.text")
#endif
/*
****************************************************************
* Audio DC-Offset Remove
* Brief : 去除直流偏移
* Notes :
*
****************************************************************
*/
#include "audio_dc_offset_remove.h"
#include "app_config.h"
//一段高通滤波器 可调中心截止频率、带宽
//默认Freq:100Hz Gain:0 Q:0.7f
static struct eq_seg_info dccs_eq_tab_8k[] = {
{0, EQ_IIR_TYPE_HIGH_PASS, 100, 0, 0.7f},
};
static struct eq_seg_info dccs_eq_tab_16k[] = {
{0, EQ_IIR_TYPE_HIGH_PASS, 100, 0, 0.7f},
};
//使用EQ模块去除直流偏置配置
#if TCFG_EQ_ENABLE
#define DCC_VIA_EQ_ENABLE 1
#else
#define DCC_VIA_EQ_ENABLE 0
#endif/*TCFG_EQ_ENABLE*/
/*
*********************************************************************
* Audio DC-Offset Remove Open
* Description:
* Arguments : sample_rate
* ch_num
* Return : Null
* Note(s) :
*********************************************************************
*/
void *audio_dc_offset_remove_open(u32 sample_rate, u32 ch_num)
{
#if DCC_VIA_EQ_ENABLE
struct audio_eq_param eq_param = {0};
eq_param.channels = ch_num;
eq_param.sr = sample_rate;
eq_param.cb = eq_get_filter_info;
eq_param.global_gain = 0;
if (sample_rate == 8000) {
eq_param.max_nsection = eq_param.nsection = ARRAY_SIZE(dccs_eq_tab_8k);
eq_param.seg = dccs_eq_tab_8k;
} else {
eq_param.max_nsection = eq_param.nsection = ARRAY_SIZE(dccs_eq_tab_16k);
eq_param.seg = dccs_eq_tab_16k;
}
struct audio_eq *eq = audio_dec_eq_open(&eq_param);
return (void *)eq;
#else
return NULL;
#endif
}
/*
*********************************************************************
* Audio DC-Offset Remove Run
* Description:
* Arguments : hdl
* data
* len
* Return : Null
* Note(s) :
*********************************************************************
*/
void audio_dc_offset_remove_run(void *hdl, void *data, u32 len)
{
#if DCC_VIA_EQ_ENABLE
if (hdl) {
audio_dec_eq_run(hdl, (s16 *)data, (s16 *)data, len);
}
#endif
}
/*
*********************************************************************
* Audio DC-Offset Remove Close
* Description:
* Arguments : hdl
* Return : Null
* Note(s) :
*********************************************************************
*/
void audio_dc_offset_remove_close(void *hdl)
{
#if DCC_VIA_EQ_ENABLE
if (hdl) {
audio_dec_eq_close(hdl);
/* hdl = NULL; */
}
#endif
}
+12
View File
@@ -0,0 +1,12 @@
#ifndef _AUDIO_DC_OFFSET_REMOVE_H
#define _AUDIO_DC_OFFSET_REMOVE_H
#include "effects/eq_config.h"
void *audio_dc_offset_remove_open(u32 samprate, u32 ch_num);
void audio_dc_offset_remove_run(void *hdl, void *data, u32 len);
void audio_dc_offset_remove_close(void *hdl);
#endif
+56
View File
@@ -0,0 +1,56 @@
#ifdef SUPPORT_MS_EXTENSIONS
#pragma bss_seg(".audio_pitch_speed_api.data.bss")
#pragma data_seg(".audio_pitch_speed_api.data")
#pragma const_seg(".audio_pitch_speed_api.text.const")
#pragma code_seg(".audio_pitch_speed_api.text")
#endif
#include "jlstream.h"
#include "app_config.h"
#include "effects/audio_pitchspeed.h"
#include "audio_pitch_speed_api.h"
#include "effects_default_param.h"
#include "node_uuid.h"
#if TCFG_PITCH_SPEED_NODE_ENABLE
static const float semi_tones_table[] = {-12.0, -10.0, -8.0, -6.0, -4.0, -2.0, 0, 2.0, 4.0, 6.0, 8.0, 10.0, 12.0};
static s8 g_pitch_mode = 6; //记录变调模式
u8 get_pitch_mode()
{
return g_pitch_mode;
}
int audio_pitch_up(char *node_name)
{
g_pitch_mode ++;
if (g_pitch_mode > ARRAY_SIZE(semi_tones_table) - 1) {
g_pitch_mode = ARRAY_SIZE(semi_tones_table) - 1;
}
printf("pitch %d\n", (int)semi_tones_table[g_pitch_mode]);
audio_pitch_speed_set(node_name, semi_tones_table[g_pitch_mode], 1);
return g_pitch_mode;
}
int audio_pitch_down(char *node_name)
{
g_pitch_mode --;
if (g_pitch_mode < 0) {
g_pitch_mode = 0;
}
printf("pitch %d\n", (int)semi_tones_table[g_pitch_mode]);
audio_pitch_speed_set(node_name, semi_tones_table[g_pitch_mode], 1);
return g_pitch_mode;
}
int audio_pitch_speed_set(char *node_name, float semi_tones, float speed)
{
pitch_speed_param_tool_set cfg = {
.pitch = semi_tones,
.speed = speed,
};
return jlstream_set_node_param(NODE_UUID_PITCH_SPEED, node_name, &cfg, sizeof(cfg));
}
#endif
+24
View File
@@ -0,0 +1,24 @@
#ifndef __AUDIO_PITCH_SPEED_ADJ_API__
#define __AUDIO_PITCH_SPEED_ADJ_API__
#include "jlstream.h"
#include "media/audio_base.h"
#include "effects/audio_pitchspeed.h"
#include "node_uuid.h"
/* 获取当前的变调模式 */
u8 get_pitch_mode();
/* 升高音调 */
int audio_pitch_up(char *node_name);
/* 降低音调 */
int audio_pitch_down(char *node_name);
/*
* 变速变调设置接口
* node_name:工具中定义的节点名称
* semi_tones:半音符,范围 -12~12
* speed:变速倍数,范围 >0.5
* */
int audio_pitch_speed_set(char *node_name, float semi_tones, float speed);
#endif
@@ -0,0 +1,42 @@
#ifdef SUPPORT_MS_EXTENSIONS
#pragma bss_seg(".audio_voice_changer_api.data.bss")
#pragma data_seg(".audio_voice_changer_api.data")
#pragma const_seg(".audio_voice_changer_api.text.const")
#pragma code_seg(".audio_voice_changer_api.text")
#endif
#include "jlstream.h"
#include "app_config.h"
#include "audio_voice_changer_api.h"
#if TCFG_VOICE_CHANGER_NODE_ENABLE
static const VOICECHANGER_PARM vparm[] = {
{0, 0, 0},
{EFFECT_VOICECHANGE_PITCHSHIFT, 130, 100},
{EFFECT_VOICECHANGE_SPECTRUM, 56, 90},
{EFFECT_VOICECHANGE_PITCHSHIFT, 50, 100},
{EFFECT_VOICECHANGE_PITCHSHIFT, 75, 80},
{EFFECT_VOICECHANGE_PITCHSHIFT, 160, 100},
{EFFECT_VOICECHANGE_CARTOON, 60, 170},
{EFFECT_VOICECHANGE_CARTOON, 50, 60},
{EFFECT_VOICECHANGE_ROBORT, 70, 80},
{EFFECT_VOICECHANGE_WHISPER, 70, 80},
{EFFECT_VOICECHANGE_MELODY, 70, 80},
{EFFECT_VOICECHANGE_FEEDBACK, 150, 80}
};
void audio_voice_changer_mode_switch(u16 uuid, char *name, VOICE_CHANGER_MODE mode)
{
voice_changer_param_tool_set cfg = {0};
cfg.is_bypass = 0;
if (mode >= ARRAY_SIZE(vparm)) {
return;
}
memcpy(&cfg.parm, &vparm[mode], sizeof(VOICECHANGER_PARM));
if (mode == VOICE_CHANGER_NONE) {
cfg.is_bypass = 1;
}
jlstream_set_node_param(uuid, name, &cfg, sizeof(cfg));
}
#endif
@@ -0,0 +1,32 @@
#ifndef ___VOICE_CHANGER_API__
#define ___VOICE_CHANGER_API__
#include "jlstream.h"
#include "media/audio_base.h"
#include "effects/audio_voice_changer.h"
#include "effects/effects_adj.h"
//参数调节的趋势:shiftv越小,音高越高, formant_shift越小,音色越明亮
typedef enum {
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,//调制音
// VOICE_CHANGER_MAX,
} VOICE_CHANGER_MODE;
void audio_voice_changer_mode_switch(u16 uuid, char *name, VOICE_CHANGER_MODE mode);
void audio_esco_ul_voice_change(u32 sound_mode);
#endif
+155
View File
@@ -0,0 +1,155 @@
#ifdef SUPPORT_MS_EXTENSIONS
#pragma bss_seg(".bass_treble.data.bss")
#pragma data_seg(".bass_treble.data")
#pragma const_seg(".bass_treble.text.const")
#pragma code_seg(".bass_treble.text")
#endif
#include "system/includes.h"
#include "media/includes.h"
#include "app_config.h"
#include "audio_config.h"
#include "effects/effects_adj.h"
#include "jlstream.h"
#include "user_cfg_id.h"
#include "online_db_deal.h"
#include "bass_treble.h"
#include "scene_switch.h"
#if TCFG_BASS_TREBLE_NODE_ENABLE
struct bass_treble_default_parm music_bass_treble_par = {0};
struct bass_treble_default_parm mic_bass_treble_par = {0};
/*
*获取musicc 高低音增益,节点调用
* */
int get_music_bass_treble_parm(int arg)
{
int ret = 0;
struct bass_treble_default_parm *par = (struct bass_treble_default_parm *)arg;
if (par->type & BASS_TREBLE_PARM_GET) {
if (music_bass_treble_par.type & (BASS_TREBLE_PARM_SET | BASS_TREBLE_PARM_SET_GLOBAL_GAIN)) {
memcpy(par, &music_bass_treble_par, sizeof(*par));
ret = 1;
}
}
par->cfg_index = 0;
par->mode_index = get_current_scene();
return ret;
}
__attribute__((weak))
u8 get_mic_current_scene()
{
return 0;
}
/*
*获取mic 高低音增益,节点调用
* */
int get_mic_bass_treble_parm(int arg)
{
int ret = 0;
struct bass_treble_default_parm *par = (struct bass_treble_default_parm *)arg;
if (par->type & BASS_TREBLE_PARM_GET) {
if (mic_bass_treble_par.type & (BASS_TREBLE_PARM_SET | BASS_TREBLE_PARM_SET_GLOBAL_GAIN)) {
memcpy(par, &mic_bass_treble_par, sizeof(*par));
ret = 1;
}
}
par->cfg_index = 0;
par->mode_index = get_mic_current_scene();
return ret;
}
/*音乐高低音更新接口,gain以外的参数在调音节点界面配置
*name:节点名称
*index:0 低音 1 中音 2 高音
*gain:增益 dB (-48~48),大于0的增益,存在失真风险,谨慎使用
*注意:gain范围由配置文件限制
* */
void music_bass_treble_eq_udpate(char *name, enum bass_treble_eff index, float gain)
{
struct bass_treble_parm par = {0};
par.type = BASS_TREBLE_PARM_SET;
par.gain.index = index;
par.gain.gain = gain;
jlstream_set_node_param(NODE_UUID_BASS_TREBLE, name, &par, sizeof(par));
music_bass_treble_par.type |= par.type;
music_bass_treble_par.gain[par.gain.index] = par.gain.gain;//记录增益
}
/*mic高低音更新接口,gain以外的参数在调音节点界面配置
*name :节点名称
*index:0 低音 1 中音 2 高音
*gain:增益 dB (-48~48),大于0的增益,存在失真风险,谨慎使用
*注意:gain范围由配置文件限制
* */
void mic_bass_treble_eq_udpate(char *name, enum bass_treble_eff index, float gain)
{
struct bass_treble_parm par = {0};
par.type = BASS_TREBLE_PARM_SET;
par.gain.index = index;
par.gain.gain = gain;
jlstream_set_node_param(NODE_UUID_BASS_TREBLE, name, &par, sizeof(par));
mic_bass_treble_par.type |= par.type;
mic_bass_treble_par.gain[par.gain.index] = par.gain.gain;//记录增益
}
/*
*音乐高低音eq,总增益更新
* */
void music_bass_treble_set_global_gain(char *name, float global_gain)
{
struct bass_treble_parm par = {0};
par.type = BASS_TREBLE_PARM_SET_GLOBAL_GAIN;
par.global_gain = global_gain;
jlstream_set_node_param(NODE_UUID_BASS_TREBLE, name, &par, sizeof(par));
music_bass_treble_par.type |= par.type;
music_bass_treble_par.global_gain = par.global_gain;
}
/*
*mic高低音eq,总增益更新
* */
void mic_bass_treble_set_global_gain(char *name, float global_gain)
{
struct bass_treble_parm par = {0};
par.type = BASS_TREBLE_PARM_SET_GLOBAL_GAIN;
par.global_gain = global_gain;
jlstream_set_node_param(NODE_UUID_BASS_TREBLE, name, &par, sizeof(par));
mic_bass_treble_par.type |= par.type;
mic_bass_treble_par.global_gain = par.global_gain;
}
//兼容旧接口
void mix_out_high_bass(u32 cmd, struct high_bass *hb)
{
if (cmd == AUDIO_EQ_HIGH) {
music_bass_treble_eq_udpate("MusicBassTre", BASS_TREBLE_HIGH, hb->gain);
} else if (cmd == AUDIO_EQ_BASS) {
music_bass_treble_eq_udpate("MusicBassTre", BASS_TREBLE_LOW, hb->gain);
}
}
void test_mid_eq(void *p)
{
static float gain = 0;
if (gain++ > 0) {
gain = -48;
}
printf("====gain %d\n", (int)gain);
music_bass_treble_eq_udpate("MusicBassTre", BASS_TREBLE_MID, gain);
/* float test_global_gain = -1; */
/* music_bass_treble_set_global_gain("MusicBassTre", test_global_gain); */
}
#endif
+48
View File
@@ -0,0 +1,48 @@
#ifndef _BASS_TREBLE_H_
#define _BASS_TREBLE_H_
#include "system/includes.h"
#include "media/includes.h"
#include "effects/audio_bass_treble_eq.h"
/*
*获取musicc 高低音增益,节点调用
* */
int get_music_bass_treble_parm(int arg);
/*
*获取mic 高低音增益,节点调用
* */
int get_mic_bass_treble_parm(int arg);
/*音乐高低音更新接口,gain以外的参数在调音节点界面配置
*name:节点名称
*index:0 低音 1 中音 2 高音
*gain:增益 dB (-48~48),大于0的增益,存在失真风险,谨慎使用
* 注意:gain范围由配置文件限制
* */
void music_bass_treble_eq_udpate(char *name, enum bass_treble_eff index, float gain);
/*mic高低音更新接口,gain以外的参数在调音节点界面配置
*name:节点名称
*index:0 低音 1 中音 2 高音
*gain:增益 dB (-48~48),大于0的增益,存在失真风险,谨慎使用
* 注意:gain范围由配置文件限制
* */
void mic_bass_treble_eq_udpate(char *name, enum bass_treble_eff index, float gain);
/*
*音乐高低音eq,总增益更新
* */
void music_bass_treble_set_global_gain(char *name, float global_gain);
/*
*mic高低音eq,总增益更新
* */
void mic_bass_treble_set_global_gain(char *name, float global_gain);
#endif
+744
View File
@@ -0,0 +1,744 @@
#ifdef SUPPORT_MS_EXTENSIONS
#pragma bss_seg(".effects_adj.data.bss")
#pragma data_seg(".effects_adj.data")
#pragma const_seg(".effects_adj.text.const")
#pragma code_seg(".effects_adj.text")
#endif
#include "system/includes.h"
#include "media/includes.h"
#include "app_config.h"
#include "audio_config.h"
#include "jlstream.h"
#include "cfg_tool.h"
#include "volume_node.h"
#include "effects/effects_adj.h"
#include "effects/eq_config.h"
#include "effects/audio_eq.h"
#include "effects/audio_bass_treble_eq.h"
#define LOG_TAG_CONST EFFECTS
#define LOG_TAG "[EFFECTS_ADJ]"
#define LOG_ERROR_ENABLE
#define LOG_INFO_ENABLE
#define LOG_DUMP_ENABLE
#include "debug.h"
#ifdef SUPPORT_MS_EXTENSIONS
#pragma code_seg(".effects_adj.text")
#pragma data_seg(".effects_adj.data")
#pragma const_seg(".effects_adj.text.const")
#endif
#if TCFG_CFG_TOOL_ENABLE
struct eff_mode {
u16 uuid;
u16 mode_num; //模式个数
u16 mode_index; //当前模式序号
} __attribute__((packed));
struct stream_crc {
u16 uuid;
u16 crc;
};
struct eff_struct { //参数结构,节点结构组成uuid name parm_struct
u16 uuid;
u16 reserve;//bit0 是否伪模块,伪模块时发送多个节点数据 bit1:表单类节点是否为手动调节,bit2-7:保留
char data[0];//多节点一起更新时[len +nodedata(struct eff_struct结构) ...]
} __attribute__((packed));
struct eff_online_packet {
int cmd;
struct eff_struct par;
};
struct eq_list_entry {
struct list_head entry;
struct eq_online *tab;
};
struct eff_list_entry {
struct list_head entry;
u32 private_type;//特殊私有类型,当前被mdrc使用
u32 len;
struct eff_online_packet *packet;
};
struct eff_list {
struct list_head head; //链表头
};
static struct eff_list eff_hdl_eq = {0};
static struct eff_list eff_hdl = {0};
static spinlock_t eff_lock[2];
static int eff_list_init(void)
{
INIT_LIST_HEAD(&eff_hdl_eq.head);
INIT_LIST_HEAD(&eff_hdl.head);
spin_lock_init(&eff_lock[0]);
spin_lock_init(&eff_lock[1]);
return 0;
}
__initcall(eff_list_init);
static u32 total_buf = 0;
void effects_adj_printf()
{
log_debug(">>>>>total_buf adj buf %d bytes>>>>>\n", total_buf);
}
/*
*eq调音临时系数更新
* */
void eq_list_entry_update(struct eq_list_entry *hdl, struct eff_online_packet *ep, u32 size, int *ret, int *start, int *end)
{
int *data = (int *)&ep->par.data[16];
if (data[0] == EQ_SPECIAL_CMD) { //type bypass global_gain sen_num
if (data[3] != hdl->tab->seg_num) {
if (hdl->tab) {
int prev_size = sizeof(struct eq_online) + hdl->tab->seg_num * sizeof(struct eq_seg_info);
if (total_buf > prev_size) {
total_buf -= prev_size;
} else {
total_buf = 0;
}
free(hdl->tab);
}
int sizet = sizeof(struct eq_online) + data[3] * sizeof(struct eq_seg_info);
hdl->tab = malloc(sizet);
total_buf += sizet;
}
hdl->tab->is_bypass = data[1];
memcpy(&hdl->tab->global_gain, &data[2], 4);//总增益是浮点
hdl->tab->seg_num = data[3];
hdl->tab->uuid = ep->par.uuid;
memcpy(hdl->tab->name, &ep->par.data, 16);
log_debug("multi hdl->tab->is_bypass %d\n", hdl->tab->is_bypass);
log_debug("multi hdl->tab->global_gain %x\n", *(int *)&hdl->tab->global_gain);
log_debug("multi hdl->tab->seg_num %d\n", hdl->tab->seg_num);
*ret = EQ_SPECIAL_CMD;
return;
} else if (data[0] == EQ_SPECIAL_SEG_CMD) { //type seg[n]
hdl->tab->uuid = ep->par.uuid;
memcpy(hdl->tab->name, &ep->par.data, 16);
struct eq_seg_info *src_seg = (struct eq_seg_info *)&data[1];
int tar_size = size - 8 - 16; ////减去cmd uuid name
*start = src_seg[0].index;
for (int i = 0; i < hdl->tab->seg_num; i++) {
if (tar_size >= sizeof(struct eq_seg_info)) {
memcpy(&hdl->tab->seg[src_seg[i].index], &src_seg[i], sizeof(struct eq_seg_info));
struct eq_seg_info *seg = (struct eq_seg_info *)&hdl->tab->seg[src_seg[i].index];
/* log_debug("multi soure idx:%d, iir:%d, freq:%d, gain:0x%08x, q:0x%08x ", seg->index, seg->iir_type, seg->freq, *(int *)&seg->gain, *(int *)&seg->q); */
tar_size -= sizeof(struct eq_seg_info);
*end = src_seg[i].index;
}
}
*ret = EQ_SPECIAL_SEG_CMD;
return;
}
struct eq_adj eq = {0};
memcpy(&eq, &ep->par.data[16], size - 8 - 16);//减去cmd uuid name
if (eq.type == EQ_IS_BYPASS_CMD) {
hdl->tab->is_bypass = eq.param.is_bypass;
log_debug("tab->is_bypass %d\n", hdl->tab->is_bypass);
} else if (eq.type == EQ_GLOBAL_GAIN_CMD) {
hdl->tab->global_gain = eq.param.global_gain;
log_debug("hdl->tab->global_gain %x\n", *(int *)&hdl->tab->global_gain);
} else if (eq.type == EQ_SEG_NUM_CMD) {
if (eq.param.seg_num != hdl->tab->seg_num) {
float global_gain = hdl->tab->global_gain;
int is_bypass = hdl->tab->is_bypass;
if (hdl->tab) {
int prev_size = sizeof(struct eq_online) + hdl->tab->seg_num * sizeof(struct eq_seg_info);
if (total_buf > prev_size) {
total_buf -= prev_size;
} else {
total_buf = 0;
}
free(hdl->tab);
}
int sizet = sizeof(struct eq_online) + eq.param.seg_num * sizeof(struct eq_seg_info);
hdl->tab = malloc(sizet);
total_buf += sizet;
hdl->tab->global_gain = global_gain;
hdl->tab->is_bypass = is_bypass;
log_debug("hdl->tab->is_bypass %d\n", hdl->tab->is_bypass);
log_debug("hdl->tab->global_gain %x\n", *(int *)&hdl->tab->global_gain);
}
hdl->tab->seg_num = eq.param.seg_num;
log_debug("hdl->tab->seg_num %d\n", hdl->tab->seg_num);
} else if (eq.type == EQ_SEG_CMD) {
memcpy(&hdl->tab->seg[eq.param.seg.index], &eq.param.seg, sizeof(struct eq_seg_info));
struct eq_seg_info *seg = (struct eq_seg_info *)&hdl->tab->seg[eq.param.seg.index];
log_debug("soure idx:%d, iir:%d, freq:%d, gain:0x%08x, q:0x%08x ", seg->index, seg->iir_type, seg->freq, *(int *)&seg->gain, *(int *)&seg->q);
}
hdl->tab->uuid = ep->par.uuid;
memcpy(hdl->tab->name, &ep->par.data, 16);
}
/*
*通用音效临时参数更新
* */
void eff_list_entry_update(struct eff_list_entry *hdl, struct eff_online_packet *ep, u32 size)
{
if (size != hdl->len) {
if (hdl->packet) {
if (total_buf > hdl->len) {
total_buf -= hdl->len;
} else {
total_buf = 0;
}
free(hdl->packet);
}
hdl->len = size;
hdl->packet = malloc(size);
total_buf += size;
}
hdl->packet->cmd = ep->cmd;
hdl->packet->par.uuid = ep->par.uuid;
memcpy(&hdl->packet->par, &ep->par, size - 4);
}
/*
*获取特殊类型节点(mdrc)参数名字后的第一个int,协议见Mdrc调试
* */
int eff_get_privete_type(struct eff_online_packet *ep)
{
int private_type = 0;
memcpy(&private_type, &ep->par.data[16], 4);
return private_type;
}
/*
*获取参数链表成员的名字
* */
void eff_get_node_name(struct eff_list_entry *hdl, char *name)
{
memcpy(name, hdl->packet->par.data, 16);
}
/*
*检测mdrc子模块的类型
*return false:私有类型不匹配, true:私有类型匹配
* */
int eff_check_mdrc_private_type(struct eff_list_entry *hdl, u16 uuid, int private_type)
{
if ((uuid == NODE_UUID_MDRC) && private_type && (private_type != hdl->private_type)) {//mdrc需要加多一个cmd的判断
return false;
}
return true;
}
/*
*把在线调试的参数建立到链表内,方便节点切歌时,获取当前已经调试的参数
* */
void eff_entry_add(void *packet, u32 size, int *ret, int *start, int *end)
{
struct eff_online_packet *ep = (struct eff_online_packet *)packet;
int private_type = 0;
char name[16];
char src_name[16];
memcpy(name, ep->par.data, sizeof(name));
if (!strlen(name)) { //节点名字未填写,不做记录
return;
}
if ((ep->par.uuid != NODE_UUID_EQ) && (ep->par.uuid != NODE_UUID_SOF_EQ)) {
spin_lock(&eff_lock[0]);
if (ep->par.uuid == NODE_UUID_MDRC) {// 特殊类型,通过cmd记录差异点
private_type = eff_get_privete_type(ep);
}
if (!list_empty(&eff_hdl.head)) {
struct eff_list_entry *hdl;
list_for_each_entry(hdl, &eff_hdl.head, entry) {
eff_get_node_name(hdl, src_name);
log_debug("cmd 0x%x hdl->hdl->packet->cmd 0x%x", ep->cmd, hdl->packet->cmd);
if ((hdl->packet->par.uuid == ep->par.uuid) && !strncmp(src_name, name, strlen(name))) { //查询已存在,更新参数
if (!eff_check_mdrc_private_type(hdl, ep->par.uuid, private_type)) {
continue;
}
eff_list_entry_update(hdl, ep, size);
log_debug("node update %x\n", ep->par.uuid);
spin_unlock(&eff_lock[0]);
return;
}
}
}
//查询未存在,记录参数,并add到链表
int sizet = sizeof(struct eff_list_entry);
struct eff_list_entry *hdl = zalloc(sizet);
total_buf += sizet;
hdl->private_type = private_type;
eff_list_entry_update(hdl, ep, size);
list_add(&hdl->entry, &eff_hdl.head);
log_debug("node add %x\n", ep->par.uuid);
spin_unlock(&eff_lock[0]);
} else {
spin_lock(&eff_lock[1]);
if (!list_empty(&eff_hdl_eq.head)) { //非空
struct eq_list_entry *hdl;
list_for_each_entry(hdl, &eff_hdl_eq.head, entry) {
if ((hdl->tab->uuid == ep->par.uuid) && !strncmp(hdl->tab->name, name, 16)) { //查询已存在,更新参数
eq_list_entry_update(hdl, ep, size, ret, start, end);
log_debug("eq_list upadate\n");
spin_unlock(&eff_lock[1]);
return;
}
}
}
//查询未存在,记录参数,并add到链表
int sizet = sizeof(struct eq_list_entry);
struct eq_list_entry *hdl = zalloc(sizet);
total_buf += sizet;
int default_section = 10;
sizet = sizeof(struct eq_online) + default_section * sizeof(struct eq_seg_info);
hdl->tab = malloc(sizet);
total_buf += sizet;
hdl->tab->seg_num = default_section;
eq_list_entry_update(hdl, ep, size, ret, start, end);
list_add(&hdl->entry, &eff_hdl_eq.head);
log_debug("eq_list add\n");
spin_unlock(&eff_lock[1]);
}
}
/*
*节点通过uuid 与name获取在线调试音效的参数
* */
int get_eff_online_param(u32 _uuid, char *name, void *packet)
{
int ret = 0;
char src_name[16];
u16 uuid = _uuid & 0xffff;
int private_type = ((_uuid & 0xffff0000) >> 16);//复用uuid变量高16bit记录mdrc type
if ((uuid != NODE_UUID_EQ) && (uuid != NODE_UUID_SOF_EQ)) {
spin_lock(&eff_lock[0]);
if (!list_empty(&eff_hdl.head)) { //非空
struct eff_list_entry *hdl;
list_for_each_entry(hdl, &eff_hdl.head, entry) {
eff_get_node_name(hdl, src_name);
if ((hdl->packet->par.uuid == uuid) && !strncmp(src_name, name, strlen(name))) {
if (!eff_check_mdrc_private_type(hdl, uuid, private_type)) {
continue;
}
int len = 0;
char *ptr = (char *)packet;//结构:uuid name param
char *src = (char *)&hdl->packet->par;
memcpy(&len, &ptr[4 + 16], 4); //4byte uuid + 16byte name
int cp_len = hdl->len - 4 - 20;// 4byte 是减去cmd的长度, 20是 uuid reserve name 长度
if (cp_len > len) {
log_error("=====node online param err %s %d %d=====\n", name, len, cp_len);
cp_len = len;
}
memcpy(&ptr[20 + 4], &src[20], cp_len);
ret = 1;
break;
}
}
}
spin_unlock(&eff_lock[0]);
} else {
spin_lock(&eff_lock[1]);
if (!list_empty(&eff_hdl_eq.head)) { //非空
struct eq_list_entry *hdl;
list_for_each_entry(hdl, &eff_hdl_eq.head, entry) {
if ((hdl->tab->uuid == uuid) && !strncmp(hdl->tab->name, name, 16)) {
struct eq_online *tar = (struct eq_online *)packet;
tar->is_bypass = hdl->tab->is_bypass;
tar->global_gain = hdl->tab->global_gain;
tar->seg_num = hdl->tab->seg_num;
memcpy(tar->seg, hdl->tab->seg, sizeof(struct eq_seg_info)*hdl->tab->seg_num);
/* log_debug("tar seg %x\n", (int)tar->seg); */
/* for (int i = 0; i < tar->seg_num; i++) { */
/* struct eq_seg_info *seg = (struct eq_seg_info *)&hdl->tab->seg[i]; */
/* log_debug("source idx:%d, iir:%d, freq:%d, gain:0x%08x, q:0x%08x ", seg->index, seg->iir_type, seg->freq, *(int *)&seg->gain, *(int *)&seg->q); */
/* } */
ret = 1;
break;
}
}
}
spin_unlock(&eff_lock[1]);
}
return ret;
}
/*
*接收上位机发来的模式信息,小机可用于播放相应模式提示音
* */
void eff_mode_switch(void *priv)
{
struct eff_mode *param = (struct eff_mode *)priv;
log_debug("uuid 0x%x\n", param->uuid);
log_debug("mode_num %d\n", param->mode_num);
log_debug("mode_index %d\n", param->mode_index);
}
/*
*在线调音开始时会检查,界面框图流程的crc与stream.bin的crc是否一致
*不一致时,需要重新更新stream.bin并编译下载代码
* */
int eff_stream_crc_check(void *priv)
{
struct stream_crc *check = (struct stream_crc *)priv;
u16 crc = jlstream_read_stream_crc();
if (crc == check->crc) {
return true;
} else {
log_error("check stream crc fail, please update stream.bin and re-download \n");
}
return false;
}
int indicator_get_param(struct eff_online_packet *ep, u8 sq)
{
struct indicator_private_cmd {
u16 uuid;
u8 subid;
u8 reserve;
char name[16];
};
struct indicator_private_cmd *indator = (struct indicator_private_cmd *)&ep->par;
struct indicator_upload_data indicator_data = {0};
int res = jlstream_get_node_param(ep->par.uuid, indator->name, &indicator_data, sizeof(indicator_data));
if (res == sizeof(indicator_data)) {
eff_node_send_packet(REPLY_TO_TOOL, sq, (u8 *)&indicator_data, sizeof(indicator_data));
res = ERR_ACCEPTABLE;
} else {
res = ERR_COMM;
}
return res;
}
/*
*高低音获取当前gain并上传
* */
static int bass_treble_get_node_param(struct eff_online_packet *ep, u8 sq)
{
int res = ERR_COMM;
struct bass_treble_private_cmd { //协议相关
u16 uuid;
char name[16];
char mark[16];
} __attribute__((packed));
struct seg_gain gain = {0};
struct bass_treble_private_cmd *get_param = (struct bass_treble_private_cmd *)&ep->par;
if (!strcmp("low", get_param->mark)) {
gain.index = 0;
} else if (!strcmp("mid", get_param->mark)) {
gain.index = 1;
} else if (!strcmp("hig", get_param->mark)) {
gain.index = 2;
}
res = jlstream_get_node_param(get_param->uuid, get_param->name, &gain, sizeof(gain));//获取当前增益
if (res == sizeof(gain)) {
struct bass_treb_upload { //协议相关
u8 len;
u8 type;
float cur_gain;
} __attribute__((packed));
struct bass_treb_upload upload_param;
upload_param.len = sizeof(struct bass_treb_upload) - 1;
upload_param.type = 0x1;//数据类型 0u32 1:float
upload_param.cur_gain = gain.gain;
log_debug("bass treble idx : %d, gain: 0x%x\n", gain.index, *(int *)&gain.gain);
eff_node_send_packet(REPLY_TO_TOOL, sq, (u8 *)&upload_param, sizeof(upload_param));//上传当前增益
res = ERR_ACCEPTABLE;
}
return res;
}
/*
*获取当前音量并上传
* */
static int volume_get_node_param(struct eff_online_packet *ep, u8 sq)
{
int res = ERR_COMM;
struct volume_private_cmd { //协议相关
u16 uuid;
char name[16];
char mark[16];
} __attribute__((packed));
struct volume_cfg cfg = {0};
struct volume_private_cmd *get_param = (struct volume_private_cmd *)&ep->par;
if (!strcmp("volume", get_param->mark)) {
res = jlstream_get_node_param(get_param->uuid, get_param->name, &cfg, sizeof(cfg));//获取当前增益
if (res == sizeof(cfg)) {
struct volume_upload { //协议相关
u8 len;
u8 type;
int cur_vol;
} __attribute__((packed));
struct volume_upload upload_param;
upload_param.len = sizeof(struct volume_upload) - 1;
upload_param.type = 0x0;//数据类型 0u32 1:float
upload_param.cur_vol = cfg.cur_vol;
log_debug("volume get cur_vol %d\n", cfg.cur_vol);
eff_node_send_packet(REPLY_TO_TOOL, sq, (u8 *)&upload_param, sizeof(upload_param));//上传当前增益
res = ERR_ACCEPTABLE;
}
}
return res;
}
/*
*表单节点获取当前值
* */
static int form_node_get_parm(struct eff_online_packet *ep, u8 sq)
{
int res = ERR_COMM;
switch (ep->par.uuid) {
case NODE_UUID_BASS_TREBLE:
res = bass_treble_get_node_param(ep, sq);
break;
case NODE_UUID_VOLUME_CTRLER:
res = volume_get_node_param(ep, sq);
break;
default:
//do smt
break;
}
return res;
}
/*
*工具获取支持在线调试的节点列表
* */
static int check_eff_node_online_support(struct eff_online_packet *ep, u8 sq)
{
int res = ERR_ACCEPTABLE;
u16 cnt = 0;
struct effects_online_adjust *p;
list_for_online_adjust_target(p) {
/* printf("uuid %x\n", p->uuid); */
cnt++;
}
eff_node_send_packet(REPLY_TO_TOOL, sq, (u8 *)effects_online_adjust_begin, (int)(cnt * sizeof(u16)));
return res;
}
/*
*工具同步界面全部参数下来时,快速更新数据给节点
* */
static void eq_fast_update(char *name, u8 type, int start, int end, u16 uuid)
{
struct eq_tool *tab = NULL;
struct eq_online *online_parm = zalloc(sizeof(struct eq_online) + sizeof(struct eq_seg_info) * AUDIO_EQ_MAX_SECTION);
if (online_parm) {
online_parm->uuid = uuid;
memcpy(online_parm->name, name, strlen(name));
int online_ret = jlstream_event_notify(STREAM_EVENT_GET_EFF_ONLINE_PARM, (int)online_parm);
if (online_ret) {
int seg_size = sizeof(struct eq_seg_info) * online_parm->seg_num;
int sizet = sizeof(struct eq_tool) + seg_size;
tab = zalloc(sizet);
tab->is_bypass = online_parm->is_bypass;
tab->global_gain = online_parm->global_gain;
tab->seg_num = online_parm->seg_num;
memcpy(tab->seg, online_parm->seg, sizeof(struct eq_seg_info)*tab->seg_num);
}
free(online_parm);
}
if (!tab) {
return;
}
struct eq_adj eff = {0};
if (type == EQ_SPECIAL_CMD) {
//运行时,直接设置更新
eff.type = EQ_SEG_NUM_CMD;
eff.param.seg_num = tab->seg_num;
jlstream_set_node_param(uuid, name, &eff, sizeof(eff));//更新滤波器段数
eff.type = EQ_IS_BYPASS_CMD;
eff.param.is_bypass = tab->is_bypass;
jlstream_set_node_param(uuid, name, &eff, sizeof(eff));//更新bypass状态
eff.type = EQ_GLOBAL_GAIN_CMD;
eff.param.global_gain = tab->global_gain;
jlstream_set_node_param(uuid, name, &eff, sizeof(eff));//更新总增益
} else if (type == EQ_SPECIAL_SEG_CMD) {
for (int i = start; i <= end; i++) {
eff.type = EQ_SEG_CMD;
memcpy(&eff.param.seg, &tab->seg[i], sizeof(struct eq_seg_info));
jlstream_set_node_param(uuid, name, &eff, sizeof(eff));//更新滤波器系数
}
}
free(tab);
}
static s32 eff_online_update_base(void *packet, u32 size, u8 sq)
{
int eq_ret = 0;
int start = 0;
int end = 0;
int res = ERR_ACCEPTABLE;
char name[16];
struct eff_online_packet *ep = (struct eff_online_packet *)packet;
log_debug("cmd %x\n", ep->cmd);
switch (ep->cmd) {
case EFF_ADJ_CMD:
memcpy(name, ep->par.data, sizeof(name));
log_debug("uuid:0x%x name %s\n", ep->par.uuid, name);
if (ep->par.uuid == NODE_UUID_VOLUME_CTRLER) {
log_debug("effects.adj.c %d,%x\n", __LINE__, (int)(ep->par.reserve & EFF_MANUAL_ADJ_NODE));
int res = ERR_COMM;
if (!(int)(ep->par.reserve & EFF_MANUAL_ADJ_NODE)) { //点开节点下发的音量
struct volume_cfg cfg = {0};
res = jlstream_get_node_param(NODE_UUID_VOLUME_CTRLER, name, &cfg, sizeof(cfg));//获取当前增益
struct volume_cfg *temp_vol_cfg = (struct volume_cfg *)(&ep->par.data[16]);
temp_vol_cfg->cur_vol = cfg.cur_vol;
log_debug("effects.adj.c%d,%d\n", __LINE__, cfg.cur_vol);
}
}
eff_entry_add(packet, size, (int *)&eq_ret, &start, &end);
if (eq_ret == EQ_SPECIAL_CMD) {
res = ERR_NONE;
eq_fast_update(name, eq_ret, start, end, ep->par.uuid);
break;
}
if (eq_ret == EQ_SPECIAL_SEG_CMD) {
res = ERR_NONE;
eq_fast_update(name, eq_ret, start, end, ep->par.uuid);
break;
}
res = jlstream_set_node_param(ep->par.uuid, name, &ep->par.data[16], size - sizeof(ep->cmd) - sizeof(ep->par.uuid) - sizeof(ep->par.reserve) - 16); //减去cmd 减uuid 减revere 减name
effects_adj_printf();
break;
case EFF_MODE_CMD:
eff_mode_switch((void *)&ep->par);
res = ERR_NONE;
break;
case EFF_CRC_CMD:
if (eff_stream_crc_check((void *)&ep->par)) {
res = ERR_NONE;
} else {
res = EFF_ERR_CRC;
}
break;
#ifdef TCFG_INDICATOR_NODE_ENABLE
case EFF_INDICATOR_CMD:
res = indicator_get_param(ep, sq);
break;
#endif
case EFF_FORM_CMD:
res = form_node_get_parm(ep, sq);
break;
case EFF_ONLINE_CMD:
res = check_eff_node_online_support(ep, sq);
break;
default:
break;
}
return res;
}
static s32 eff_online_update(void *packet, u32 size, u8 sq)
{
int res = ERR_ACCEPTABLE;
struct eff_online_packet *ep = (struct eff_online_packet *)packet;
switch (ep->cmd) {
case EFF_ADJ_CMD:
if (ep->par.reserve & EFF_NODE_MERGE_UPDATE) { //多节点数据一次更新
struct eff_online_packet *new_ep = NULL;
u8 *next_node = (u8 *)ep->par.data;
u16 offset = 0;
u16 eff_struct_len = 0;
size = size - 4 - 2 - 2;//4cmd 2uuid 2reserve
/* printf("start %x, end:%x\n", (u32)ep->par.data, (u32)ep->par.data + size); */
while (offset < size && ((u32)next_node < (u32)((u32)ep->par.data + size))) {
memcpy(&eff_struct_len, next_node, 2);
if (!eff_struct_len) {
log_error("eff_struct_len error offset %d size %d\n", offset, size);
break;
}
new_ep = (struct eff_online_packet *)malloc(eff_struct_len + 4);//struct eff_struct结构长度 + cmd长度
if (new_ep) {//重组packet并做更新
/* printf("offset %d ,size %d, eff_struct_len %d\n", offset, size, eff_struct_len); */
new_ep->cmd = EFF_ADJ_CMD;
memcpy((void *)&new_ep->par, &next_node[2], eff_struct_len);
eff_online_update_base((void *)new_ep, eff_struct_len + 4, sq);
free(new_ep);
new_ep = NULL;
next_node = &next_node[eff_struct_len + 2]; //取下一个节点的数据地址
offset += (eff_struct_len + 2);//struct eff_struct长度+ 2byte len
} else {
log_error("alloc new_packet error\n");
break;
}
}
res = ERR_NONE;
} else {
res = eff_online_update_base(ep, size, sq);
}
break;
default:
res = eff_online_update_base(ep, size, sq);
break;
}
return res;
}
static void eff_send_packet(u32 id, u8 sq, u8 *packet, int size)
{
all_assemble_package_send_to_pc(id, sq, packet, size);
}
void eff_node_send_packet(u32 id, u8 sq, u8 *packet, int size)
{
all_assemble_package_send_to_pc(id, sq, packet, size);
}
static void effect_tool_callback(u8 *packet, u32 size)
{
int res = 0;
u8 id = packet[0];
u8 sq = packet[1];
u8 *eff_packet = (u8 *)&packet[2];
ASSERT(((int)eff_packet & 0x3) == 0, "packet %x size %d\n", (unsigned int)eff_packet, size - 2);
res = eff_online_update((void *)&packet[2], size - 2, sq);
switch (res) {
case EFF_ERR_TYPE_PTR_NULL:
log_debug("buf err");
eff_send_packet(REPLY_TO_TOOL, sq, (u8 *)"ER_FLOW_OPEN_BUF", strlen("ER_FLOW_OPEN_BUF"));
break;
case EFF_ERR_TYPE_ALGORITHM_NULL:
log_debug("algorithm err");
eff_send_packet(REPLY_TO_TOOL, sq, (u8 *)"ER_FLOW_OPEN_ALGORITHM", strlen("ER_FLOW_OPEN_ALGORITHM"));
break;
case ERR_COMM:
log_debug("Nack");
eff_send_packet(REPLY_TO_TOOL, sq, (u8 *)"ER", strlen("ER"));
break;
case EFF_ERR_CRC:
log_debug("crc err");
eff_send_packet(REPLY_TO_TOOL, sq, (u8 *)"ER_FLOW_CRC", strlen("ER_FLOW_CRC"));
break;
case ERR_ACCEPTABLE:
//可接受的错误,由case内部处理,返回内部数据
log_debug("accept");
break;
default:
log_debug("Ack");
eff_send_packet(REPLY_TO_TOOL, sq, (u8 *)"OK", strlen("OK"));
break;
}
}
REGISTER_DETECT_TARGET(eff_adj_target) = {
.id = EFF_CONFIG_ID,
.tool_message_deal = effect_tool_callback,
};
#endif
+256
View File
@@ -0,0 +1,256 @@
#ifdef SUPPORT_MS_EXTENSIONS
#pragma bss_seg(".effects_default_param.data.bss")
#pragma data_seg(".effects_default_param.data")
#pragma const_seg(".effects_default_param.text.const")
#pragma code_seg(".effects_default_param.text")
#endif
#include "system/includes.h"
#include "media/includes.h"
#include "app_config.h"
#include "audio_config.h"
#include "jlstream.h"
#include "cfg_tool.h"
#include "effects/effects_adj.h"
#include "effects/audio_eq.h"
#include "effects/eq_config.h"
#include "effects/audio_wdrc.h"
#include "effects/audio_pitchspeed.h"
#include "effects/audio_spk_eq.h"
#include "media/audio_energy_detect.h"
#include "bass_treble.h"
#include "scene_switch.h"
#include "effects_default_param.h"
#include "ascii.h"
struct effect_default_hdl {
u16 pitchV;
};
struct effect_default_hdl effect_default = {
.pitchV = 32768,
};
static u32 effect_strcmp(const char *str1, const char *str2);
u8 __attribute__((weak)) get_current_scene()
{
return 0;
}
u8 __attribute__((weak)) get_mic_current_scene()
{
return 0;
}
u8 __attribute__((weak)) get_music_eq_preset_index(void)
{
return 0;
}
float powf(float x, float y);
static int get_pitchV(float pitch)
{
int pitchV = 32768 * powf(2.0f, pitch / 12);
pitchV = (pitchV >= 65536) ? 65534 : pitchV; //传入算法是u16类型,作特殊处理防止溢出
return pitchV;
}
u16 audio_pitch_default_parm_set(u8 pitch_mode)
{
float pitch_param_table[] = {-12, -10, -8, -6, -4, -2, 0, 2, 4, 6, 8, 10, 12};
effect_default.pitchV = get_pitchV(pitch_param_table[pitch_mode]);
return effect_default.pitchV;
}
static void audio_energy_det_handler(void *prive, u8 event, u8 ch, u8 ch_total)
{
char name[16];
memcpy(name, prive, strlen(prive));
//name 模块名称,唯一标识
// ch < ch_total 时:表示通道(ch)触发的事件
// ch = ch_total 时:表示全部通道都触发的事件
if (ch < ch_total) {
/*
*针对独立通道,比如立体声场景,这里就分别显示ch0和ch1的能量
*适用于独立控制声道mute的场景
*/
printf(">>>>name:%s ch:%d %s\n", name, ch, event ? ("MUTE") : ("UNMUTE"));
}
if (ch == ch_total) {
/*
*针对所有通道,比如立体声场景,只有ch0和ch1都是muteall_ch才是mute
*适用于控制整体
*/
printf(">>>>name:%s ch_total %s\n", name, event ? ("MUTE") : ("UNMUTE"));
}
}
/*
*获取需要指定得默认配置
* */
int get_eff_default_param(int arg)
{
int ret = 0;
/* struct node_id *nodeid = (struct node_id *)arg; */
struct _name {
char name[16];
};
struct _name *name = (struct _name *)arg;
#if TCFG_SPEAKER_EQ_NODE_ENABLE
if (!strcmp(name->name, "spk_eq")) {
ret = spk_eq_read_from_vm((void *)arg);
}
#endif
#if TCFG_PITCH_SPEED_NODE_ENABLE
if (!strncmp(name->name, "PitchSpeed", strlen("PitchSpeed"))) { //音乐变速变调 默认参数获取
struct pitch_speed_update_parm *get_parm = (struct pitch_speed_update_parm *)arg;
get_parm->speedV = 80;
get_parm->pitchV = effect_default.pitchV;
ret = 1;
}
#endif
#if TCFG_EQ_ENABLE
if (!strncmp(name->name, "MusicEq", strlen("MusicEq"))) { //音乐eq命名默认: MusicEq + 类型,例如蓝牙音乐eqMusicEqBt
struct eq_default_parm *get_eq_parm = (struct eq_default_parm *)arg;
/*
*默认系数使用eq文件内的哪个配置表
* */
char tar_cfg_index = 0;
get_cur_eq_num(&tar_cfg_index);//获取当前配置项序号
get_eq_parm->cfg_index = tar_cfg_index;
/*
*是否使用sdk内的默认系数表
* */
get_eq_parm->default_tab.seg_num = get_cur_eq_tab(&get_eq_parm->default_tab.global_gain, &get_eq_parm->default_tab.seg);
ret = 1;
}
#endif
#if TCFG_ENERGY_DETECT_NODE_ENABLE
if (!strncmp(name->name, "EnergyDet", strlen("EnergyDet"))) {//能量检查 回调接口配置
struct energy_detect_get_parm *get_parm = (struct energy_detect_get_parm *)arg;
if (get_parm->type == SET_ENERGY_DET_EVENT_HANDLER) {
get_parm->event_handler = audio_energy_det_handler;
ret = 1;
}
}
#endif
#if TCFG_WDRC_NODE_ENABLE
if (!strncmp(name->name, "MusicDrc", strlen("MusicDrc"))) {
struct eff_default_parm *get_parm = (struct eff_default_parm *)arg;
get_parm->cfg_index = 0;//目标配置项
ret = 1;
}
#endif
#if TCFG_BASS_TREBLE_NODE_ENABLE
if (!strncmp(name->name, "MusicBassTre", strlen("MusicBassTre")) || (!effect_strcmp(name->name, "BassMedia"))) {
ret = get_music_bass_treble_parm(arg);
}
#endif
#if TCFG_BASS_TREBLE_NODE_ENABLE
if (!strncmp(name->name, "MicBassTre", strlen("MicBassTre")) || (!effect_strcmp(name->name, "BassTreEff"))) {
ret = get_mic_bass_treble_parm(arg);
}
#endif
#if TCFG_SURROUND_NODE_ENABLE
if (!effect_strcmp(name->name, "SurMedia")) {
struct eff_default_parm *get_parm = (struct eff_default_parm *)arg;
get_parm->cfg_index = 0;
get_parm->mode_index = get_current_scene();
ret = 1;
}
#endif
#if TCFG_CROSSOVER_NODE_ENABLE
if (!effect_strcmp(name->name, "CrossMedia")) {
struct eff_default_parm *get_parm = (struct eff_default_parm *)arg;
get_parm->cfg_index = 0;
get_parm->mode_index = get_current_scene();
ret = 1;
}
#endif
#if (TCFG_3BAND_MERGE_ENABLE || TCFG_2BAND_MERGE_ENABLE)
if (!effect_strcmp(name->name, "BandMedia")) {
struct eff_default_parm *get_parm = (struct eff_default_parm *)arg;
get_parm->cfg_index = 0;
get_parm->mode_index = get_current_scene();
ret = 1;
}
#endif
#if TCFG_BASS_TREBLE_NODE_ENABLE
if (!effect_strcmp(name->name, "BassMedia")) {
struct bass_treble_default_parm *get_bass_parm = (struct bass_treble_default_parm *)arg;
get_bass_parm->cfg_index = 0;
get_bass_parm->mode_index = get_current_scene();
ret = 1;
}
#endif
#if TCFG_STEROMIX_NODE_ENABLE
if (!effect_strcmp(name->name, "Smix*Media")) {
struct eff_default_parm *get_parm = (struct eff_default_parm *)arg;
get_parm->cfg_index = 0;
get_parm->mode_index = get_current_scene();
ret = 1;
}
#endif
#if TCFG_WDRC_NODE_ENABLE
if (!effect_strcmp(name->name, "Drc*Media")) {
struct eff_default_parm *get_parm = (struct eff_default_parm *)arg;
get_parm->cfg_index = 0;
get_parm->mode_index = get_current_scene();
ret = 1;
}
#endif
#if TCFG_EQ_ENABLE
if (!effect_strcmp(name->name, "Eq*Media")) {
struct eq_default_parm *get_eq_parm = (struct eq_default_parm *)arg;
if (!effect_strcmp(name->name, "Eq0Media")) {
get_eq_parm->cfg_index = get_music_eq_preset_index();
} else {
get_eq_parm->cfg_index = 0;
}
get_eq_parm->mode_index = get_current_scene();
ret = 1;
}
#endif
#if TCFG_VOCAL_REMOVER_NODE_ENABLE
if (!effect_strcmp(name->name, "VocalRemovMedia")) {
}
#endif
#if TCFG_EQ_ENABLE
if (!effect_strcmp(name->name, "EscoDlEq") || !effect_strcmp(name->name, "EscoUlEq")) {
struct eq_default_parm *get_eq_parm = (struct eq_default_parm *)arg;
int type = lmp_private_get_esco_packet_type();
int media_type = type & 0xff;
if (media_type == 0) {//narrow band
get_eq_parm->cfg_index = 1;
} else {//wide band
get_eq_parm->cfg_index = 0;
}
ret = 1;
}
#endif
return ret;
}
static u32 effect_strcmp(const char *str1, const char *str2)
{
return ASCII_StrCmp(str1, str2, strlen(str1) + 1);
}
+24
View File
@@ -0,0 +1,24 @@
#ifndef _EFFECTS_DEFAULT_PARAM_
#define _EFFECTS_DEFAULT_PARAM_
#include "generic/typedef.h"
enum _pitch_level {
PITCH_12N = 0x0, //-12 半音符
PITCH_10N, //-10
PITCH_8N, //-8
PITCH_6N, //-6
PITCH_4N, //-4
PITCH_2N, //-2
PITCH_0, //0
PITCH_2, //2
PITCH_4, //4
PITCH_6, //6
PITCH_8, //8
PITCH_10, //10
PITCH_12, //12
};
u16 audio_pitch_default_parm_set(u8 pitch_mode);
#endif
+523
View File
@@ -0,0 +1,523 @@
#ifdef SUPPORT_MS_EXTENSIONS
#pragma bss_seg(".eq_config.data.bss")
#pragma data_seg(".eq_config.data")
#pragma const_seg(".eq_config.text.const")
#pragma code_seg(".eq_config.text")
#endif
#include "system/includes.h"
#include "media/includes.h"
#include "app_config.h"
#include "effects/eq_config.h"
#include "effects/effects_adj.h"
#include "audio_config.h"
#include "jlstream.h"
/*
*双核EQ选配策略
*0: 自动选配,适合无混响环境,或者有混响但有eq的数据流不大于2条的环境
*1:混响固定选配到EQ1,其余eq选配到EQ0
* */
#if defined(TCFG_MIC_EFFECT_ENABLE)&& TCFG_MIC_EFFECT_ENABLE
const int audio_eq_core_sel = 1;
#else
const int audio_eq_core_sel = 0;
#endif
#if TCFG_EQ_ENABLE
#define mSECTION_MAX eq_get_table_nsection(eq_mode)
#define EQ_FADE_TIME 10 //新版sdk该宏定义只是本文件内eq淡入更新系数相关应用的使能位,旧版本则是更新系数timer的运行周期单位ms
#define EQ_FADE_STEP 0.1f //增益的淡入步进,单位dB
#define MODE_INDEX_DEFAULT 0
const struct eq_seg_info eq_tab_normal[] = {
{0, EQ_IIR_TYPE_BAND_PASS, 31, 0, 0.7f},
{1, EQ_IIR_TYPE_BAND_PASS, 62, 0, 0.7f},
{2, EQ_IIR_TYPE_BAND_PASS, 125, 0, 0.7f},
{3, EQ_IIR_TYPE_BAND_PASS, 250, 0, 0.7f},
{4, EQ_IIR_TYPE_BAND_PASS, 500, 0, 0.7f},
{5, EQ_IIR_TYPE_BAND_PASS, 1000, 0, 0.7f},
{6, EQ_IIR_TYPE_BAND_PASS, 2000, 0, 0.7f},
{7, EQ_IIR_TYPE_BAND_PASS, 4000, 0, 0.7f},
{8, EQ_IIR_TYPE_BAND_PASS, 8000, 0, 0.7f},
{9, EQ_IIR_TYPE_BAND_PASS, 16000, 0, 0.7f},
};
const struct eq_seg_info eq_tab_rock[] = {
{0, EQ_IIR_TYPE_BAND_PASS, 31, -2, 0.7f},
{1, EQ_IIR_TYPE_BAND_PASS, 62, 0, 0.7f},
{2, EQ_IIR_TYPE_BAND_PASS, 125, 2, 0.7f},
{3, EQ_IIR_TYPE_BAND_PASS, 250, 4, 0.7f},
{4, EQ_IIR_TYPE_BAND_PASS, 500, -2, 0.7f},
{5, EQ_IIR_TYPE_BAND_PASS, 1000, -2, 0.7f},
{6, EQ_IIR_TYPE_BAND_PASS, 2000, 0, 0.7f},
{7, EQ_IIR_TYPE_BAND_PASS, 4000, 0, 0.7f},
{8, EQ_IIR_TYPE_BAND_PASS, 8000, 4, 0.7f},
{9, EQ_IIR_TYPE_BAND_PASS, 16000, 4, 0.7f},
};
const struct eq_seg_info eq_tab_pop[] = {
{0, EQ_IIR_TYPE_BAND_PASS, 31, 3, 0.7f},
{1, EQ_IIR_TYPE_BAND_PASS, 62, 1, 0.7f},
{2, EQ_IIR_TYPE_BAND_PASS, 125, 0, 0.7f},
{3, EQ_IIR_TYPE_BAND_PASS, 250, -2, 0.7f},
{4, EQ_IIR_TYPE_BAND_PASS, 500, -4, 0.7f},
{5, EQ_IIR_TYPE_BAND_PASS, 1000, -4, 0.7f},
{6, EQ_IIR_TYPE_BAND_PASS, 2000, -2, 0.7f},
{7, EQ_IIR_TYPE_BAND_PASS, 4000, 0, 0.7f},
{8, EQ_IIR_TYPE_BAND_PASS, 8000, 1, 0.7f},
{9, EQ_IIR_TYPE_BAND_PASS, 16000, 2, 0.7f},
};
const struct eq_seg_info eq_tab_classic[] = {
{0, EQ_IIR_TYPE_BAND_PASS, 31, 0, 0.7f},
{1, EQ_IIR_TYPE_BAND_PASS, 62, 8, 0.7f},
{2, EQ_IIR_TYPE_BAND_PASS, 125, 8, 0.7f},
{3, EQ_IIR_TYPE_BAND_PASS, 250, 4, 0.7f},
{4, EQ_IIR_TYPE_BAND_PASS, 500, 0, 0.7f},
{5, EQ_IIR_TYPE_BAND_PASS, 1000, 0, 0.7f},
{6, EQ_IIR_TYPE_BAND_PASS, 2000, 0, 0.7f},
{7, EQ_IIR_TYPE_BAND_PASS, 4000, 0, 0.7f},
{8, EQ_IIR_TYPE_BAND_PASS, 8000, 2, 0.7f},
{9, EQ_IIR_TYPE_BAND_PASS, 16000, 2, 0.7f},
};
const struct eq_seg_info eq_tab_country[] = {
{0, EQ_IIR_TYPE_BAND_PASS, 31, -2, 0.7f},
{1, EQ_IIR_TYPE_BAND_PASS, 62, 0, 0.7f},
{2, EQ_IIR_TYPE_BAND_PASS, 125, 0, 0.7f},
{3, EQ_IIR_TYPE_BAND_PASS, 250, 2, 0.7f},
{4, EQ_IIR_TYPE_BAND_PASS, 500, 2, 0.7f},
{5, EQ_IIR_TYPE_BAND_PASS, 1000, 0, 0.7f},
{6, EQ_IIR_TYPE_BAND_PASS, 2000, 0, 0.7f},
{7, EQ_IIR_TYPE_BAND_PASS, 4000, 0, 0.7f},
{8, EQ_IIR_TYPE_BAND_PASS, 8000, 4, 0.7f},
{9, EQ_IIR_TYPE_BAND_PASS, 16000, 4, 0.7f},
};
const struct eq_seg_info eq_tab_jazz[] = {
{0, EQ_IIR_TYPE_BAND_PASS, 31, 0, 0.7f},
{1, EQ_IIR_TYPE_BAND_PASS, 62, 0, 0.7f},
{2, EQ_IIR_TYPE_BAND_PASS, 125, 0, 0.7f},
{3, EQ_IIR_TYPE_BAND_PASS, 250, 4, 0.7f},
{4, EQ_IIR_TYPE_BAND_PASS, 500, 4, 0.7f},
{5, EQ_IIR_TYPE_BAND_PASS, 1000, 4, 0.7f},
{6, EQ_IIR_TYPE_BAND_PASS, 2000, 0, 0.7f},
{7, EQ_IIR_TYPE_BAND_PASS, 4000, 2, 0.7f},
{8, EQ_IIR_TYPE_BAND_PASS, 8000, 3, 0.7f},
{9, EQ_IIR_TYPE_BAND_PASS, 16000, 4, 0.7f},
};
struct eq_seg_info eq_tab_custom[] = {
{0, EQ_IIR_TYPE_BAND_PASS, 31, 0, 0.7f},
{1, EQ_IIR_TYPE_BAND_PASS, 62, 0, 0.7f},
{2, EQ_IIR_TYPE_BAND_PASS, 125, 0, 0.7f},
{3, EQ_IIR_TYPE_BAND_PASS, 250, 0, 0.7f},
{4, EQ_IIR_TYPE_BAND_PASS, 500, 0, 0.7f},
{5, EQ_IIR_TYPE_BAND_PASS, 1000, 0, 0.7f},
{6, EQ_IIR_TYPE_BAND_PASS, 2000, 0, 0.7f},
{7, EQ_IIR_TYPE_BAND_PASS, 4000, 0, 0.7f},
{8, EQ_IIR_TYPE_BAND_PASS, 8000, 0, 0.7f},
{9, EQ_IIR_TYPE_BAND_PASS, 16000, 0, 0.7f},
};
// 默认系数表,用户可修改
const struct eq_seg_info *eq_type_tab[EQ_MODE_MAX] = {
eq_tab_normal, eq_tab_rock, eq_tab_pop, eq_tab_classic, eq_tab_jazz, eq_tab_country, eq_tab_custom
};
// 默认系数表,每个表对应的总增益,用户可修改
float global_gain_tab[EQ_MODE_MAX] = {0, 0, 0, 0, 0, 0, 0};
static const u8 tab_section_num[] = {
ARRAY_SIZE(eq_tab_normal), ARRAY_SIZE(eq_tab_rock),
ARRAY_SIZE(eq_tab_pop), ARRAY_SIZE(eq_tab_classic),
ARRAY_SIZE(eq_tab_jazz), ARRAY_SIZE(eq_tab_country),
ARRAY_SIZE(eq_tab_custom)
};
/*
*mode:枚举型EQ_MODE
*return 返回对应系数表的段数
* */
u8 eq_get_table_nsection(EQ_MODE mode)
{
if (mode >= ARRAY_SIZE(eq_type_tab)) {
log_e("mode error %d\n", mode);
return 0;
}
if (mode >= ARRAY_SIZE(tab_section_num)) {
log_e("mode error %d\n", mode);
return 0;
}
return tab_section_num[mode];
}
#define USE_SDK_DEFAULT_EQ_TAB 1//使用sdk内置的默认系数表,
#define USE_FILE_DEFAULT_EQ_TAB 2//使用效果文件内内置的默认系数表
static u8 eq_mode = 0;
static u8 use_eq_tab_mark = 0;//使用过eq_mode_sw或者eq_mode_set接口, use_eq_tab_mark = 1
//使用过eq_file_cfg_switch接口, use_eq_tab_mark = 2
static u8 eq_cfg_num = 0;//记录音乐eq配置项序号
static char music_eq_name[][16] = {"MusicEqBt", "Eq0Media"};//耳机蓝牙模式音乐eq节点,音箱蓝牙音乐eq节点定义的名称
//eq效果表切换
int eq_mode_sw(void)
{
eq_mode++;
if (eq_mode >= ARRAY_SIZE(eq_type_tab)) {
eq_mode = 0;
}
struct eq_seg_info *seg = (struct eq_seg_info *)eq_type_tab[eq_mode];
u8 nsection = eq_get_table_nsection(eq_mode);
if (nsection > mSECTION_MAX) {
log_e("ERROR nsection:%d > mSECTION_MAX:%d ", nsection, mSECTION_MAX);
return -1;//
}
if (!nsection) {
log_e("nsection is %d\n", nsection);
return -1;
}
for (int i = 0; i < ARRAY_SIZE(music_eq_name); i++) {
//music eq运行时,直接设置更新
struct eq_adj eff = {0};
eff.type = EQ_GLOBAL_GAIN_CMD;
eff.param.global_gain = global_gain_tab[eq_mode];
eff.fade_parm.fade_time = EQ_FADE_TIME;
eff.fade_parm.fade_step = EQ_FADE_STEP;
int ret = jlstream_set_node_param(NODE_UUID_EQ, music_eq_name[i], &eff, sizeof(eff));
if (ret == false) {
continue ;
}
eff.type = EQ_SEG_NUM_CMD;
eff.param.seg_num = nsection ;
ret = jlstream_set_node_param(NODE_UUID_EQ, music_eq_name[i], &eff, sizeof(eff));
if (ret == false) {
continue ;
}
for (int j = 0; j < nsection; j++) {
eff.type = EQ_SEG_CMD;
memcpy(&eff.param.seg, &seg[j], sizeof(struct eq_seg_info));
jlstream_set_node_param(NODE_UUID_EQ, music_eq_name[i], &eff, sizeof(eff));
}
}
use_eq_tab_mark = USE_SDK_DEFAULT_EQ_TAB;
return 0;
}
//指定设置某个eq效果表
int eq_mode_set(EQ_MODE mode)
{
if (mode >= ARRAY_SIZE(eq_type_tab)) {
log_e("mode err %d\n", mode);
return -1;//
}
eq_mode = mode;
struct eq_seg_info *seg = (struct eq_seg_info *)eq_type_tab[eq_mode];
u8 nsection = eq_get_table_nsection(eq_mode);
if (nsection > mSECTION_MAX) {
log_e("ERROR nsection:%d > mSECTION_MAX:%d ", nsection, mSECTION_MAX);
return -1;//
}
if (!nsection) {
log_e("nsection is %d\n", nsection);
return -1;
}
for (int i = 0; i < ARRAY_SIZE(music_eq_name); i++) {
//music eq运行时,直接设置更新
struct eq_adj eff = {0};
eff.type = EQ_GLOBAL_GAIN_CMD;
eff.param.global_gain = global_gain_tab[eq_mode];
eff.fade_parm.fade_time = EQ_FADE_TIME;
eff.fade_parm.fade_step = EQ_FADE_STEP;
int ret = jlstream_set_node_param(NODE_UUID_EQ, music_eq_name[i], &eff, sizeof(eff));
if (ret == false) {
continue ;
}
eff.type = EQ_SEG_NUM_CMD;
eff.param.seg_num = nsection ;
ret = jlstream_set_node_param(NODE_UUID_EQ, music_eq_name[i], &eff, sizeof(eff));
if (ret == false) {
continue ;
}
for (int j = 0; j < nsection; j++) {
eff.type = EQ_SEG_CMD;
memcpy(&eff.param.seg, &seg[j], sizeof(struct eq_seg_info));
jlstream_set_node_param(NODE_UUID_EQ, music_eq_name[i], &eff, sizeof(eff));
}
}
use_eq_tab_mark = USE_SDK_DEFAULT_EQ_TAB;
return 0;
}
//返回某个eq效果模式标号
EQ_MODE eq_mode_get_cur(void)
{
return eq_mode;
}
/*----------------------------------------------------------------------------*/
/**@brief 设置custom系数表的某一段系数
@param seg->index:第几段(从0开始)
@param seg->iir_type:滤波器类型(EQ_IIR_TYPE_HIGH_PASS, EQ_IIR_TYPE_LOW_PASS, EQ_IIR_TYPE_BAND_PASS, EQ_IIR_TYPE_HIGH_SHELF,EQ_IIR_TYPE_LOW_SHELF)
@param seg->freq:中心截止频率(20~22kHz)
@param seg->gain:总增益(-18~18)
@param seg->q : q值(0.3~30
@return
@note 外部使用
*/
/*----------------------------------------------------------------------------*/
int eq_mode_set_custom_seg(struct eq_seg_info *seg)
{
struct eq_seg_info *tar_seg = eq_tab_custom;
u8 index = seg->index;
if (index > ARRAY_SIZE(eq_tab_custom)) {
log_e("index %d > max_nsection %d", index, ARRAY_SIZE(eq_tab_custom));
return -1;
}
memcpy(&tar_seg[index], seg, sizeof(struct eq_seg_info));
return 0;
}
/*----------------------------------------------------------------------------*/
/**@brief 获取某个模式eq表内,某一段eq的信息
@param
@param
@return 返回eq信息
@note
*/
/*----------------------------------------------------------------------------*/
struct eq_seg_info *eq_mode_get_seg(EQ_MODE mode, u8 index)
{
if (mode >= ARRAY_SIZE(eq_type_tab)) {
log_e("mode error %d\n", mode);
return NULL;
}
if (index >= eq_get_table_nsection(mode)) {
log_e("index error %d\n", index);
return NULL;
}
struct eq_seg_info *seg = (struct eq_seg_info *)eq_type_tab[mode];
return &seg[index];
}
int get_cur_eq_tab(float *global_gain, struct eq_seg_info **seg)
{
if (use_eq_tab_mark == USE_SDK_DEFAULT_EQ_TAB) {
*global_gain = global_gain_tab[eq_mode];
*seg = (struct eq_seg_info *)eq_type_tab[eq_mode];
return tab_section_num[eq_mode];
}
return 0;
}
/*----------------------------------------------------------------------------*/
/**@brief 获取custom系数表的增益、频率
@param index:哪一段
@param freq:中心截止频率
@param gain:增益
@return
@note 外部使用
*/
/*----------------------------------------------------------------------------*/
int eq_mode_set_custom_info(u16 index, int freq, float gain)
{
struct eq_seg_info *seg = eq_mode_get_seg(EQ_MODE_CUSTOM, index);//获取某段eq系数
if (!seg) {
return -1;
}
seg->freq = freq;//修改freq gain
seg->gain = gain;
eq_mode_set_custom_seg(seg);//重设系数
eq_mode_set(EQ_MODE_CUSTOM);//设置更新系数
return 0;
}
/*----------------------------------------------------------------------------*/
/**@brief 设置用custom系数表一段eq的增益
@param index:哪一段
@param gain:增益
@return
@note 外部使用
*/
/*----------------------------------------------------------------------------*/
int eq_mode_set_custom_param(u16 index, int gain)
{
struct eq_seg_info *seg = eq_mode_get_seg(EQ_MODE_CUSTOM, index);//获取某段eq系数
if (!seg) {
return -1;
}
seg->gain = gain;
eq_mode_set_custom_seg(seg);//重设系数
eq_mode_set(EQ_MODE_CUSTOM);//设置更新系数
return 0;
}
s8 eq_mode_get_gain(EQ_MODE mode, u16 index)
{
struct eq_seg_info *seg = eq_mode_get_seg(mode, index);
if (!seg) {
return 0;
}
return seg->gain;
}
/*----------------------------------------------------------------------------*/
/**@brief 获取某eq系数表一段eq的中心截止频率
@param mode:EQ_MODE_NORMAL, EQ_MODE_ROCK,EQ_MODE_POP,EQ_MODE_CLASSIC,EQ_MODE_JAZZ,EQ_MODE_COUNTRY, EQ_MODE_CUSTOM
@param index:哪一段
@return 中心截止频率
@note 外部使用
*/
/*----------------------------------------------------------------------------*/
int eq_mode_get_freq(EQ_MODE mode, u16 index)
{
struct eq_seg_info *seg = eq_mode_get_seg(mode, index);
if (!seg) {
return 0;
}
return seg->freq;
}
/*----------------------------------------------------------------------------*/
/**@brief 设置用custom系数表一段eq的增益
@param index:哪一段
@param gain:增益
@return
@note 外部使用
*/
/*----------------------------------------------------------------------------*/
void set_global_gain(EQ_MODE mode, float global_gain)
{
global_gain_tab[mode] = global_gain;
struct eq_adj eff = {0};
for (int i = 0; i < ARRAY_SIZE(music_eq_name); i++) {
eff.type = EQ_GLOBAL_GAIN_CMD;
eff.param.global_gain = global_gain_tab[mode];
eff.fade_parm.fade_time = EQ_FADE_TIME;
eff.fade_parm.fade_step = EQ_FADE_STEP;
int ret = jlstream_set_node_param(NODE_UUID_EQ, music_eq_name[i], &eff, sizeof(eff));
if (ret == true) {
break;
}
}
}
/*
*获取指定偏移内的eq配置
*info结构通过jlstream_read_form_node_info_base接口获取
* */
void eq_file_cfg_update(char *name, struct cfg_info info)
{
struct eq_tool *tab = zalloc(info.size);
int len = jlstream_read_form_cfg_data(&info, tab);
#if 0
printf("tab->global_gain 0x%x\n", *(int *)&tab->global_gain);
printf("tab->seg_num %d\n", tab->seg_num);
for (int i = 0; i < tab->seg_num; i++) {
struct eq_seg_info *seg = (struct eq_seg_info *)&tab->seg[i];
printf("idx:%d, iir:%d, freq:%d, gain:0x%08x, q:0x%08x ", seg->index, seg->iir_type, seg->freq, *(int *)&seg->gain, *(int *)&seg->q);
}
#endif
if (!len) {
printf("user eq cfg parm read err %d, %d\n", len, info.size);
free(tab);
return;
}
if (tab->seg_num > AUDIO_EQ_MAX_SECTION) {
printf("error:info.max_nsection(%d) > max(%d)\n", tab->seg_num, AUDIO_EQ_MAX_SECTION);
free(tab);
return;
}
//运行时,直接设置更新
struct eq_adj eff = {0};
eff.type = EQ_GLOBAL_GAIN_CMD;
eff.param.global_gain = tab->global_gain;
eff.fade_parm.fade_time = EQ_FADE_TIME;
eff.fade_parm.fade_step = EQ_FADE_STEP;
jlstream_set_node_param(NODE_UUID_EQ, name, &eff, sizeof(eff));
eff.type = EQ_SEG_NUM_CMD;
eff.param.seg_num = tab->seg_num;
jlstream_set_node_param(NODE_UUID_EQ, name, &eff, sizeof(eff));
for (int j = 0; j < tab->seg_num; j++) {
eff.type = EQ_SEG_CMD;
memcpy(&eff.param.seg, &tab->seg[j], sizeof(struct eq_seg_info));
jlstream_set_node_param(NODE_UUID_EQ, name, &eff, sizeof(eff));
}
free(tab);
}
/*
*调用本接口,可切换到eq节点内指定的配置项
*name:eq节点的名字
*cfg_index:eq配置项的序号
* */
void eq_file_cfg_switch(char *name, char cfg_index)
{
struct cfg_info info = {0};
if (jlstream_read_form_node_info_base(MODE_INDEX_DEFAULT, name, cfg_index, &info)) {
printf("user read eq node info err\n");
return;
}
eq_file_cfg_update(name, info);
if (!strncmp(name, "MusicEq", 7)) {
eq_cfg_num = cfg_index;
use_eq_tab_mark = USE_FILE_DEFAULT_EQ_TAB;
}
}
// 使用过eq_file_cfg_switch接口时,本接口可获取musicEq的序号
int get_cur_eq_num(char *cfg_index)
{
int ret = 0;
if (use_eq_tab_mark == USE_FILE_DEFAULT_EQ_TAB) {
*cfg_index = eq_cfg_num;
ret = 1;
}
return ret;
}
void test_eq_switch(void *p)
{
static u8 cnt = 0 ;
cnt++;
if (cnt == 3) {
puts("-------------------------0\n");
eq_file_cfg_switch("MusicEqBt", 0);
} else if (cnt == 6) {
puts("-------------------------1\n");
eq_file_cfg_switch("MusicEqBt", 1);
cnt = 0;
}
}
#endif
+18
View File
@@ -0,0 +1,18 @@
#ifdef SUPPORT_MS_EXTENSIONS
#pragma bss_seg(".esco_ul_voice_changer.data.bss")
#pragma data_seg(".esco_ul_voice_changer.data")
#pragma const_seg(".esco_ul_voice_changer.text.const")
#pragma code_seg(".esco_ul_voice_changer.text")
#endif
#include "audio_voice_changer_api.h"
#include "esco_recoder.h"
#include "app_config.h"
#if TCFG_VOICE_CHANGER_NODE_ENABLE
void audio_esco_ul_voice_change(u32 sound_mode)
{
audio_voice_changer_mode_switch(NODE_UUID_VOICE_CHANGER, "esco_vchanger", sound_mode);
}
#endif
+273
View File
@@ -0,0 +1,273 @@
#ifdef SUPPORT_MS_EXTENSIONS
#pragma bss_seg(".node_param_update.data.bss")
#pragma data_seg(".node_param_update.data")
#pragma const_seg(".node_param_update.text.const")
#pragma code_seg(".node_param_update.text")
#endif
#include "jlstream.h"
#include "node_uuid.h"
#include "effects/effects_adj.h"
#include "node_param_update.h"
/* 各模块参数更新接口 */
void stero_mix_update_parm(u8 mode_index, char *node_name, u8 cfg_index)
{
stereo_mix_gain_param_tool_set cfg = {0};
int ret = jlstream_read_form_data(mode_index, node_name, cfg_index, &cfg);
if (!ret) {
printf("read parm err, %s, %s\n", __func__, node_name);
return;
}
jlstream_set_node_param(NODE_UUID_STEROMIX, node_name, &cfg, sizeof(cfg));
}
void surround_effect_update_parm(u8 mode_index, char *node_name, u8 cfg_index)
{
surround_effect_param_tool_set cfg = {0};
int ret = jlstream_read_form_data(mode_index, node_name, cfg_index, &cfg);
if (!ret) {
printf("read parm err, %s, %s\n", __func__, node_name);
return;
}
jlstream_set_node_param(NODE_UUID_SURROUND, node_name, &cfg, sizeof(cfg));
}
void crossover_update_parm(u8 mode_index, char *node_name, u8 cfg_index)
{
crossover_param_tool_set cfg = {0};
int ret = jlstream_read_form_data(mode_index, node_name, cfg_index, &cfg);
if (!ret) {
printf("read parm err, %s, %s\n", __func__, node_name);
return;
}
if (cfg.parm.way_num == 3) {
jlstream_set_node_param(NODE_UUID_CROSSOVER, node_name, &cfg, sizeof(cfg));
} else {
jlstream_set_node_param(NODE_UUID_CROSSOVER_2BAND, node_name, &cfg, sizeof(cfg));
}
}
void band_merge_update_parm(u8 mode_index, char *node_name, u8 cfg_index)
{
multi_mix_param_tool_set cfg = {0};
int ret = jlstream_read_form_data(mode_index, node_name, cfg_index, &cfg);
if (!ret) {
printf("read parm err, %s, %s\n", __func__, node_name);
return;
}
jlstream_set_node_param(NODE_UUID_3BAND_MERGE, node_name, &cfg, sizeof(cfg));
}
void drc_update_parm(u8 mode_index, char *node_name, u8 cfg_index)
{
wdrc_param_tool_set cfg = {0};
int ret = jlstream_read_form_data(mode_index, node_name, cfg_index, &cfg);
if (!ret) {
printf("read parm err, %s, %s\n", __func__, node_name);
return;
}
jlstream_set_node_param(NODE_UUID_WDRC, node_name, &cfg, sizeof(cfg));
}
void bass_treble_update_parm(u8 mode_index, char *node_name, u8 cfg_index)
{
bass_treble_param_tool_set cfg = {0};
int ret = jlstream_read_form_data(mode_index, node_name, cfg_index, &cfg);
if (!ret) {
printf("read parm err, %s, %s\n", __func__, node_name);
return;
}
jlstream_set_node_param(NODE_UUID_BASS_TREBLE, node_name, &cfg, sizeof(cfg));
}
void autotune_update_parm(u8 mode_index, char *node_name, u8 cfg_index)
{
autotune_param_tool_set cfg = {0};
int ret = jlstream_read_form_data(mode_index, node_name, cfg_index, &cfg);
if (!ret) {
printf("read parm err, %s, %s\n", __func__, node_name);
return;
}
jlstream_set_node_param(NODE_UUID_AUTOTUNE, node_name, &cfg, sizeof(cfg));
}
void chorus_udpate_param(u8 mode_index, char *node_name, u8 cfg_index)
{
chorus_param_tool_set cfg = {0};
int ret = jlstream_read_form_data(mode_index, node_name, cfg_index, &cfg);
if (!ret) {
printf("read parm err, %s, %s\n", __func__, node_name);
return;
}
jlstream_set_node_param(NODE_UUID_CHORUS, node_name, &cfg, sizeof(cfg));
}
void dynamic_eq_update_parm(u8 mode_index, char *node_name, u8 cfg_index)
{
dynamic_eq_param_tool_set cfg = {0};
int ret = jlstream_read_form_data(mode_index, node_name, cfg_index, &cfg);
if (!ret) {
printf("read parm err, %s, %s\n", __func__, node_name);
return;
}
jlstream_set_node_param(NODE_UUID_DYNAMIC_EQ, node_name, &cfg, sizeof(cfg));
}
void echo_update_parm(u8 mode_index, char *node_name, u8 cfg_index)
{
echo_param_tool_set cfg = {0};
int ret = jlstream_read_form_data(mode_index, node_name, cfg_index, &cfg);
if (!ret) {
printf("read parm err, %s, %s\n", __func__, node_name);
return;
}
jlstream_set_node_param(NODE_UUID_ECHO, node_name, &cfg, sizeof(cfg));
}
void howling_frequency_shift_update_parm(u8 mode_index, char *node_name, u8 cfg_index)
{
howling_pitchshift_param_tool_set cfg = {0};
int ret = jlstream_read_form_data(mode_index, node_name, cfg_index, &cfg);
if (!ret) {
printf("read parm err, %s, %s\n", __func__, node_name);
return;
}
jlstream_set_node_param(NODE_UUID_FREQUENCY_SHIFT, node_name, &cfg, sizeof(cfg));
}
void howling_suppress_update_parm(u8 mode_index, char *node_name, u8 cfg_index)
{
notch_howling_param_tool_set cfg = {0};
int ret = jlstream_read_form_data(mode_index, node_name, cfg_index, &cfg);
if (!ret) {
printf("read parm err, %s, %s\n", __func__, node_name);
return;
}
jlstream_set_node_param(NODE_UUID_HOWLING_SUPPRESS, node_name, &cfg, sizeof(cfg));
}
void gain_update_parm(u8 mode_index, char *node_name, u8 cfg_index)
{
gain_param_tool_set cfg = {0};
int ret = jlstream_read_form_data(mode_index, node_name, cfg_index, &cfg);
if (!ret) {
printf("read parm err, %s, %s\n", __func__, node_name);
return;
}
jlstream_set_node_param(NODE_UUID_GAIN, node_name, &cfg, sizeof(cfg));
}
void noisegate_update_parm(u8 mode_index, char *node_name, u8 cfg_index)
{
noisegate_param_tool_set cfg = {0};
int ret = jlstream_read_form_data(mode_index, node_name, cfg_index, &cfg);
if (!ret) {
printf("read parm err, %s, %s\n", __func__, node_name);
return;
}
jlstream_set_node_param(NODE_UUID_NOISEGATE, node_name, &cfg, sizeof(cfg));
}
void reverb_update_parm(u8 mode_index, char *node_name, u8 cfg_index)
{
plate_reverb_param_tool_set cfg = {0};
int ret = jlstream_read_form_data(mode_index, node_name, cfg_index, &cfg);
if (!ret) {
printf("read parm err, %s, %s\n", __func__, node_name);
return;
}
jlstream_set_node_param(NODE_UUID_PLATE_REVERB, node_name, &cfg, sizeof(cfg));
}
void reverb_advance_update_parm(u8 mode_index, char *node_name, u8 cfg_index)
{
plate_reverb_param_tool_set cfg = {0};
int ret = jlstream_read_form_data(mode_index, node_name, cfg_index, &cfg);
if (!ret) {
printf("read parm err, %s, %s\n", __func__, node_name);
return;
}
jlstream_set_node_param(NODE_UUID_PLATE_REVERB_ADVANCE, node_name, &cfg, sizeof(cfg));
}
void spectrum_update_parm(u8 mode_index, char *node_name, u8 cfg_index)
{
struct spectrum_parm cfg = {0};
int ret = jlstream_read_form_data(mode_index, node_name, cfg_index, &cfg);
if (!ret) {
printf("read parm err, %s, %s\n", __func__, node_name);
return;
}
jlstream_set_node_param(NODE_UUID_SPECTRUM, node_name, &cfg, sizeof(cfg));
}
void stereo_widener_update_parm(u8 mode_index, char *node_name, u8 cfg_index)
{
stereo_widener_param_tool_set cfg = {0};
int ret = jlstream_read_form_data(mode_index, node_name, cfg_index, &cfg);
if (!ret) {
printf("read parm err, %s, %s\n", __func__, node_name);
return;
}
jlstream_set_node_param(NODE_UUID_STEREO_WIDENER, node_name, &cfg, sizeof(cfg));
}
void virtual_bass_update_parm(u8 mode_index, char *node_name, u8 cfg_index)
{
virtual_bass_param_tool_set cfg = {0};
int ret = jlstream_read_form_data(mode_index, node_name, cfg_index, &cfg);
if (!ret) {
printf("read parm err, %s, %s\n", __func__, node_name);
return;
}
jlstream_set_node_param(NODE_UUID_VBASS, node_name, &cfg, sizeof(cfg));
}
void voice_changer_update_parm(u8 mode_index, char *node_name, u8 cfg_index)
{
voice_changer_param_tool_set cfg = {0};
int ret = jlstream_read_form_data(mode_index, node_name, cfg_index, &cfg);
if (!ret) {
return;
}
jlstream_set_node_param(NODE_UUID_VOICE_CHANGER, node_name, &cfg, sizeof(cfg));
}
void channel_expander_update_parm(u8 mode_index, char *node_name, u8 cfg_index)
{
channel_expander_param_tool_set cfg = {0};
int ret = jlstream_read_form_data(mode_index, node_name, cfg_index, &cfg);
if (!ret) {
printf("read parm err, %s, %s\n", __func__, node_name);
return;
}
jlstream_set_node_param(NODE_UUID_CHANNEL_EXPANDER, node_name, &cfg, sizeof(cfg));
}
void harmonic_exciter_update_parm(u8 mode_index, char *node_name, u8 cfg_index)
{
harmonic_exciter_param_tool_set cfg = {0};
int ret = jlstream_read_form_data(mode_index, node_name, cfg_index, &cfg);
if (!ret) {
printf("read parm err, %s, %s\n", __func__, node_name);
return;
}
jlstream_set_node_param(NODE_UUID_HARMONIC_EXCITER, node_name, &cfg, sizeof(cfg));
}
/* eq参数更新接口 */
void eq_update_parm(u8 mode_index, char *node_name, u8 cfg_index)
{
struct cfg_info info = {0}; //节点配置相关信息(参数存储的目标地址、配置项大小)
int ret = jlstream_read_form_node_info_base(mode_index, node_name, cfg_index, &info);
if (!ret) {
struct eq_tool *tab = zalloc(info.size);
if (!jlstream_read_form_cfg_data(&info, tab)) {
printf("user eq cfg parm read err\n");
free(tab);
return;
}
//运行时,直接设置更新
struct eq_adj eff = {0};
eff.type = EQ_GLOBAL_GAIN_CMD;
eff.param.global_gain = tab->global_gain;
eff.fade_parm.fade_time = 10; //ms,淡入timer执行的周期
eff.fade_parm.fade_step = 0.1f; //淡入步进
jlstream_set_node_param(NODE_UUID_EQ, node_name, &eff, sizeof(eff));//更新总增益
eff.type = EQ_SEG_NUM_CMD;
eff.param.seg_num = tab->seg_num;
jlstream_set_node_param(NODE_UUID_EQ, node_name, &eff, sizeof(eff));//更新滤波器段数
for (int i = 0; i < tab->seg_num; i++) {
eff.type = EQ_SEG_CMD;
memcpy(&eff.param.seg, &tab->seg[i], sizeof(struct eq_seg_info));
jlstream_set_node_param(NODE_UUID_EQ, node_name, &eff, sizeof(eff));//更新滤波器系数
}
free(tab);
}
}
+73
View File
@@ -0,0 +1,73 @@
#ifndef __NODE_PARAM_UPDATE_H_
#define __NODE_PARAM_UPDATE_H_
#include "effects/audio_gain_process.h"
#include "effects/audio_surround.h"
#include "effects/audio_bass_treble_eq.h"
#include "effects/audio_crossover.h"
#include "effects/multi_ch_mix.h"
#include "effects/eq_config.h"
#include "effects/audio_wdrc.h"
#include "effects/audio_autotune.h"
#include "effects/audio_chorus.h"
#include "effects/dynamic_eq.h"
#include "effects/audio_echo.h"
#include "effects/audio_frequency_shift_howling.h"
#include "effects/audio_noisegate.h"
#include "effects/audio_notch_howling.h"
#include "effects/audio_pitchspeed.h"
#include "effects/audio_reverb.h"
#include "effects/spectrum/spectrum_fft.h"
#include "effects/audio_stereo_widener.h"
#include "effects/audio_vbass.h"
#include "effects/audio_voice_changer.h"
#include "effects/channel_adapter.h"
#include "effects/audio_harmonic_exciter.h"
/* 左右声道按照不同比例混合参数更新 */
void stereo_mix_update_parm(u8 mode_index, char *node_name, u8 cfg_index);
/* 环绕声参数更新 */
void surround_effect_update_parm(u8 mode_index, char *node_name, u8 cfg_index);
/* 分频器参数更新 */
void crossover_update_parm(u8 mode_index, char *node_name, u8 cfg_index);
/* 多带合并参数更新 */
void band_merge_update_parm(u8 mode_index, char *node_name, u8 cfg_index);
/* drc参数更新 */
void drc_update_parm(u8 mode_index, char *node_name, u8 cfg_index);
/* 高低音参数更新 */
void bass_treble_update_parm(u8 mode_index, char *node_name, u8 cfg_index);
/* 电音参数更新 */
void autotune_update_parm(u8 mode_index, char *node_name, u8 cfg_index);
/* 合唱参数更新 */
void chorus_update_param(u8 mode_index, char *node_name, u8 cfg_index);
/* 动态eq参数更新 */
void dynamic_eq_update_parm(u8 mode_index, char *node_name, u8 cfg_index);
/* 回声参数更新 */
void echo_update_parm(u8 mode_index, char *node_name, u8 cfg_index);
/* 啸叫抑制-移频参数更新 */
void howling_frequency_shift_update_parm(u8 mode_index, char *node_name, u8 cfg_index);
/* 啸叫抑制-陷波参数更新 */
void howling_suppress_update_parm(u8 mode_index, char *node_name, u8 cfg_index);
/* 增益控制参数更新 */
void gain_update_parm(u8 mode_index, char *node_name, u8 cfg_index);
/* 噪声门限参数更新 */
void noisegate_update_parm(u8 mode_index, char *node_name, u8 cfg_index);
/* 混响参数更新 */
void reverb_update_parm(u8 mode_index, char *node_name, u8 cfg_index);
/* 高阶混响参数更新 */
void reverb_advance_update_parm(u8 mode_index, char *node_name, u8 cfg_index);
/* 频谱计算参数更新 */
void spectrum_update_parm(u8 mode_index, char *node_name, u8 cfg_index);
/* 立体声增强参数更新 */
void stereo_widener_update_parm(u8 mode_index, char *node_name, u8 cfg_index);
/* 虚拟低音参数更新 */
void virtual_bass_update_parm(u8 mode_index, char *node_name, u8 cfg_index);
/* 变声参数更新 */
void voice_changer_update_parm(u8 mode_index, char *node_name, u8 cfg_index);
/* 声道扩展参数更新 */
void channel_expander_update_parm(u8 mode_index, char *node_name, u8 cfg_index);
/* eq参数更新 */
void eq_update_parm(u8 mode_index, char *node_name, u8 cfg_index);
/* 谐波激励参数更新 */
void harmonic_exciter_update_parm(u8 mode_index, char *node_name, u8 cfg_index);
#endif
+373
View File
@@ -0,0 +1,373 @@
#ifdef SUPPORT_MS_EXTENSIONS
#pragma bss_seg(".spk_eq.data.bss")
#pragma data_seg(".spk_eq.data")
#pragma const_seg(".spk_eq.text.const")
#pragma code_seg(".spk_eq.text")
#endif
#include "system/includes.h"
#include "media/includes.h"
#include "app_config.h"
#include "audio_config.h"
#include "effects/effects_adj.h"
#include "effects/audio_spk_eq.h"
#include "jlstream.h"
#include "user_cfg_id.h"
#include "online_db_deal.h"
#if TCFG_SPEAKER_EQ_NODE_ENABLE
static u8 spk_eq_read_from_ram = 0;
static float spk_eq_global_gain[2];
static struct eq_seg_info spk_eq_tab[20] = {
//left
{0, EQ_IIR_TYPE_BAND_PASS, 31, 0, 0.7f},
{1, EQ_IIR_TYPE_BAND_PASS, 62, 0, 0.7f},
{2, EQ_IIR_TYPE_BAND_PASS, 125, 0, 0.7f},
{3, EQ_IIR_TYPE_BAND_PASS, 250, 0, 0.7f},
{4, EQ_IIR_TYPE_BAND_PASS, 500, 0, 0.7f},
{5, EQ_IIR_TYPE_BAND_PASS, 1000, 0, 0.7f},
{6, EQ_IIR_TYPE_BAND_PASS, 2000, 0, 0.7f},
{7, EQ_IIR_TYPE_BAND_PASS, 4000, 0, 0.7f},
{8, EQ_IIR_TYPE_BAND_PASS, 8000, 0, 0.7f},
{9, EQ_IIR_TYPE_BAND_PASS, 16000, 0, 0.7f},
//right
{0, EQ_IIR_TYPE_BAND_PASS, 31, 0, 0.7f},
{1, EQ_IIR_TYPE_BAND_PASS, 62, 0, 0.7f},
{2, EQ_IIR_TYPE_BAND_PASS, 125, 0, 0.7f},
{3, EQ_IIR_TYPE_BAND_PASS, 250, 0, 0.7f},
{4, EQ_IIR_TYPE_BAND_PASS, 500, 0, 0.7f},
{5, EQ_IIR_TYPE_BAND_PASS, 1000, 0, 0.7f},
{6, EQ_IIR_TYPE_BAND_PASS, 2000, 0, 0.7f},
{7, EQ_IIR_TYPE_BAND_PASS, 4000, 0, 0.7f},
{8, EQ_IIR_TYPE_BAND_PASS, 8000, 0, 0.7f},
{9, EQ_IIR_TYPE_BAND_PASS, 16000, 0, 0.7f},
};
/*
*spk_eq 系数更新接口,更新第几段eq系数
*parm: *seg
*seg->index:第几段(0~9)
*seg->iir_type:滤波器类型(EQ_IIR_TYPE)
*seg->freq:中心截止频率(20~20kHz)
*seg->gain:增益(-12~13dB
* */
void spk_eq_seg_update(struct eq_seg_info *seg)
{
//段系数更新
struct spk_eq_seg_parm sparm;
sparm.type = UPDATE_SPK_EQ_SEG;
sparm.left_right = 0;
memcpy(&sparm.seg, seg, sizeof(struct eq_seg_info));
int ret = jlstream_set_node_param(NODE_UUID_SPEAKER_EQ, "spk_eq", &sparm, sizeof(sparm));
if (ret <= 0) {
struct eq_seg_info *tar_seg = (struct eq_seg_info *)spk_eq_tab;
memcpy(&tar_seg[sparm.seg.index], &sparm.seg, sizeof(struct eq_seg_info));
}
}
/*
*spk_eq 右声道系数更新接口,更新第几段eq系数
*parm: *seg
*seg->index:第几段(0~9)
*seg->iir_type:滤波器类型(EQ_IIR_TYPE)
*seg->freq:中心截止频率(20~20kHz)
*seg->gain:增益(-12~13dB
* */
void spk_eq_seg_update_R(struct eq_seg_info *seg)
{
//段系数更新
struct spk_eq_seg_parm sparm;
sparm.type = UPDATE_SPK_EQ_SEG;
sparm.left_right = 1;
memcpy(&sparm.seg, seg, sizeof(struct eq_seg_info));
int ret = jlstream_set_node_param(NODE_UUID_SPEAKER_EQ, "spk_eq", &sparm, sizeof(sparm));
if (ret <= 0) {
struct eq_seg_info *tar_seg = (struct eq_seg_info *)&spk_eq_tab[10];
memcpy(&tar_seg[sparm.seg.index], &sparm.seg, sizeof(struct eq_seg_info));
}
}
/*
*spk_eq 左声道总增益更新
* */
void spk_eq_global_gain_udapte(float global_gain)
{
struct spk_eq_global_gain gparm;
gparm.type = UPDATE_SPK_EQ_GLOBAL_GAIN;
gparm.left_right = 0;
gparm.global_gain = global_gain;
printf("dbug 1\n");
int ret = jlstream_set_node_param(NODE_UUID_SPEAKER_EQ, "spk_eq", &gparm, sizeof(gparm));
spk_eq_global_gain[gparm.left_right] = gparm.global_gain;
}
/*
*spk_eq 右声道总增益更新
* */
void spk_eq_global_gain_udapte_R(float global_gain)
{
struct spk_eq_global_gain gparm;
gparm.type = UPDATE_SPK_EQ_GLOBAL_GAIN;
gparm.left_right = 1;
gparm.global_gain = global_gain;
int ret = jlstream_set_node_param(NODE_UUID_SPEAKER_EQ, "spk_eq", &gparm, sizeof(gparm));
spk_eq_global_gain[gparm.left_right] = gparm.global_gain;
}
int spk_eq_save_to_vm(void)
{
int ret_tmp = 0;
struct spk_eq_get_seg_tab seg_tab = {0};
seg_tab.type = GET_SPK_EQ_SEG_TAB;//获取系数表
int ret = jlstream_get_node_param(NODE_UUID_SPEAKER_EQ, "spk_eq", (void *)&seg_tab, sizeof(seg_tab));
if (ret <= 0) {
seg_tab.seg = (struct eq_seg_info *)spk_eq_tab;
seg_tab.tab_size = sizeof(spk_eq_tab);
}
ret = syscfg_write(CFG_SPK_EQ_SEG_SAVE, seg_tab.seg, seg_tab.tab_size);
if (ret <= 0) {
printf("spk_eq tab write to vm err, ret %d\n", ret);
ret_tmp = -1;
}
struct spk_eq_get_global_gain g_gain = {0};
g_gain.type = GET_SPK_EQ_GLOBAL_GAIN;//获取总增益
ret = jlstream_get_node_param(NODE_UUID_SPEAKER_EQ, "spk_eq", (void *)&g_gain, sizeof(g_gain));
if (ret <= 0) {
memcpy(g_gain.global_gain, spk_eq_global_gain, sizeof(spk_eq_global_gain));
}
ret = syscfg_write(CFG_SPK_EQ_GLOBAL_GAIN_SAVE, g_gain.global_gain, sizeof(g_gain.global_gain));
if (ret <= 0) {
printf("spk_eq global gain write to vm err ret %d\n", ret);
ret_tmp = -1;
}
return ret_tmp;
}
/*
*spk_eq 系数表从vm中读取
* */
int spk_eq_read_from_vm(void *priv)
{
struct spk_eq_get_parm *spk_parm = (struct spk_eq_get_parm *)priv;
if (spk_parm->type == GET_SPK_EQ_SEG_TAB) {
spk_parm->seg_tab.seg = (struct eq_seg_info *)spk_eq_tab;
spk_parm->seg_tab.tab_size = sizeof(spk_eq_tab) / 2;
//printf("-------spk tab %x, %d\n", (int)spk_eq_tab, spk_parm->seg_tab.tab_size);
} else if (spk_parm->type == GET_SPK_EQ_VM_DATA) {
struct spk_eq_get_seg_tab *seg_tab = (struct spk_eq_get_seg_tab *)&spk_parm->seg_tab;
struct spk_eq_get_global_gain *g_gain = (struct spk_eq_get_global_gain *)&spk_parm->g_gain;
if (spk_eq_read_from_ram) {
memcpy(g_gain->global_gain, spk_eq_global_gain, sizeof(spk_eq_global_gain));
return 0;
}
spk_eq_read_from_ram = 1;
int ret = syscfg_read(CFG_SPK_EQ_SEG_SAVE, seg_tab->seg, seg_tab->tab_size);
if (ret <= 0) {
printf("skp_eq read from vm err\n");
return -1;
}
ret = syscfg_read(CFG_SPK_EQ_GLOBAL_GAIN_SAVE, g_gain->global_gain, sizeof(g_gain->global_gain));
if (ret <= 0) {
printf("spk_eq global gain read from vm err\n");
return -1;
}
}
return 0;
}
typedef struct {
u16 magic; //0x3344
u16 crc; //data crc
u8 data[32]; //data
} SPK_EQ_PACK;
#define CMD_SEG 0x1
#define CMD_GLOBAL 0x2
#define CMD_SAVE_PARM 0x3
#define CMD_RESET_PARM 0x4
/*
*右声道更新命令
* */
#define CMD_SEG_R 0x5
#define CMD_GLOBAL_R 0x6
#define CMD_SUPPORT_GLOBAL_GAIN 0x7
#define CMD_READ_SEG_L 0x8//左声道或者单声道获取系数表
#define CMD_READ_SEG_R 0x9//右声道获取系数表
#define CMD_READ_GLOBAL_L 0xa //左声道或者单声道获取总增益
#define CMD_READ_GLOBAL_R 0xb //右声道获取总增益
#define SPK_EQ_CRC_EN 0//是否使能crc校验
static u8 parse_seq = 0;
void (*send_data_handler)(u8 seq, u8 *packet, u8 size);
static int spk_eq_ack_packet(u8 seq, u8 *packet, u8 size)
{
if (send_data_handler) {
send_data_handler(seq, packet, size);
} else {
return app_online_db_ack(seq, packet, size);
}
return 0;
}
int spk_eq_spp_rx_packet(u8 *packet, u8 len)
{
SPK_EQ_PACK pack = {0};//packet;
memcpy(&pack, packet, len);
if (pack.magic != 0x3344) {
printf("magic err 0x%x\n", pack.magic);
return -1;
}
struct eq_seg_info seg = {0};
float global_gain = 0;
u8 cmd = pack.data[0];
u16 crc;
printf("cmd %d\n", cmd);
switch (cmd) {
case CMD_SEG:
#if SPK_EQ_CRC_EN
crc = CRC16(pack.data, len - 4);
if (crc != pack.crc) {
printf("spk_seg pack crc err %x, %x\n", crc, pack.crc);
return -1;
}
#endif
memcpy(&seg, &pack.data[1], sizeof(struct eq_seg_info));
spk_eq_seg_update(&seg);
printf("idx:%d, iir:%d, frq:%d, gain:0x%x, q:0x%x \n", seg.index, seg.iir_type, seg.freq, *(int *)&seg.gain, *(int *)&seg.q);
break;
case CMD_GLOBAL:
#if SPK_EQ_CRC_EN
crc = CRC16(pack.data, len - 4);
if (crc != pack.crc) {
printf("spk global gain info pack crc err %x, %x\n", crc, pack.crc);
return -1;
}
#endif
memcpy(&global_gain, &pack.data[1], sizeof(float));
spk_eq_global_gain_udapte(global_gain);
printf("global_gain 0x%x\n", *(int *)&global_gain);
break;
case CMD_SEG_R:
#if SPK_EQ_CRC_EN
crc = CRC16(pack.data, len - 4);
if (crc != pack.crc) {
printf("spk_seg_r pack crc err %x, %x\n", crc, pack.crc);
return -1;
}
#endif
memcpy(&seg, &pack.data[1], sizeof(struct eq_seg_info));
spk_eq_seg_update_R(&seg);
printf("R idx:%d, iir:%d, frq:%d, gain:0x%x, q:0x%x \n", seg.index, seg.iir_type, seg.freq, *(int *)&seg.gain, *(int *)&seg.q);
break;
case CMD_GLOBAL_R:
#if SPK_EQ_CRC_EN
crc = CRC16(pack.data, len - 4);
if (crc != pack.crc) {
printf("spk global gain info pack crc err %x, %x\n", crc, pack.crc);
return -1;
}
#endif
memcpy(&global_gain, &pack.data[1], sizeof(float));
spk_eq_global_gain_udapte_R(global_gain);
printf("R global_gain 0x%x\n", *(int *)&global_gain);
break;
case CMD_SAVE_PARM:
return spk_eq_save_to_vm();
break;
case CMD_RESET_PARM:
struct eq_seg_info seg;
for (int i = 0; i < 10; i++) {
seg.index = i;
seg.freq = 100;
seg.iir_type = EQ_IIR_TYPE_BAND_PASS;
seg.gain = 0.0f;
seg.q = 0.7f;
spk_eq_seg_update(&seg);
spk_eq_seg_update_R(&seg);
}
spk_eq_global_gain_udapte(0);
spk_eq_global_gain_udapte_R(0);
return spk_eq_save_to_vm();
break;
case CMD_SUPPORT_GLOBAL_GAIN:
//suuport global_gain
break;
case CMD_READ_SEG_L:
spk_eq_ack_packet(parse_seq, (u8 *)spk_eq_tab, sizeof(spk_eq_tab) / 2);
return 1;
case CMD_READ_SEG_R:
spk_eq_ack_packet(parse_seq, (u8 *)&spk_eq_tab[10], sizeof(spk_eq_tab) / 2);
return 1;
case CMD_READ_GLOBAL_L:
spk_eq_ack_packet(parse_seq, (u8 *)&spk_eq_global_gain[0], 4);
return 1;
case CMD_READ_GLOBAL_R:
spk_eq_ack_packet(parse_seq, (u8 *)&spk_eq_global_gain[1], 4);
return 1;
default:
printf("crc %d\n", pack.crc);
printf("cmd err %x\n", cmd);
return -1;
}
return 0;
}
int spk_eq_read_seg_l(u8 **buf)
{
*buf = (u8 *)(&spk_eq_tab[0]);
return sizeof(spk_eq_tab) / 2;
}
int spk_eq_read_seg_r(u8 **buf)
{
#if AUDIO_SPK_EQ_STERO
*buf = (u8 *)(&spk_eq_tab[10]);
return sizeof(spk_eq_tab) / 2;
#else
return 0;
#endif
}
int spk_eq_app_online_parse(u8 *packet, u8 size, u8 *ext_data, u16 ext_size)
{
if (ext_data) {
parse_seq = ext_data[1];
} else {
parse_seq = 0xff;
}
printf("parse_seq %x\n", parse_seq);
int ret = spk_eq_spp_rx_packet(packet, size);
if (!ret) {
u8 ack[] = "OK";
spk_eq_ack_packet(parse_seq, ack, sizeof(ack));
} else if (ret != 1) {
u8 ack[] = "ER";
spk_eq_ack_packet(parse_seq, ack, sizeof(ack));
}
return 0;
}
void spk_eq_set_send_data_handler(void (*handler)(u8 seq, u8 *packet, u8 size))
{
send_data_handler = handler;
}
int spk_eq_init(void)
{
#if APP_ONLINE_DEBUG
app_online_db_register_handle(DB_PKT_TYPE_SPK_EQ, spk_eq_app_online_parse);
#endif
return 0;
}
__initcall(spk_eq_init);
#endif