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

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.  *   form_FirCoeffCal.cpp
  40.  *
  41.  * Project:
  42.  * --------
  43.  *   Maui META APP
  44.  *
  45.  * Description:
  46.  * ------------
  47.  *  FIR coefficient calibration form 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 <vcl.h>
  67. #include <math.h>
  68. #include <IniFiles.hpp>
  69. #include <SyncObjs.hpp>
  70. //#include "freqz.hpp"
  71. //#include "libmatlb.h"
  72. //#include "freqz.h"
  73. //#include "psdoptions.h"
  74. //#include "engine.h"
  75. //firls
  76. //#include "firls.h"
  77. #pragma hdrstop
  78. #include "form_FirResponse.h"
  79. #ifndef _FORM_MAIN_H_
  80. #include "form_main.h"
  81. #endif
  82. #include "sp_coef_cal.h"
  83. #include "form_FirCoeffCal.h"
  84. #include "man_dll.h"
  85. #include "man_active.h"
  86. #include "meta_msg.h"
  87. #include "meta_utils.h"
  88. // misc
  89. #ifndef  _MISC_AUDIO_H_
  90. #include "misc_audio.h"
  91. #endif
  92. #ifndef  _FT_UTILS_H_
  93. #include "ft_utils.h"
  94. #endif
  95. #ifndef  _MATH_UTILS_H_
  96. #include "math_utils.h"
  97. #endif
  98. // file
  99. #ifndef  _MFSETUPUTIL_H_
  100. #include "mfsetuputil.h"
  101. #endif
  102. //---------------------------------------------------------------------------
  103. #pragma package(smart_init)
  104. #pragma resource "*.dfm"
  105. typedef enum
  106. {
  107.     ITEMIDX_BOUNDARY_SPEC = 0,
  108.     ITEMIDX_BOUNDARY_GOOD_SOUND,
  109.     ITEMIDX_BOUNDARY_3G_HANDSET_AND_HEADSET,
  110.     ITEMIDX_BOUNDARY_3G_HANDSFREE_DESKTOP_AND_VEHICLE,
  111.     ITEMIDX_BOUNDARY_3G_HANDSFREE_HANDHELD,
  112.     ITEMIDX_BOUNDARY_VOIP_HANDSET,
  113.     ITEMIDX_BOUNDARY_VOIP_HEADSET,
  114.     ITEMIDX_BOUNDARY_VOIP_HANDSFREE,
  115.     ITEMIDX_BOUNDARY_TYPE_3_3
  116. }E_ITEMIDX_BOUNDARY_T;
  117. typedef enum
  118. {
  119.     ACOUSTIC_EQUIPMENT_UPL = 0,
  120.     ACOUSTIC_EQUIPMENT_ACQUA,
  121.     ACOUSTIC_EQUIPMENT_MICROTRONIX,
  122.     ACOUSTIC_EQUIPMENT_VITA
  123. }E_ACOUSTIC_EQUIPMENT_T;
  124. //---------------------------------------------------------------------------
  125. TfrmFIRCoeffCal *frmFIRCoeffCal;
  126. //---------------------------------------------------------------------------
  127. void Req_freqz(void)
  128. {
  129.     frmFIRCoeffCal->Req_freqz();
  130. }
  131. //==============================================================================
  132. void _fastcall TfrmFIRCoeffCal::SubClassWndProc(Messages::TMessage &Message)
  133. {
  134.     switch (Message.Msg)
  135.     {
  136.         default:
  137.         {
  138.             this->WndProc(Message);
  139.         }    
  140.         break;
  141.     }
  142. }
  143. //---------------------------------------------------------------------------
  144. __fastcall TfrmFIRCoeffCal::TfrmFIRCoeffCal(TComponent* Owner)
  145.         : TForm(Owner)
  146. {
  147.     int i;
  148.     // initialization
  149.     FirScale = 0.5;
  150.     isTRCLoadOk = false;
  151.     isOrgCurvePlot = false;
  152.     isWantedCurvePlot = false;
  153.     isCompensateCurvePlot = false;
  154.     LogFloor = pow(10, -10);
  155.     pi = 3.1416;
  156.     lblVertical[0] = lblVertical0;
  157.     lblVertical[1] = lblVertical1;
  158.     lblVertical[2] = lblVertical2;
  159.     lblVertical[3] = lblVertical3;
  160.     lblVertical[4] = lblVertical4;
  161.     lblVertical[5] = lblVertical5;
  162.     lblVertical[6] = lblVertical6;
  163.     lblVertical[7] = lblVertical7;
  164.     lblVertical[8] = lblVertical8;
  165.     lblHz[0] = lbl1xxHz;
  166.     lblHz[1] = lbl2xxHz;
  167.     lblHz[2] = lbl3xxHz;
  168.     lblHz[3] = lbl5xxHz;
  169.     lblHz[4] = lbl6xxHz;
  170.     lblHz[5] = lbl7xxHz;
  171.     lblHz[6] = lbl8xxHz;
  172.     lblHz[7] = lbl1xxxHz;
  173.     lblHz[8] = lbl13xxHz;
  174.     lblHz[9] = lbl18xxHz;
  175.     lblHz[10] = lbl2xxxHz;
  176.     lblHz[11] = lbl25xxHz;
  177.     lblHz[12] = lbl3xxxHz;
  178.     lblHz[13] = lbl34xxHz;
  179.     lblHz[14] = lbl39xxHz;
  180.     edtHzdB[0] = edt1xxHzdB;
  181.     edtHzdB[1] = edt2xxHzdB;
  182.     edtHzdB[2] = edt3xxHzdB;
  183.     edtHzdB[3] = edt5xxHzdB;
  184.     edtHzdB[4] = edt6xxHzdB;
  185.     edtHzdB[5] = edt7xxHzdB;
  186.     edtHzdB[6] = edt8xxHzdB;
  187.     edtHzdB[7] = edt1xxxHzdB;
  188.     edtHzdB[8] = edt13xxHzdB;
  189.     edtHzdB[9] = edt18xxHzdB;
  190.     edtHzdB[10] = edt2xxxHzdB;
  191.     edtHzdB[11] = edt25xxHzdB;
  192.     edtHzdB[12] = edt3xxxHzdB;
  193.     edtHzdB[13] = edt34xxHzdB;
  194.     edtHzdB[14] = edt39xxHzdB;
  195.     m_dTxUpLimit[0] = -12;    //  100 Hz
  196.     m_dTxUpLimit[1] =   0;    //  200 Hz
  197.     m_dTxUpLimit[2] =   0;    //  300 Hz
  198.     m_dTxUpLimit[3] =   0;    // 1000 Hz
  199.     m_dTxUpLimit[4] =   4;    // 2000 Hz
  200.     m_dTxUpLimit[5] =   4;    // 3000 Hz
  201.     m_dTxUpLimit[6] =   4;    // 3400 Hz
  202.     m_dTxUpLimit[7] =   0;     // 4000 Hz
  203.     m_iTxLimitFreq[0] =  100;
  204.     m_iTxLimitFreq[1] =  200;
  205.     m_iTxLimitFreq[2] =  300;
  206.     m_iTxLimitFreq[3] = 1000;
  207.     m_iTxLimitFreq[4] = 2000;
  208.     m_iTxLimitFreq[5] = 3000;
  209.     m_iTxLimitFreq[6] = 3400;
  210.     m_iTxLimitFreq[7] = 4000;
  211. //    UITxLimitFreq[0] =  100;
  212. //    UITxLimitFreq[1] =  200;
  213. //    UITxLimitFreq[2] =  300;
  214. //    UITxLimitFreq[3] = 1000;
  215. //    UITxLimitFreq[4] = 2000;
  216. //    UITxLimitFreq[5] = 3000;
  217. //    UITxLimitFreq[6] = 3400;
  218. //    UITxLimitFreq[7] = 4000;
  219.     m_dTxLowLimit[0] = -100;    //  100 Hz
  220.     m_dTxLowLimit[1] = -100;    //  200 Hz
  221.     m_dTxLowLimit[2] =  -12;    //  300 Hz
  222.     m_dTxLowLimit[3] =   -6;    // 1000 Hz
  223.     m_dTxLowLimit[4] =   -6;    // 2000 Hz
  224.     m_dTxLowLimit[5] =   -6;    // 3000 Hz
  225.     m_dTxLowLimit[6] =   -9;    // 3400 Hz
  226.     m_dTxLowLimit[7] = -100;    // 4000 Hz
  227.     m_dRxUpLimit[0] = -12;    //  100 Hz
  228.     m_dRxUpLimit[1] =   0;    //  200 Hz
  229.     m_dRxUpLimit[2] =   2;    //  300 Hz
  230.     m_dRxUpLimit[3] =   2+(20*log10(500)-20*log10(300))*(0-2)/(20*log10(1000)-20*log10(300)); // 500 Hz
  231.     m_dRxUpLimit[4] =   0;    // 1000 Hz
  232.     m_dRxUpLimit[5] =   2;    // 3000 Hz
  233.     m_dRxUpLimit[6] =   2;    // 3400 Hz
  234.     m_dRxUpLimit[7] =   2;    // 4000 Hz
  235.     m_iRxLimitFreq[0] =  100;
  236.     m_iRxLimitFreq[1] =  200;
  237.     m_iRxLimitFreq[2] =  300;
  238.     m_iRxLimitFreq[3] =  500;
  239.     m_iRxLimitFreq[4] = 1000;
  240.     m_iRxLimitFreq[5] = 3000;
  241.     m_iRxLimitFreq[6] = 3400;
  242.     m_iRxLimitFreq[7] = 4000;
  243.    // UIRxLimitFreq[0] =  100;
  244.    // UIRxLimitFreq[1] =  200;
  245.    // UIRxLimitFreq[2] =  300;
  246.    // UIRxLimitFreq[3] =  500;
  247.   //  UIRxLimitFreq[4] = 1000;
  248.   //  UIRxLimitFreq[5] = 3000;
  249.   //  UIRxLimitFreq[6] = 3400;
  250.   //  UIRxLimitFreq[7] = 4000;
  251.     m_dRxLowLimit[0] = -100;    //  100 Hz
  252.     m_dRxLowLimit[1] = -100;    //  200 Hz
  253.     m_dRxLowLimit[2] =   -7;    //  300 Hz
  254.     m_dRxLowLimit[3] =   -5;    //  500 Hz
  255.     m_dRxLowLimit[4] =   -5;    // 1000 Hz
  256.     m_dRxLowLimit[5] =   -5;    // 3000 Hz
  257.     m_dRxLowLimit[6] =  -10;    // 3400 Hz
  258.     m_dRxLowLimit[7] = -100;    // 4000 Hz
  259. //    UITxUpLimit[0] = m_dTxUpLimit[0];    //  100 Hz
  260. //    UITxUpLimit[1] = m_dTxUpLimit[1];    //  200 Hz
  261. //    UITxUpLimit[2] = m_dTxUpLimit[2];    //  300 Hz
  262. //    UITxUpLimit[3] = m_dTxUpLimit[3];    // 1000 Hz
  263. //    UITxUpLimit[4] = m_dTxUpLimit[4];    // 2000 Hz
  264. //    UITxUpLimit[5] = m_dTxUpLimit[5];    // 3000 Hz
  265. //    UITxUpLimit[6] = m_dTxUpLimit[6];    // 3400 Hz
  266. //    UITxUpLimit[7] = m_dTxUpLimit[7];     // 4000 Hz
  267. //    UITxLowLimit[0] = m_dTxLowLimit[0];    //  100 Hz
  268. //    UITxLowLimit[1] = m_dTxLowLimit[1];    //  200 Hz
  269. //    UITxLowLimit[2] = m_dTxLowLimit[2];    //  300 Hz
  270. //    UITxLowLimit[3] = m_dTxLowLimit[3];    // 1000 Hz
  271. //    UITxLowLimit[4] = m_dTxLowLimit[4];    // 2000 Hz
  272. //    UITxLowLimit[5] = m_dTxLowLimit[5];    // 3000 Hz
  273. //    UITxLowLimit[6] = m_dTxLowLimit[6];    // 3400 Hz
  274. //    UITxLowLimit[7] = m_dTxLowLimit[7];    // 4000 Hz
  275. //    UIRxUpLimit[0] = m_dRxUpLimit[0];    //  100 Hz
  276. //    UIRxUpLimit[1] = m_dRxUpLimit[1];    //  200 Hz
  277. //    UIRxUpLimit[2] = m_dRxUpLimit[2];    //  300 Hz
  278. //    UIRxUpLimit[3] = m_dRxUpLimit[3]; // 500 Hz
  279. //    UIRxUpLimit[4] = m_dRxUpLimit[4];    // 1000 Hz
  280. //    UIRxUpLimit[5] = m_dRxUpLimit[5];    // 3000 Hz
  281. //    UIRxUpLimit[6] = m_dRxUpLimit[6];    // 3400 Hz
  282. //    UIRxUpLimit[7] = m_dRxUpLimit[7];    // 4000 Hz
  283. //    UIRxLowLimit[0] = m_dRxLowLimit[0];    //  100 Hz
  284. //    UIRxLowLimit[1] = m_dRxLowLimit[1];    //  200 Hz
  285. //    UIRxLowLimit[2] = m_dRxLowLimit[2];    //  300 Hz
  286. //    UIRxLowLimit[3] = m_dRxLowLimit[3];    //  500 Hz
  287. //    UIRxLowLimit[4] = m_dRxLowLimit[4];    // 1000 Hz
  288. //    UIRxLowLimit[5] = m_dRxLowLimit[5];    // 3000 Hz
  289. //    UIRxLowLimit[6] = m_dRxLowLimit[6];    // 3400 Hz
  290. //    UIRxLowLimit[7] = m_dRxLowLimit[7];    // 4000 Hz
  291.     for( i=0; i<TOTAL_TRC_FREQ_NUM; i++ )
  292.     {
  293.         OrgSpCoef.MagdB[i] = 0;
  294.     }
  295.     vDistance = 40;
  296.     hDistance = 50;
  297.     vScale = 10;
  298.     hOutScale1 = 250;
  299.     hOutScale2 = 150;
  300.     hInScale1 = 20;
  301.     hInScale2 = 50;
  302.     vStart = 10;
  303.     hStart = 100;
  304.     hStart2 = hOutScale1*log10(100*9/hInScale1);
  305.     
  306.     PlotGrid(100, 4000, -20, 15);
  307.     PlotBoundaryCurve();
  308. }
  309. //==============================================================================
  310. void __fastcall TfrmFIRCoeffCal::FormCreate(TObject *Sender)
  311. {
  312.     cbBoundary->ItemIndex = 0;
  313.     for (int i=0; i<TOTAL_SEL_FREQ_NUM; i++)
  314.     {
  315.         UISelectedSpCoef.Hz[i] = 0.0;
  316.         UISelectedSpCoef.MagdB[i] = 0.0;
  317.     }
  318.     // taps
  319.     edtFIRTaps->Text = (AnsiString) 30;
  320.     m_iWantedTaps = 30;
  321.     isWantedCircleOnDrag = false;
  322.     WantedCircleOnDragIndex = -1;
  323.     // 100, 200, 300, 500, 700, 1000, 2000, 3000, 3400, 3950
  324.     //  100, 200, 300, 500, 600, 700, 800, 1000, 1300, 1800, 2000, 2500, 3000, 3400, 3950
  325.     m_iWantedHz[0]  =  100;
  326.     m_iWantedHz[1]  =  200;
  327.     m_iWantedHz[2]  =  300;
  328.     m_iWantedHz[3]  =  500;
  329.     m_iWantedHz[4]  =  600;
  330.     m_iWantedHz[5]  =  700;
  331.     m_iWantedHz[6]  =  800;
  332.     m_iWantedHz[7]  = 1000;
  333.     m_iWantedHz[8]  = 1300;
  334.     m_iWantedHz[9]  = 1800;
  335.     m_iWantedHz[10] = 2000;
  336.     m_iWantedHz[11] = 2500;
  337.     m_iWantedHz[12] = 3000;
  338.     m_iWantedHz[13] = 3400;
  339.     m_iWantedHz[14] = 3900;
  340.     m_bFirstFormShow = true;
  341.     Init();
  342. }
  343. //---------------------------------------------------------------------------
  344. void TfrmFIRCoeffCal::Init(void)
  345. {
  346.     m_bInit = true;
  347. }
  348. //---------------------------------------------------------------------------
  349. void __fastcall TfrmFIRCoeffCal::btnLoadClick(TObject *Sender)
  350. {
  351.     bool ok;
  352.     if (rbAcqua->Checked)
  353.     {
  354.         ok = dlgOpenAcqua->Execute();
  355.     }
  356.     else if (rbMicrotronix->Checked)
  357.     {
  358.         ok = dlgOpenMicrotronix->Execute();
  359.     }
  360.     else if (rbUPL->Checked)
  361.     {
  362.         ok = dlgOpenUpl->Execute();
  363.     }
  364.     else if (m_rbUPV->Checked)
  365.     {
  366.         ok = m_dlgUPV->Execute();
  367.     }
  368.     else
  369.     {
  370.         ok = m_dlgOpenVita->Execute();
  371.     }
  372.     if( !ok )
  373.     {
  374.         sbAudioCal->Panels->Items[0]->Text = (AnsiString) "  Load TRC file fail";
  375.         Application->MessageBox( "Execution Failure : Load TRC file", "FAILURE", MB_OK );
  376.         return;
  377.     }
  378.     if (rbAcqua->Checked)
  379.     {
  380.         ok = LoadAcquaFile (dlgOpenAcqua->FileName.c_str());
  381.     }
  382.     else if (rbMicrotronix->Checked)
  383.     {
  384.         ok = LoadMicrotronixFile(dlgOpenMicrotronix->FileName.c_str());
  385.     }
  386.     if (rbUPL->Checked)
  387.     {
  388.         ok = LoadTRCFile(dlgOpenUpl->FileName.c_str());
  389.     }
  390.     else if (m_rbUPV->Checked)
  391.     {
  392.         ok = LoadUpvFile(m_dlgUPV->FileName.c_str());
  393.     }
  394.     else
  395.     {
  396.         ok = LoadVitaFile(m_dlgOpenVita->FileName.c_str());
  397.     }
  398.     if (!ok)
  399.     {
  400.         sbAudioCal->Panels->Items[0]->Text = (AnsiString) "  Load file fail";
  401.         Application->MessageBox( "Execution Failure : Load file", "FAILURE", MB_OK );
  402.     }
  403. }
  404. //---------------------------------------------------------------------------
  405.     
  406. //---------------------------------------------------------------------------
  407. void __fastcall TfrmFIRCoeffCal::cbExtraFreqChange(TObject *Sender)
  408. {
  409.     char str[256];
  410.     if( cbExtraFreq->ItemIndex < 0)  return;
  411.     sprintf(str, "%.3f", WantedSpCoef.MagdB[cbExtraFreq->ItemIndex] );
  412.     edtExtraDB->Text = (AnsiString) str;
  413. }
  414. //---------------------------------------------------------------------------
  415. void TfrmFIRCoeffCal::ClearImage( void )
  416. {
  417.     imAudioCal->Canvas->Brush->Color = clWhite;
  418.     imAudioCal->Canvas->Brush->Style = bsSolid;
  419.     imAudioCal->Canvas->FillRect(Rect(0,0,imAudioCal->Width,imAudioCal->Height));
  420. }
  421. //------------------------------------------------------------------------------
  422. void  TfrmFIRCoeffCal::PlotBoundaryCurve( void )
  423. {
  424.     int i;
  425. //    float k = k=2+(20*log10(500)-20*log10(300))*(0-2)/(20*log10(1000)-20*log10(300));;
  426.     imAudioCal->Canvas->Pen->Color = clLime;
  427.     imAudioCal->Canvas->Pen->Width = 1;
  428.     imAudioCal->Canvas->Pen->Style = psSolid;
  429.     if( rbTx->Checked )
  430.     {
  431.         // draw upper limit
  432.        // imAudioCal->Canvas->MoveTo( 1, vStart + vDistance*( (max_y_grid-UITxUpLimit[0])/vScale) );
  433.         imAudioCal->Canvas->MoveTo( 1, vStart + vDistance*( (max_y_grid-m_dTxUpLimit[0])/vScale) );
  434.         for( i=1; i<m_iTxLimitNum; i++ )
  435.         {
  436.            // if( UITxLimitFreq[i] <= 1000 )
  437.             if( m_iTxLimitFreq[i] <= 1000 )
  438.             {
  439.                // if( log10(1.0*(UITxLimitFreq[i]-hStart)/hInScale1) > 0 )
  440.                 if( log10(1.0*(m_iTxLimitFreq[i]-hStart)/hInScale1) > 0 )
  441.                 {
  442.                    // imAudioCal->Canvas->LineTo( hOutScale1*log10(1.0*(UITxLimitFreq[i]-hStart)/hInScale1), vStart + vDistance*((max_y_grid-UITxUpLimit[i])/vScale) );
  443.                    imAudioCal->Canvas->LineTo( hOutScale1*log10(1.0*(m_iTxLimitFreq[i]-hStart)/hInScale1), vStart + vDistance*((max_y_grid-m_dTxUpLimit[i])/vScale) );
  444.                 }
  445.                 else
  446.                 {
  447.                    // imAudioCal->Canvas->LineTo( 1, vStart + vDistance*((max_y_grid-UITxUpLimit[i])/vScale) );
  448.                     imAudioCal->Canvas->LineTo( 1, vStart + vDistance*((max_y_grid-m_dTxUpLimit[i])/vScale) );
  449.                 }
  450.             }
  451.             else
  452.             {
  453.                 //if( log10(1.0*(UITxLimitFreq[i]- 1000)/(hInScale2)) > 0 )
  454.                 if( log10(1.0*(m_iTxLimitFreq[i]- 1000)/(hInScale2)) > 0 )
  455.                 {
  456.                     //imAudioCal->Canvas->LineTo( hStart2 + hOutScale2*log10(1.0*(UITxLimitFreq[i]- 1000)/(hInScale2)) , vStart + vDistance*( (max_y_grid-UITxUpLimit[i])/vScale) );
  457.                     imAudioCal->Canvas->LineTo( hStart2 + hOutScale2*log10(1.0*(m_iTxLimitFreq[i]- 1000)/(hInScale2)) , vStart + vDistance*( (max_y_grid-m_dTxUpLimit[i])/vScale) );
  458.                 }
  459.                 else
  460.                 {
  461.                    // imAudioCal->Canvas->LineTo( hStart2, vStart + vDistance*( (max_y_grid-UITxUpLimit[i])/vScale) );
  462.                     imAudioCal->Canvas->LineTo( hStart2, vStart + vDistance*( (max_y_grid-m_dTxUpLimit[i])/vScale) );
  463.                 }
  464.             }
  465.         }
  466.         // draw lower limit
  467.         imAudioCal->Canvas->MoveTo( 1, vStart + vDistance*( (max_y_grid-m_dTxLowLimit[0])/vScale) );
  468.         for( i=1; i<m_iTxLimitNum; i++ )
  469.         {
  470.             //if( UITxLimitFreq[i] <= 1000 )
  471.             if( m_iTxLimitFreq[i] <= 1000 )
  472.             {
  473.                // if( log10(1.0*(UITxLimitFreq[i]-hStart)/hInScale1) > 0 )
  474.                 if( log10(1.0*(m_iTxLimitFreq[i]-hStart)/hInScale1) > 0 )
  475.                 {
  476.                    // imAudioCal->Canvas->LineTo( hOutScale1*log10(1.0*(UITxLimitFreq[i]-hStart)/hInScale1), vStart + vDistance*( (max_y_grid-UITxLowLimit[i])/vScale) );
  477.                     imAudioCal->Canvas->LineTo( hOutScale1*log10(1.0*(m_iTxLimitFreq[i]-hStart)/hInScale1), vStart + vDistance*( (max_y_grid-m_dTxLowLimit[i])/vScale) );
  478.                 }
  479.                 else
  480.                 {
  481.                     imAudioCal->Canvas->LineTo( 1, vStart + vDistance*( (max_y_grid-m_dTxLowLimit[i])/vScale) );
  482.                 }
  483.             }
  484.             else
  485.             {
  486.                // if( log10(1.0*(UITxLimitFreq[i]- 1000)/(hInScale2)) > 0 )
  487.                 if( log10(1.0*(m_iTxLimitFreq[i]- 1000)/(hInScale2)) > 0 )
  488.                 {
  489.                    // imAudioCal->Canvas->LineTo( hStart2 + hOutScale2*log10(1.0*(UITxLimitFreq[i]- 1000)/(hInScale2)) , vStart + vDistance*((max_y_grid-UITxLowLimit[i])/vScale) );
  490.                     imAudioCal->Canvas->LineTo( hStart2 + hOutScale2*log10(1.0*(m_iTxLimitFreq[i]- 1000)/(hInScale2)) , vStart + vDistance*((max_y_grid-m_dTxLowLimit[i])/vScale) );
  491.                 }
  492.                 else
  493.                 {
  494.                    // imAudioCal->Canvas->LineTo( hStart2, vStart + vDistance*((max_y_grid-UITxLowLimit[i])/vScale) );
  495.                     imAudioCal->Canvas->LineTo( hStart2, vStart + vDistance*((max_y_grid-m_dTxLowLimit[i])/vScale) );
  496.                 }
  497.             }
  498.         }
  499.     }
  500.     else // RX
  501.     {
  502.         // draw upper limit
  503.         //imAudioCal->Canvas->MoveTo( 1, vStart + vDistance*( (max_y_grid-UIRxUpLimit[0])/vScale) );
  504.         imAudioCal->Canvas->MoveTo( 1, vStart + vDistance*( (max_y_grid-m_dRxUpLimit[0])/vScale) );
  505.         for( i=1; i<m_iRxLimitNum; i++ )
  506.         {
  507.            // if( UIRxLimitFreq[i] <= 1000 )
  508.             if( m_iRxLimitFreq[i] <= 1000 )
  509.             {
  510.                 if( log10(1.0*(m_iRxLimitFreq[i]-hStart)/hInScale1) > 0 )
  511.                 {
  512.                     //imAudioCal->Canvas->LineTo( hOutScale1*log10(1.0*(UIRxLimitFreq[i]-hStart)/hInScale1), vStart + vDistance*( (max_y_grid-UIRxUpLimit[i])/vScale) );
  513.                     imAudioCal->Canvas->LineTo( hOutScale1*log10(1.0*(m_iRxLimitFreq[i]-hStart)/hInScale1), vStart + vDistance*( (max_y_grid-m_dRxUpLimit[i])/vScale) );
  514.                 }
  515.                 else
  516.                 {
  517.                    // imAudioCal->Canvas->LineTo( 1, vStart + vDistance*( (max_y_grid-UIRxUpLimit[i])/vScale) );
  518.                     imAudioCal->Canvas->LineTo( 1, vStart + vDistance*( (max_y_grid-m_dRxUpLimit[i])/vScale) );
  519.                 }
  520.             }
  521.             else
  522.             {
  523.                // if( log10(1.0*(UIRxLimitFreq[i]- 1000)/hInScale2) > 0 )
  524.                 if( log10(1.0*(m_iRxLimitFreq[i]- 1000)/hInScale2) > 0 )
  525.                 {
  526.                     //imAudioCal->Canvas->LineTo( hStart2 + hOutScale2*log10(1.0*(UIRxLimitFreq[i]- 1000)/(hInScale2)) , vStart + vDistance*( (max_y_grid-UIRxUpLimit[i])/vScale) );
  527.                     imAudioCal->Canvas->LineTo( hStart2 + hOutScale2*log10(1.0*(m_iRxLimitFreq[i]- 1000)/(hInScale2)) , vStart + vDistance*( (max_y_grid-m_dRxUpLimit[i])/vScale) );
  528.                 }
  529.                 else
  530.                 {
  531.                     //imAudioCal->Canvas->LineTo( hStart2 , vStart + vDistance*( (max_y_grid-UIRxUpLimit[i])/vScale) );
  532.                     imAudioCal->Canvas->LineTo( hStart2 , vStart + vDistance*( (max_y_grid-m_dRxUpLimit[i])/vScale) );
  533.                 }
  534.             }
  535.         }
  536.         // draw lower limit
  537.         //imAudioCal->Canvas->MoveTo( 1, vStart + vDistance*( (max_y_grid-UIRxLowLimit[0])/vScale) );
  538.         imAudioCal->Canvas->MoveTo( 1, vStart + vDistance*( (max_y_grid-m_dRxLowLimit[0])/vScale) );
  539.         for( i=1; i<m_iRxLimitNum; i++ )
  540.         {
  541.            // if( UIRxLimitFreq[i] <= 1000 )
  542.             if( m_iRxLimitFreq[i] <= 1000 )
  543.             {
  544.                // if( log10(1.0*(UIRxLimitFreq[i]-hStart)/hInScale1) > 0 )
  545.                 if( log10(1.0*(m_iRxLimitFreq[i]-hStart)/hInScale1) > 0 )
  546.                 {
  547.                     //imAudioCal->Canvas->LineTo( hOutScale1*log10(1.0*(UIRxLimitFreq[i]-hStart)/hInScale1), vStart + vDistance*( (max_y_grid-UIRxLowLimit[i])/vScale) );
  548.                     imAudioCal->Canvas->LineTo( hOutScale1*log10(1.0*(m_iRxLimitFreq[i]-hStart)/hInScale1), vStart + vDistance*( (max_y_grid-m_dRxLowLimit[i])/vScale) );
  549.                 }
  550.                 else
  551.                 {
  552.                     //imAudioCal->Canvas->LineTo( 1, vStart + vDistance*( (max_y_grid-UIRxLowLimit[i])/vScale) );
  553.                     imAudioCal->Canvas->LineTo( 1, vStart + vDistance*( (max_y_grid-m_dRxLowLimit[i])/vScale) );
  554.                 }
  555.             }
  556.             else
  557.             {
  558.                // if( log10(1.0*(UIRxLimitFreq[i]- 1000)/hInScale2) > 0 )
  559.                 if( log10(1.0*(m_iRxLimitFreq[i]- 1000)/hInScale2) > 0 )
  560.                 {
  561.                    // imAudioCal->Canvas->LineTo( hStart2 + hOutScale2*log10(1.0*(UIRxLimitFreq[i]- 1000)/(hInScale2)) , vStart + vDistance*( (max_y_grid-UIRxLowLimit[i])/vScale) );
  562.                    imAudioCal->Canvas->LineTo( hStart2 + hOutScale2*log10(1.0*(m_iRxLimitFreq[i]- 1000)/(hInScale2)) , vStart + vDistance*( (max_y_grid-m_dRxLowLimit[i])/vScale) );
  563.                 }
  564.                 else
  565.                 {
  566.                    // imAudioCal->Canvas->LineTo( hStart2 , vStart + vDistance*( (max_y_grid-UIRxLowLimit[i])/vScale) );
  567.                     imAudioCal->Canvas->LineTo( hStart2 , vStart + vDistance*( (max_y_grid-m_dRxLowLimit[i])/vScale) );
  568.                 }
  569.             }
  570.         }
  571.     }
  572. }
  573. //==============================================================================
  574. void __fastcall TfrmFIRCoeffCal::rbTxClick(TObject *Sender)
  575. {
  576.     double min_y, max_y;
  577.     btnSetupOutputTxFile->Enabled = true;
  578.     btnSetupOutpuRxFile->Enabled = false;
  579.     stOutputTxFileName->Enabled = true;
  580.     stOutputRxFileName->Enabled = false;
  581.     GetMinMaxY( &OrgSpCoef, &min_y, &max_y );
  582.     if( min_y == max_y || isTRCLoadOk == false || OrgSpCoef.num>TOTAL_TRC_FREQ_NUM)
  583.     {
  584.         PlotGrid(100, 4000, -20, 15);
  585.     }
  586.     else
  587.     {
  588.         PlotGrid( 100, 4000, min_y, max_y);
  589.     }
  590.     PlotBoundaryCurve();
  591.     if( isOrgCurvePlot )
  592.     {
  593.         PlotOrgCurve();
  594.     }
  595.      
  596.     sbAudioCal->Panels->Items[0]->Text = (AnsiString) "  Change to TX";
  597. }
  598. //---------------------------------------------------------------------------
  599. void __fastcall TfrmFIRCoeffCal::rbRxClick(TObject *Sender)
  600. {
  601.     double min_y, max_y;
  602.     btnSetupOutputTxFile->Enabled = false;
  603.     btnSetupOutpuRxFile->Enabled = true;
  604.     stOutputTxFileName->Enabled = false;
  605.     stOutputRxFileName->Enabled = true;
  606.     GetMinMaxY( &OrgSpCoef, &min_y, &max_y );
  607.     if( min_y == max_y || isTRCLoadOk == false || OrgSpCoef.num>TOTAL_TRC_FREQ_NUM)
  608.     {
  609.         PlotGrid(100, 4000, -20, 15);
  610.     }
  611.     else
  612.     {
  613.         PlotGrid( 100, 4000, min_y, max_y);
  614.     }
  615.     PlotBoundaryCurve();
  616.     if( isOrgCurvePlot )
  617.     {
  618.         PlotOrgCurve();
  619.     }
  620.     sbAudioCal->Panels->Items[0]->Text = (AnsiString) "  Change to RX";
  621. }
  622. //---------------------------------------------------------------------------
  623. void TfrmFIRCoeffCal::IdealizeExcute(void)
  624. {
  625.     //int i;
  626.     int total_boundary_num;
  627.     int *Af, Pyf[TOTAL_TRC_FREQ_NUM+1];
  628.     int px, qx;
  629.     double *AdB, Pyy[TOTAL_TRC_FREQ_NUM+1];
  630.     double py, qy;
  631.   //  if( rbGoodSound->Checked )
  632.   //  {
  633.   //      total_boundary_num = 15;
  634.    // }
  635.   //  else
  636.   //  {
  637.   //      total_boundary_num = 8;
  638.   //  }
  639.     // getting bounday
  640.     if (rbTx->Checked)
  641.     {
  642.         total_boundary_num = m_iTxLimitNum;
  643.         for (int i=0; i<total_boundary_num; i++)
  644.         {
  645.             m_iHz_bound[i] = m_iTxLimitFreq[i];
  646.             m_dLow_bound_dB[i] = m_dTxLowLimit[i];
  647.             m_dUp_bound_dB[i]= m_dTxUpLimit[i];
  648.         }
  649.         m_dLow_limit_dB = -30;
  650.         m_dHz100_limit_dB = -40;
  651.     }
  652.     else
  653.     {
  654.         total_boundary_num = m_iRxLimitNum;
  655.         for (int i=0; i<total_boundary_num; i++)
  656.         {
  657.             m_iHz_bound[i] = m_iRxLimitFreq[i];
  658.             m_dLow_bound_dB[i] = m_dRxLowLimit[i];
  659.             m_dUp_bound_dB[i] = m_dRxUpLimit[i];
  660.         }
  661.         m_dLow_limit_dB = -20;
  662.         m_dHz100_limit_dB = -30;
  663.     }
  664.     if ((ITEMIDX_BOUNDARY_SPEC                   == cbBoundary->ItemIndex) ||
  665.         (ITEMIDX_BOUNDARY_3G_HANDSET_AND_HEADSET == cbBoundary->ItemIndex)
  666.        )
  667.     {
  668.         for (int i=0; i<total_boundary_num; i++)
  669.         {
  670.             if (m_dLow_bound_dB[i] < -25)
  671.             {
  672.                 m_dLow_bound_dB[i] = m_dLow_limit_dB;
  673.             }
  674.         }
  675.         m_dLow_bound_dB[0] = -90 - m_dUp_bound_dB[0];
  676.         m_dLow_bound_dB[7] = -90 - m_dUp_bound_dB[7];
  677.     }
  678.     if (
  679.         (ITEMIDX_BOUNDARY_3G_HANDSFREE_DESKTOP_AND_VEHICLE == cbBoundary->ItemIndex) ||
  680.         (ITEMIDX_BOUNDARY_3G_HANDSFREE_HANDHELD            == cbBoundary->ItemIndex) ||
  681.         (ITEMIDX_BOUNDARY_VOIP_HANDSET                     == cbBoundary->ItemIndex) ||
  682.         (ITEMIDX_BOUNDARY_VOIP_HEADSET                     == cbBoundary->ItemIndex) ||
  683.         (ITEMIDX_BOUNDARY_TYPE_3_3                         == cbBoundary->ItemIndex)
  684.       )
  685.     {
  686.         for (int i=0; i<total_boundary_num; i++)
  687.         {
  688.             if (m_dLow_bound_dB[i] < -25)
  689.             {
  690.                 m_dLow_bound_dB[i] = m_dLow_limit_dB;
  691.             }
  692.         }
  693.     }
  694.     // getting mean boundary
  695.     for (int i=0; i<total_boundary_num; i++)
  696.     {
  697.         m_dMean_bound_dB[i] = (m_dLow_bound_dB[i] + m_dUp_bound_dB[i]) * 0.5;
  698.     }
  699.   //  Af = m_iHz_bound;
  700.   //  AdB = m_dMean_bound_dB;
  701.     IdealSpCoef.Hz[0] = OrgSpCoef.Hz[0];
  702.     IdealSpCoef.MagdB[0] = m_dMean_bound_dB[0]+(OrgSpCoef.Hz[0]-m_iHz_bound[0])*(m_dMean_bound_dB[1]-m_dMean_bound_dB[0])/(m_iHz_bound[1]-m_iHz_bound[0]);
  703.     IdealSpCoef.Mag[0] = pow(10, IdealSpCoef.MagdB[0]/20.0);
  704.     for (unsigned int i=1; i<OrgSpCoef.num; i++)
  705.     {
  706.         bool b_hit = false;
  707.         IdealSpCoef.Hz[i] = OrgSpCoef.Hz[i];
  708.         for (int j=1; j<total_boundary_num; j++)
  709.         {
  710.             if ((OrgSpCoef.Hz[i] > m_iHz_bound[j-1]) && (OrgSpCoef.Hz[i] <= m_iHz_bound[j]))
  711.             {
  712.                 b_hit = true;
  713.                 px=m_iHz_bound[j-1];
  714.                 qx=m_iHz_bound[j];
  715.                 py=m_dMean_bound_dB[j-1];
  716.                 qy=m_dMean_bound_dB[j];
  717.             }
  718.         }
  719.         if (b_hit)
  720.         {
  721.             IdealSpCoef.MagdB[i]=py+(qy-py)/(qx-px)*(OrgSpCoef.Hz[i]-px);
  722.             //IdealSpCoef.Mag[i] = pow(10, IdealSpCoef.MagdB[i]/20.0);
  723.         }
  724.         else
  725.         {
  726.             IdealSpCoef.MagdB[i] = m_dMean_bound_dB[i]+(OrgSpCoef.Hz[i]-m_iHz_bound[i])*(m_dMean_bound_dB[i+1]-m_dMean_bound_dB[i])/(m_iHz_bound[i+1]-m_iHz_bound[i]);
  727.         }
  728.         if (IdealSpCoef.MagdB[i] < m_dLow_limit_dB)
  729.         {
  730.             IdealSpCoef.MagdB[i] = m_dLow_limit_dB;
  731.         }
  732.         IdealSpCoef.Mag[i] = pow(10, IdealSpCoef.MagdB[i]/20.0);
  733.     }
  734.     IdealSpCoef.num = OrgSpCoef.num;
  735.     WantedSpCoef.num = OrgSpCoef.num;
  736.     for (unsigned int i=0; i<WantedSpCoef.num; i++)
  737.     {
  738.         WantedSpCoef.Hz[i] = IdealSpCoef.Hz[i];
  739.         WantedSpCoef.Mag[i] = IdealSpCoef.Mag[i];
  740.         WantedSpCoef.MagdB[i] = IdealSpCoef.MagdB[i];
  741.     }
  742. }
  743. //==============================================================================
  744. void TfrmFIRCoeffCal::PlotCurve(int plot_mask)
  745. {
  746.     // plot grid
  747.     
  748.     if (plot_mask & PLOT_GRID)
  749.     {
  750.         double min_y, max_y;
  751.         GetMinMaxY( &OrgSpCoef, &min_y, &max_y );
  752.         if( min_y == max_y || isTRCLoadOk == false || OrgSpCoef.num>TOTAL_TRC_FREQ_NUM)
  753.         {
  754.             PlotGrid(100, 4000, -20, 15);
  755.         }
  756.         else
  757.         {
  758.             PlotGrid( 100, 4000, min_y, max_y);
  759.         }
  760.     }
  761.     // plot boundary
  762.     if (plot_mask & PLOT_BOUNDARY_CURVE)
  763.     {
  764.         Set_Boundary();
  765.         PlotBoundaryCurve();
  766.     }
  767.     // plot wanted curve
  768.     if( plot_mask & PLOT_WANTED_CURVE )
  769.     {
  770.         PlotWantedCurve();
  771.         PlotWantedCircle();
  772.     }
  773.     // plot original curve
  774.     if( plot_mask & PLOT_ORG_CURVE )
  775.     {
  776.         PlotOrgCurve();
  777.     }
  778.     // plot compensate curve
  779.     if( plot_mask & PLOT_COMPENSATED_CURVE )
  780.     {
  781.         PlotCompensatedCurve();
  782.     }
  783. }
  784. //------------------------------------------------------------------------
  785. void TfrmFIRCoeffCal::PlotGrid(int min_x, int max_x, int min_y, int max_y)
  786. {
  787.      int i;
  788.      double range;
  789.      ClearImage();
  790.      // get max_y_grid, min_y_grid;
  791.      max_y_grid = getMaxYBound( max_y, 10 );
  792.      min_y_grid = getMinYBound( min_y, 10 );
  793.      if( min_y_grid < -20 )
  794.      {
  795.          min_y_grid = -20;
  796.      }    
  797.      range = max_y_grid - min_y_grid;
  798.      // recalculate vDistance
  799.     // vDistance = imAudioCal->Height / (max_y - min_y) * 10;
  800. //     vScale = (max_y - min_y)/8;
  801.      for( i=1; i<=100; i++ )
  802.      {
  803.          vScale = i*VSCALE_UNIT;
  804.          if( vScale * 8 > range)
  805.          {
  806.             break;
  807.          }
  808.      }
  809.      vDistance = imAudioCal->Height / (range+1) * vScale;
  810.     // vScale =  range/8;
  811.     // if( vScale > 5 )
  812.     // {
  813.     //    vScale = 10;
  814.     // }
  815.     // else
  816.     // {
  817.     //    vScale = 5;
  818.     // }
  819.     // if( (imAudioCal->Height % vDistance) != 0 )
  820.     // {
  821.     //      Segments = imAudioCal->Height/vDistance + 1;
  822.     // }
  823.     // else
  824.     // {
  825.      //     Segments = imAudioCal->Height/vDistance;
  826.      //}
  827.    // if( (range % vScale) != 0 )
  828.     {
  829.         Segments = (range / vScale) + 1;
  830.     }
  831.    // else
  832.    // {
  833.    //     Segments = (range / vScale);
  834.    // }
  835.     // hDistance = 50;
  836.     imAudioCal->Canvas->Pen->Color = clBlack;
  837.     imAudioCal->Canvas->Pen->Width = 1;
  838.     imAudioCal->Canvas->Pen->Style = psDot;
  839.     // plot horizotal grid & label
  840.     for( i=0; i<Segments && i<VERTICAL_LABEL_NUM; i++ )
  841.     {
  842.         if( (i*vDistance + vStart) > imAudioCal->Height )
  843.         {
  844.             break;
  845.         }
  846.         lblVertical[i]->Visible = true;
  847.         lblVertical[i]->Top =  imAudioCal->Top + i*vDistance - 5 + vStart;
  848.         lblVertical[i]->Left = imAudioCal->Left - 20;
  849.         lblVertical[i]->Caption = IntToStr( max_y_grid - i*vScale );
  850.         imAudioCal->Canvas->MoveTo( 1, i*vDistance + vStart );
  851.         imAudioCal->Canvas->LineTo( 1 + imAudioCal->Width, i*vDistance +vStart );
  852.     }
  853.     for(; i<VERTICAL_LABEL_NUM; i++)
  854.     {
  855.         lblVertical[i]->Visible = false;
  856.     }
  857.     // plot vertical grid
  858.     lbl100Hz->Left = imAudioCal->Left - 10;
  859.     lbl100Hz->Top = imAudioCal->Top + imAudioCal->Height + 5;
  860.     lbl1000Hz->Left = imAudioCal->Left + hStart2 - 10;
  861.     lbl1000Hz->Top = imAudioCal->Top + imAudioCal->Height + 5;
  862.     for( i=1; i<=9; i++ )
  863.     {
  864.         if( log10(100.0*i/hInScale1) > 0 )
  865.         {
  866.             imAudioCal->Canvas->MoveTo( hOutScale1*log10(100.0*i/hInScale1), 1 );
  867.             imAudioCal->Canvas->LineTo( hOutScale1*log10(100.0*i/hInScale1), imAudioCal->Height );
  868.         }
  869.         else
  870.         {
  871.             imAudioCal->Canvas->MoveTo( 1, 1 );
  872.             imAudioCal->Canvas->LineTo( 1, imAudioCal->Height );
  873.         }
  874.     }
  875.     for( i=1; i<4; i++ )
  876.     {
  877.         if( log10(i*1000.0/hInScale2) > 0 )
  878.         {
  879.             imAudioCal->Canvas->MoveTo( hStart2 + hOutScale2*log10(i*1000.0/(hInScale2)) , 1 );
  880.             imAudioCal->Canvas->LineTo( hStart2 + hOutScale2*log10(i*1000.0/(hInScale2)), imAudioCal->Height );
  881.         }
  882.         else
  883.         {
  884.             imAudioCal->Canvas->MoveTo( hStart2, 1 );
  885.             imAudioCal->Canvas->LineTo( hStart2, imAudioCal->Height );
  886.         }
  887.     }
  888. }
  889. //------------------------------------------------------------------------
  890. void TfrmFIRCoeffCal::GetMinMaxY( sSpCoefCalParameters *p_SpCoef, double *p_min_y, double *p_max_y )
  891. {
  892.     *p_min_y = 1000000.0;
  893.     *p_max_y =  -1000000.0;
  894.     for (unsigned int i=0; i<p_SpCoef->num; i++)
  895.     {
  896.         if( *(p_SpCoef->MagdB+i) < *p_min_y )
  897.         {
  898.             *p_min_y = *(p_SpCoef->MagdB+i);
  899.         }
  900.         if( *(p_SpCoef->MagdB+i) > *p_max_y )
  901.         {
  902.              *p_max_y = *(p_SpCoef->MagdB+i);
  903.         }
  904.     }
  905. }
  906. //---------------------------------------------------------------------------
  907. void TfrmFIRCoeffCal::PlotOrgCurve( void )
  908. {
  909.     isOrgCurvePlot = true;
  910.     imAudioCal->Canvas->Pen->Color = clBlue;
  911.     imAudioCal->Canvas->Pen->Width = 1;
  912.     imAudioCal->Canvas->Pen->Style = psSolid;
  913.     imAudioCal->Canvas->MoveTo( 1,  vStart + vDistance*((max_y_grid-OrgSpCoef.MagdB[0])/vScale) );
  914.     for (unsigned int i=0; i<OrgSpCoef.num; i++)
  915.     {
  916.         if( OrgSpCoef.Hz[i]<=100.0 )
  917.         {
  918.         }
  919.         else if( OrgSpCoef.Hz[i]>100.0 && OrgSpCoef.Hz[i]<= 1000.0 )
  920.         {
  921.             if( log10((OrgSpCoef.Hz[i]-hStart)/hInScale1) > 0 )
  922.             {
  923.                 imAudioCal->Canvas->LineTo( hOutScale1*log10((OrgSpCoef.Hz[i]-hStart)/hInScale1), vStart + vDistance*(( max_y_grid-OrgSpCoef.MagdB[i])/vScale) );
  924.             }
  925.             else
  926.             {
  927.                 imAudioCal->Canvas->LineTo( 1, vStart + vDistance*(( max_y_grid-OrgSpCoef.MagdB[i])/vScale) );
  928.             }
  929.         }
  930.         else
  931.         {
  932.             if( log10(1.0*(OrgSpCoef.Hz[i]- 1000)/hInScale2) > 0 )
  933.             {
  934.                 imAudioCal->Canvas->LineTo( hStart2 + hOutScale2*log10(1.0*(OrgSpCoef.Hz[i]- 1000)/(hInScale2)) , vStart + vDistance*((max_y_grid-OrgSpCoef.MagdB[i])/vScale) );
  935.             }
  936.             else
  937.             {
  938.                 imAudioCal->Canvas->LineTo( hStart2 ,vStart + vDistance*( (max_y_grid-OrgSpCoef.MagdB[i])/vScale) );
  939.             }
  940.         }
  941.     }
  942.     
  943. }
  944. //---------------------------------------------------------------------------
  945. void TfrmFIRCoeffCal::PlotWantedCurve( void )
  946. {
  947.     isWantedCurvePlot = true;
  948.     imAudioCal->Canvas->Pen->Color = clRed;
  949.     imAudioCal->Canvas->Pen->Width = 1;
  950.     imAudioCal->Canvas->Pen->Style = psDot;
  951.     WantedPoint.num = WantedSpCoef.num;
  952.     WantedPoint.x[0] = 1;
  953.     WantedPoint.y[0] = vStart + vDistance*((max_y_grid-WantedSpCoef.MagdB[0])/vScale);
  954.     imAudioCal->Canvas->MoveTo( 1,  vStart + vDistance*((max_y_grid-WantedSpCoef.MagdB[0])/vScale) );
  955.     for (unsigned int i=0; i<WantedSpCoef.num; i++)
  956.     {
  957.         if( WantedSpCoef.Hz[i]<=100.0 )
  958.         {
  959.         }
  960.         else if( WantedSpCoef.Hz[i]>100.0 && WantedSpCoef.Hz[i]<= 1000.0 )
  961.         {
  962.             if( log10((WantedSpCoef.Hz[i]-hStart)/hInScale1) > 0 )
  963.             {
  964.                 WantedPoint.x[i] = hOutScale1*log10((WantedSpCoef.Hz[i]-hStart)/hInScale1);
  965.             }
  966.             else
  967.             {
  968.                 WantedPoint.x[i] = 1;
  969.             }
  970.             WantedPoint.y[i] = vStart + vDistance*((max_y_grid-WantedSpCoef.MagdB[i])/vScale);
  971.             imAudioCal->Canvas->LineTo(WantedPoint.x[i], WantedPoint.y[i] );
  972.         }
  973.         else
  974.         {
  975.             if( log10(1.0*(WantedSpCoef.Hz[i]- 1000)/hInScale2) > 0 )
  976.             {
  977.                 WantedPoint.x[i] = hStart2 + hOutScale2*log10(1.0*(WantedSpCoef.Hz[i]- 1000)/(hInScale2));
  978.                 WantedPoint.y[i] = vStart + vDistance*( (max_y_grid-WantedSpCoef.MagdB[i])/vScale);
  979.                 imAudioCal->Canvas->LineTo( WantedPoint.x[i] , WantedPoint.y[i] );
  980.             }
  981.             else
  982.             {
  983.                 WantedPoint.x[i] = hStart2;
  984.                 WantedPoint.y[i] = vStart + vDistance*( (max_y_grid-WantedSpCoef.MagdB[i])/vScale);
  985.                 imAudioCal->Canvas->LineTo( WantedPoint.x[i] , WantedPoint.y[i] );
  986.             }
  987.         }
  988.     }
  989. }
  990. //---------------------------------------------------------------------------
  991. void TfrmFIRCoeffCal::PlotCompensatedCurve( void )
  992. {
  993.     isWantedCurvePlot = true;
  994.     imAudioCal->Canvas->Pen->Color = clBlack;
  995.     imAudioCal->Canvas->Pen->Width = 1;
  996.     imAudioCal->Canvas->Pen->Style = psSolid;
  997.     imAudioCal->Canvas->MoveTo( 1,  vStart + vDistance*((max_y_grid-ck_NewSpCoef.MagdB[0])/vScale) );
  998.     for (unsigned int i=0; i<ck_NewSpCoef.num; i++)
  999.     {
  1000.         if( ck_NewSpCoef.Hz[i]<=100.0 )
  1001.         {
  1002.         }
  1003.         else if( ck_NewSpCoef.Hz[i]>100.0 && ck_NewSpCoef.Hz[i]<= 1000.0 )
  1004.         {
  1005.             if( log10((ck_NewSpCoef.Hz[i]-hStart)/hInScale1) > 0 )
  1006.             {
  1007.                 imAudioCal->Canvas->LineTo( hOutScale1*log10((ck_NewSpCoef.Hz[i]-hStart)/hInScale1), vStart + vDistance*( (max_y_grid-ck_NewSpCoef.MagdB[i])/vScale) );
  1008.             }
  1009.             else
  1010.             {
  1011.                 imAudioCal->Canvas->LineTo( 1, vStart + vDistance*( (max_y_grid-ck_NewSpCoef.MagdB[i])/vScale) );
  1012.             }
  1013.         }
  1014.         else
  1015.         {
  1016.             if( log10(1.0*(ck_NewSpCoef.Hz[i]- 1000)/hInScale2) > 0 )
  1017.             {
  1018.                 imAudioCal->Canvas->LineTo( hStart2 + hOutScale2*log10(1.0*(ck_NewSpCoef.Hz[i]- 1000)/(hInScale2)) , vStart + vDistance*((max_y_grid-ck_NewSpCoef.MagdB[i])/vScale) );
  1019.             }
  1020.             else
  1021.             {
  1022.                 imAudioCal->Canvas->LineTo( hStart2, vStart + vDistance*((max_y_grid-ck_NewSpCoef.MagdB[i])/vScale) );
  1023.             }
  1024.         }
  1025.     }
  1026. }
  1027. //------------------------------------------------------------------------------
  1028. void  TfrmFIRCoeffCal::PlotWantedCircle( void )
  1029. {
  1030.     imAudioCal->Canvas->Brush->Color = clAqua;
  1031.     for(int i=0; i<WantedPoint.num; i++)
  1032.     {
  1033.         imAudioCal->Canvas->Ellipse(WantedPoint.x[i]-2, WantedPoint.y[i]-2, WantedPoint.x[i]+2, WantedPoint.y[i]+2);
  1034.     }
  1035. }
  1036. //---------------------------------------------------------------------------
  1037. void  TfrmFIRCoeffCal::UpdatecbExtraFreq(sSpCoefCalParameters* p_SpCoef)
  1038. {
  1039.     cbExtraFreq->Items->Clear();
  1040.     for (unsigned int i=0; i<p_SpCoef->num; i++)
  1041.     {
  1042.         cbExtraFreq->Items->Add( Double_To_AnsiString(p_SpCoef->Hz[i]) + " Hz" );
  1043.     }
  1044.     cbExtraFreq->ItemIndex = 0;
  1045.     edtExtraDB->Text = p_SpCoef->MagdB[cbExtraFreq->ItemIndex];
  1046. }
  1047. //---------------------------------------------------------------------------
  1048. void  TfrmFIRCoeffCal::Updatecb1xxHz( sSpCoefCalParameters* p_SpCoef, int idx )
  1049. {
  1050.     cb1xxHz->Items->Clear();
  1051.     //for(int i=0; i<p_SpCoef->num /15; i++ )
  1052.     for(int i=SelectedSpCoef.index[0]; i<SelectedSpCoef.index[1]; i++ )
  1053.     {
  1054.         cb1xxHz->Items->Add( Double_To_AnsiString(p_SpCoef->Hz[i]) + " Hz" );
  1055.     }
  1056.     cb1xxHz->ItemIndex = idx;
  1057.     edt1xxHzdB->Text = p_SpCoef->MagdB[ SelectedSpCoef.index[0] + idx ];
  1058. }
  1059. //---------------------------------------------------------------------------
  1060. void  TfrmFIRCoeffCal::Updatecb2xxHz( sSpCoefCalParameters* p_SpCoef, int idx )
  1061. {
  1062.     cb2xxHz->Items->Clear();
  1063.    // for(int i=p_SpCoef->num /15; i<2*p_SpCoef->num/15; i++ )
  1064.     for(int i=SelectedSpCoef.index[1]; i<SelectedSpCoef.index[2]; i++ )
  1065.     {
  1066.         cb2xxHz->Items->Add( Double_To_AnsiString(p_SpCoef->Hz[i]) + " Hz" );
  1067.     }
  1068.     cb2xxHz->ItemIndex = idx;
  1069.     edt2xxHzdB->Text = p_SpCoef->MagdB[ SelectedSpCoef.index[1] + idx ];
  1070. }
  1071. //---------------------------------------------------------------------------
  1072. void  TfrmFIRCoeffCal::Updatecb3xxHz( sSpCoefCalParameters* p_SpCoef, int idx )
  1073. {
  1074.     cb3xxHz->Items->Clear();
  1075.     //for(int i=2*p_SpCoef->num /15; i<3*p_SpCoef->num/15; i++ )
  1076.     for(int i=SelectedSpCoef.index[2]; i<SelectedSpCoef.index[3]; i++ )
  1077.     {
  1078.         cb3xxHz->Items->Add( Double_To_AnsiString(p_SpCoef->Hz[i]) + " Hz" );
  1079.     }
  1080.     cb3xxHz->ItemIndex = idx;
  1081.     edt3xxHzdB->Text = p_SpCoef->MagdB[ SelectedSpCoef.index[2] + idx ];
  1082. }
  1083. //---------------------------------------------------------------------------
  1084. void  TfrmFIRCoeffCal::Updatecb5xxHz( sSpCoefCalParameters* p_SpCoef, int idx )
  1085. {
  1086.     cb5xxHz->Items->Clear();
  1087.     //for(int i=3*p_SpCoef->num /15; i<4*p_SpCoef->num/15; i++ )
  1088.     for(int i=SelectedSpCoef.index[3]; i<SelectedSpCoef.index[4]; i++ )
  1089.     {
  1090.         cb5xxHz->Items->Add( Double_To_AnsiString(p_SpCoef->Hz[i]) + " Hz" );
  1091.     }
  1092.     cb5xxHz->ItemIndex = idx;
  1093.     edt5xxHzdB->Text = p_SpCoef->MagdB[ SelectedSpCoef.index[3] + idx ];
  1094. }
  1095. //---------------------------------------------------------------------------
  1096. void  TfrmFIRCoeffCal::Updatecb6xxHz( sSpCoefCalParameters* p_SpCoef, int idx )
  1097. {
  1098.     cb6xxHz->Items->Clear();
  1099.     //for(int i=4*p_SpCoef->num /15; i<5*p_SpCoef->num/15; i++ )
  1100.     for(int i=SelectedSpCoef.index[4]; i<SelectedSpCoef.index[5]; i++ )
  1101.     {
  1102.         cb6xxHz->Items->Add( Double_To_AnsiString(p_SpCoef->Hz[i]) + " Hz" );
  1103.     }
  1104.     cb6xxHz->ItemIndex = idx;
  1105.     edt6xxHzdB->Text = p_SpCoef->MagdB[ SelectedSpCoef.index[4] + idx ];
  1106. }
  1107. //---------------------------------------------------------------------------
  1108. void  TfrmFIRCoeffCal::Updatecb7xxHz( sSpCoefCalParameters* p_SpCoef, int idx )
  1109. {
  1110.     cb7xxHz->Items->Clear();
  1111.    // for(int i=5*p_SpCoef->num /15; i<6*p_SpCoef->num/15; i++ )
  1112.     for(int i=SelectedSpCoef.index[5]; i<SelectedSpCoef.index[6]; i++ )
  1113.     {
  1114.         cb7xxHz->Items->Add( Double_To_AnsiString(p_SpCoef->Hz[i]) + " Hz" );
  1115.     }
  1116.     cb7xxHz->ItemIndex = idx;
  1117.     edt7xxHzdB->Text = p_SpCoef->MagdB[ SelectedSpCoef.index[5] + idx ];
  1118. }
  1119. //---------------------------------------------------------------------------
  1120. void  TfrmFIRCoeffCal::Updatecb8xxHz( sSpCoefCalParameters* p_SpCoef, int idx )
  1121. {
  1122.     cb8xxHz->Items->Clear();
  1123.    // for(int i=6*p_SpCoef->num /15; i<7*p_SpCoef->num/15; i++ )
  1124.     for(int i=SelectedSpCoef.index[6]; i<SelectedSpCoef.index[7]; i++ )
  1125.     {
  1126.         cb8xxHz->Items->Add( Double_To_AnsiString(p_SpCoef->Hz[i]) + " Hz" );
  1127.     }
  1128.     cb8xxHz->ItemIndex = idx;
  1129.     edt8xxHzdB->Text = p_SpCoef->MagdB[ SelectedSpCoef.index[6] + idx ];
  1130. }
  1131. //---------------------------------------------------------------------------
  1132. void  TfrmFIRCoeffCal::Updatecb1xxxHz( sSpCoefCalParameters* p_SpCoef, int idx )
  1133. {
  1134.     cb1xxxHz->Items->Clear();
  1135.     //for(int i=7*p_SpCoef->num /15; i<8*p_SpCoef->num/15; i++ )
  1136.     for(int i=SelectedSpCoef.index[7]; i<SelectedSpCoef.index[8]; i++ )
  1137.     {
  1138.         cb1xxxHz->Items->Add( Double_To_AnsiString(p_SpCoef->Hz[i]) + " Hz" );
  1139.     }
  1140.     cb1xxxHz->ItemIndex = idx;
  1141.     edt1xxxHzdB->Text = p_SpCoef->MagdB[ SelectedSpCoef.index[7] + idx ];
  1142. }
  1143. //---------------------------------------------------------------------------
  1144. void  TfrmFIRCoeffCal::Updatecb15xxHz( sSpCoefCalParameters* p_SpCoef, int idx )
  1145. {
  1146.     cb13xxHz->Items->Clear();
  1147.    // for(int i=8*p_SpCoef->num /15; i<9*p_SpCoef->num/15; i++ )
  1148.     for(int i=SelectedSpCoef.index[8]; i<SelectedSpCoef.index[9]; i++ )
  1149.     {
  1150.         cb13xxHz->Items->Add( Double_To_AnsiString(p_SpCoef->Hz[i]) + " Hz" );
  1151.     }
  1152.     cb13xxHz->ItemIndex = idx;
  1153.     edt13xxHzdB->Text = p_SpCoef->MagdB[ SelectedSpCoef.index[8] + idx ];
  1154. }
  1155. //---------------------------------------------------------------------------
  1156. void  TfrmFIRCoeffCal::Updatecb18xxHz( sSpCoefCalParameters* p_SpCoef, int idx )
  1157. {
  1158.     cb18xxHz->Items->Clear();
  1159.     //for(int i=9*p_SpCoef->num /15; i<10*p_SpCoef->num/15; i++ )
  1160.     for(int i=SelectedSpCoef.index[9]; i<SelectedSpCoef.index[10]; i++ )
  1161.     {
  1162.         cb18xxHz->Items->Add( Double_To_AnsiString(p_SpCoef->Hz[i]) + " Hz" );
  1163.     }
  1164.     cb18xxHz->ItemIndex = idx;
  1165.     edt18xxHzdB->Text = p_SpCoef->MagdB[ SelectedSpCoef.index[9] + idx ];
  1166. }
  1167. //---------------------------------------------------------------------------
  1168. void  TfrmFIRCoeffCal::Updatecb2xxxHz( sSpCoefCalParameters* p_SpCoef, int idx )
  1169. {
  1170.     cb2xxxHz->Items->Clear();
  1171.     //for(int i=10*p_SpCoef->num /15; i<11*p_SpCoef->num/15; i++ )
  1172.     for(int i=SelectedSpCoef.index[10]; i<SelectedSpCoef.index[11]; i++ )
  1173.     {
  1174.         cb2xxxHz->Items->Add( Double_To_AnsiString(p_SpCoef->Hz[i]) + " Hz" );
  1175.     }
  1176.     cb2xxxHz->ItemIndex = idx;
  1177.     edt2xxxHzdB->Text = p_SpCoef->MagdB[ SelectedSpCoef.index[10] + idx ];
  1178. }
  1179. //---------------------------------------------------------------------------
  1180. void  TfrmFIRCoeffCal::Updatecb25xxHz( sSpCoefCalParameters* p_SpCoef, int idx )
  1181. {
  1182.     cb25xxHz->Items->Clear();
  1183.     //for(int i=11*p_SpCoef->num /15; i<12*p_SpCoef->num/15; i++ )
  1184.     for(int i=SelectedSpCoef.index[11]; i<SelectedSpCoef.index[12]; i++ )
  1185.     {
  1186.         cb25xxHz->Items->Add( Double_To_AnsiString(p_SpCoef->Hz[i]) + " Hz" );
  1187.     }
  1188.     cb25xxHz->ItemIndex = idx;
  1189.     edt25xxHzdB->Text = p_SpCoef->MagdB[ SelectedSpCoef.index[11] + idx ];
  1190. }
  1191. //---------------------------------------------------------------------------
  1192. void  TfrmFIRCoeffCal::Updatecb3xxxHz( sSpCoefCalParameters* p_SpCoef, int idx )
  1193. {
  1194.     cb3xxxHz->Items->Clear();
  1195.     //for(int i=12*p_SpCoef->num /15; i<13*p_SpCoef->num/15; i++ )
  1196.     for(int i=SelectedSpCoef.index[12]; i<SelectedSpCoef.index[13]; i++ )
  1197.     {
  1198.         cb3xxxHz->Items->Add( Double_To_AnsiString(p_SpCoef->Hz[i]) + " Hz" );
  1199.     }
  1200.     cb3xxxHz->ItemIndex = idx;
  1201.     edt3xxxHzdB->Text = p_SpCoef->MagdB[ SelectedSpCoef.index[12] + idx ];
  1202. }
  1203. //---------------------------------------------------------------------------
  1204. void  TfrmFIRCoeffCal::Updatecb34xxHz( sSpCoefCalParameters* p_SpCoef, int idx )
  1205. {
  1206.     cb34xxHz->Items->Clear();
  1207.    // for(int i=13*p_SpCoef->num /15; i<14*p_SpCoef->num/15; i++ )
  1208.     for(int i=SelectedSpCoef.index[13]; i<SelectedSpCoef.index[14]; i++ )
  1209.     {
  1210.         cb34xxHz->Items->Add( Double_To_AnsiString(p_SpCoef->Hz[i]) + " Hz" );
  1211.     }
  1212.     cb34xxHz->ItemIndex = idx;
  1213.     edt34xxHzdB->Text = p_SpCoef->MagdB[ SelectedSpCoef.index[13] + idx ];
  1214. }
  1215. //---------------------------------------------------------------------------
  1216. void  TfrmFIRCoeffCal::Updatecb39xxHz( sSpCoefCalParameters* p_SpCoef, int idx )
  1217. {
  1218.     cb39xxHz->Items->Clear();
  1219.     //for(int i=14*p_SpCoef->num /15; i<p_SpCoef->num; i++ )
  1220.     for (unsigned int i=SelectedSpCoef.index[14]; i<p_SpCoef->num; i++ )
  1221.     {
  1222.         cb39xxHz->Items->Add( Double_To_AnsiString(p_SpCoef->Hz[i]) + " Hz" );
  1223.     }
  1224.     cb39xxHz->ItemIndex = idx;
  1225.     edt39xxHzdB->Text = p_SpCoef->MagdB[ SelectedSpCoef.index[14] + idx ];
  1226. }
  1227. //---------------------------------------------------------------------------
  1228. void  TfrmFIRCoeffCal::UpdateAllSelectParameters( void )
  1229. {
  1230.     for( int i=0; i<TOTAL_SEL_FREQ_NUM; i++ )
  1231.     {
  1232.         SelectedSpCoef.MagdB[i] = WantedSpCoef.MagdB[SelectedSpCoef.index[i]];
  1233.     }
  1234. }
  1235. //---------------------------------------------------------------------------
  1236. void  TfrmFIRCoeffCal::UpdateAllSelectEditor( void )
  1237. {
  1238.     char str[256];
  1239.     for( int i=0; i<TOTAL_SEL_FREQ_NUM; i++ )
  1240.     {
  1241.         UISelectedSpCoef.MagdB[i] = SelectedSpCoef.MagdB[i];
  1242.         sprintf(str, "%.3f", SelectedSpCoef.MagdB[i]);
  1243.         edtHzdB[i]->Text  = (AnsiString ) str;
  1244.     }
  1245. }
  1246. //---------------------------------------------------------------------------
  1247. void  TfrmFIRCoeffCal::UpdateExtradBEditor( void )
  1248. {
  1249.      char str[256];
  1250.      sprintf(str, "%.3f", WantedSpCoef.MagdB[cbExtraFreq->ItemIndex]);
  1251.      edtExtraDB->Text = (AnsiString) str;
  1252. }
  1253. //---------------------------------------------------------------------------
  1254. void  TfrmFIRCoeffCal::UpdateEditor( void )
  1255. {
  1256.     GetWantedIndex( &WantedSpCoef, &SelectedSpCoef );
  1257.     char str[256];
  1258.     for( int i=0; i<TOTAL_SEL_FREQ_NUM; i++ )
  1259.     {
  1260.          UISelectedSpCoef.Hz[i] = SelectedSpCoef.Hz[i];
  1261.          UISelectedSpCoef.MagdB[i] = SelectedSpCoef.MagdB[i];
  1262.          //lblHz[i]->Caption = Double_To_AnsiString( SelectedSpCoef.Hz[i] ) + " Hz";
  1263.          sprintf(str, "%.3f", SelectedSpCoef.MagdB[i]);
  1264.          edtHzdB[i]->Text  = (AnsiString ) str;
  1265.     }
  1266. }
  1267. //---------------------------------------------------------------------------
  1268. void  TfrmFIRCoeffCal::UpdateSelectedLabel( void )
  1269. {
  1270.     for( int i=0; i<TOTAL_SEL_FREQ_NUM; i++ )
  1271.     {
  1272.          lblHz[i]->Caption = Double_To_AnsiString( SelectedSpCoef.Hz[i] ) + " Hz";
  1273.     }
  1274. }
  1275. //---------------------------------------------------------------------------
  1276. void  TfrmFIRCoeffCal::GetWantedIndex( sSpCoefCalParameters *p_SpCoefCal, sSelectedParameters *p_SpSelected )
  1277. {
  1278.     
  1279.     unsigned index;
  1280.     for( int j=0; j<TOTAL_SEL_FREQ_NUM; j++ )
  1281.     {
  1282.         GetIndexOfMostSimilar( m_iWantedHz[j], p_SpCoefCal, &index );
  1283.         p_SpSelected->index[j] = index;
  1284.         p_SpSelected->Hz[j] =  p_SpCoefCal->Hz[index];
  1285.         p_SpSelected->MagdB[j] = p_SpCoefCal->MagdB[index];
  1286.     }
  1287. }
  1288. //---------------------------------------------------------------------------
  1289. void  TfrmFIRCoeffCal::GetIndexOfMostSimilar( int wanted_Hz, sSpCoefCalParameters *p_SpCoefCal, unsigned int* p_index )
  1290. {
  1291.     int distance;
  1292.     distance = abs( wanted_Hz - p_SpCoefCal->Hz[0] );
  1293.     *p_index = 0;
  1294.     for (unsigned int i=1; i<p_SpCoefCal->num; i++ )
  1295.     {
  1296.         if( distance > abs( wanted_Hz - p_SpCoefCal->Hz[i] ) )
  1297.         {
  1298.              *p_index = i;
  1299.              distance = abs( wanted_Hz - p_SpCoefCal->Hz[i] );
  1300.         }
  1301.     }
  1302. }
  1303. //==============================================================================
  1304. void __fastcall TfrmFIRCoeffCal::btnIdealizeClick(TObject *Sender)
  1305. {
  1306.     IdealizeExcute();
  1307.     //PlotWantedCurve();
  1308.     //PlotWantedCircle();
  1309.     PlotCurve( PLOT_GRID | PLOT_BOUNDARY_CURVE | PLOT_WANTED_CURVE | PLOT_ORG_CURVE );
  1310.     UpdateAllSelectParameters();
  1311.     UpdateExtradBEditor();
  1312.     UpdateAllSelectEditor();
  1313.     sbAudioCal->Panels->Items[0]->Text = (AnsiString) "  Idealize successfully";
  1314. }
  1315. //---------------------------------------------------------------------------
  1316. void __fastcall TfrmFIRCoeffCal::btnRunClick(TObject *Sender)
  1317. {
  1318.     AFT_RESULT ret;
  1319.     int wanted_ord;
  1320.     //static bool isMfileDllLoaded = false;
  1321.     //sSpCoefCalParameters   temp_OrgSpCoef, temp_WantedSpCoef, ProcessSpCoef, ProcessOddSpCoef, WithoutFirSpCoef, NewFirOddSpCoef, ck_NewFirSpCoef;
  1322.     sSpCoefCalParameters   temp_OrgSpCoef, temp_WantedSpCoef, ProcessOddSpCoef, WithoutFirSpCoef, NewFirOddSpCoef, ck_NewFirSpCoef;
  1323.     sSpCoefCalParameters  impulse_hw_FIR;
  1324.    // sFirCoefParameters   old_FIR_norm, NewFirF1Coef, NewFirCoeffF, NewFirCoeffF_abs, NewFirCoeffF1, NewFirCoeffF_norm, ZeroFirCoeff;
  1325.     sFirCoefParameters   NewFirF1Coef, NewFirCoeffF, NewFirCoeffF_abs, NewFirCoeffF1, NewFirCoeffF_norm, ZeroFirCoeff;
  1326.     sFirCoefParameters  NewFirCoeffF_norm_fx;
  1327.     sWeightParameters   Weight;
  1328.     //bool odd_flag;
  1329.     double  d_max, d_gain;
  1330.     AnsiString as_Filename;
  1331.     double min_y, max_y;
  1332.     //static bool isFirstConnectMatlab = true;
  1333. //    static bool result = false;
  1334.     // check Matlab license.dat
  1335.    // if( !SP_COEF_CAL_Object.CheckLicenseDat() )
  1336.    // {
  1337.     //    sbAudioCal->Panels->Items[0]->Text = (AnsiString) "  Please put Matlab license.dat under the same folder as Meta2.exe";
  1338.     //    Application->MessageBox( "Please put Matlab license.dat under the same folder as Meta2.exe" , "ERROR", MB_OK );
  1339.    //     return;
  1340.    // }
  1341.     // connect with Matlab check
  1342.   //  if( isFirstConnectMatlab )
  1343.   //  {
  1344.   //      isFirstConnectMatlab = false;
  1345.   //      sbAudioCal->Panels->Items[0]->Text = (AnsiString) "  Connect with Matlab progressing";
  1346.   //      result = SP_COEF_CAL_Object.CheckEngineExist();
  1347.   //
  1348.   //  }
  1349.   //  if( result == false )
  1350.   //  {
  1351.   //      sbAudioCal->Panels->Items[0]->Text = (AnsiString) "  Connect with Matlab fail";
  1352.  //       Application->MessageBox( "  Connect with Matlab fail" , "ERROR", MB_OK );
  1353.   //      return;
  1354.   //  }
  1355.   //  if( isMfileDllLoaded == false )
  1356.   //  {
  1357.   //
  1358.   //     // if( DllMan->LoadMfilesDllFunctions( this->Handle ) == false )
  1359.   //      {
  1360.   //
  1361.   //          return;
  1362.   //      }
  1363.   //      isMfileDllLoaded = true;
  1364.    // }
  1365.     m_iWantedTaps = edtFIRTaps->Text.ToInt();
  1366.     wanted_ord=m_iWantedTaps-1;
  1367.     // original frequency response
  1368.     temp_OrgSpCoef.num = OrgSpCoef.num;
  1369.     for (unsigned int i=0; i<temp_OrgSpCoef.num; i++)
  1370.     {
  1371.         temp_OrgSpCoef.Hz[i] = OrgSpCoef.Hz[i];
  1372.         temp_OrgSpCoef.Mag[i] = OrgSpCoef.Mag[i];
  1373.         temp_OrgSpCoef.MagdB[i] = 20*log10(temp_OrgSpCoef.Mag[i]+LogFloor);
  1374.     }
  1375.     temp_WantedSpCoef.num = WantedSpCoef.num;
  1376.     for (unsigned int i=0; i<temp_WantedSpCoef.num; i++)
  1377.     {
  1378.         temp_WantedSpCoef.Hz[i] = WantedSpCoef.Hz[i];
  1379.         temp_WantedSpCoef.Mag[i] = WantedSpCoef.Mag[i];
  1380.         temp_WantedSpCoef.MagdB[i] = 20*log10(temp_WantedSpCoef.Mag[i]+LogFloor);
  1381.     }
  1382.     // processing
  1383.     ProcessSpCoef.num = temp_OrgSpCoef.num;
  1384.     for (unsigned int i=0; i<temp_OrgSpCoef.num; i++)
  1385.     {
  1386.         ProcessSpCoef.Hz[i] = temp_OrgSpCoef.Hz[i];
  1387.     }
  1388.     if( temp_OrgSpCoef.num%2 != 0)
  1389.     {
  1390.         // odd length
  1391.         for (int i= (int) ProcessSpCoef.num-1; i>=0; i--)
  1392.         {
  1393.             ProcessSpCoef.Hz[i+1] = ProcessSpCoef.Hz[i];
  1394.             temp_OrgSpCoef.MagdB[i+1] = temp_OrgSpCoef.MagdB[i];
  1395.             temp_WantedSpCoef.MagdB[i+1] = temp_WantedSpCoef.MagdB[i];
  1396.         }
  1397.         ProcessSpCoef.Hz[0] = 1;
  1398.         ProcessSpCoef.num++;
  1399.         temp_OrgSpCoef.num++;
  1400.         temp_WantedSpCoef.num++;
  1401.         //odd_flag = true;
  1402.     }
  1403.    // else
  1404.    // {
  1405.    //     odd_flag = false;
  1406.    // }
  1407.     //if( rbTx->Checked )
  1408.     {
  1409.        // old_FIR.taps = Tx_old_FIR.taps;
  1410.        old_FIR_norm.taps = old_FIR.taps;
  1411.         for (unsigned int i=0; i<old_FIR.taps; i++)
  1412.         {
  1413.             old_FIR_norm.FirCoef[i] = old_FIR.FirCoef[i]/(1.0*FIR_COEFF_SCALE);
  1414.         }
  1415.         //ActiveMan->SetActiveFunction( ::Req_freqz );
  1416.         ret = SP_COEF_CAL_Object.freqz( m_b45TapSupport, &old_FIR_norm, &ProcessSpCoef, 8000.0, &OldFirSpCoef );
  1417.         if( ret )
  1418.         {
  1419.             char str[256];
  1420.             strcpy( str, SP_COEF_CAL_Object.Get_ErrorString( ret ) );
  1421.             Application->MessageBox( str, "Fail", MB_OK );
  1422.             return;
  1423.         }
  1424.        //p_MfileEvent->ResetEvent();
  1425.        //wait_result = p_MfileEvent->WaitFor( 5000 );
  1426.         //p_event = new TEvent();
  1427.       //  ResetEvent( MfileEvent );
  1428.         //wait_result = WaitForMultipleObjects(
  1429.         //                                      1, // number of handles in array
  1430.         //                                      &MfileEvent,      // array of event handles
  1431.         //                                      TRUE,         // wait till all are signaled
  1432.         //                                      5000);
  1433.         //wait_result = WaitForSingleObject( MfileEvent, 5000 );
  1434.         //if( wait_result == 1 ) // timeout
  1435.         //{
  1436.         //    sbAudioCal->Panels->Items[0]->Text = (AnsiString) "  Connect with Matlab timeout";
  1437.         //    Application->MessageBox( "  Connect with Matlab timeout" , "ERROR", MB_OK );
  1438.         //    return;
  1439.         //}
  1440.     }
  1441.     WithoutFirSpCoef.num = temp_OrgSpCoef.num;
  1442.     for (unsigned int i=0; i<WithoutFirSpCoef.num; i++)
  1443.     {
  1444.         WithoutFirSpCoef.MagdB[i] = temp_OrgSpCoef.MagdB[i] - OldFirSpCoef.MagdB[i];
  1445.     }
  1446.     impulse_hw_FIR.num = WithoutFirSpCoef.num;
  1447.     for (unsigned int i=0; i<impulse_hw_FIR.num; i++)
  1448.     {
  1449.         impulse_hw_FIR.Mag[i] = WithoutFirSpCoef.Mag[i];
  1450.         impulse_hw_FIR.MagdB[i] = WithoutFirSpCoef.MagdB[i];
  1451.     }
  1452.     NewFirSpCoef.num = WithoutFirSpCoef.num;
  1453.     for (unsigned int i=0; i<NewFirSpCoef.num; i++)
  1454.     {
  1455.         NewFirSpCoef.MagdB[i] = temp_WantedSpCoef.MagdB[i] - WithoutFirSpCoef.MagdB[i];
  1456.         NewFirSpCoef.Mag[i]=pow(10, NewFirSpCoef.MagdB[i]/20.0);
  1457.     }
  1458.     if( wanted_ord>0 )
  1459.     {
  1460.         ProcessOddSpCoef.num = ProcessSpCoef.num + 2;
  1461.         ProcessOddSpCoef.Hz[0] = 0;
  1462.         for (unsigned int i=0; i<ProcessSpCoef.num; i++)
  1463.         {
  1464.             ProcessOddSpCoef.Hz[i+1]=ProcessSpCoef.Hz[i];
  1465.         }
  1466.         ProcessOddSpCoef.Hz[ProcessOddSpCoef.num-1] = 4000;
  1467.         NewFirOddSpCoef.num = NewFirSpCoef.num + 2;
  1468.         NewFirOddSpCoef.Mag[0] = NewFirSpCoef.Mag[0];
  1469.         for (unsigned int i=0; i<NewFirOddSpCoef.num; i++)
  1470.         {
  1471.             NewFirOddSpCoef.Mag[i+1] = NewFirSpCoef.Mag[i];
  1472.         }
  1473.         NewFirOddSpCoef.Mag[NewFirOddSpCoef.num-1] = 0;
  1474.         // weight
  1475.         Weight.num = NewFirOddSpCoef.num / 2;
  1476.         for (unsigned int i=0; i<Weight.num; i++)
  1477.         {
  1478.             Weight.weight[i] = 1;
  1479.         }
  1480.         
  1481.         ret = SP_COEF_CAL_Object.firls( wanted_ord, &ProcessOddSpCoef, &NewFirOddSpCoef, 8000.0, &NewFirCoeffF1);
  1482.         if( ret )
  1483.         {
  1484.             char str[256];
  1485.             strcpy( str, SP_COEF_CAL_Object.Get_ErrorString( ret ) );
  1486.             Application->MessageBox( str, "Fail", MB_OK );
  1487.             return;
  1488.         }
  1489.       //  SP_COEF_CAL_Object.firls4input( wanted_ord, &ProcessOddSpCoef, &NewFirOddSpCoef, &Weight, 8000.0, &NewFirCoeffF1);
  1490.         
  1491.     }
  1492.     else
  1493.     {
  1494.         NewFirCoeffF1.taps = 3;
  1495.         NewFirCoeffF1.FirCoef[0] = 1;
  1496.         NewFirCoeffF1.FirCoef[1] = 0;
  1497.         NewFirCoeffF1.FirCoef[2] = 0;
  1498.         m_iWantedTaps=3;
  1499.         wanted_ord=m_iWantedTaps-1;
  1500.         Application->MessageBox( "The wanted order is less than or equal to 0. Force the wanted order to 3." , "Warnning", MB_OK );
  1501.     }
  1502.     NewFirCoeffF.taps = NewFirCoeffF1.taps;
  1503.     for (unsigned int i=0; i<NewFirCoeffF.taps; i++)
  1504.     {
  1505.         NewFirCoeffF.FirCoef[i] = NewFirCoeffF1.FirCoef[i];
  1506.     }
  1507.     if (m_b45TapSupport)
  1508.     {   ZeroFirCoeff.taps = SPEECH_FIR_44_TAPS_NUM;
  1509.     }
  1510.     else
  1511.     {
  1512.         ZeroFirCoeff.taps = SPEECH_FIR_30_TAPS_NUM;
  1513.     }
  1514.     for (unsigned int i=0; i<ZeroFirCoeff.taps; i++)
  1515.     {
  1516.         ZeroFirCoeff.FirCoef[i] = 0.0;
  1517.     }
  1518.     AbsOfComplexArray( NewFirCoeffF.FirCoef, ZeroFirCoeff.FirCoef, NewFirCoeffF.taps, NewFirCoeffF_abs.FirCoef );
  1519.     NewFirCoeffF_abs.taps = NewFirCoeffF.taps;
  1520.     MaxOfDoubleArray( NewFirCoeffF_abs.FirCoef, NewFirCoeffF_abs.taps, &d_max );
  1521.     if( d_max == 0.0 ) d_max = 1.0;
  1522.     d_gain = 1.0 / d_max;
  1523.     NewFirCoeffF_norm.taps = wanted_ord+1;
  1524.     for (unsigned int i=0; i<NewFirCoeffF_norm.taps; i++)
  1525.     {
  1526.          NewFirCoeffF_norm.FirCoef[i] =  NewFirCoeffF.FirCoef[i]*d_gain;
  1527.     }
  1528.     // check frequency
  1529.     ret = SP_COEF_CAL_Object.freqz( m_b45TapSupport, &NewFirCoeffF, &ProcessSpCoef, 8000.0, &ck_NewFirSpCoef );
  1530.     if( ret )
  1531.     {
  1532.             char str[256];
  1533.             strcpy( str, SP_COEF_CAL_Object.Get_ErrorString( ret ) );
  1534.             Application->MessageBox( str, "Fail", MB_OK );
  1535.             return;
  1536.     }
  1537.     
  1538.     ck_NewSpCoef.num = ck_NewFirSpCoef.num;
  1539.     for (unsigned int i=0; i<ck_NewSpCoef.num; i++)
  1540.     {
  1541.         ck_NewSpCoef.MagdB[i] = ck_NewFirSpCoef.MagdB[i] +  impulse_hw_FIR.MagdB[i];
  1542.         ck_NewSpCoef.Hz[i] = ProcessSpCoef.Hz[i];
  1543.     }
  1544.     // Write output data
  1545.     // write data to output
  1546.     // Output coeffs. in floating-point format ==>new_fir_coeff_F_normalized
  1547.     // with length ==> new_fir_coeff_F_normalized_taps
  1548.     // Re-ordering old FIR coeffs. from [B(0), ..., B(N-1), B(N)] to  [B(N), B(N-1), ..., B(0)]
  1549.     NewFirCoeffF_norm_fx.taps = NewFirCoeffF_norm.taps;
  1550.     for (unsigned int i=0; i<NewFirCoeffF_norm_fx.taps; i++)
  1551.     {
  1552.         NewFirCoeffF_norm_fx.FirCoef[i] = Round_double( FIR_COEFF_SCALE * NewFirCoeffF_norm.FirCoef[i]*FirScale );
  1553.     }
  1554.     SP_COEF_CAL_Object.ReorderFirCoef( &NewFirCoeffF_norm_fx );
  1555.     //  mTimer->Enabled = true;
  1556.    // SP_COEF_CAL_Object.freqz2out( sFirCoefParameters  *p_new_fir_coeff_F_normalized_fixed_point, double N, double freqz_N, double Fs, sFirRespParameters *p_FirResp_freqz_H, sFirRespParameters *p_FirResp_freqz_F );
  1557.    // mTimer->Enabled = false;
  1558.     // write FIR coefficient to file
  1559.     if( rbTx->Checked )
  1560.     {
  1561.         as_Filename = stOutputTxFileName->Caption;
  1562.     }
  1563.     else
  1564.     {
  1565.         as_Filename = stOutputRxFileName->Caption;
  1566.     }
  1567.    // as_Filename = getFullPathFileName( as_Filename );
  1568.     SP_COEF_CAL_Object.REQ_Write_FIR_File( as_Filename.c_str(), &NewFirCoeffF_norm_fx );
  1569.     // plot curve
  1570.     GetMinMaxY( &OrgSpCoef, &min_y, &max_y );
  1571.     if( min_y == max_y || isTRCLoadOk == false || OrgSpCoef.num>TOTAL_TRC_FREQ_NUM)
  1572.     {
  1573.         PlotGrid(100, 4000, -20, 15);
  1574.     }
  1575.     else
  1576.     {
  1577.         PlotGrid( 100, 4000, min_y, max_y);
  1578.     }
  1579.     PlotBoundaryCurve();
  1580.     PlotOrgCurve();
  1581.     PlotWantedCurve();
  1582.     PlotWantedCircle();
  1583.     PlotCompensatedCurve();
  1584.     // plot frequency response
  1585.     // mTimer->Enabled = true;
  1586.    // SP_COEF_CAL_Object.freqz2out( &NewFirCoeffF_norm_fx, 1.0, 1024.0, 8000.0, &FirResp_freqz_H, &FirResp_freqz_F );
  1587.     // mTimer->Enabled = false;
  1588.     //frmFirResponse->Top  = 104;//frmRFTool->Top  + (frmRFTool->Height-frmApcProfile->Height)/2;
  1589.     //frmFirResponse->Left = 42;//frmRFTool->Left + (frmRFTool->Width -frmApcProfile->Width)/2;
  1590.     //frmFirResponse->Show();
  1591.     sbAudioCal->Panels->Items[0]->Text = (AnsiString) "  Run successfully";
  1592.     //frmFirResponse->imFirResponseExp->Canvas->Ellipse(50,50, 70, 70);
  1593. }
  1594. //---------------------------------------------------------------------------
  1595. void  TfrmFIRCoeffCal::Update_dB(sSelectedParameters *p_SelPar, int index, double dB, sSpCoefCalParameters *p_UPL_database)
  1596. {
  1597.     int dB_now_idx=0;
  1598.     int dB_num, max_dB_num=TOTAL_SEL_FREQ_NUM-1, min_dB_num=0;
  1599.    // int Anum, Bnum;
  1600.     sInterpolateParameters S;
  1601.    // double  Pyy[4], Pyf[4];//Org_Hz[4];
  1602.     double px, qx, py, qy;
  1603.     double min_y, max_y;
  1604.     sModifiedParameters  Mod;
  1605.     // read database and write to dB editor using dB_idx
  1606.     //update UPL database
  1607. //    dB_num_len = 0;
  1608.     for (unsigned int i=0; i<p_UPL_database->num; i++)
  1609.     {
  1610.         if( p_UPL_database->Hz[i] == p_SelPar->Hz[index] )
  1611.         //if( UPL_database.Hz[i] == p_SpCoefCal->Hz[index] )
  1612.         {
  1613.             dB_now_idx = i;
  1614.             break;
  1615.         }
  1616.     }
  1617.     dB_num = index;
  1618.     p_UPL_database->Mag[dB_now_idx] = pow(10.0, dB/20.0);
  1619.     for (unsigned int i=0; i<p_UPL_database->num; i++)
  1620.     {
  1621.         p_UPL_database->MagdB[i] = 20.0*log10(p_UPL_database->Mag[i]+LogFloor);
  1622.     }
  1623.     // read all dB
  1624.     // interpolation
  1625.     if(dB_num==min_dB_num)
  1626.     {
  1627.         S.Anum=p_SelPar->index[min_dB_num];
  1628.         S.Bnum=p_SelPar->index[min_dB_num+1];
  1629.         S.num = 2;
  1630.         S.Hz[0] = p_UPL_database->Hz[S.Anum];
  1631.         S.Hz[1] = p_UPL_database->Hz[S.Bnum];
  1632.         S.MagdB[0] = p_UPL_database->MagdB[S.Anum];
  1633.         S.MagdB[1] = p_UPL_database->MagdB[S.Bnum];
  1634.         S.distance=S.Bnum-S.Anum+1;
  1635.         S.Start_data_idx=S.Anum;
  1636.         S.End_data_idx=S.Bnum;
  1637.     }
  1638.     else if(dB_num==max_dB_num)
  1639.     {
  1640.         S.Anum=p_SelPar->index[max_dB_num-1];
  1641.         S.Bnum=p_SelPar->index[max_dB_num];
  1642.         S.num = 2;
  1643.         S.Hz[0] = p_UPL_database->Hz[S.Anum];
  1644.         S.Hz[1] = p_UPL_database->Hz[S.Bnum];
  1645.         S.MagdB[0] = p_UPL_database->MagdB[S.Anum];
  1646.         S.MagdB[1] = p_UPL_database->MagdB[S.Bnum];
  1647.         S.distance=S.Bnum-S.Anum+1;
  1648.         S.Start_data_idx=S.Anum;
  1649.         S.End_data_idx=S.Bnum;
  1650.     }
  1651.     else
  1652.     {
  1653.         S.Anum = p_SelPar->index[dB_num-1];
  1654.         S.Bnum = p_SelPar->index[dB_num];
  1655.         S.Cnum = p_SelPar->index[dB_num+1];
  1656.         S.num = 3;
  1657.         S.Hz[0] = p_UPL_database->Hz[S.Anum];
  1658.         S.Hz[1] = p_UPL_database->Hz[S.Bnum];
  1659.         S.Hz[2] = p_UPL_database->Hz[S.Cnum];
  1660.         S.MagdB[0] = p_UPL_database->MagdB[S.Anum];
  1661.         S.MagdB[1] = p_UPL_database->MagdB[S.Bnum];
  1662.         S.MagdB[2] = p_UPL_database->MagdB[S.Cnum];
  1663.         S.distance=S.Cnum-S.Anum+1;
  1664.         S.Start_data_idx=S.Anum;
  1665.         S.End_data_idx=S.Cnum;
  1666.     }
  1667.     Mod.num=S.End_data_idx-S.Start_data_idx+1;
  1668.     for (int i=0; i<Mod.num; i++)
  1669.     {
  1670.         Mod.Pyy[i] = 0.0;
  1671.         Mod.Pyf[i] = 0.0;
  1672.     }
  1673.     for (int i=S.Start_data_idx; i<=S.End_data_idx; i++)
  1674.     {
  1675.         Mod.Hz[i-S.Start_data_idx] = p_UPL_database->Hz[i];
  1676.     }
  1677.     Mod.Pyf[0] = Mod.Hz[0];
  1678.     Mod.Pyy[0] = S.MagdB[0]+(Mod.Hz[0]-S.Hz[0])*(S.MagdB[1]-S.MagdB[0])/(S.Hz[1]-S.Hz[0]);
  1679.     for (int i=1; i<S.distance; i++)
  1680.     {
  1681.         double a=Mod.Hz[i];
  1682.         Mod.Pyf[i]=a;
  1683.         for(int j=1; j<S.num; j++)
  1684.         {
  1685.             if(a>S.Hz[j-1] && a<=S.Hz[j])
  1686.             {
  1687.                 px=S.Hz[j-1];
  1688.                 qx=S.Hz[j];
  1689.                 py=S.MagdB[j-1];
  1690.                 qy=S.MagdB[j];
  1691.              }
  1692.         }
  1693.         Mod.Pyy[i]=py+(qy-py)/(qx-px)*(a-px);
  1694.     }
  1695.     // Update UPL_database
  1696.     for (int i=S.Start_data_idx; i<=S.End_data_idx; i++)
  1697.     {
  1698.         p_UPL_database->MagdB[i]= Mod.Pyy[i-S.Start_data_idx];
  1699.     }
  1700.     for (unsigned int i=0; i<p_UPL_database->num; i++)
  1701.     {
  1702.         p_UPL_database->Mag[i]=pow(10.0, p_UPL_database->MagdB[i]/20.0);
  1703.     }
  1704.     // update orginal data
  1705.     OrgSpCoef.num = p_UPL_database->num;
  1706.     for (unsigned int i=0; i<OrgSpCoef.num; i++)
  1707.     {
  1708.         OrgSpCoef.MagdB[i] = 20.0*log10(OrgSpCoef.Mag[i]+LogFloor);
  1709.     }
  1710.     // update wanted data
  1711.     WantedSpCoef.num = p_UPL_database->num;
  1712.     for (unsigned int i=0; i<WantedSpCoef.num; i++)
  1713.     {
  1714.         WantedSpCoef.Mag[i] = p_UPL_database->Mag[i];
  1715.         WantedSpCoef.MagdB[i] = 20*log10(WantedSpCoef.Mag[i]+LogFloor);
  1716.     }
  1717.     // plot curve
  1718.     GetMinMaxY( &OrgSpCoef, &min_y, &max_y );
  1719.     if( min_y == max_y || isTRCLoadOk == false || OrgSpCoef.num>TOTAL_TRC_FREQ_NUM)
  1720.     {
  1721.         PlotGrid(100, 4000, -20, 15);
  1722.     }
  1723.     else
  1724.     {
  1725.         PlotGrid( 100, 4000, min_y, max_y);
  1726.     }
  1727.     PlotBoundaryCurve();
  1728.     PlotOrgCurve();
  1729.     PlotWantedCurve();
  1730.     PlotWantedCircle();
  1731. }
  1732. //==============================================================================
  1733. bool TfrmFIRCoeffCal::edtdBCheck(TObject *Sender)
  1734. {
  1735.     double  data;
  1736.     AnsiString  text;
  1737.     TEdit *edit = (TEdit*)Sender;
  1738.     char  hint[] = " character is not valid ";
  1739.     text = edit->Text;
  1740.     if( !IsValidMagdB( text, data ) )
  1741.     {
  1742.        ShowHintLabel( edit, hint );
  1743.        edit->SetFocus();
  1744.        return false;
  1745.     }
  1746.     return true;
  1747. }
  1748. //-------------------------------------------------------------------------
  1749. void __fastcall TfrmFIRCoeffCal::edt1xxHzdBExit(TObject *Sender)
  1750. {
  1751.     double dB;
  1752.     if( ! edtdBCheck(Sender) )
  1753.     {
  1754.         return;
  1755.     }    
  1756.     
  1757.     dB = atof(edt1xxHzdB->Text.c_str());
  1758.     if( dB !=  UISelectedSpCoef.MagdB[0] )
  1759.     {
  1760.         UISelectedSpCoef.MagdB[0] = dB;
  1761.         Update_dB(&SelectedSpCoef, 0, dB, &WantedSpCoef);
  1762.         Update_edtExtraDB( 0, dB );
  1763.     }
  1764. }
  1765. //---------------------------------------------------------------------------
  1766. void __fastcall TfrmFIRCoeffCal::edt2xxHzdBExit(TObject *Sender)
  1767. {
  1768.     double dB;
  1769.     if( ! edtdBCheck(Sender) )
  1770.     {
  1771.         return;
  1772.     }
  1773.     dB = atof(edt2xxHzdB->Text.c_str());
  1774.     
  1775.     if( dB !=  UISelectedSpCoef.MagdB[1] )
  1776.     {
  1777.         UISelectedSpCoef.MagdB[1] = dB;
  1778.         Update_dB(&SelectedSpCoef, 1, dB, &WantedSpCoef);
  1779.         Update_edtExtraDB( 1, dB );
  1780.     }
  1781. }
  1782. //---------------------------------------------------------------------------
  1783. void __fastcall TfrmFIRCoeffCal::edt3xxHzdBExit(TObject *Sender)
  1784. {
  1785.     double dB;
  1786.     if( ! edtdBCheck(Sender) )
  1787.     {
  1788.         return;
  1789.     }
  1790.     dB = atof(edt3xxHzdB->Text.c_str());
  1791.     if( dB !=  UISelectedSpCoef.MagdB[2] )
  1792.     {
  1793.         UISelectedSpCoef.MagdB[2] = dB;
  1794.         Update_dB(&SelectedSpCoef, 2, dB, &WantedSpCoef);
  1795.         Update_edtExtraDB( 2, dB );
  1796.     }
  1797. }
  1798. //---------------------------------------------------------------------------
  1799. void __fastcall TfrmFIRCoeffCal::edt5xxHzdBExit(TObject *Sender)
  1800. {
  1801.     double dB;
  1802.     if( ! edtdBCheck(Sender) )
  1803.     {
  1804.         return;
  1805.     }
  1806.     dB = atof(edt5xxHzdB->Text.c_str());
  1807.     
  1808.     if( dB !=  UISelectedSpCoef.MagdB[3] )
  1809.     {
  1810.         UISelectedSpCoef.MagdB[3] = dB;
  1811.         Update_dB(&SelectedSpCoef, 3, dB, &WantedSpCoef);
  1812.         Update_edtExtraDB( 3, dB );
  1813.     }
  1814. }
  1815. //---------------------------------------------------------------------------
  1816. void __fastcall TfrmFIRCoeffCal::edt6xxHzdBExit(TObject *Sender)
  1817. {
  1818.     double dB;
  1819.     if( ! edtdBCheck(Sender) )
  1820.     {
  1821.         return;
  1822.     }
  1823.     dB = atof(edt6xxHzdB->Text.c_str());
  1824.     
  1825.     if( dB !=  UISelectedSpCoef.MagdB[4] )
  1826.     {
  1827.         UISelectedSpCoef.MagdB[4] = dB;
  1828.         Update_dB(&SelectedSpCoef, 4, dB, &WantedSpCoef);
  1829.         Update_edtExtraDB( 4, dB );
  1830.     }
  1831. }
  1832. //---------------------------------------------------------------------------
  1833. void __fastcall TfrmFIRCoeffCal::edt7xxHzdBExit(TObject *Sender)
  1834. {
  1835.     double dB;
  1836.     if( ! edtdBCheck(Sender) )
  1837.     {
  1838.         return;
  1839.     }
  1840.     dB = atof(edt7xxHzdB->Text.c_str());
  1841.     
  1842.     if( dB !=  UISelectedSpCoef.MagdB[5] )
  1843.     {
  1844.         UISelectedSpCoef.MagdB[5] = dB;
  1845.         Update_dB(&SelectedSpCoef, 5, dB, &WantedSpCoef);
  1846.         Update_edtExtraDB( 5, dB );
  1847.     }
  1848. }
  1849. //---------------------------------------------------------------------------
  1850. void __fastcall TfrmFIRCoeffCal::edt8xxHzdBExit(TObject *Sender)
  1851. {
  1852.     double dB;
  1853.     if( ! edtdBCheck(Sender) )
  1854.     {
  1855.         return;
  1856.     }
  1857.     dB = atof(edt8xxHzdB->Text.c_str());
  1858.     
  1859.     if( dB !=  UISelectedSpCoef.MagdB[6] )
  1860.     {
  1861.         UISelectedSpCoef.MagdB[6] = dB;
  1862.         Update_dB(&SelectedSpCoef, 6, dB, &WantedSpCoef);
  1863.         Update_edtExtraDB( 6, dB );
  1864.     }
  1865. }
  1866. //---------------------------------------------------------------------------
  1867. void __fastcall TfrmFIRCoeffCal::edt1xxxHzdBExit(TObject *Sender)
  1868. {
  1869.     double dB;
  1870.     if( ! edtdBCheck(Sender) )
  1871.     {
  1872.         return;
  1873.     }
  1874.     dB = atof(edt1xxxHzdB->Text.c_str());
  1875.     
  1876.     if( dB !=  UISelectedSpCoef.MagdB[7] )
  1877.     {
  1878.         UISelectedSpCoef.MagdB[7] = dB;
  1879.         Update_dB(&SelectedSpCoef, 7, dB, &WantedSpCoef);
  1880.         Update_edtExtraDB( 7, dB );
  1881.     }
  1882. }
  1883. //---------------------------------------------------------------------------
  1884. void __fastcall TfrmFIRCoeffCal::edt13xxHzdBExit(TObject *Sender)
  1885. {
  1886.     double dB;
  1887.     if( ! edtdBCheck(Sender) )
  1888.     {
  1889.         return;
  1890.     }
  1891.     dB = atof(edt13xxHzdB->Text.c_str());
  1892.     
  1893.     if( dB !=  UISelectedSpCoef.MagdB[8] )
  1894.     {
  1895.         UISelectedSpCoef.MagdB[8] = dB;
  1896.         Update_dB(&SelectedSpCoef, 8, dB, &WantedSpCoef);
  1897.         Update_edtExtraDB( 8, dB );
  1898.     }
  1899. }
  1900. //---------------------------------------------------------------------------
  1901. void __fastcall TfrmFIRCoeffCal::edt18xxHzdBExit(TObject *Sender)
  1902. {
  1903.     double dB;
  1904.     if( ! edtdBCheck(Sender) )
  1905.     {
  1906.         return;
  1907.     }
  1908.     dB = atof(edt18xxHzdB->Text.c_str());
  1909.     
  1910.     if( dB !=  UISelectedSpCoef.MagdB[9] )
  1911.     {
  1912.         UISelectedSpCoef.MagdB[9] = dB;
  1913.         Update_dB(&SelectedSpCoef, 9, dB, &WantedSpCoef);
  1914.         Update_edtExtraDB( 9, dB );
  1915.     }
  1916. }
  1917. //---------------------------------------------------------------------------
  1918. void __fastcall TfrmFIRCoeffCal::edt2xxxHzdBExit(TObject *Sender)
  1919. {
  1920.     double dB;
  1921.     if( ! edtdBCheck(Sender) )
  1922.     {
  1923.         return;
  1924.     }
  1925.     dB = atof(edt2xxxHzdB->Text.c_str());
  1926.     
  1927.     if( dB !=  UISelectedSpCoef.MagdB[10] )
  1928.     {
  1929.         UISelectedSpCoef.MagdB[10] = dB;
  1930.         Update_dB(&SelectedSpCoef, 10, dB, &WantedSpCoef);
  1931.         Update_edtExtraDB( 10, dB );
  1932.     }
  1933. }
  1934. //---------------------------------------------------------------------------
  1935. void __fastcall TfrmFIRCoeffCal::edt25xxHzdBExit(TObject *Sender)
  1936. {
  1937.     double dB;
  1938.     if( ! edtdBCheck(Sender) )
  1939.     {
  1940.         return;
  1941.     }
  1942.     dB = atof(edt25xxHzdB->Text.c_str());
  1943.     
  1944.     if( dB !=  UISelectedSpCoef.MagdB[11] )
  1945.     {
  1946.         UISelectedSpCoef.MagdB[11] = dB;
  1947.         Update_dB(&SelectedSpCoef, 11, dB, &WantedSpCoef);
  1948.         Update_edtExtraDB( 11, dB );
  1949.     }
  1950. }
  1951. //---------------------------------------------------------------------------
  1952. void __fastcall TfrmFIRCoeffCal::edt3xxxHzdBExit(TObject *Sender)
  1953. {
  1954.     double dB;
  1955.     if( ! edtdBCheck(Sender) )
  1956.     {
  1957.         return;
  1958.     }
  1959.     dB = atof(edt3xxxHzdB->Text.c_str());
  1960.     if( dB !=  UISelectedSpCoef.MagdB[12] )
  1961.     {
  1962.         UISelectedSpCoef.MagdB[12] = dB;
  1963.         Update_dB(&SelectedSpCoef, 12, dB, &WantedSpCoef);
  1964.         Update_edtExtraDB( 12, dB );
  1965.     }
  1966. }
  1967. //---------------------------------------------------------------------------
  1968. void __fastcall TfrmFIRCoeffCal::edt34xxHzdBExit(TObject *Sender)
  1969. {
  1970.     double dB;
  1971.     if( ! edtdBCheck(Sender) )
  1972.     {
  1973.         return;
  1974.     }
  1975.     dB = atof(edt34xxHzdB->Text.c_str());
  1976.     
  1977.     if( dB !=  UISelectedSpCoef.MagdB[13] )
  1978.     {
  1979.         UISelectedSpCoef.MagdB[13] = dB;
  1980.         Update_dB(&SelectedSpCoef, 13, dB, &WantedSpCoef);
  1981.         Update_edtExtraDB( 13, dB );
  1982.     }
  1983. }
  1984. //---------------------------------------------------------------------------
  1985. void __fastcall TfrmFIRCoeffCal::edt39xxHzdBExit(TObject *Sender)
  1986. {
  1987.     double dB;