aec.cpp
上传用户:gelin96
上传日期:2017-01-08
资源大小:20993k
文件大小:30k
源码类别:

MTK

开发平台:

C++ Builder

  1. /*****************************************************************************
  2. *  Copyright Statement:
  3. *  --------------------
  4. *  This software is protected by Copyright and the information contained
  5. *  herein is confidential. The software may not be copied and the information
  6. *  contained herein may not be used or disclosed except with the written
  7. *  permission of MediaTek Inc. (C) 2005
  8. *
  9. *  BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
  10. *  THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
  11. *  RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
  12. *  AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
  13. *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
  14. *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
  15. *  NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
  16. *  SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
  17. *  SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
  18. *  THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
  19. *  NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
  20. *  SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
  21. *
  22. *  BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
  23. *  LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
  24. *  AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
  25. *  OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
  26. *  MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
  27. *
  28. *  THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
  29. *  WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
  30. *  LAWS PRINCIPLES.  ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
  31. *  RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
  32. *  THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
  33. *
  34. *****************************************************************************/
  35. /*****************************************************************************
  36.  *
  37.  * Filename:
  38.  * ---------
  39.  *   AEC.cpp
  40.  *
  41.  * Project:
  42.  * --------
  43.  *   Maui META APP
  44.  *
  45.  * Description:
  46.  * ------------
  47.  *  Acoustic Echo Cancellation (AEC) calibration in loud speaker mode source
  48.  *
  49.  * Author:
  50.  * -------
  51.  *  Andy Ueng (mtk00490)
  52.  *
  53.  *============================================================================
  54.  *             HISTORY
  55.  * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
  56.  *------------------------------------------------------------------------------
  57.  * $Revision$
  58.  * $Modtime$
  59.  * $Log$
  60.  * 
  61.  *------------------------------------------------------------------------------
  62.  * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
  63.  *============================================================================
  64.  ****************************************************************************/
  65. //---------------------------------------------------------------------------
  66. #include <IniFiles.hpp>
  67. #pragma hdrstop
  68. #ifndef _AEC_H_
  69. #include "aec.h"
  70. #endif
  71. #ifndef  _MAN_ACTIVE_H_
  72. #include "man_active.h"
  73. #endif
  74. #ifndef  _FT_UTILS_H_
  75. #include "ft_utils.h"
  76. #endif
  77. //---------------------------------------------------------------------------
  78. #pragma package(smart_init)
  79. //===========================================================================
  80. static CAECLS*  g_aec_ptr;
  81. static bool g_bIsRunning = false;
  82. //=============================  static function  ==============================
  83. static void REQ_TimeOut(void)
  84. {
  85.     g_aec_ptr->REQ_TimeOut();
  86. }
  87. //----------------------------------------------------------------------------
  88. static void REQ_Finish(void)
  89. {
  90.     g_aec_ptr->REQ_Finish();
  91. }
  92. //----------------------------------------------------------------------------
  93. static void REQ_Read_FIR_From_NVRAM(void)
  94. {
  95.     g_aec_ptr->REQ_Read_FIR_From_NVRAM();
  96. }
  97. //----------------------------------------------------------------------------
  98. static void CNF_ReadFirFromNVRAM(void)
  99. {
  100.     g_aec_ptr->CNF_ReadFirFromNVRAM();
  101. }
  102. //----------------------------------------------------------------------------
  103. static void REQ_Write_FIR_To_NVRAM(void)
  104. {
  105.     g_aec_ptr->REQ_Write_FIR_To_NVRAM();
  106. }
  107. //----------------------------------------------------------------------------
  108. static void CNF_WriteFirToNVRAM(void)
  109. {
  110.     g_aec_ptr->CNF_WriteFirToNVRAM();
  111. }
  112. //----------------------------------------------------------------------------
  113. static void REQ_Read_Volume_Setting_From_NVRAM(void)
  114. {
  115.     g_aec_ptr->REQ_Read_Volume_Setting_From_NVRAM();
  116. }
  117. //----------------------------------------------------------------------------
  118. static void CNF_ReadVolSettingFromNVRAM(void)
  119. {
  120.     g_aec_ptr->CNF_ReadVolSettingFromNVRAM();
  121. }
  122. //----------------------------------------------------------------------------
  123. static void CNF_WriteVolSettingToNVRAM(void)
  124. {
  125.     g_aec_ptr->CNF_WriteVolSettingToNVRAM();
  126. }
  127. //----------------------------------------------------------------------------
  128. static void REQ_Audio_Tone_Loop_Back_Rec(void)
  129. {
  130.     g_aec_ptr->REQ_Audio_Tone_Loop_Back_Rec();
  131. }
  132. //===========================================================================
  133. CAECLS::CAECLS(void)
  134. {
  135.    g_bIsRunning = false;
  136.    ConfirmCallback = NULL;
  137.    m_cpBuf = NULL;
  138. }
  139. //---------------------------------------------------------------------------
  140. CAECLS::~CAECLS( )
  141. {
  142.    g_bIsRunning = false;
  143.    ConfirmCallback = NULL;
  144.    ReleaseDynMemory();
  145. }
  146. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  147. void CAECLS::AllocateDynMemory(void)
  148. {
  149.     if (NULL == m_cpBuf)
  150.     {
  151.         if (AEC_TYPE_LOUD_SPEAKER_8K == m_sAEC.e_aec_type)
  152.         {
  153.             m_cpBuf = new char[AEC_BUF_SIZE_8K*AEC_PLAY_FREQ_NUM];
  154.         }
  155.         else
  156.         {
  157.             m_cpBuf = new char[AEC_BUF_SIZE_2K*AEC_PLAY_FREQ_NUM];
  158.         }
  159.     }
  160. }
  161. //---------------------------------------------------------------------------
  162. void CAECLS::ReleaseDynMemory(void)
  163. {
  164.     if (NULL != m_cpBuf)
  165.     {
  166.         delete [] m_cpBuf;
  167.         m_cpBuf = NULL;
  168.     }
  169. }
  170. //---------------------------------------------------------------------------
  171. void  CAECLS::Confirm(E_METAAPP_RESULT_T confirm_state)
  172. {
  173.     if (!g_bIsRunning)
  174.     {
  175.         return;
  176.     }
  177.     g_bIsRunning = false;
  178.     if (NULL == ConfirmCallback)
  179.     {
  180.         return;
  181.     }
  182.     m_eConfirmState = confirm_state;
  183.     ActiveMan->SetActiveFunction(ConfirmCallback);
  184. }
  185. //---------------------------------------------------------------------------
  186. void CAECLS::REQ_Finish(void)
  187. {
  188.     if (!g_bIsRunning)
  189.     {
  190.         return;
  191.     }
  192.     Confirm(METAAPP_SUCCESS);
  193. }
  194. //---------------------------------------------------------------------------
  195. void CAECLS::REQ_Stop(void)
  196. {
  197.     if (!g_bIsRunning)
  198.     {
  199.         return;
  200.     }
  201.     g_bIsRunning = false;
  202.     META_CancelAllBlockingCall_r(m_META_HANDLE_Obj.Get_MainHandle());
  203.     Confirm(METAAPP_STOP);
  204. }
  205. //---------------------------------------------------------------------------
  206. void  CAECLS::REQ_TimeOut( void )
  207. {
  208.     if(!g_bIsRunning)  return;
  209.     META_CancelAllBlockingCall_r(m_META_HANDLE_Obj.Get_MainHandle());
  210.     Confirm(METAAPP_TIMEOUT);
  211. }
  212. //==============================================================================
  213. void CAECLS::Req_Start(S_AEC_LS_T s_aec)
  214. {
  215.     g_aec_ptr = this;
  216.     g_bIsRunning = true;
  217.     m_sAEC = s_aec;
  218.     AllocateDynMemory();
  219.     ActiveMan->SetActiveFunction(::REQ_Read_FIR_From_NVRAM);
  220. }
  221. //===========================================================================
  222. void CAECLS::REQ_Read_FIR_From_NVRAM(void)
  223. {
  224.     if (!g_bIsRunning)
  225.     {
  226.         return;
  227.     }
  228.     m_cSP_COEF_Obj.ConfirmCallback = ::CNF_ReadFirFromNVRAM;
  229.     m_cSP_COEF_Obj.REQ_Read_From_NVRAM(m_sAEC.e_audio_param_type);
  230. }
  231. //-------------------------------------
  232. void CAECLS::CNF_ReadFirFromNVRAM(void)
  233. {
  234.     if (!g_bIsRunning)
  235.     {
  236.         return;
  237.     }
  238.     E_METAAPP_RESULT_T state = m_cSP_COEF_Obj.Get_ConfirmState();
  239.     switch (state)
  240.     {
  241.         case METAAPP_SUCCESS:
  242.         {
  243.             m_cSP_COEF_Obj.Get_FirCoef(m_sFirCoeff);
  244.             // set initial RX FIR
  245.             if (!REQ_Set_LoudSpk_FIR_Coeffs(m_sAECFir.s_fir_coeffs))
  246.             {
  247.                 Confirm(METAAPP_FAIL);
  248.                 return;
  249.             }
  250.             // set initial speech enhacement
  251.             if (!REQ_Set_LoudSpk_Speech_Enhacement_FIR_Coeffs(m_sAECSeFir.us_se_fir_coeffs))
  252.             {
  253.                 Confirm(METAAPP_FAIL);
  254.                 return;
  255.             }
  256.             // set initial common parameter
  257.             if (!REQ_Set_Speech_Common_And_Mode_FIR_Coeffs(m_sFirCoeff.us_speech_common_para, m_sAECSeFir.us_se_fir_coeffs))
  258.             {
  259.                 Confirm(METAAPP_FAIL);
  260.                 return;
  261.             }
  262.             m_eStep = AEC_STEP_1;
  263.             ActiveMan->SetActiveFunction(::REQ_Audio_Tone_Loop_Back_Rec);
  264.         }
  265.         break;
  266.         default:
  267.         {
  268.             Confirm(state);
  269.         }
  270.         break;
  271.     }
  272. }
  273. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  274. void CAECLS::REQ_Write_FIR_To_NVRAM(void)
  275. {
  276.     if (!g_bIsRunning)
  277.     {
  278.         return;
  279.     }
  280.     m_cSP_COEF_Obj.Set_FirCoef(m_sFirCoeff);
  281.     m_cSP_COEF_Obj.ConfirmCallback = ::CNF_WriteFirToNVRAM;
  282.     m_cSP_COEF_Obj.REQ_Write_To_NVRAM(m_sAEC.e_audio_param_type, m_sAEC.b_fir_runtime_support);
  283. }
  284. //-----------------------------------------
  285. void CAECLS::CNF_WriteFirToNVRAM(void)
  286. {
  287.     if (!g_bIsRunning)
  288.     {
  289.         return;
  290.     }
  291.     E_METAAPP_RESULT_T state = m_cSP_COEF_Obj.Get_ConfirmState();
  292.     if (METAAPP_SUCCESS == state)
  293.     {
  294.         ActiveMan->SetActiveFunction(::REQ_Read_Volume_Setting_From_NVRAM);
  295.     }
  296.     else
  297.     {
  298.         Confirm(state);
  299.     }
  300. }
  301. //===========================================================================
  302. void CAECLS::REQ_Read_Volume_Setting_From_NVRAM(void)
  303. {
  304.     if (!g_bIsRunning)
  305.     {
  306.         return;
  307.     }
  308.     m_cVOL_SET_Obj.ConfirmCallback = ::CNF_ReadVolSettingFromNVRAM;
  309.     m_cVOL_SET_Obj.REQ_Read_From_NVRAM(m_sAEC.b_cust_vol_16);
  310. }
  311. //--------------------------------------------
  312. void CAECLS::CNF_ReadVolSettingFromNVRAM(void)
  313. {
  314.     if (!g_bIsRunning)
  315.     {
  316.         return;
  317.     }
  318.     E_METAAPP_RESULT_T state = m_cVOL_SET_Obj.Get_ConfirmState();
  319.     switch (state)
  320.     {
  321.         case METAAPP_SUCCESS:
  322.         {
  323.             if (m_sAEC.b_cust_vol_16)
  324.             {
  325.                 CustAcousticVol16lvl_T* p_cust_vol = m_cVOL_SET_Obj.Get_CustVol16();
  326.                 m_sCustVolEx = *p_cust_vol;
  327.                 for (int level=0; level<CUST_VOL_LEVEL_NUM; level++)
  328.                 {
  329.                     m_sCustVolEx.volume_gain[HANDSFREE_MODE][SPEECH_TONE_TYPE][level] = m_sSpkGain.volume[level];
  330.                     m_sCustVolEx.volume_gain[HANDSFREE_MODE][MICROPHONE_TYPE][level]  = m_sMicGain.volume;
  331.                 }
  332.                 m_cVOL_SET_Obj.Set_CustVol16(m_sCustVolEx);
  333.             }
  334.             else
  335.             {
  336.                 CustAcousticVol_T* p_cust_vol = m_cVOL_SET_Obj.Get_CustVol();
  337.                 m_sCustVol = *p_cust_vol;
  338.                 for (int level=0; level<CUST_VOL_LEVEL_NUM; level++)
  339.                 {
  340.                     m_sCustVol.volume_gain[HANDSFREE_MODE][SPEECH_TONE_TYPE][level] = m_sSpkGain.volume[level];
  341.                     m_sCustVol.volume_gain[HANDSFREE_MODE][MICROPHONE_TYPE][level]  = m_sMicGain.volume;
  342.                 }
  343.                 m_cVOL_SET_Obj.Set_CustVol(m_sCustVol);
  344.             }
  345.             REQ_Write_Volume_Setting_To_NVRAM();
  346.         }
  347.         break;
  348.         default:
  349.         {
  350.             Confirm(state);
  351.         }
  352.         break;
  353.    }
  354. }
  355. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  356. void CAECLS::REQ_Write_Volume_Setting_To_NVRAM(void)
  357. {
  358.     if (!g_bIsRunning)
  359.     {
  360.         return;
  361.     }
  362.     m_cVOL_SET_Obj.ConfirmCallback = ::CNF_WriteVolSettingToNVRAM;
  363.     m_cVOL_SET_Obj.REQ_Write_To_NVRAM(m_sAEC.b_cust_vol_16, m_sAEC.b_cust_vol_runtime_support);
  364. }
  365. //-------------------------------------------------
  366. void CAECLS::CNF_WriteVolSettingToNVRAM(void)
  367. {
  368.     if (!g_bIsRunning)
  369.     {
  370.         return;
  371.     }
  372.     E_METAAPP_RESULT_T state = m_cVOL_SET_Obj.Get_ConfirmState();
  373.     if (state != METAAPP_SUCCESS)
  374.     {
  375.         Confirm(state);
  376.     }
  377.     // write volume gain to file
  378.     bool ok = m_cVOL_SET_Obj.REQ_Write_To_File(m_sAEC.as_volume_gain_file.c_str(), true, m_sAEC.b_cust_vol_16);
  379.     if (!ok)
  380.     {
  381.         Confirm(METAAPP_FAIL);
  382.     }
  383.     else
  384.     {
  385.         Confirm(METAAPP_SUCCESS);
  386.     }
  387. }
  388. //---------------------------------------------------------------------------
  389. void CAECLS::REQ_Audio_Tone_Loop_Back_Rec(void)
  390. {
  391.     if (!g_bIsRunning)
  392.     {
  393.         return;
  394.     }
  395.     META_RESULT MetaResult;
  396.     Audio_Tone_LoopBackRec_Req req;
  397.     Audio_Tone_LoopBackRec_Cnf cnf_8k;
  398.     Audio_Tone_LoopBackRec_Cnf_2K cnf_2k;
  399.     unsigned short us_freq[] = {500, 750, 1000, 1500, 2000, 2500, 3000, 3500};
  400.     if (!calibrate_mic(&m_sMicGain, m_sAEC.i_micgain, (int) m_sAEC.e_mic_device_type))
  401.     {
  402.         Confirm(METAAPP_FAIL);
  403.         return;
  404.     }
  405.     if (!calibrate_spk(&m_sSpkGain, m_sAEC.i_spkgain, (int) m_sAEC.e_speaker_dac_type))
  406.     {
  407.         Confirm(METAAPP_FAIL);
  408.         return;
  409.     }
  410.     req.spkgain = m_sSpkGain.cal_gain;
  411.     req.micgain = m_sMicGain.cal_gain;
  412.     req.ulgain  = m_usUpDigiGain;
  413.     req.dlgain  = m_usDnDigiGain;
  414.     req.amp     = m_usKTGain[m_eStep-1];
  415.     for (int i=0; i<AEC_PLAY_FREQ_NUM; i++)
  416.     {
  417.         req.fre = us_freq[i];
  418.         switch (m_sAEC.e_aec_type)
  419.         {
  420.             case AEC_TYPE_LOUD_SPEAKER_8K:
  421.             {
  422.                 MetaResult = META_Audio_Tone_Loop_Back_Rec_r(m_META_HANDLE_Obj.Get_MainHandle(), 15000 , &req, &cnf_8k);
  423.             }
  424.             break;
  425.             case AEC_TYPE_LOUD_SPEAKER_2K:
  426.             {
  427.                 MetaResult = META_Audio_Tone_Loop_Back_Rec_2K_r(m_META_HANDLE_Obj.Get_MainHandle(), 15000 , &req, &cnf_2k);
  428.             }
  429.             break;
  430.         }
  431.         if (MetaResult != META_SUCCESS)
  432.         {
  433.             if (MetaResult != META_TIMEOUT)
  434.             {
  435.                 Confirm(METAAPP_FAIL);
  436.             }
  437.             else
  438.             {
  439.                 Confirm(METAAPP_TIMEOUT);
  440.             }
  441.             return;
  442.         }
  443.         if (AEC_TYPE_LOUD_SPEAKER_8K == m_sAEC.e_aec_type)
  444.         {
  445.             memcpy((void *)(m_cpBuf+i*AEC_BUF_SIZE_8K), (void *)cnf_8k.buffer, AEC_BUF_SIZE_8K);
  446.         }
  447.         else
  448.         {
  449.             memcpy((void *)(m_cpBuf+i*AEC_BUF_SIZE_2K), (void *)cnf_2k.buffer, AEC_BUF_SIZE_2K);
  450.         }
  451.     }
  452.     switch (m_eStep)
  453.     {
  454.         case AEC_STEP_1:
  455.         {
  456.             switch (m_sAEC.e_aec_type)
  457.             {
  458.                 case AEC_TYPE_LOUD_SPEAKER_8K:
  459.                 {
  460.                     if (!calibrate_step_1(&m_sResultFir, (short *)m_cpBuf, m_sAEC.b_debug))
  461.                     {
  462.                         Confirm(METAAPP_FAIL);
  463.                         return;
  464.                     }
  465.                 }
  466.                 break;
  467.                 case AEC_TYPE_LOUD_SPEAKER_2K:
  468.                 {
  469.                     if (!calibrate_step_1_2k(&m_sResultFir, (short *)m_cpBuf, m_sAEC.b_debug))
  470.                     {
  471.                         Confirm(METAAPP_FAIL);
  472.                         return;
  473.                     }
  474.                 }
  475.                 break;
  476.             } // switch (e_aec_type)
  477.             // set FIR result to target RAM
  478.             if (!REQ_Set_LoudSpk_FIR_Coeffs(m_sResultFir.coef))
  479.             {
  480.                 Confirm(METAAPP_FAIL);
  481.             }
  482.             m_eStep = AEC_STEP_2;
  483.             ActiveMan->SetActiveFunction(::REQ_Audio_Tone_Loop_Back_Rec);
  484.         }
  485.         break;
  486.         case AEC_STEP_2:
  487.         {
  488.             switch (m_sAEC.e_aec_type)
  489.             {
  490.                 case AEC_TYPE_LOUD_SPEAKER_8K:
  491.                 {
  492.                     if (!calibrate_step_2(&m_sResultFir, (short *)m_cpBuf, m_sResultFir.flt_index, m_sAEC.b_debug))
  493.                     {
  494.                         Confirm(METAAPP_FAIL);
  495.                         return;
  496.                     }
  497.                 }
  498.                 break;
  499.                 case AEC_TYPE_LOUD_SPEAKER_2K:
  500.                 {
  501.                     if (!calibrate_step_2_2k(&m_sResultFir, (short *)m_cpBuf, m_sResultFir.flt_index, m_sAEC.b_debug))
  502.                     {
  503.                         Confirm(METAAPP_FAIL);
  504.                         return;
  505.                     }
  506.                 }
  507.                 break;
  508.                // case AEC_TYPE_NORMAL_2K:
  509.                // {
  510.                // }
  511.                // break;
  512.             } // switch (m_sAEC.e_aec_type)
  513.             // set result to FIR coefficient structure
  514.             for (int i=0; i<SPEECH_FIR_45_TAPS_NUM; i++)
  515.             {
  516.                 m_sFirCoeff.s_speech_output_FIR_coeffs[SPEECH_OUTPUT_FIR_2G_3G_HANDSFREE_IDX][i] = m_sResultFir.coef[i];
  517.                 m_sFirCoeff.s_speech_output_FIR_coeffs[SPEECH_OUTPUT_FIR_VOIP_HANDSFREE_IDX][i]  = m_sResultFir.coef[i];
  518.             }
  519.             // write output speech FIR to file
  520.             m_cSP_COEF_Obj.Set_FirCoef(m_sFirCoeff);
  521.             if (!m_cSP_COEF_Obj.REQ_Write_Speech_Output_Coeff_To_File(m_sAEC.as_output_speech_fir.c_str(), m_sAEC.e_audio_param_type, SPEECH_OUTPUT_FIR_2G_3G_HANDSFREE_IDX))
  522.             {
  523.                 Confirm(METAAPP_FAIL);
  524.             }
  525.             // set FIR result to target RAM
  526.             if (!REQ_Set_LoudSpk_FIR_Coeffs(m_sResultFir.coef))
  527.             {
  528.                 Confirm(METAAPP_FAIL);
  529.             }
  530.             m_eStep = AEC_STEP_3;
  531.             ActiveMan->SetActiveFunction(::REQ_Audio_Tone_Loop_Back_Rec);
  532.         }
  533.         break;
  534.         case AEC_STEP_3:
  535.         {
  536.             if ((AUDIO_FIR_VER_W0547_45_TAP == m_sAEC.e_audio_param_type) ||
  537.                 (AUDIO_FIR_VER_W0712        == m_sAEC.e_audio_param_type) ||
  538.                 (AUDIO_FIR_VER_W0740        == m_sAEC.e_audio_param_type)
  539.                )
  540.             {
  541.                 switch (m_sAEC.e_aec_type)
  542.                 {
  543.                     case AEC_TYPE_LOUD_SPEAKER_8K:
  544.                     {
  545.                         if (!calibrate_step_3(&m_sResultSEFir, (short *)m_cpBuf, m_sAEC.b_drc_support, m_sAEC.b_debug))
  546.                         {
  547.                             Confirm(METAAPP_FAIL);
  548.                             return;
  549.                         }
  550.                     }
  551.                     break;
  552.                     case AEC_TYPE_LOUD_SPEAKER_2K:
  553.                     {
  554.                         if (!calibrate_step_3_2k(&m_sResultSEFir, (short *)m_cpBuf, m_sAEC.b_drc_support, m_sAEC.b_debug))
  555.                         {
  556.                             Confirm(METAAPP_FAIL);
  557.                             return;
  558.                         }
  559.                     }
  560.                     break;
  561.                 }
  562.             }
  563.             else
  564.             {
  565.                 if (!calibrate_step_3_2k_08A(&m_sResultSEFir, (short *)m_cpBuf, m_sAEC.b_drc_support, m_sAEC.b_debug))
  566.                 {
  567.                     Confirm(METAAPP_FAIL);
  568.                     return;
  569.                 }
  570.             }
  571.             // write Audcoeff_default.h
  572.             unsigned char uc_se_mode_para_num = m_cSP_COEF_Obj.Get_SpeechModeDependentParameterNum(m_sAEC.e_audio_param_type);
  573.             if ((AUDIO_FIR_VER_W0547_45_TAP == m_sAEC.e_audio_param_type) ||
  574.                 (AUDIO_FIR_VER_W0712        == m_sAEC.e_audio_param_type) ||
  575.                 (AUDIO_FIR_VER_W0740        == m_sAEC.e_audio_param_type)
  576.                )
  577.             {
  578.                 for (int i=0; i<uc_se_mode_para_num; i++)
  579.                 {
  580.                      m_sFirCoeff.us_speech_mode_para[SPEECH_LOUDSPEAKER_MODE][i] = m_sResultSEFir.sp_enhace[i];
  581.                 }
  582.                 for (int i = uc_se_mode_para_num; i<SE_MODE_PARA_NUM_16; i++)
  583.                 {
  584.                     m_sFirCoeff.us_speech_mode_para[SPEECH_LOUDSPEAKER_MODE][i] = 0;
  585.                 }
  586.             }
  587.             else
  588.             {
  589.                 for (int i=0; i<uc_se_mode_para_num; i++)
  590.                 {
  591.                      m_sFirCoeff.us_speech_mode_para[SPEECH_LOUDSPEAKER_MODE][i] = m_sResultSEFir.sp_enhace_08A[i];
  592.                 }
  593.                 for (int i = uc_se_mode_para_num; i<SE_MODE_PARA_NUM_16; i++)
  594.                 {
  595.                     m_sFirCoeff.us_speech_mode_para[SPEECH_LOUDSPEAKER_MODE][i] = 0;
  596.                 }
  597.             }
  598.             if (!REQ_Write_To_Audcoeff_Default(m_sAEC.as_audcoeff_default_h.c_str(), m_sAEC.e_audio_param_type))
  599.             {
  600.                 Confirm(METAAPP_FAIL);
  601.             }
  602.             // write FIR to NVRAM
  603.             ActiveMan->SetActiveFunction(::REQ_Write_FIR_To_NVRAM);
  604.         }
  605.         break;
  606.         default:
  607.         {
  608.         }
  609.         break;
  610.     }
  611. }
  612. //===========================================================================
  613. //////////////////////////////  Runtime setting   ///////////////////////////
  614. //===========================================================================
  615. bool CAECLS::REQ_Set_LoudSpk_FIR_Coeffs(short* p_output_coeff)
  616. {
  617.     if (!g_bIsRunning)
  618.     {
  619.         return false;
  620.     }
  621.     Audio_Set_LoudSpk_FIR_Coeffs_Req req;
  622.     for (int i=0; i<SPEECH_FIR_45_TAPS_NUM; i++)
  623.     {
  624.         req.out_fir_coeffs[i] = *(p_output_coeff + i);
  625.     }
  626.     for (int i=0; i<SPEECH_FIR_45_TAPS_NUM; i++)
  627.     {
  628.         req.in_fir_coeffs[i] = m_sFirCoeff.s_speech_input_FIR_coeffs[SPEECH_INPUT_FIR_2G_3G_HANDSFREE_IDX][i];
  629.     }
  630.         
  631.     META_RESULT MetaResult = META_Audio_Set_LoudSpk_FIR_Coeffs_r(m_META_HANDLE_Obj.Get_MainHandle(), 5000, &req);
  632.     if (MetaResult != META_SUCCESS)
  633.     {
  634.         if (MetaResult != META_TIMEOUT)
  635.         {
  636.             Confirm(METAAPP_FAIL);
  637.         }
  638.         else
  639.         {
  640.             Confirm(METAAPP_TIMEOUT);
  641.         }
  642.         return false;
  643.     }
  644.     return true;
  645. }
  646. //---------------------------------------------------------------------------
  647. bool CAECLS::REQ_Set_LoudSpk_Speech_Enhacement_FIR_Coeffs(unsigned short *p_coeff)
  648. {
  649.     if (!g_bIsRunning)
  650.     {
  651.         return false;
  652.     }
  653.     Audio_Set_LoudSpk_Mode_Req req;
  654.     unsigned char uc_se_mode_para_num = m_cSP_COEF_Obj.Get_SpeechModeDependentParameterNum(m_sAEC.e_audio_param_type);
  655.     for (int i=0; i<uc_se_mode_para_num; i++)
  656.     {
  657.         req.speech_loudspk_mode_para[i] = *(p_coeff+i);
  658.     }
  659.     META_RESULT MetaResult = META_Audio_Set_LoudSpk_Mode_r(m_META_HANDLE_Obj.Get_MainHandle(), 5000, &req);
  660.     if (MetaResult != META_SUCCESS)
  661.     {
  662.         if (MetaResult != META_TIMEOUT)
  663.         {
  664.             Confirm(METAAPP_FAIL);
  665.         }
  666.         else
  667.         {
  668.             Confirm(METAAPP_TIMEOUT);
  669.         }
  670.         return false;
  671.     }
  672.     return true;
  673. }
  674. //---------------------------------------------------------------------------
  675. bool CAECLS::REQ_Set_Speech_Common_And_Mode_FIR_Coeffs(unsigned short *p_comm_coeff, unsigned short *p_mode_coeff)
  676. {
  677.     if (!g_bIsRunning)
  678.     {
  679.         return false;
  680.     }
  681.     Audio_Set_Speech_Common_And_Mode_Req req;
  682.     unsigned char uc_se_speech_common_num = m_cSP_COEF_Obj.Get_SpeechCommonParameterNum(m_sAEC.e_audio_param_type);
  683.     for (int i=0; i<uc_se_speech_common_num; i++)
  684.     {
  685.         req.speech_common_para[i] = *(p_comm_coeff+i);
  686.     }
  687.     unsigned char uc_se_mode_para_num = m_cSP_COEF_Obj.Get_SpeechModeDependentParameterNum(m_sAEC.e_audio_param_type);
  688.     for (int i = 0; i < uc_se_mode_para_num; i++)
  689.     {
  690.         req.speech_loudspk_mode_para[i] = *(p_mode_coeff+i);
  691.     }
  692.     for (int i = uc_se_mode_para_num; i < SE_MODE_PARA_NUM_16; i++)
  693.     {
  694.         req.speech_loudspk_mode_para[i] = 0;
  695.     }
  696.     META_RESULT MetaResult = META_Audio_Set_Speech_Common_And_Mode_r(m_META_HANDLE_Obj.Get_MainHandle(), 5000, &req);
  697.     if (MetaResult != META_SUCCESS)
  698.     {
  699.         if (MetaResult != META_TIMEOUT)
  700.         {
  701.             Confirm(METAAPP_FAIL);
  702.         }
  703.         else
  704.         {
  705.             Confirm(METAAPP_TIMEOUT);
  706.         }
  707.         return false;
  708.     }
  709.     return true;
  710. }
  711. //===========================================================================
  712. //////////////////////////////        File        ///////////////////////////
  713. //===========================================================================
  714. static AnsiString as_SECTION_NAME = "AEC calibration";
  715. //--------------------------------------------------------------------------
  716. bool CAECLS::REQ_Read_From_File(char *filename, E_AUDIO_FIR_VER_T audio_param_type)
  717. {
  718.     TIniFile   *ini_file;
  719.     AnsiString  as_data;
  720.     ini_file = new TIniFile(filename);
  721.     if (NULL == ini_file)
  722.     {
  723.         return false;
  724.     }
  725.     // Rx default FIR
  726.     as_data = ini_file->ReadString(as_SECTION_NAME,
  727.                                    "Rx default FIR",
  728.                                    "32767,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" );
  729.     String_To_Array_short(as_data.c_str(), m_sAECFir.s_fir_coeffs, SPEECH_FIR_45_TAPS_NUM);
  730.     // LoudSpeaker Mode Debug Parameter
  731.     as_data = ini_file->ReadString(as_SECTION_NAME,
  732.                                    "LoudSpeaker Mode Debug Parameter",
  733.                                    "0,479,0,0,0,0,400,0");
  734.     unsigned char uc_se_mode_para_num = m_cSP_COEF_Obj.Get_SpeechModeDependentParameterNum(m_sAEC.e_audio_param_type);
  735.     String_To_Array_UnsignedShort(as_data.c_str(), m_sAECSeFir.us_se_fir_coeffs, uc_se_mode_para_num);
  736.     // microphone default gain
  737.     m_iMicGain = ini_file->ReadInteger(as_SECTION_NAME, "microphone default gain", 0);
  738.     // speaker default gain
  739.     m_iSpkGain = ini_file->ReadInteger(as_SECTION_NAME, "speaker default gain", 18);
  740.     // uplink digital gain
  741.     m_usUpDigiGain = ini_file->ReadInteger(as_SECTION_NAME, "uplink digital gain", 0x1400);
  742.     // downlink digital gain
  743.     m_usDnDigiGain = ini_file->ReadInteger(as_SECTION_NAME, "downlink digital gain", 0x1000);
  744.     AnsiString as_key_name;
  745.     for (int i=0; i<3; i++)
  746.     {
  747.         as_key_name = "KT gain step" +IntToStr(i+1);
  748.         m_usKTGain[i] = ini_file->ReadInteger(as_SECTION_NAME, as_key_name, 0x3fff);
  749.     }
  750.     delete  ini_file;
  751.     return true;
  752. }
  753. //---------------------------------------------------------------------------
  754. bool CAECLS::REQ_Write_To_Audcoeff_Default(char *filename, E_AUDIO_FIR_VER_T audio_param_type)
  755. {
  756.     if ((AUDIO_FIR_VER_ORG == audio_param_type) || (AUDIO_FIR_VER_W0547 == audio_param_type))
  757.     {
  758.         return false;
  759.     }
  760.     FILE *fs;
  761.     fs = fopen(filename, "w");
  762.     if (NULL == fs)
  763.     {
  764.         return false;
  765.     }
  766.     fprintf(fs, "#ifndef AUDCOEFF_COMMON_DOT_Hn");
  767.     fprintf(fs, "#define AUDCOEFF_COMMON_DOT_Hnn");
  768.     fprintf(fs, "#define DEFAULT_SPEECH_LOUDSPK_MODE_PARA \");
  769.     fprintf(fs, "n");
  770.     fprintf(fs, "{ \");
  771.     fprintf(fs, "n");
  772.     unsigned char uc_se_mode_para_num = m_cSP_COEF_Obj.Get_SpeechModeDependentParameterNum(m_sAEC.e_audio_param_type);
  773.     for (int i=0; i<uc_se_mode_para_num; i++)
  774.     {
  775.         fprintf(fs, "%6d", m_sFirCoeff.us_speech_mode_para[SPEECH_LOUDSPEAKER_MODE][i]);
  776.         if (i != uc_se_mode_para_num - 1)
  777.         {
  778.             fprintf(fs, ",");
  779.         }
  780.         else
  781.         {
  782.             fprintf(fs, " \");
  783.         }
  784.     }
  785.     fprintf(fs, "n}nn");
  786.     fprintf(fs, "#endif // ... AUDCOEFF_COMMON_DOT_Hnn");
  787.     
  788.     fclose(fs);
  789.     return true;
  790. }
  791. //---------------------------------------------------------------------------
  792. bool CAECLS::REQ_Write_Record_To_File(char *filename)
  793. {
  794.     FILE *fs;
  795.     fs = fopen(filename, "wb");
  796.     if (NULL == fs)
  797.     {
  798.         return false;
  799.     }
  800.     if (AEC_TYPE_LOUD_SPEAKER_8K == m_sAEC.e_aec_type)
  801.     {
  802.         fwrite(m_cpBuf, AEC_BUF_SIZE_8K*AEC_PLAY_FREQ_NUM, 1, fs);
  803.     }
  804.     else
  805.     {
  806.         fwrite(m_cpBuf, AEC_BUF_SIZE_2K*AEC_PLAY_FREQ_NUM, 1, fs);
  807.     }
  808.     fclose(fs);
  809.     return true;
  810. }
  811. //===========================================================================
  812. /////////////////////////////        Query        ///////////////////////////
  813. //===========================================================================
  814. bool CAECLS::Query_DRC_Support_Start(void)
  815. {
  816.     g_aec_ptr = this;
  817.     g_bIsRunning = true;
  818.     bool b_DRCSupport = Query_DRC_Support();
  819.     return b_DRCSupport;
  820. }
  821. //--------------------------------------------------------------------------
  822. bool CAECLS::Query_DRC_Support(void)
  823. {
  824.     META_RESULT  MetaResult = META_QueryIfTargetSupportDRC_r(m_META_HANDLE_Obj.Get_MainHandle(), 300);
  825.     if (MetaResult != META_SUCCESS)
  826.     {
  827.         return false;
  828.     }
  829.     return true;
  830. }
  831. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  832. bool CAECLS::Query_Aec2kSupport_Start(void)
  833. {
  834.     META_RESULT MetaResult = META_QueryIfFunctionSupportedByTarget_r(m_META_HANDLE_Obj.Get_MainHandle(), 500, "META_Audio_Tone_Loop_Back_Rec_2K_r");
  835.     if (MetaResult != META_SUCCESS)
  836.     {
  837.         return false;
  838.     }
  839.     return true;
  840. }
  841. //===========================================================================
  842. ////////////////////////////  Global information  ///////////////////////////
  843. //===========================================================================
  844. E_METAAPP_RESULT_T CAECLS::Get_ConfirmState(void)
  845. {
  846.     return m_eConfirmState;
  847. }
  848. //---------------------------------------------------------------------------
  849. int CAECLS::Get_MicGain(void)
  850. {
  851.     return m_iMicGain;
  852. }
  853. //---------------------------------------------------------------------------
  854. int CAECLS::Get_SpkGain(void)
  855. {
  856.     return m_iSpkGain;
  857. }
  858. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  859. E_AEC_RESULT_T CAECLS::Get_Result(void)
  860. {
  861.     return (E_AEC_RESULT_T) m_sResultSEFir.mechanism;
  862. }