745 lines
26 KiB
C
745 lines
26 KiB
C
#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
|
||
|
||
|