374 lines
11 KiB
C
374 lines
11 KiB
C
#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
|