初版
This commit is contained in:
@@ -0,0 +1,532 @@
|
||||
#ifdef SUPPORT_MS_EXTENSIONS
|
||||
#pragma bss_seg(".volume_node.data.bss")
|
||||
#pragma data_seg(".volume_node.data")
|
||||
#pragma const_seg(".volume_node.text.const")
|
||||
#pragma code_seg(".volume_node.text")
|
||||
#endif
|
||||
#include "jlstream.h"
|
||||
#include "classic/tws_api.h"
|
||||
#include "media/audio_base.h"
|
||||
#include "app_main.h"
|
||||
#include "audio_config.h"
|
||||
#include "audio_dvol.h"
|
||||
#include "effects/effects_adj.h"
|
||||
#include "volume_node.h"
|
||||
#include "scene_switch.h"
|
||||
#include "app_config.h"
|
||||
|
||||
struct volume_hdl {
|
||||
char name[16]; //节点名称
|
||||
enum stream_scene scene;
|
||||
dvol_handle *dvol_hdl; //音量操作句柄
|
||||
struct stream_node *node; //节点句柄
|
||||
struct node_port_data_wide data_wide;
|
||||
u8 Qval;//数据的饱和位宽
|
||||
u8 state;
|
||||
u8 bypass;//是否跳过节点处理
|
||||
struct volume_cfg *vol_cfg;
|
||||
u16 cfg_len;//配置数据实际大小
|
||||
u8 online_update_disable;//是否支持在线音量更新
|
||||
u16 target_dig_volume;//优化底噪时的固定数字音量
|
||||
};
|
||||
|
||||
//默认音量配置
|
||||
struct volume_cfg default_vol_cfg = {
|
||||
.bypass = 0,
|
||||
.cfg_level_max = 16,
|
||||
.cfg_vol_min = -45,
|
||||
.cfg_vol_max = 0,
|
||||
.vol_table_custom = 0,
|
||||
.cur_vol = 11,
|
||||
};
|
||||
|
||||
__STREAM_CACHE_CODE
|
||||
static void volume_handle_frame(struct stream_iport *iport, struct stream_note *note)
|
||||
{
|
||||
struct stream_frame *frame;
|
||||
struct stream_node *node = iport->node;
|
||||
struct volume_hdl *hdl = (struct volume_hdl *)iport->private_data;
|
||||
|
||||
while (1) {
|
||||
frame = jlstream_pull_frame(iport, note);
|
||||
if (!frame) {
|
||||
break;
|
||||
}
|
||||
if (!hdl->bypass) {
|
||||
audio_digital_vol_run(hdl->dvol_hdl, (s16 *)frame->data, frame->len);
|
||||
}
|
||||
if (node->oport) {
|
||||
jlstream_push_frame(node->oport, frame);
|
||||
} else {
|
||||
jlstream_free_frame(frame);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int volume_bind(struct stream_node *node, u16 uuid)
|
||||
{
|
||||
struct volume_hdl *hdl = zalloc(sizeof(*hdl));
|
||||
|
||||
node->private_data = hdl;
|
||||
|
||||
hdl->node = node;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void volume_open_iport(struct stream_iport *iport)
|
||||
{
|
||||
iport->handle_frame = volume_handle_frame;
|
||||
iport->private_data = iport->node->private_data;
|
||||
}
|
||||
|
||||
/*节点参数协商*/
|
||||
static int volume_ioc_negotiate(struct stream_iport *iport)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void audio_digital_vol_cfg_init(dvol_handle *dvol, struct volume_cfg *vol_cfg) //初始化配置
|
||||
{
|
||||
if (dvol) {
|
||||
dvol-> cfg_vol_max = vol_cfg->cfg_vol_max;
|
||||
dvol-> cfg_vol_min = vol_cfg->cfg_vol_min;
|
||||
dvol-> cfg_level_max = vol_cfg->cfg_level_max;
|
||||
dvol-> vol_table_custom = vol_cfg->vol_table_custom;
|
||||
#if VOL_TAB_CUSTOM_EN
|
||||
if (dvol->vol_table_custom == VOLUME_TABLE_CUSTOM_EN) {
|
||||
dvol->vol_table = vol_cfg->vol_table ;
|
||||
}
|
||||
#endif
|
||||
dvol->vol_limit = (dvol->vol_limit > dvol->cfg_level_max) ? dvol->cfg_level_max : dvol->vol_limit;
|
||||
u16 vol_level = dvol->vol * dvol->vol_limit / dvol->vol_max;
|
||||
if (vol_level == 0) {
|
||||
dvol->vol_target = 0;
|
||||
} else if (dvol->vol_table) {
|
||||
dvol->vol_target = dvol->vol_table[vol_level - 1];
|
||||
} else {
|
||||
extern float eq_db2mag(float x);
|
||||
u16 step = (dvol->cfg_level_max - 1 > 0) ? (dvol->cfg_level_max - 1) : 1;
|
||||
float step_db = (dvol->cfg_vol_max - dvol->cfg_vol_min) / (float)step;
|
||||
float dvol_db = dvol->cfg_vol_min + (vol_level - 1) * step_db;
|
||||
float dvol_gain = eq_db2mag(dvol_db);//dB转换倍数
|
||||
dvol->vol_target = (s16)(DVOL_MAX_FLOAT * dvol_gain + 0.5f);
|
||||
printf("vol param:%d,(%d/100)dB,cur:%d,max:%d,(%d/100)dB", dvol->vol_target, (int)step_db * 100, vol_level, vol_cfg->cfg_level_max, (int)dvol_db * 100);
|
||||
#if 0
|
||||
//打印音量表每一级的目标音量值和dB值,调试用
|
||||
printf("=========================================vol table=================================================================");
|
||||
int i = 1;
|
||||
for (i = 1; i < dvol->cfg_level_max + 1; i++) {
|
||||
float debug_db = dvol->cfg_vol_min + (i - 1) * step_db;
|
||||
float debug_gain = eq_db2mag(debug_db);//dB转换倍数
|
||||
int debug_target = (s16)(DVOL_MAX_FLOAT * debug_gain + 0.5);
|
||||
printf("dvol[%d] = %d,(%d / 100)dB", i, debug_target, (int)(debug_db * 100));
|
||||
}
|
||||
printf("====================================================================================================================");
|
||||
#endif
|
||||
}
|
||||
|
||||
dvol->vol_fade = 0; //从0开始淡入到目标音量
|
||||
if ((dvol->cfg_vol_min == -45) && (dvol->cfg_level_max == 31) && (dvol->cfg_vol_max == 0)) {
|
||||
dvol-> vol_table_default = 1; //使用默认的音量表
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void volume_ioc_start(struct volume_hdl *hdl)
|
||||
{
|
||||
/*
|
||||
*获取配置文件内的参数,及名字
|
||||
* */
|
||||
int len = 0;
|
||||
struct audio_vol_params params = {0};
|
||||
struct volume_cfg *vol_cfg = NULL;
|
||||
if (!hdl->vol_cfg) {
|
||||
struct cfg_info info = {0}; //节点配置相关信息(参数存储的目标地址、配置项大小)
|
||||
int ret = jlstream_read_node_info_data(hdl->node->uuid, hdl->node->subid, hdl->name, &info);
|
||||
/* printf("enter volume_node.c %d,%d,%d\n", __LINE__, ret, info.size); */
|
||||
if (ret) {
|
||||
hdl->cfg_len = info.size;
|
||||
vol_cfg = hdl->vol_cfg = zalloc(info.size);
|
||||
len = jlstream_read_form_cfg_data(&info, (void *)vol_cfg);
|
||||
if (info.size > sizeof(struct volume_cfg)) { //有自定义音量表,dB转成对应音量
|
||||
for (int i = 0; i < vol_cfg->cfg_level_max ; i++) {
|
||||
/* printf("custom dvol [%d] = %d / 100 dB", i, (int)(hdl->vol_cfg->vol_table[i] * 100)); */
|
||||
float dvol_gain = eq_db2mag(hdl->vol_cfg->vol_table[i]);//dB转换倍数
|
||||
hdl->vol_cfg->vol_table [i] = (s16)(DVOL_MAX_FLOAT * dvol_gain + 0.5f);
|
||||
/* printf("custom dvol[%d] = %d", i, (int)hdl->vol_cfg->vol_table[i]); */
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
len = hdl->cfg_len;
|
||||
vol_cfg = hdl->vol_cfg;
|
||||
}
|
||||
if (!len) {
|
||||
printf("%s, read node data err\n", __FUNCTION__);
|
||||
}
|
||||
|
||||
hdl->data_wide.iport_data_wide = hdl->node->iport->prev->fmt.bit_wide;
|
||||
hdl->data_wide.oport_data_wide = hdl->node->oport->fmt.bit_wide;
|
||||
log_d("%s bit_wide, %d %d %d\n", __FUNCTION__, hdl->data_wide.iport_data_wide, hdl->data_wide.oport_data_wide, hdl->node->oport->fmt.Qval);
|
||||
|
||||
printf("%s len %d, sizeof(cfg) %d\n", __func__, len, (int)sizeof(struct volume_cfg));
|
||||
if (len != hdl->cfg_len) {
|
||||
if (hdl->vol_cfg) {
|
||||
free(hdl->vol_cfg);
|
||||
hdl->vol_cfg = NULL;
|
||||
}
|
||||
vol_cfg = &default_vol_cfg;
|
||||
} else {
|
||||
printf("vol read config ok :%d,%d,%d,%d,%d\n", vol_cfg->cfg_level_max, (int)vol_cfg->cfg_vol_min, (int)vol_cfg->cfg_vol_max, vol_cfg->vol_table_custom, vol_cfg->bypass);
|
||||
}
|
||||
|
||||
/*
|
||||
*获取在线调试的临时参数
|
||||
* */
|
||||
u32 online_cfg_len = sizeof(struct volume_cfg) + DIGITAL_VOLUME_LEVEL_MAX * sizeof(float);
|
||||
struct volume_cfg *online_vol_cfg = zalloc(online_cfg_len);
|
||||
if (jlstream_read_effects_online_param(hdl->node->uuid, hdl->name, online_vol_cfg, online_cfg_len)) {
|
||||
/* printf("cfg_level_max = %d\n", online_vol_cfg->cfg_level_max); */
|
||||
/* printf("cfg_vol_min = %d\n", online_vol_cfg->cfg_vol_min); */
|
||||
/* printf("cfg_vol_max = %d\n", online_vol_cfg->cfg_vol_max); */
|
||||
/* printf("vol_table_custom = %d\n", online_vol_cfg->vol_table_custom); */
|
||||
/* printf("cur_vol = %d\n", online_vol_cfg->cur_vol); */
|
||||
/* printf("tab_len = %d\n", online_vol_cfg->tab_len); */
|
||||
hdl->vol_cfg-> cfg_vol_max = online_vol_cfg->cfg_vol_max;
|
||||
hdl->vol_cfg-> cfg_vol_min = online_vol_cfg->cfg_vol_min;
|
||||
hdl->vol_cfg-> bypass = online_vol_cfg->bypass;
|
||||
#if VOL_TAB_CUSTOM_EN
|
||||
if (hdl->vol_cfg->tab_len == online_vol_cfg->tab_len && hdl->vol_cfg->tab_len) {
|
||||
for (int i = 0; i < hdl->vol_cfg->cfg_level_max ; i++) {//重新计算音量表的值
|
||||
printf("custom dvol [%d] = %d / 100 dB", i, (int)(online_vol_cfg->vol_table[i] * 100));
|
||||
float dvol_gain = eq_db2mag(online_vol_cfg->vol_table[i]);//dB转换倍数
|
||||
hdl->vol_cfg->vol_table [i] = (s16)(DVOL_MAX_FLOAT * dvol_gain + 0.5f);
|
||||
printf("custom dvol[%d] = %d", i, (int)online_vol_cfg->vol_table[i]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
printf("get volume online param\n");
|
||||
}
|
||||
free(online_vol_cfg);
|
||||
hdl->bypass = vol_cfg->bypass;
|
||||
switch (hdl->scene) {
|
||||
case STREAM_SCENE_TONE:
|
||||
case STREAM_SCENE_RING:
|
||||
case STREAM_SCENE_KEY_TONE:
|
||||
/*puts("set_tone_volume\n");*/
|
||||
hdl->state = APP_AUDIO_STATE_WTONE;
|
||||
#if TONE_BGM_FADEOUT
|
||||
/*printf("tone_player.c %d tone play,BGM fade_out automatically\n", __LINE__);*/
|
||||
audio_digital_vol_bg_fade(1);
|
||||
#endif/*TONE_BGM_FADEOUT*/
|
||||
params.vol = app_audio_get_volume(APP_AUDIO_STATE_WTONE);
|
||||
params.vol_max = vol_cfg->cfg_level_max;
|
||||
params.fade_step = TONE_DVOL_FS;
|
||||
params.vol_limit = -1;
|
||||
break;
|
||||
case STREAM_SCENE_OPUS:
|
||||
case STREAM_SCENE_A2DP:
|
||||
case STREAM_SCENE_LINEIN:
|
||||
case STREAM_SCENE_IIS:
|
||||
case STREAM_SCENE_SPDIF:
|
||||
case STREAM_SCENE_PC_SPK:
|
||||
case STREAM_SCENE_PC_MIC:
|
||||
case STREAM_SCENE_MUSIC:
|
||||
case STREAM_SCENE_FM:
|
||||
case STREAM_SCENE_MIC_EFFECT:
|
||||
case STREAM_SCENE_HEARING_AID:
|
||||
puts("set_a2dp_volume\n");
|
||||
hdl->state = APP_AUDIO_STATE_MUSIC;
|
||||
params.vol = app_audio_get_volume(APP_AUDIO_STATE_MUSIC);
|
||||
params.vol_max = vol_cfg->cfg_level_max;
|
||||
params.fade_step = MUSIC_DVOL_FS;
|
||||
params.vol_limit = -1;
|
||||
break;
|
||||
case STREAM_SCENE_ESCO:
|
||||
puts("set_esco_volume\n");
|
||||
hdl->state = APP_AUDIO_STATE_CALL;
|
||||
params.vol = app_audio_get_volume(APP_AUDIO_STATE_CALL);
|
||||
params.vol_max = vol_cfg->cfg_level_max;
|
||||
params.fade_step = CALL_DVOL_FS;
|
||||
params.vol_limit = -1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
params.bit_wide = hdl->node->oport->fmt.bit_wide;
|
||||
if (!hdl->dvol_hdl) {
|
||||
hdl->dvol_hdl = audio_digital_vol_open(params);
|
||||
}
|
||||
audio_digital_vol_cfg_init(hdl->dvol_hdl, vol_cfg);
|
||||
|
||||
if (hdl->dvol_hdl) {
|
||||
hdl->dvol_hdl->mute_en = app_audio_get_mute_state(hdl->state);
|
||||
if (hdl->dvol_hdl->mute_en) {
|
||||
hdl->dvol_hdl->vol_fade = 0;
|
||||
}
|
||||
}
|
||||
if (hdl->scene == STREAM_SCENE_MIC_EFFECT) {
|
||||
return;
|
||||
}
|
||||
#ifdef DVOL_2P1_CH_DVOL_ADJUST_NODE
|
||||
#if (DVOL_2P1_CH_DVOL_ADJUST_NODE == DVOL_2P1_CH_DVOL_ADJUST_LR)
|
||||
char *substr = strstr(hdl->name, "Music");
|
||||
if (!strcmp(substr, "Music") || !strcmp(substr, "Music2")) { //找到默认初始化为最大音量的节点
|
||||
//printf("enter volume_node.c %d,%p,%s\n", __LINE__, hdl->dvol_hdl, substr);
|
||||
audio_digital_vol_set(hdl->dvol_hdl, hdl->dvol_hdl->vol_max);
|
||||
hdl->dvol_hdl->mute_en = 0;
|
||||
hdl->online_update_disable = 1;
|
||||
} else {
|
||||
//printf("enter volume_node.c %d,%p,%s\n", __LINE__, hdl->dvol_hdl, substr);
|
||||
app_audio_state_switch(hdl->state, vol_cfg->cfg_level_max, hdl->dvol_hdl);
|
||||
}
|
||||
#elif (DVOL_2P1_CH_DVOL_ADJUST_NODE == DVOL_2P1_CH_DVOL_ADJUST_SW)
|
||||
char *substr = strstr(hdl->name, "Music");
|
||||
if (!strcmp(substr, "Music") || !strcmp(substr, "Music1")) { //找到默认初始化为最大音量的节点
|
||||
// printf("enter volume_node.c %d,%p,%s\n", __LINE__, hdl->dvol_hdl, substr);
|
||||
audio_digital_vol_set(hdl->dvol_hdl, hdl->dvol_hdl->vol_max);
|
||||
hdl->dvol_hdl->mute_en = 0;
|
||||
hdl->online_update_disable = 1;
|
||||
} else {
|
||||
// printf("enter volume_node.c %d,%p,%s\n", __LINE__, hdl->dvol_hdl, substr);
|
||||
app_audio_state_switch(hdl->state, vol_cfg->cfg_level_max, hdl->dvol_hdl);
|
||||
}
|
||||
#else
|
||||
if (memchr(hdl->name, '1', 16) || memchr(hdl->name, '2', 16)) { //找到默认初始化为最大音量的节点
|
||||
//printf("enter volume_node.c %d,%p\n", __LINE__, hdl->dvol_hdl);
|
||||
audio_digital_vol_set(hdl->dvol_hdl, hdl->dvol_hdl->vol_max);
|
||||
hdl->online_update_disable = 1;
|
||||
hdl->dvol_hdl->mute_en = 0;
|
||||
} else {
|
||||
//printf("enter volume_node.c %d,%p\n", __LINE__, hdl->dvol_hdl);
|
||||
app_audio_state_switch(hdl->state, vol_cfg->cfg_level_max, hdl->dvol_hdl);
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
app_audio_state_switch(hdl->state, vol_cfg->cfg_level_max, hdl->dvol_hdl);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void volume_ioc_stop(struct volume_hdl *hdl)
|
||||
{
|
||||
if (hdl->scene != STREAM_SCENE_MIC_EFFECT) {
|
||||
app_audio_state_exit(hdl->state);
|
||||
}
|
||||
#if TONE_BGM_FADEOUT
|
||||
printf("tone_player.c %d tone play,BGM fade_out close\n", __LINE__);
|
||||
audio_digital_vol_bg_fade(0);
|
||||
#endif/*TONE_BGM_FADEOUT*/
|
||||
audio_digital_vol_close(hdl->dvol_hdl);
|
||||
hdl->dvol_hdl = NULL;
|
||||
}
|
||||
|
||||
int volume_ioc_get_cfg(const char *name, struct volume_cfg *vol_cfg)
|
||||
{
|
||||
char mode_index = get_current_scene();
|
||||
struct cfg_info info = {0}; //节点配置相关信息(参数存储的目标地址、配置项大小)
|
||||
int ret = jlstream_read_info_data(mode_index, name, 0, &info);
|
||||
if (!ret) {
|
||||
*vol_cfg = default_vol_cfg;
|
||||
} else {
|
||||
struct volume_cfg *temp_vol_cfg = zalloc(info.size);
|
||||
int len = jlstream_read_form_cfg_data(&info, (void *)temp_vol_cfg);
|
||||
if (len == info.size) {
|
||||
*vol_cfg = *temp_vol_cfg;
|
||||
} else {
|
||||
*vol_cfg = default_vol_cfg;
|
||||
}
|
||||
free(temp_vol_cfg); //赋值完结构体释放内存
|
||||
/* printf("volume node read cfg name %s", name); */
|
||||
/* printf("cfg_level_max = %d\n", vol_cfg->cfg_level_max); */
|
||||
/* printf("cfg_vol_min = %d\n", vol_cfg->cfg_vol_min); */
|
||||
/* printf("cfg_vol_max = %d\n", vol_cfg->cfg_vol_max); */
|
||||
/* printf("vol_table_custom = %d\n", vol_cfg->vol_table_custom); */
|
||||
/* printf("cur_vol = %d\n", vol_cfg->cur_vol); */
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
u16 volume_ioc_get_max_level(const char *name)
|
||||
{
|
||||
struct volume_cfg vol_cfg;
|
||||
volume_ioc_get_cfg(name, &vol_cfg);
|
||||
return vol_cfg.cfg_level_max;
|
||||
}
|
||||
|
||||
|
||||
float volume_ioc_2_dB(struct volume_hdl *hdl, s16 volume)
|
||||
{
|
||||
if (hdl->dvol_hdl) {
|
||||
dvol_handle *dvol = hdl->dvol_hdl;
|
||||
u8 vol_level = volume * dvol->vol_limit / dvol->vol_max;
|
||||
u16 step = (dvol->cfg_level_max - 1 > 0) ? (dvol->cfg_level_max - 1) : 1;
|
||||
float step_db = (dvol->cfg_vol_max - dvol->cfg_vol_min) / (float)step;
|
||||
float dvol_db = dvol->cfg_vol_min + (vol_level - 1) * step_db;
|
||||
printf("vol_dB :%d,%d\n", __LINE__, (int)dvol_db);
|
||||
return (dvol_db);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int volume_ioc_update_parm(struct volume_hdl *hdl, int parm)
|
||||
{
|
||||
struct volume_cfg *vol_cfg = (struct volume_cfg *)parm;
|
||||
int ret = false;
|
||||
int cmd = (vol_cfg->bypass & 0xf0);
|
||||
int value = vol_cfg->cur_vol;
|
||||
|
||||
switch (cmd) {
|
||||
case VOLUME_NODE_CMD_SET_VOL:
|
||||
s16 volume = value & 0xffff;
|
||||
if (volume < 0) {
|
||||
volume = 0;
|
||||
}
|
||||
if (hdl && hdl->dvol_hdl) {
|
||||
#if defined(VOL_NOISE_OPTIMIZE) &&( VOL_NOISE_OPTIMIZE)
|
||||
if (volume) {
|
||||
if (volume_ioc_2_dB(hdl, volume) < TARGET_DIG_DB && hdl->state == APP_AUDIO_STATE_MUSIC) {
|
||||
if (!hdl->target_dig_volume) {
|
||||
s16 temp_volume = 0;
|
||||
for (temp_volume = hdl->dvol_hdl->vol_max; volume_ioc_2_dB(hdl, temp_volume) > TARGET_DIG_DB; temp_volume--) {};
|
||||
hdl->target_dig_volume = temp_volume + 1;
|
||||
}
|
||||
|
||||
//printf("enter volume_node.c %d,%d/100,%d/100,%d,%d,%d\n",__LINE__,(int)(volume_ioc_2_dB(hdl,volume) * 100),(int)(volume_ioc_2_dB(hdl,hdl->target_dig_volume)* 100), hdl->target_dig_volume,volume,hdl->dvol_hdl->vol);
|
||||
|
||||
float dac_dB = volume_ioc_2_dB(hdl, volume) - volume_ioc_2_dB(hdl, hdl->target_dig_volume) ;
|
||||
|
||||
app_audio_dac_set_dB(dac_dB);
|
||||
volume = hdl->target_dig_volume;
|
||||
} else { //把DAC 设回0dB
|
||||
app_audio_dac_set_dB(0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
audio_digital_vol_set(hdl->dvol_hdl, volume);
|
||||
printf("SET VOL volume update success : %d\n", volume);
|
||||
ret = true;
|
||||
}
|
||||
break;
|
||||
case VOLUME_NODE_CMD_SET_MUTE:
|
||||
s16 mute_en = value & 0xffff;
|
||||
if (hdl && hdl->dvol_hdl) {
|
||||
audio_digital_vol_mute_set(hdl->dvol_hdl, mute_en);
|
||||
printf("SET MUTE mute update success : %d\n", mute_en);
|
||||
ret = true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (hdl && hdl->dvol_hdl) {
|
||||
if (!hdl->online_update_disable) {
|
||||
hdl->dvol_hdl-> cfg_vol_max = vol_cfg->cfg_vol_max;
|
||||
hdl->dvol_hdl-> cfg_vol_min = vol_cfg->cfg_vol_min;
|
||||
#if VOL_TAB_CUSTOM_EN
|
||||
if (hdl->vol_cfg->tab_len == vol_cfg->tab_len && hdl->vol_cfg->tab_len) {
|
||||
for (int i = 0; i < hdl->vol_cfg->cfg_level_max ; i++) {//重新计算音量表的值
|
||||
//printf("custom dvol [%d] = %d / 100 dB", i, (int)(vol_cfg->vol_table[i] * 100));
|
||||
float dvol_gain = eq_db2mag(vol_cfg->vol_table[i]);//dB转换倍数
|
||||
hdl->vol_cfg->vol_table [i] = (s16)(DVOL_MAX_FLOAT * dvol_gain + 0.5f);
|
||||
//printf("custom dvol[%d] = %d", i, (int)vol_cfg->vol_table[i]);
|
||||
}
|
||||
if (hdl->dvol_hdl->vol_table_custom == VOLUME_TABLE_CUSTOM_EN) {
|
||||
hdl->dvol_hdl->vol_table = hdl->vol_cfg->vol_table ;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
hdl->bypass = vol_cfg->bypass;
|
||||
audio_digital_vol_set(hdl->dvol_hdl, vol_cfg->cur_vol);
|
||||
if (hdl->scene != STREAM_SCENE_MIC_EFFECT) {//混响在线调试音量不更新音量状态的值
|
||||
app_audio_change_volume(app_audio_get_state(), vol_cfg->cur_vol);
|
||||
}
|
||||
}
|
||||
/* printf("cfg_level_max = %d\n", vol_cfg->cfg_level_max); */
|
||||
/* printf("cfg_vol_min = %d\n", vol_cfg->cfg_vol_min); */
|
||||
/* printf("cfg_vol_max = %d\n", vol_cfg->cfg_vol_max); */
|
||||
/* printf("vol_table_custom = %d\n", vol_cfg->vol_table_custom); */
|
||||
/* printf("cur_vol = %d\n", vol_cfg->cur_vol); */
|
||||
printf("volume update success : %d\n", vol_cfg->cur_vol);
|
||||
ret = true;
|
||||
return ret;
|
||||
}
|
||||
printf("parm update failed : %x\n", value);
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int get_volume_ioc_parm(struct volume_hdl *hdl, int parm)
|
||||
{
|
||||
int ret = 0;
|
||||
struct volume_cfg *cfg = (struct volume_cfg *)parm;
|
||||
if (hdl && hdl->dvol_hdl) {
|
||||
hdl->vol_cfg->cur_vol = hdl->dvol_hdl->vol;
|
||||
}
|
||||
memcpy(cfg, hdl->vol_cfg, sizeof(struct volume_cfg));
|
||||
ret = sizeof(struct volume_cfg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int volume_ioctl(struct stream_iport *iport, int cmd, int arg)
|
||||
{
|
||||
struct volume_hdl *hdl = (struct volume_hdl *)iport->private_data;
|
||||
|
||||
int ret = 0;
|
||||
switch (cmd) {
|
||||
case NODE_IOC_OPEN_IPORT:
|
||||
volume_open_iport(iport);
|
||||
break;
|
||||
case NODE_IOC_SET_SCENE:
|
||||
hdl->scene = (enum stream_scene)arg;
|
||||
break;
|
||||
case NODE_IOC_NEGOTIATE:
|
||||
*(int *)arg |= volume_ioc_negotiate(iport);
|
||||
break;
|
||||
case NODE_IOC_START:
|
||||
volume_ioc_start(hdl);
|
||||
break;
|
||||
case NODE_IOC_STOP:
|
||||
case NODE_IOC_SUSPEND:
|
||||
volume_ioc_stop(hdl);
|
||||
break;
|
||||
case NODE_IOC_NAME_MATCH:
|
||||
/* printf("volume_node name match :%s,%s\n", hdl->name, (const char *)arg); */
|
||||
if (!strcmp((const char *)arg, hdl->name)) {
|
||||
ret = 1;
|
||||
}
|
||||
break;
|
||||
case NODE_IOC_SET_PARAM:
|
||||
ret = volume_ioc_update_parm(hdl, arg);
|
||||
break;
|
||||
case NODE_IOC_GET_PARAM:
|
||||
ret = get_volume_ioc_parm(hdl, arg);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void volume_release(struct stream_node *node)
|
||||
{
|
||||
struct volume_hdl *hdl = (struct volume_hdl *)node->private_data;
|
||||
if (hdl->vol_cfg) {
|
||||
free(hdl->vol_cfg);
|
||||
hdl->vol_cfg = NULL;
|
||||
}
|
||||
free(hdl);
|
||||
}
|
||||
|
||||
|
||||
REGISTER_STREAM_NODE_ADAPTER(volume_node_adapter) = {
|
||||
.name = "volume",
|
||||
.uuid = NODE_UUID_VOLUME_CTRLER,
|
||||
.bind = volume_bind,
|
||||
.ioctl = volume_ioctl,
|
||||
.release = volume_release,
|
||||
};
|
||||
|
||||
REGISTER_ONLINE_ADJUST_TARGET(volume) = {
|
||||
.uuid = NODE_UUID_VOLUME_CTRLER,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user