QCC308X--Adaptive leakthrough 调试

本文档介绍了如何使用MDE和ancdesigner工具进行QCC308X芯片的Adaptive Leakthrough ANC(自适应通透主动降噪)调试。步骤包括进入ANC调试状态、配置Filter_PEQ和Automatic_Hybrid模式、调整参数以及最终保存和烧录优化后的参数到设备,以实现良好的通透效果和避免啸叫问题。
摘要由CSDN通过智能技术生成
/*!
\copyright  Copyright (c) 2017-2023 Qualcomm Technologies International, Ltd.
            All Rights Reserved.
            Qualcomm Technologies International, Ltd. Confidential and Proprietary.
\version
\file       kymera_anc.c
\brief      Kymera ANC code
*/
 
#include "kymera_anc.h"
#include "kymera_dsp_clock.h"
#include "kymera_lock.h"
#include "kymera_internal_msg_ids.h"
#include "kymera_tones_prompts.h"
#include "kymera_anc_common.h"
 
#include <audio_power.h>
#include <vmal.h>
#include <file.h>
#include <cap_id_prim.h>
#include <opmsg_prim.h>
 
#include "kymera_config.h"
#include "kymera_anc_common.h"
#include "kymera.h"
#include "microphones.h"
#include "kymera_source_sync.h"
#include "kymera_setup.h"
#include "kymera_mic_if.h"
#include "anc_state_manager.h"
#include "av_seids.h"
 
#ifdef ENABLE_ANC
typedef struct
{
 
   uint8 anc_ff_gain[MAXIMUM_AUDIO_ANC_INSTANCES];
} kymera_anc_data_t;
 
static kymera_anc_data_t kymera_anc_data;
#define kymeraAnc_GetData() (&kymera_anc_data)
 
#define ANC_TUNING_SINK_USB_LEFT      0 /*can be any other backend device. PCM used in this tuning graph*/
#define ANC_TUNING_SINK_USB_RIGHT     1
#define ANC_TUNING_SINK_FBMON_LEFT    2 /*reserve slots for FBMON tap. Always connected.*/
#define ANC_TUNING_SINK_FBMON_RIGHT   3
#define ANC_TUNING_SINK_MIC1_LEFT     4 /* must be connected to internal ADC. Analog or digital */
#define ANC_TUNING_SINK_MIC1_RIGHT    5
#define ANC_TUNING_SINK_MIC2_LEFT     6
#define ANC_TUNING_SINK_MIC2_RIGHT    7
 
#define ANC_TUNING_SOURCE_USB_LEFT    0 /*can be any other backend device. USB used in the tuning graph*/
#define ANC_TUNING_SOURCE_USB_RIGHT   1
#define ANC_TUNING_SOURCE_DAC_LEFT    2 /* must be connected to internal DAC */
#define ANC_TUNING_SOURCE_DAC_RIGHT   3
 
#define ANC_TUNNING_START_DELAY       (200U)
#define ANC_TUNNING_USB_SAMPLING_RATE  48000   /* Only 48KHz supported for anc tuning */
#define ANC_TUNNING_USB_AUDIO_CHANNELS  2   /* Number of mic and speaker channels in the audio data stream */
 
#define KYMERA_ANC_MIC_SAMPLE_RATE    (16000U)
 
/*! Macro for creating messages */
#define MAKE_KYMERA_MESSAGE(TYPE) \
    TYPE##_T *message = PanicUnlessNew(TYPE##_T);
 
/* Qualcomm-provided downloadable anc tuning capability for QCC517x */
#define CAP_ID_DOWNLOAD_ANC_TUNING_QCC517X (0x40B2)
 
#ifdef DOWNLOAD_USB_AUDIO
#define EB_CAP_ID_USB_AUDIO_RX CAP_ID_DOWNLOAD_USB_AUDIO_RX
#define EB_CAP_ID_USB_AUDIO_TX CAP_ID_DOWNLOAD_USB_AUDIO_TX
#else
#define EB_CAP_ID_USB_AUDIO_RX CAP_ID_USB_AUDIO_RX
#define EB_CAP_ID_USB_AUDIO_TX CAP_ID_USB_AUDIO_TX
#endif
 
#ifdef ENABLE_ADAPTIVE_ANC
#define ancConfigIsAdvancedAdaptiveAnc()     (AncConfig_IsAdvancedAnc())
#else
#define ancConfigIsAdvancedAdaptiveAnc()     (FALSE)
#endif
 
#define GAIN_20_12_FORMAT_TO_Q2N_SF_FACTOR                  (43541) /* 2^(20-2)/20*log(2) = 43541 */
#define GAIN_dB_TO_FIXED_POINT(x, num_fractional_bits)      ((x << num_fractional_bits))
#define GAIN_dB_TO_Q6_9_FIXED_POINT(x)                      (GAIN_dB_TO_FIXED_POINT(x, 9))
#define GAIN_dB_TO_Q20_12_FIXED_POINT(x)                    (GAIN_dB_TO_FIXED_POINT(x, 12))
#define GAIN_20_12_FORMAT_TO_6_9_FORMAT(x)                  ((int16)(x >> 3))
#define GAIN_20_12_FORMAT_TO_Q2N_SF(x)                      (x * GAIN_20_12_FORMAT_TO_Q2N_SF_FACTOR)
#define GAIN_Q2N_SF_FORMAT_TO_20_12(x)                      (x / GAIN_20_12_FORMAT_TO_Q2N_SF_FACTOR)
 
#define GET_INTEGRAL_PART_FROM_FIXED_POINT(x, num_fractional_bits)      (x >> num_fractional_bits)
#define GET_INTEGRAL_PART_FROM_20_12_FORMAT(x)                          (GET_INTEGRAL_PART_FROM_FIXED_POINT(x, 12))
 
#define MAX_TARGET_GAIN 255
 
typedef struct
{
 
    Source mic_in1;
    Source mic_in2;
    Source fb_mon;
    Sink DAC;
}chan_data_t;
 
static chan_data_t left, right;
 
#ifdef ENHANCED_ANC_USE_2ND_DAC_ENDPOINT
static Sink eanc_second_dac;
 
#define SPLITTER_TERMINAL_IN_0       0
#define SPLITTER_TERMINAL_OUT_0      0
#define SPLITTER_TERMINAL_OUT_1      1
 
/*Splitter is needed for eANC tuning mode to activate second DAC path. ANC tuning capability output is required
for both the ANC instances through a Splitter to DAC EP Left and Right for the Echo Cancellation purpose.*/
static void kymeraAnc_CreateSplitter(void)
{
 
    kymeraTaskData *theKymera = KymeraGetTaskData();
    theKymera->output_splitter = (Operator)(VmalOperatorCreate(CAP_ID_SPLITTER));
}
 
static void kymeraAnc_ConfigureSplitter(void)
{
 
    kymeraTaskData *theKymera = KymeraGetTaskData();
    OperatorsSplitterSetWorkingMode(theKymera->output_splitter, splitter_mode_clone_input);
    OperatorsSplitterEnableSecondOutput(theKymera->output_splitter, FALSE);
    OperatorsSplitterSetDataFormat(theKymera->output_splitter, operator_data_format_pcm);
}
#endif
 
static kymera_chain_handle_t chain_handle;
 
static kymera_chain_handle_t KymeraAnc_GetChain(void)
{
 
    return chain_handle;
}
 
static void kymeraAnc_SetChain(kymera_chain_handle_t chain)
{
 
    chain_handle = chain;
}
 
static Sink kymeraAnc_MicSink(kymera_chain_handle_t chain_handle, unsigned input_role)
{
 
    return (ChainGetInput(chain_handle, input_role));
}
 
static uint8_t kymeraAnc_GetRequiredAncMics(void)
{
 
    uint8_t num_mics = 0;
    anc_path_enable anc_path = appConfigAncPathEnable();
 
    switch(anc_path)
    {
 
        case feed_forward_mode_left_only:
        case feed_back_mode_left_only:
            num_mics = 1;
            break;
 
        case feed_forward_mode:
        case feed_back_mode:
        case hybrid_mode_left_only:
            num_mics = 2;
            break;
 
        case hybrid_mode:
            num_mics = 4;
        break;
 
        default:
            break;
    }
    return num_mics;
}
 
static void kymeraAnc_GetAncMicConfig(uint16 *mic_ids)
{
 
    anc_path_enable anc_path = appConfigAncPathEnable();
 
    switch(anc_path)
    {
 
        case feed_forward_mode:
            mic_ids[0] = getAncFeedForwardLeftMic();
            mic_ids[1] = getAncFeedForwardRightMic();
        break;
 
        case feed_back_mode:
            mic_ids[0] = getAncFeedBackLeftMic();
            mic_ids[1] = getAncFeedBackRightMic();
        break;
 
        case hybrid_mode:
            mic_ids[0] = getAncFeedForwardLeftMic();
            mic_ids[1] = getAncFeedForwardRightMic();
            mic_ids[2] = getAncFeedBackLeftMic();
            mic_ids[3] = getAncFeedBackRightMic();
        break;
 
        case feed_forward_mode_left_only:
            mic_ids[0] = getAncFeedForwardLeftMic();
        break;
 
        case feed_back_mode_left_only:
            mic_ids[0] = getAncFeedBackLeftMic();
        break;
 
        case hybrid_mode_left_only:
            mic_ids[0] = getAncFeedForwardLeftMic();
            mic_ids[1] = getAncFeedBackLeftMic();
        break;
 
    default:
        break;
    }
}
 
static void kymeraAnc_GetAncMicSinks(Sink *mic_sinks)
{
 
    anc_path_enable anc_path = appConfigAncPathEnable();
 
    switch(anc_path)
    {
 
        case feed_forward_mode_left_only:
        case feed_back_mode_left_only:
            mic_sinks[0] = kymeraAnc_MicSink(KymeraAnc_GetChain(), EPR_ANC_SPC_1_IN);
        break;
 
        case feed_forward_mode:
        case feed_back_mode:
        case hybrid_mode_left_only:
            mic_sinks[0] = kymeraAnc_MicSink(KymeraAnc_GetChain(), EPR_ANC_SPC_1_IN);
            mic_sinks[1] = kymeraAnc_MicSink(KymeraAnc_GetChain(), EPR_ANC_SPC_2_IN);
        break;
 
        case hybrid_mode:
            mic_sinks[0] = kymeraAnc_MicSink(KymeraAnc_GetChain(), EPR_ANC_SPC_1_IN);
            mic_sinks[1] = kymeraAnc_MicSink(KymeraAnc_GetChain(), EPR_ANC_SPC_2_IN);
            mic_sinks[2] = kymeraAnc_MicSink(KymeraAnc_GetChain(), EPR_ANC_SPC_3_IN);
            mic_sinks[3] = kymeraAnc_MicSink(KymeraAnc_GetChain(), EPR_ANC_SPC_4_IN);
        break;
 
    default:
        break;
    }
}
 
static bool kymeraAnc_MicGetConnectionParameters(uint16 *mic_ids, Sink *mic_sinks, uint8 *num_of_mics, uint32 *sample_rate, Sink *aec_ref_sink)
{
 
    *sample_rate = KYMERA_ANC_MIC_SAMPLE_RATE;
    *num_of_mics = kymeraAnc_GetRequiredAncMics();
    kymeraAnc_GetAncMicConfig(mic_ids);
    kymeraAnc_GetAncMicSinks(mic_sinks);
    aec_ref_sink[0] = NULL;
 
    return TRUE;
}
 
static mic_user_state_t kymeraAnc_GetUserState(void)
{
 
    return mic_user_state_interruptible;
}
 
static bool kymeraAnc_MicDisconnectIndication(const mic_change_info_t *info)
{
 
    DEBUG_LOG("kymeraAnc_MicDisconnectIndication");
    UNUSED(info);
 
    kymera_chain_handle_t chain = KymeraAnc_GetChain();
 
    if(chain != NULL)
    {
 
        ChainStop(chain);
    }
 
    return TRUE;
}
 
static void kymeraAnc_MicReconnectedIndication(void)
{
 
    DEBUG_LOG("kymeraAnc_MicReconnectedIndication");
    ChainStart(KymeraAnc_GetChain());
}
 
static const mic_callbacks_t kymeraAnc_Callbacks =
{
 
    .MicGetConnectionParameters = kymeraAnc_MicGetConnectionParameters,
    .MicDisconnectIndication = kymeraAnc_MicDisconnectIndication,
    .MicReconnectedIndication = kymeraAnc_MicReconnectedIndication,
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值