public static unsafe int cha_agc_prepare(IntPtr[] cp, CHA_DSL dsl, CHA_WDRC gha)
        {
            double cltk;
            float *tk;
            float *cr;
            float *tkgn;
            float *bolt;
            float  alfa, beta;
            int    i, nc, cs;

            float[] alfa_beta;

            cha_prepare(cp);
            cs = CHA_IVAR[_cs];
            if (cs == 0)
            {
                return(1);
            }

            // allocate envelope buffer
            cha_allocate(cp, cs, sizeof(float), _xpk);

            // save WDRC parameters
            alfa_beta = new float[2];
            alfa_beta = time_const(dsl.attack, dsl.release, gha.fs);
            alfa      = alfa_beta[0];
            beta      = alfa_beta[1];

            CHA_DVAR[_alfa] = alfa;
            CHA_DVAR[_beta] = beta;
            CHA_DVAR[_fs]   = gha.fs;
            CHA_DVAR[_mxdb] = gha.maxdB;
            CHA_DVAR[_tkgn] = gha.tkgain;
            CHA_DVAR[_cr]   = gha.cr;
            CHA_DVAR[_tk]   = gha.tk;
            CHA_DVAR[_bolt] = gha.bolt;
            cha_allocate(cp, 2, sizeof(float), _ppk);

            // save DSL prescription
            nc = dsl.nchannel;
            cha_allocate(cp, nc, sizeof(float), _gctk);
            cha_allocate(cp, nc, sizeof(float), _gccr);
            cha_allocate(cp, nc, sizeof(float), _gctkgn);
            cha_allocate(cp, nc, sizeof(float), _gcbolt);
            cha_allocate(cp, nc, sizeof(float), _gcppk);

            tk   = (float *)cp[_gctk];
            cr   = (float *)cp[_gccr];
            tkgn = (float *)cp[_gctkgn];
            bolt = (float *)cp[_gcbolt];

            alfa_beta = new float[2];
            alfa_beta = time_const(dsl.attack, dsl.release, gha.fs);
            alfa      = alfa_beta[0];
            beta      = alfa_beta[1];

            CHA_DVAR[_gcalfa] = alfa;
            CHA_DVAR[_gcbeta] = beta;
            for (i = 0; i < nc; i++)
            {
                tk[i]   = (float)dsl.tk[i];
                cr[i]   = (float)dsl.cr[i];
                tkgn[i] = (float)dsl.tkgain[i];
                bolt[i] = (float)dsl.bolt[i];
            }
            // adjust BOLT
            cltk = gha.tk;
            for (i = 0; i < nc; i++)
            {
                if (bolt[i] > cltk)
                {
                    bolt[i] = (float)cltk;
                }
                if (tkgn[i] < 0)
                {
                    bolt[i] = (float)(bolt[i] + tkgn[i]);
                }
            }

            return(0);
        }
        public static unsafe void UploadBoard(CHA_DSL dsl, CHA_WDRC gha)
        {
            IntPtr[] cpi;
            cpi = new IntPtr[NPTR];

            int    nc = dsl.nchannel;
            double fs = 24000;
            //double atk = dsl.attack;
            //double rel = dsl.release;
            double atk, rel;

            float[] alfa_beta;
            int     nw = 128;
            int     wt = 0;
            int     cs = 128;

            atk = gha.attack;
            rel = gha.release;

            alfa_beta = new float[2];
            alfa_beta = time_const(atk, rel, fs);

            CHA_IVAR[_cs] = cs;
            CHA_IVAR[_nw] = nw;
            CHA_IVAR[_nc] = nc;

            CHA_DVAR[_alfa] = alfa_beta[0];
            CHA_DVAR[_beta] = alfa_beta[1];
            CHA_DVAR[_fs]   = gha.fs;
            CHA_DVAR[_mxdb] = gha.maxdB;
            CHA_DVAR[_tkgn] = gha.tkgain;
            CHA_DVAR[_cr]   = gha.cr;
            CHA_DVAR[_tk]   = gha.tk;
            CHA_DVAR[_bolt] = gha.bolt;


            double[] cf = dsl.cross_freq;

            try
            {
                fixed(void *cp = &cpi[0])
                {
                    // prepare FIRFB
                    cha_firfb_prepare(cp, cf, nc, fs, nw, wt, cs);

                    // prepare chunk buffers
                    cha_allocate(cp, nc * cs * 2, sizeof(float), 3);

                    // Initialize unmanged memory to hold the struct
                    IntPtr dsl_pnt = Marshal.AllocHGlobal(Marshal.SizeOf(dsl));

                    // Copy dsl struct to unmanaged memory.
                    Marshal.StructureToPtr(dsl, dsl_pnt, true);

                    // prepare AGC
                    cha_agc_prepare(cp, ref dsl_pnt, ref gha);

                    // generate C code from prepared data
                    cha_data_gen(cp, "cha_ff_data_c.h");

                    // Free the unmanaged memory
                    Marshal.FreeHGlobal(dsl_pnt);
                }
            }
            catch (Exception ex)
            {
                System.Windows.Forms.MessageBox.Show(ex.Message);
            }
            // generate C code from prepared data
            cha_data_gen(cpi, "cha_ff_data_cs.h");

            //toolStripStatusLabel1.Text = "Uploading to board... ";
        }
 public static extern int cha_agc_prepare(void *cp, ref IntPtr dsl, ref CHA_WDRC gha);