初版
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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;//数据类型 0:u32 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;//数据类型 0:u32 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
|
||||
|
||||
|
||||
@@ -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都是mute,all_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 + 类型,例如蓝牙音乐eq:MusicEqBt
|
||||
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);
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user