络达开发----如何手工实时调整ANC和PassThrough的增益

芯片型号:AB1565

功能模块:ANC和PassThrough

功能描述:ANC和PassThrough支持动态调整其增益,比如ANC的消噪强度,或者PassThourgh的透传比例;PassThourgh其实就是在FF的ANC类型的基础上实现的,与ANC的消噪模式所不同的是滤波器的实现不同。Airoha官止提供的APP端,提供有接口可以调整这两类开增益,APP上显示的调整值的范围为[-20~0],如图1所示,那么本文讲解如何用物理按钮来实现该操作。

第一步:定义好物理按键的动作;

如下表为笔者物理按钮的定义:

单击

双击

Power

电话接听/挂起/结束

电话拒接/HOLD

音乐暂停/播放

进入配对模式

KEY2

音量+

透传开关

KEY8

音量-

ANC开关

KEY9

MIC MUTE打开/关闭

其中“透传”即为络达的PassThrough;

源SDK中其实并没有定义ANC/PassThrough增益调节的事件码,因此我们可以自己添加,

所在的文件为:

bta_sdk\mcu\project\ab1565_ab1568_evk\apps\headset_design\inc\apps\config\apps_config_event_list.h

在该头文件中结构体“apps_config_key_action_t”中的末尾添加如下定义:

   /*------------------add by micmind-----------------*/
    KEY_ANC_GAIN_UP   = 0xF010,
    KEY_ANC_GAIN_DOWN = 0xF011,
} apps_config_key_action_t;

第二步:定义UI;

如下代码为笔者UI中相关的定义:

const apps_config_key_event_map_t temp_key_short_click_configs[] = {
	......
{
        EINT_KEY_0, //GPIO2---EINT2 --- KEY2
        KEY_ANC_GAIN_UP, //KEY_VOICE_UP,
        (1 << APP_CONNECTED) | (1 << APP_HFP_INCOMING) | (1 << APP_HFP_OUTGOING) | (1 << APP_HFP_CALLACTIVE)
        | (1 << APP_HFP_TWC_INCOMING) | (1 << APP_HFP_TWC_OUTGOING) | (1 << APP_HFP_MULTITPART_CALL) | (1 << APP_A2DP_PLAYING)
        | (1 << APP_STATE_HELD_ACTIVE) | (1 << APP_ULTRA_LOW_LATENCY_PLAYING) | (1 << APP_WIRED_MUSIC_PLAY)
    },
    {
        EINT_KEY_1, //GPIO8---EINT8 --- KEY8
        KEY_ANC_GAIN_DOWN, //KEY_VOICE_DN,
        (1 << APP_CONNECTED) | (1 << APP_HFP_INCOMING) | (1 << APP_HFP_OUTGOING) | (1 << APP_HFP_CALLACTIVE)
        | (1 << APP_HFP_TWC_INCOMING) | (1 << APP_HFP_TWC_OUTGOING) | (1 << APP_HFP_MULTITPART_CALL) | (1 << APP_A2DP_PLAYING)
        | (1 << APP_STATE_HELD_ACTIVE) | (1 << APP_ULTRA_LOW_LATENCY_PLAYING) | (1 << APP_WIRED_MUSIC_PLAY)
    },

};

const apps_config_key_event_map_t temp_key_double_click_configs[] = {
	......
	{
        EINT_KEY_0, //GPIO2---EINT2 --- KEY2
        KEY_PASS_THROUGH,//KEY_SWITCH_ANC_AND_PASSTHROUGH,
        (1 << APP_DISCONNECTED) | (1 << APP_CONNECTABLE) | (1 << APP_CONNECTED) | (1 << APP_A2DP_PLAYING)
    },
    {
        EINT_KEY_1, //GPIO8---EINT8 --- KEY8
        KEY_ANC,//KEY_SWITCH_ANC_AND_PASSTHROUGH,
        (1 << APP_DISCONNECTED) | (1 << APP_CONNECTABLE) | (1 << APP_CONNECTED) | (1 << APP_A2DP_PLAYING)
        | (1 << APP_ULTRA_LOW_LATENCY_PLAYING) | (1 << APP_WIRED_MUSIC_PLAY)
    },
};

第三步:处理增益加和减的事件

那么,如何知道新添加的事件应该在哪里被处理呢?我们可以通过搜索“KEY_ANC”来确定,新添加的事件和该KEY_ANC的处理位置应该是同一个地方。

通过搜索可以知道,其事件处理位置是:

bta_sdk\mcu\project\ab1565_ab1568_evk\apps\headset_design\src\apps\app_idle\app_home_screen_idle_activity.c

中的函数:

static bool _proc_key_event_group(ui_shell_activity_t *self,
                                  uint32_t event_id,
                                  void *extra_data,
                                  size_t data_len)

比葫芦画瓢,我们添加类似的对增益的处理case,如笔者的代码:

#ifdef MTK_ANC_ENABLE
        case KEY_PASS_THROUGH:
        case KEY_ANC:
        case KEY_SWITCH_ANC_AND_PASSTHROUGH:
        case KEY_BETWEEN_ANC_PASSTHROUGH:
            /* Handle ANC key event. */
            ret = app_home_screen_process_anc_and_pass_through(self, action);
            break;
        case KEY_ANC_GAIN_UP:
        case KEY_ANC_GAIN_DOWN:
            ret = app_home_screen_process_anc_volumn_change(action);
            break;
#endif

笔者在此处添加了一个独立的函数来处理增益,该函数定义如下:

#define ANC_VOLUMN_MAX  0
#define ANC_VOLUMN_MIN -2000
#define ANC_VOLUMN_STEP 200
static bool app_home_screen_process_anc_volumn_change(apps_config_key_action_t key_action)
{
    bool ret = false;
    uint8_t anc_enable;
    audio_anc_control_filter_id_t anc_current_filter_id;
    audio_anc_control_type_t anc_current_type;
    int16_t anc_runtime_gain, new_gain;
    uint8_t support_hybrid_enable=0;

    audio_anc_control_get_status(&anc_enable, &anc_current_filter_id, &anc_current_type, &anc_runtime_gain, &support_hybrid_enable, NULL);
    
    GHP_LOG_MSGID_I("volumn:ancEn:%d,anctype:%d,gain:%d,fltId:%d,hyEn:%d",5,anc_enable, anc_current_type,anc_runtime_gain,anc_current_filter_id,support_hybrid_enable);
    new_gain = anc_runtime_gain;
    if(KEY_ANC_GAIN_UP == key_action)
    {
        new_gain += ANC_VOLUMN_STEP;
        if(new_gain > ANC_VOLUMN_MAX) new_gain = ANC_VOLUMN_MAX;
    } 
    else if(KEY_ANC_GAIN_DOWN == key_action)
    {
        new_gain -= ANC_VOLUMN_STEP;
        if(new_gain < ANC_VOLUMN_MIN) new_gain = ANC_VOLUMN_MIN;
    }

    if(anc_enable)
    {
        //ret = app_anc_service_set_runtime_gain(anc_current_type,new_gain);
        //GHP_LOG_MSGID_I("KEY_ANC_GAIN_DOWN[%d],oldG:%d, newG:%d",3,ret,anc_runtime_gain, new_gain);

        ret = app_anc_service_enable(anc_current_filter_id, anc_current_type, new_gain, NULL);
        GHP_LOG_MSGID_I("prev_gain:%d new_gain: %d, ret:%d", 3, anc_runtime_gain, new_gain, ret);
    }
    else
    {
        GHP_LOG_MSGID_I("ANC no enabled.",0);
    }
    return ret;
}

这里有几个事件需要搞清楚:

  1. 增益用哪个函数来调整;
  2. 增益调整值的范围是多少

这些我们可以通过日志来分析出来,我们用文章开始提到的APP来调整增益的最大值和最小值,然后分析日志得出它的范围是多少,如下图所示是用APP用ANC Filter1把增益调整为最小值-20时的相关日志:

图中可以看出,增益的值为-2000, type为0表示ANC的类型为Hybrid,其值的定义如下代码:

 /** @brief ANC and Pass-through type values. */
typedef enum {
    AUDIO_ANC_CONTROL_TYPE_HYBRID       = 0,  /**< The hybrid anc type.   */
    AUDIO_ANC_CONTROL_TYPE_FF           = 1,  /**< The feedforward anc type.   */
    AUDIO_ANC_CONTROL_TYPE_FB           = 2,  /**< The feedback anc type.   */
    AUDIO_ANC_CONTROL_TYPE_USER_DEFINED = 3,  /**< The user defined anc type.   */
    AUDIO_ANC_CONTROL_TYPE_PASSTHRU_FF  = 4,  /**< The pass-through feedforward anc type.   */

    AUDIO_ANC_CONTROL_TYPE_DUMMY        = 0x7FFFFFFF,
} audio_anc_control_type_t;

并且从中也可以看出来,其调整的RACE_ANC_SET_RUNTIME_VOL,我们在工程是搜索该定义,可以发现:

case RACE_ANC_SET_RUNTIME_VOL:
     if (anc_param_length >= 2) {
        pEvt->param.runtime_gain = pAnc_cmd->param.runtime_gain;
        anc_ret = audio_anc_set_runtime_volume(pAnc_cmd->param.runtime_gain);
     }
     break;

从中可以看出,调用的是函数audio_anc_set_runtime_volume(),且值按无符号整数为:0xFFFFF830,因此按道理我们只需要把物理按钮的动作关联到该函数即可。 同时,也能看出,通过手机APP调整益所调用的函数为:

void* RACE_DSPREALTIME_ANC_HDR(ptr_race_pkt_t pCmdMsg, uint8_t channel_id)

那么还有另一个问题,用APP写的是绝对 值,但用按钮应该是在当前增益的基础上进行增加或减少固定的偏移,因此就需要知道当前的增益是多少。

通过代码分析可以发现,下面函数是用来获取当前ANC的配置及状态:

audio_anc_control_get_status()

它会返回ANC的开关状态,滤波器的类型,ANC的类型,当前的动态增益,是否支持hybrid;

并且还有一个函数:

bool app_anc_service_enable(audio_anc_control_filter_id_t filter_id,
                            audio_anc_control_type_t anc_type,
                            audio_anc_control_gain_t runtime_gain,
                            audio_anc_control_misc_t *control_misc);

用来在应用层打开或关闭ANC,以ANC的类型的增益等; 因此,笔者采用该函数来对增益进行动态调整。

第三:完成述改造之后,我们可以通过日志来验证;

如处图为用物理按键调整ANC增益的日志,anctype为0,表示ANC工作在hybrid模式下,fltid为1 表示ANC Filter1;

如下图为PassThrough增益的调节时的日志,type为4表示是ANC工作在PassThrough模式下,即:AUDIO_ANC_CONTROL_TYPE_PASSTHRU_FF

fltId为9表示滤波器为:AUDIO_ANC_CONTROL_FILTER_ID_PASS_THRU_1

至此,完成需求的功能,并验证成功;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值