//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-
//
//   File: MeasureLibrary.cpp   Created 12-MAY-2007   Richard B. Johnson
//                                                    RichardBJohnson@comcast.net
//  
//   The data, text, and source-code within these files are presumed to
//   be accurate and free of encumbrances. Use at your own risk.
//

#include <stdio.h>
#include <math.h>
#include <string.h>
#include "MeasureLibrary.h"
#include "altmath.h"



#define HYST  0.05
#define TRUE  true
#define FALSE false

//#define AVG_METHOD

#define NoDEBUG
#ifdef  DEBUG
#define DEB(f) f
#else
#define DEB(f)
#endif

#define UNROLL

extern SIG sig;
MSL msl;

const double MSL::hcent = 100.0;
const double MSL::pcent = 0.001;
const double MSL::turn  = 360.0;

//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-
//
// METHOD NAME
//
//   AddWaveforms
//
// DESCRIPTION
//
//   This routine will mathematically add every sample of two waveforms.
//
//  Author:                      17-JAN-2003      Richard B. Johnson
//
// INPUTS
//
//   Pointer to start of data array1
//   Pointer to start of data array2
//   Length of array
//
// OUTPUTS
//
//   Results are stored in pdData1
//


#define ADD_WAVE(n) pdData1[n] += pdData2[n]

void MSL::AddWaveforms( double * pdData1, double * pdData2, long nLength )
{
#ifdef UNROLL
    while(nLength >= 0x100)
    {
        pdData1 += 0x100;
        pdData2 += 0x100;
        nLength -= 0x100;
ALIGN;
        ADD_WAVE(-0x100);
        ADD_WAVE(-0x0ff);
        ADD_WAVE(-0x0fe);
        ADD_WAVE(-0x0fd);
        ADD_WAVE(-0x0fc);
        ADD_WAVE(-0x0fb);
        ADD_WAVE(-0x0fa);
        ADD_WAVE(-0x0f9);
        ADD_WAVE(-0x0f8);
        ADD_WAVE(-0x0f7);
        ADD_WAVE(-0x0f6);
        ADD_WAVE(-0x0f5);
        ADD_WAVE(-0x0f4);
        ADD_WAVE(-0x0f3);
        ADD_WAVE(-0x0f2);
        ADD_WAVE(-0x0f1);
        ADD_WAVE(-0x0f0);
        ADD_WAVE(-0x0ef);
        ADD_WAVE(-0x0ee);
        ADD_WAVE(-0x0ed);
        ADD_WAVE(-0x0ec);
        ADD_WAVE(-0x0eb);
        ADD_WAVE(-0x0ea);
        ADD_WAVE(-0x0e9);
        ADD_WAVE(-0x0e8);
        ADD_WAVE(-0x0e7);
        ADD_WAVE(-0x0e6);
        ADD_WAVE(-0x0e5);
        ADD_WAVE(-0x0e4);
        ADD_WAVE(-0x0e3);
        ADD_WAVE(-0x0e2);
        ADD_WAVE(-0x0e1);
        ADD_WAVE(-0x0e0);
        ADD_WAVE(-0x0df);
        ADD_WAVE(-0x0de);
        ADD_WAVE(-0x0dd);
        ADD_WAVE(-0x0dc);
        ADD_WAVE(-0x0db);
        ADD_WAVE(-0x0da);
        ADD_WAVE(-0x0d9);
        ADD_WAVE(-0x0d8);
        ADD_WAVE(-0x0d7);
        ADD_WAVE(-0x0d6);
        ADD_WAVE(-0x0d5);
        ADD_WAVE(-0x0d4);
        ADD_WAVE(-0x0d3);
        ADD_WAVE(-0x0d2);
        ADD_WAVE(-0x0d1);
        ADD_WAVE(-0x0d0);
        ADD_WAVE(-0x0cf);
        ADD_WAVE(-0x0ce);
        ADD_WAVE(-0x0cd);
        ADD_WAVE(-0x0cc);
        ADD_WAVE(-0x0cb);
        ADD_WAVE(-0x0ca);
        ADD_WAVE(-0x0c9);
        ADD_WAVE(-0x0c8);
        ADD_WAVE(-0x0c7);
        ADD_WAVE(-0x0c6);
        ADD_WAVE(-0x0c5);
        ADD_WAVE(-0x0c4);
        ADD_WAVE(-0x0c3);
        ADD_WAVE(-0x0c2);
        ADD_WAVE(-0x0c1);
        ADD_WAVE(-0x0c0);
        ADD_WAVE(-0x0bf);
        ADD_WAVE(-0x0be);
        ADD_WAVE(-0x0bd);
        ADD_WAVE(-0x0bc);
        ADD_WAVE(-0x0bb);
        ADD_WAVE(-0x0ba);
        ADD_WAVE(-0x0b9);
        ADD_WAVE(-0x0b8);
        ADD_WAVE(-0x0b7);
        ADD_WAVE(-0x0b6);
        ADD_WAVE(-0x0b5);
        ADD_WAVE(-0x0b4);
        ADD_WAVE(-0x0b3);
        ADD_WAVE(-0x0b2);
        ADD_WAVE(-0x0b1);
        ADD_WAVE(-0x0b0);
        ADD_WAVE(-0x0af);
        ADD_WAVE(-0x0ae);
        ADD_WAVE(-0x0ad);
        ADD_WAVE(-0x0ac);
        ADD_WAVE(-0x0ab);
        ADD_WAVE(-0x0aa);
        ADD_WAVE(-0x0a9);
        ADD_WAVE(-0x0a8);
        ADD_WAVE(-0x0a7);
        ADD_WAVE(-0x0a6);
        ADD_WAVE(-0x0a5);
        ADD_WAVE(-0x0a4);
        ADD_WAVE(-0x0a3);
        ADD_WAVE(-0x0a2);
        ADD_WAVE(-0x0a1);
        ADD_WAVE(-0x0a0);
        ADD_WAVE(-0x09f);
        ADD_WAVE(-0x09e);
        ADD_WAVE(-0x09d);
        ADD_WAVE(-0x09c);
        ADD_WAVE(-0x09b);
        ADD_WAVE(-0x09a);
        ADD_WAVE(-0x099);
        ADD_WAVE(-0x098);
        ADD_WAVE(-0x097);
        ADD_WAVE(-0x096);
        ADD_WAVE(-0x095);
        ADD_WAVE(-0x094);
        ADD_WAVE(-0x093);
        ADD_WAVE(-0x092);
        ADD_WAVE(-0x091);
        ADD_WAVE(-0x090);
        ADD_WAVE(-0x08f);
        ADD_WAVE(-0x08e);
        ADD_WAVE(-0x08d);
        ADD_WAVE(-0x08c);
        ADD_WAVE(-0x08b);
        ADD_WAVE(-0x08a);
        ADD_WAVE(-0x089);
        ADD_WAVE(-0x088);
        ADD_WAVE(-0x087);
        ADD_WAVE(-0x086);
        ADD_WAVE(-0x085);
        ADD_WAVE(-0x084);
        ADD_WAVE(-0x083);
        ADD_WAVE(-0x082);
        ADD_WAVE(-0x081);
        ADD_WAVE(-0x080);
        ADD_WAVE(-0x07f);
        ADD_WAVE(-0x07e);
        ADD_WAVE(-0x07d);
        ADD_WAVE(-0x07c);
        ADD_WAVE(-0x07b);
        ADD_WAVE(-0x07a);
        ADD_WAVE(-0x079);
        ADD_WAVE(-0x078);
        ADD_WAVE(-0x077);
        ADD_WAVE(-0x076);
        ADD_WAVE(-0x075);
        ADD_WAVE(-0x074);
        ADD_WAVE(-0x073);
        ADD_WAVE(-0x072);
        ADD_WAVE(-0x071);
        ADD_WAVE(-0x070);
        ADD_WAVE(-0x06f);
        ADD_WAVE(-0x06e);
        ADD_WAVE(-0x06d);
        ADD_WAVE(-0x06c);
        ADD_WAVE(-0x06b);
        ADD_WAVE(-0x06a);
        ADD_WAVE(-0x069);
        ADD_WAVE(-0x068);
        ADD_WAVE(-0x067);
        ADD_WAVE(-0x066);
        ADD_WAVE(-0x065);
        ADD_WAVE(-0x064);
        ADD_WAVE(-0x063);
        ADD_WAVE(-0x062);
        ADD_WAVE(-0x061);
        ADD_WAVE(-0x060);
        ADD_WAVE(-0x05f);
        ADD_WAVE(-0x05e);
        ADD_WAVE(-0x05d);
        ADD_WAVE(-0x05c);
        ADD_WAVE(-0x05b);
        ADD_WAVE(-0x05a);
        ADD_WAVE(-0x059);
        ADD_WAVE(-0x058);
        ADD_WAVE(-0x057);
        ADD_WAVE(-0x056);
        ADD_WAVE(-0x055);
        ADD_WAVE(-0x054);
        ADD_WAVE(-0x053);
        ADD_WAVE(-0x052);
        ADD_WAVE(-0x051);
        ADD_WAVE(-0x050);
        ADD_WAVE(-0x04f);
        ADD_WAVE(-0x04e);
        ADD_WAVE(-0x04d);
        ADD_WAVE(-0x04c);
        ADD_WAVE(-0x04b);
        ADD_WAVE(-0x04a);
        ADD_WAVE(-0x049);
        ADD_WAVE(-0x048);
        ADD_WAVE(-0x047);
        ADD_WAVE(-0x046);
        ADD_WAVE(-0x045);
        ADD_WAVE(-0x044);
        ADD_WAVE(-0x043);
        ADD_WAVE(-0x042);
        ADD_WAVE(-0x041);
        ADD_WAVE(-0x040);
        ADD_WAVE(-0x03f);
        ADD_WAVE(-0x03e);
        ADD_WAVE(-0x03d);
        ADD_WAVE(-0x03c);
        ADD_WAVE(-0x03b);
        ADD_WAVE(-0x03a);
        ADD_WAVE(-0x039);
        ADD_WAVE(-0x038);
        ADD_WAVE(-0x037);
        ADD_WAVE(-0x036);
        ADD_WAVE(-0x035);
        ADD_WAVE(-0x034);
        ADD_WAVE(-0x033);
        ADD_WAVE(-0x032);
        ADD_WAVE(-0x031);
        ADD_WAVE(-0x030);
        ADD_WAVE(-0x02f);
        ADD_WAVE(-0x02e);
        ADD_WAVE(-0x02d);
        ADD_WAVE(-0x02c);
        ADD_WAVE(-0x02b);
        ADD_WAVE(-0x02a);
        ADD_WAVE(-0x029);
        ADD_WAVE(-0x028);
        ADD_WAVE(-0x027);
        ADD_WAVE(-0x026);
        ADD_WAVE(-0x025);
        ADD_WAVE(-0x024);
        ADD_WAVE(-0x023);
        ADD_WAVE(-0x022);
        ADD_WAVE(-0x021);
        ADD_WAVE(-0x020);
        ADD_WAVE(-0x01f);
        ADD_WAVE(-0x01e);
        ADD_WAVE(-0x01d);
        ADD_WAVE(-0x01c);
        ADD_WAVE(-0x01b);
        ADD_WAVE(-0x01a);
        ADD_WAVE(-0x019);
        ADD_WAVE(-0x018);
        ADD_WAVE(-0x017);
        ADD_WAVE(-0x016);
        ADD_WAVE(-0x015);
        ADD_WAVE(-0x014);
        ADD_WAVE(-0x013);
        ADD_WAVE(-0x012);
        ADD_WAVE(-0x011);
        ADD_WAVE(-0x010);
        ADD_WAVE(-0x00f);
        ADD_WAVE(-0x00e);
        ADD_WAVE(-0x00d);
        ADD_WAVE(-0x00c);
        ADD_WAVE(-0x00b);
        ADD_WAVE(-0x00a);
        ADD_WAVE(-0x009);
        ADD_WAVE(-0x008);
        ADD_WAVE(-0x007);
        ADD_WAVE(-0x006);
        ADD_WAVE(-0x005);
        ADD_WAVE(-0x004);
        ADD_WAVE(-0x003);
        ADD_WAVE(-0x002);
        ADD_WAVE(-0x001);
    }
    while(nLength >= 0x10)
    {
        pdData1 += 0x10;
        pdData2 += 0x10;
        nLength -= 0x10;
        ADD_WAVE(-0x10);
        ADD_WAVE(-0x0f);
        ADD_WAVE(-0x0e);
        ADD_WAVE(-0x0d);
        ADD_WAVE(-0x0c);
        ADD_WAVE(-0x0b);
        ADD_WAVE(-0x0a);
        ADD_WAVE(-0x09);
        ADD_WAVE(-0x08);
        ADD_WAVE(-0x07);
        ADD_WAVE(-0x06);
        ADD_WAVE(-0x05);
        ADD_WAVE(-0x04);
        ADD_WAVE(-0x03);
        ADD_WAVE(-0x02);
        ADD_WAVE(-0x01);
    }
#endif
    while(nLength--)
        *pdData1++ += *pdData2++;
    return;
}
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-
//
// METHOD NAME
//
//   SubtractWaveforms
//
//  Author:                      21-JAN-2003      Richard B. Johnson
//
// DESCRIPTION
//
//   This routine will mathematically subtract every sample of waveform
//   pdData2 from waveform pdData1.
//
// INPUTS
//
//   Pointer to start of data array1
//   Pointer to start of data array2
//   Length of array
//
// OUTPUTS
//
//   Results are stored in pdData1
//

#define SUB_WAVE(n) pdData1[n] -= pdData2[n]

void MSL::SubtractWaveforms( double * pdData1, double * pdData2, long nLength )
{
#ifdef UNROLL
    while(nLength >= 0x100)
    {
        pdData1 += 0x100;
        pdData2 += 0x100;
        nLength -= 0x100;
ALIGN;
        SUB_WAVE(-0x100);
        SUB_WAVE(-0x0ff);
        SUB_WAVE(-0x0fe);
        SUB_WAVE(-0x0fd);
        SUB_WAVE(-0x0fc);
        SUB_WAVE(-0x0fb);
        SUB_WAVE(-0x0fa);
        SUB_WAVE(-0x0f9);
        SUB_WAVE(-0x0f8);
        SUB_WAVE(-0x0f7);
        SUB_WAVE(-0x0f6);
        SUB_WAVE(-0x0f5);
        SUB_WAVE(-0x0f4);
        SUB_WAVE(-0x0f3);
        SUB_WAVE(-0x0f2);
        SUB_WAVE(-0x0f1);
        SUB_WAVE(-0x0f0);
        SUB_WAVE(-0x0ef);
        SUB_WAVE(-0x0ee);
        SUB_WAVE(-0x0ed);
        SUB_WAVE(-0x0ec);
        SUB_WAVE(-0x0eb);
        SUB_WAVE(-0x0ea);
        SUB_WAVE(-0x0e9);
        SUB_WAVE(-0x0e8);
        SUB_WAVE(-0x0e7);
        SUB_WAVE(-0x0e6);
        SUB_WAVE(-0x0e5);
        SUB_WAVE(-0x0e4);
        SUB_WAVE(-0x0e3);
        SUB_WAVE(-0x0e2);
        SUB_WAVE(-0x0e1);
        SUB_WAVE(-0x0e0);
        SUB_WAVE(-0x0df);
        SUB_WAVE(-0x0de);
        SUB_WAVE(-0x0dd);
        SUB_WAVE(-0x0dc);
        SUB_WAVE(-0x0db);
        SUB_WAVE(-0x0da);
        SUB_WAVE(-0x0d9);
        SUB_WAVE(-0x0d8);
        SUB_WAVE(-0x0d7);
        SUB_WAVE(-0x0d6);
        SUB_WAVE(-0x0d5);
        SUB_WAVE(-0x0d4);
        SUB_WAVE(-0x0d3);
        SUB_WAVE(-0x0d2);
        SUB_WAVE(-0x0d1);
        SUB_WAVE(-0x0d0);
        SUB_WAVE(-0x0cf);
        SUB_WAVE(-0x0ce);
        SUB_WAVE(-0x0cd);
        SUB_WAVE(-0x0cc);
        SUB_WAVE(-0x0cb);
        SUB_WAVE(-0x0ca);
        SUB_WAVE(-0x0c9);
        SUB_WAVE(-0x0c8);
        SUB_WAVE(-0x0c7);
        SUB_WAVE(-0x0c6);
        SUB_WAVE(-0x0c5);
        SUB_WAVE(-0x0c4);
        SUB_WAVE(-0x0c3);
        SUB_WAVE(-0x0c2);
        SUB_WAVE(-0x0c1);
        SUB_WAVE(-0x0c0);
        SUB_WAVE(-0x0bf);
        SUB_WAVE(-0x0be);
        SUB_WAVE(-0x0bd);
        SUB_WAVE(-0x0bc);
        SUB_WAVE(-0x0bb);
        SUB_WAVE(-0x0ba);
        SUB_WAVE(-0x0b9);
        SUB_WAVE(-0x0b8);
        SUB_WAVE(-0x0b7);
        SUB_WAVE(-0x0b6);
        SUB_WAVE(-0x0b5);
        SUB_WAVE(-0x0b4);
        SUB_WAVE(-0x0b3);
        SUB_WAVE(-0x0b2);
        SUB_WAVE(-0x0b1);
        SUB_WAVE(-0x0b0);
        SUB_WAVE(-0x0af);
        SUB_WAVE(-0x0ae);
        SUB_WAVE(-0x0ad);
        SUB_WAVE(-0x0ac);
        SUB_WAVE(-0x0ab);
        SUB_WAVE(-0x0aa);
        SUB_WAVE(-0x0a9);
        SUB_WAVE(-0x0a8);
        SUB_WAVE(-0x0a7);
        SUB_WAVE(-0x0a6);
        SUB_WAVE(-0x0a5);
        SUB_WAVE(-0x0a4);
        SUB_WAVE(-0x0a3);
        SUB_WAVE(-0x0a2);
        SUB_WAVE(-0x0a1);
        SUB_WAVE(-0x0a0);
        SUB_WAVE(-0x09f);
        SUB_WAVE(-0x09e);
        SUB_WAVE(-0x09d);
        SUB_WAVE(-0x09c);
        SUB_WAVE(-0x09b);
        SUB_WAVE(-0x09a);
        SUB_WAVE(-0x099);
        SUB_WAVE(-0x098);
        SUB_WAVE(-0x097);
        SUB_WAVE(-0x096);
        SUB_WAVE(-0x095);
        SUB_WAVE(-0x094);
        SUB_WAVE(-0x093);
        SUB_WAVE(-0x092);
        SUB_WAVE(-0x091);
        SUB_WAVE(-0x090);
        SUB_WAVE(-0x08f);
        SUB_WAVE(-0x08e);
        SUB_WAVE(-0x08d);
        SUB_WAVE(-0x08c);
        SUB_WAVE(-0x08b);
        SUB_WAVE(-0x08a);
        SUB_WAVE(-0x089);
        SUB_WAVE(-0x088);
        SUB_WAVE(-0x087);
        SUB_WAVE(-0x086);
        SUB_WAVE(-0x085);
        SUB_WAVE(-0x084);
        SUB_WAVE(-0x083);
        SUB_WAVE(-0x082);
        SUB_WAVE(-0x081);
        SUB_WAVE(-0x080);
        SUB_WAVE(-0x07f);
        SUB_WAVE(-0x07e);
        SUB_WAVE(-0x07d);
        SUB_WAVE(-0x07c);
        SUB_WAVE(-0x07b);
        SUB_WAVE(-0x07a);
        SUB_WAVE(-0x079);
        SUB_WAVE(-0x078);
        SUB_WAVE(-0x077);
        SUB_WAVE(-0x076);
        SUB_WAVE(-0x075);
        SUB_WAVE(-0x074);
        SUB_WAVE(-0x073);
        SUB_WAVE(-0x072);
        SUB_WAVE(-0x071);
        SUB_WAVE(-0x070);
        SUB_WAVE(-0x06f);
        SUB_WAVE(-0x06e);
        SUB_WAVE(-0x06d);
        SUB_WAVE(-0x06c);
        SUB_WAVE(-0x06b);
        SUB_WAVE(-0x06a);
        SUB_WAVE(-0x069);
        SUB_WAVE(-0x068);
        SUB_WAVE(-0x067);
        SUB_WAVE(-0x066);
        SUB_WAVE(-0x065);
        SUB_WAVE(-0x064);
        SUB_WAVE(-0x063);
        SUB_WAVE(-0x062);
        SUB_WAVE(-0x061);
        SUB_WAVE(-0x060);
        SUB_WAVE(-0x05f);
        SUB_WAVE(-0x05e);
        SUB_WAVE(-0x05d);
        SUB_WAVE(-0x05c);
        SUB_WAVE(-0x05b);
        SUB_WAVE(-0x05a);
        SUB_WAVE(-0x059);
        SUB_WAVE(-0x058);
        SUB_WAVE(-0x057);
        SUB_WAVE(-0x056);
        SUB_WAVE(-0x055);
        SUB_WAVE(-0x054);
        SUB_WAVE(-0x053);
        SUB_WAVE(-0x052);
        SUB_WAVE(-0x051);
        SUB_WAVE(-0x050);
        SUB_WAVE(-0x04f);
        SUB_WAVE(-0x04e);
        SUB_WAVE(-0x04d);
        SUB_WAVE(-0x04c);
        SUB_WAVE(-0x04b);
        SUB_WAVE(-0x04a);
        SUB_WAVE(-0x049);
        SUB_WAVE(-0x048);
        SUB_WAVE(-0x047);
        SUB_WAVE(-0x046);
        SUB_WAVE(-0x045);
        SUB_WAVE(-0x044);
        SUB_WAVE(-0x043);
        SUB_WAVE(-0x042);
        SUB_WAVE(-0x041);
        SUB_WAVE(-0x040);
        SUB_WAVE(-0x03f);
        SUB_WAVE(-0x03e);
        SUB_WAVE(-0x03d);
        SUB_WAVE(-0x03c);
        SUB_WAVE(-0x03b);
        SUB_WAVE(-0x03a);
        SUB_WAVE(-0x039);
        SUB_WAVE(-0x038);
        SUB_WAVE(-0x037);
        SUB_WAVE(-0x036);
        SUB_WAVE(-0x035);
        SUB_WAVE(-0x034);
        SUB_WAVE(-0x033);
        SUB_WAVE(-0x032);
        SUB_WAVE(-0x031);
        SUB_WAVE(-0x030);
        SUB_WAVE(-0x02f);
        SUB_WAVE(-0x02e);
        SUB_WAVE(-0x02d);
        SUB_WAVE(-0x02c);
        SUB_WAVE(-0x02b);
        SUB_WAVE(-0x02a);
        SUB_WAVE(-0x029);
        SUB_WAVE(-0x028);
        SUB_WAVE(-0x027);
        SUB_WAVE(-0x026);
        SUB_WAVE(-0x025);
        SUB_WAVE(-0x024);
        SUB_WAVE(-0x023);
        SUB_WAVE(-0x022);
        SUB_WAVE(-0x021);
        SUB_WAVE(-0x020);
        SUB_WAVE(-0x01f);
        SUB_WAVE(-0x01e);
        SUB_WAVE(-0x01d);
        SUB_WAVE(-0x01c);
        SUB_WAVE(-0x01b);
        SUB_WAVE(-0x01a);
        SUB_WAVE(-0x019);
        SUB_WAVE(-0x018);
        SUB_WAVE(-0x017);
        SUB_WAVE(-0x016);
        SUB_WAVE(-0x015);
        SUB_WAVE(-0x014);
        SUB_WAVE(-0x013);
        SUB_WAVE(-0x012);
        SUB_WAVE(-0x011);
        SUB_WAVE(-0x010);
        SUB_WAVE(-0x00f);
        SUB_WAVE(-0x00e);
        SUB_WAVE(-0x00d);
        SUB_WAVE(-0x00c);
        SUB_WAVE(-0x00b);
        SUB_WAVE(-0x00a);
        SUB_WAVE(-0x009);
        SUB_WAVE(-0x008);
        SUB_WAVE(-0x007);
        SUB_WAVE(-0x006);
        SUB_WAVE(-0x005);
        SUB_WAVE(-0x004);
        SUB_WAVE(-0x003);
        SUB_WAVE(-0x002);
        SUB_WAVE(-0x001);
    }
    while(nLength >= 0x10)
    {
        pdData1 += 0x10;
        pdData2 += 0x10;
        nLength -= 0x10;
        SUB_WAVE(-0x10);
        SUB_WAVE(-0x0f);
        SUB_WAVE(-0x0e);
        SUB_WAVE(-0x0d);
        SUB_WAVE(-0x0c);
        SUB_WAVE(-0x0b);
        SUB_WAVE(-0x0a);
        SUB_WAVE(-0x09);
        SUB_WAVE(-0x08);
        SUB_WAVE(-0x07);
        SUB_WAVE(-0x06);
        SUB_WAVE(-0x05);
        SUB_WAVE(-0x04);
        SUB_WAVE(-0x03);
        SUB_WAVE(-0x02);
        SUB_WAVE(-0x01);
    }
#endif
    while(nLength--)
        *pdData1++ -= *pdData2++;
    return;
}
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-
//
// METHOD NAME
//
//   MultiplyWaveforms
//
//  Author:                      21-JAN-2003      Richard B. Johnson
//
// DESCRIPTION
//
//   This routine will mathematically multiply every sample of two waveforms.
//
// INPUTS
//
//   Pointer to start of data array1
//   Pointer to start of data array2
//   Length of array
//
// OUTPUTS
//
//   Results are stored in pdData1
//
void MSL::MultiplyWaveforms( double * pdData1, double * pdData2, long nLength )
{
	sig.MultArray(pdData1, pdData2, nLength);
    return;
}
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-
//
// METHOD NAME
//
//   InvertWaveform
//
//  Author:                      21-JAN-2003      Richard B. Johnson
//
// DESCRIPTION
//
//   This routine will mathematically multiply every sample of waveform by -1.
//
// INPUTS
//
//   Pointer to start of data array
//   Length of array
//
// OUTPUTS
//
//   Results are stored in pdData
//

#define INVERT(n) pdData[n] *= minus

void MSL::InvertWaveform( double * pdData, long nLength )
{
    double minus = -1.0;

#ifdef UNROLL
    while(nLength >= 0x100)
    {
        pdData  += 0x100;
        nLength -= 0x100;
ALIGN;
        INVERT(-0x100);
        INVERT(-0x0ff);
        INVERT(-0x0fe);
        INVERT(-0x0fd);
        INVERT(-0x0fc);
        INVERT(-0x0fb);
        INVERT(-0x0fa);
        INVERT(-0x0f9);
        INVERT(-0x0f8);
        INVERT(-0x0f7);
        INVERT(-0x0f6);
        INVERT(-0x0f5);
        INVERT(-0x0f4);
        INVERT(-0x0f3);
        INVERT(-0x0f2);
        INVERT(-0x0f1);
        INVERT(-0x0f0);
        INVERT(-0x0ef);
        INVERT(-0x0ee);
        INVERT(-0x0ed);
        INVERT(-0x0ec);
        INVERT(-0x0eb);
        INVERT(-0x0ea);
        INVERT(-0x0e9);
        INVERT(-0x0e8);
        INVERT(-0x0e7);
        INVERT(-0x0e6);
        INVERT(-0x0e5);
        INVERT(-0x0e4);
        INVERT(-0x0e3);
        INVERT(-0x0e2);
        INVERT(-0x0e1);
        INVERT(-0x0e0);
        INVERT(-0x0df);
        INVERT(-0x0de);
        INVERT(-0x0dd);
        INVERT(-0x0dc);
        INVERT(-0x0db);
        INVERT(-0x0da);
        INVERT(-0x0d9);
        INVERT(-0x0d8);
        INVERT(-0x0d7);
        INVERT(-0x0d6);
        INVERT(-0x0d5);
        INVERT(-0x0d4);
        INVERT(-0x0d3);
        INVERT(-0x0d2);
        INVERT(-0x0d1);
        INVERT(-0x0d0);
        INVERT(-0x0cf);
        INVERT(-0x0ce);
        INVERT(-0x0cd);
        INVERT(-0x0cc);
        INVERT(-0x0cb);
        INVERT(-0x0ca);
        INVERT(-0x0c9);
        INVERT(-0x0c8);
        INVERT(-0x0c7);
        INVERT(-0x0c6);
        INVERT(-0x0c5);
        INVERT(-0x0c4);
        INVERT(-0x0c3);
        INVERT(-0x0c2);
        INVERT(-0x0c1);
        INVERT(-0x0c0);
        INVERT(-0x0bf);
        INVERT(-0x0be);
        INVERT(-0x0bd);
        INVERT(-0x0bc);
        INVERT(-0x0bb);
        INVERT(-0x0ba);
        INVERT(-0x0b9);
        INVERT(-0x0b8);
        INVERT(-0x0b7);
        INVERT(-0x0b6);
        INVERT(-0x0b5);
        INVERT(-0x0b4);
        INVERT(-0x0b3);
        INVERT(-0x0b2);
        INVERT(-0x0b1);
        INVERT(-0x0b0);
        INVERT(-0x0af);
        INVERT(-0x0ae);
        INVERT(-0x0ad);
        INVERT(-0x0ac);
        INVERT(-0x0ab);
        INVERT(-0x0aa);
        INVERT(-0x0a9);
        INVERT(-0x0a8);
        INVERT(-0x0a7);
        INVERT(-0x0a6);
        INVERT(-0x0a5);
        INVERT(-0x0a4);
        INVERT(-0x0a3);
        INVERT(-0x0a2);
        INVERT(-0x0a1);
        INVERT(-0x0a0);
        INVERT(-0x09f);
        INVERT(-0x09e);
        INVERT(-0x09d);
        INVERT(-0x09c);
        INVERT(-0x09b);
        INVERT(-0x09a);
        INVERT(-0x099);
        INVERT(-0x098);
        INVERT(-0x097);
        INVERT(-0x096);
        INVERT(-0x095);
        INVERT(-0x094);
        INVERT(-0x093);
        INVERT(-0x092);
        INVERT(-0x091);
        INVERT(-0x090);
        INVERT(-0x08f);
        INVERT(-0x08e);
        INVERT(-0x08d);
        INVERT(-0x08c);
        INVERT(-0x08b);
        INVERT(-0x08a);
        INVERT(-0x089);
        INVERT(-0x088);
        INVERT(-0x087);
        INVERT(-0x086);
        INVERT(-0x085);
        INVERT(-0x084);
        INVERT(-0x083);
        INVERT(-0x082);
        INVERT(-0x081);
        INVERT(-0x080);
        INVERT(-0x07f);
        INVERT(-0x07e);
        INVERT(-0x07d);
        INVERT(-0x07c);
        INVERT(-0x07b);
        INVERT(-0x07a);
        INVERT(-0x079);
        INVERT(-0x078);
        INVERT(-0x077);
        INVERT(-0x076);
        INVERT(-0x075);
        INVERT(-0x074);
        INVERT(-0x073);
        INVERT(-0x072);
        INVERT(-0x071);
        INVERT(-0x070);
        INVERT(-0x06f);
        INVERT(-0x06e);
        INVERT(-0x06d);
        INVERT(-0x06c);
        INVERT(-0x06b);
        INVERT(-0x06a);
        INVERT(-0x069);
        INVERT(-0x068);
        INVERT(-0x067);
        INVERT(-0x066);
        INVERT(-0x065);
        INVERT(-0x064);
        INVERT(-0x063);
        INVERT(-0x062);
        INVERT(-0x061);
        INVERT(-0x060);
        INVERT(-0x05f);
        INVERT(-0x05e);
        INVERT(-0x05d);
        INVERT(-0x05c);
        INVERT(-0x05b);
        INVERT(-0x05a);
        INVERT(-0x059);
        INVERT(-0x058);
        INVERT(-0x057);
        INVERT(-0x056);
        INVERT(-0x055);
        INVERT(-0x054);
        INVERT(-0x053);
        INVERT(-0x052);
        INVERT(-0x051);
        INVERT(-0x050);
        INVERT(-0x04f);
        INVERT(-0x04e);
        INVERT(-0x04d);
        INVERT(-0x04c);
        INVERT(-0x04b);
        INVERT(-0x04a);
        INVERT(-0x049);
        INVERT(-0x048);
        INVERT(-0x047);
        INVERT(-0x046);
        INVERT(-0x045);
        INVERT(-0x044);
        INVERT(-0x043);
        INVERT(-0x042);
        INVERT(-0x041);
        INVERT(-0x040);
        INVERT(-0x03f);
        INVERT(-0x03e);
        INVERT(-0x03d);
        INVERT(-0x03c);
        INVERT(-0x03b);
        INVERT(-0x03a);
        INVERT(-0x039);
        INVERT(-0x038);
        INVERT(-0x037);
        INVERT(-0x036);
        INVERT(-0x035);
        INVERT(-0x034);
        INVERT(-0x033);
        INVERT(-0x032);
        INVERT(-0x031);
        INVERT(-0x030);
        INVERT(-0x02f);
        INVERT(-0x02e);
        INVERT(-0x02d);
        INVERT(-0x02c);
        INVERT(-0x02b);
        INVERT(-0x02a);
        INVERT(-0x029);
        INVERT(-0x028);
        INVERT(-0x027);
        INVERT(-0x026);
        INVERT(-0x025);
        INVERT(-0x024);
        INVERT(-0x023);
        INVERT(-0x022);
        INVERT(-0x021);
        INVERT(-0x020);
        INVERT(-0x01f);
        INVERT(-0x01e);
        INVERT(-0x01d);
        INVERT(-0x01c);
        INVERT(-0x01b);
        INVERT(-0x01a);
        INVERT(-0x019);
        INVERT(-0x018);
        INVERT(-0x017);
        INVERT(-0x016);
        INVERT(-0x015);
        INVERT(-0x014);
        INVERT(-0x013);
        INVERT(-0x012);
        INVERT(-0x011);
        INVERT(-0x010);
        INVERT(-0x00f);
        INVERT(-0x00e);
        INVERT(-0x00d);
        INVERT(-0x00c);
        INVERT(-0x00b);
        INVERT(-0x00a);
        INVERT(-0x009);
        INVERT(-0x008);
        INVERT(-0x007);
        INVERT(-0x006);
        INVERT(-0x005);
        INVERT(-0x004);
        INVERT(-0x003);
        INVERT(-0x002);
        INVERT(-0x001);
    }
    while(nLength >= 0x10)
    {
        pdData  += 0x10;
        nLength -= 0x10;
        INVERT(-0x10);
        INVERT(-0x0f);
        INVERT(-0x0e);
        INVERT(-0x0d);
        INVERT(-0x0c);
        INVERT(-0x0b);
        INVERT(-0x0a);
        INVERT(-0x09);
        INVERT(-0x08);
        INVERT(-0x07);
        INVERT(-0x06);
        INVERT(-0x05);
        INVERT(-0x04);
        INVERT(-0x03);
        INVERT(-0x02);
        INVERT(-0x01);
    }
#endif
    while(nLength--)
        *pdData++ *= minus;
    return;
}
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-
//
// METHOD NAME
//
//   MeasureRiseTime
//
//  Author:                      21-JAN-2003      Richard B. Johnson
//
// DESCRIPTION
//
//   This routine will calculate the rise time of the first
//   rising edge in the specified waveform data array.
//
// INPUTS
//
//   Pointer to data array in volts
//   Length of data array
//   Sample rate in Hz
//   LO reference voltage (in percent (0->100)).
//   HI reference voltage (in percent (0->100)).
//
// OUTPUTS
//
//   Result value, in Seconds
//
double MSL::MeasureRiseTime( double * pdData, long nLength, double dRate, double dLoRefVolt, double dHiRefVolt)
{
    int start, stop, nr, i;
    double *fp, pos_peak, neg_peak, span;
    nr = (int) nLength;
//
//  Set reference, relative to the peak.
//
    pos_peak = MeasurePosPeak(pdData, nLength);  // Get the peak voltage
    neg_peak = MeasureNegPeak(pdData, nLength);
    span = pos_peak - neg_peak;
    span *= pcent;
    dHiRefVolt = neg_peak + (span * dHiRefVolt);
    dLoRefVolt = neg_peak + (span * dLoRefVolt);

    i = sig.TimeToNegRef(pdData, dLoRefVolt, nr);

    nr -= i;
    fp = pdData + i;
//
//  Find where we first equal or exceed the low value.
//
        for(i = start = 0; i< nr; i++, fp++)
        {
            if(*fp >= dLoRefVolt)
            {
                 start = i;
                 break;
            }
        }
//
//  Find where we exceed or equal the high value.
//
        for(stop = 0; i< nr; i++, fp++)
        {
            if(*fp >= dHiRefVolt)
            {
                 stop = i;
                 break;
            }
        }

    i = stop - start;  /* Number of samples between */
    return (double)i/dRate;
}
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-
//
// METHOD NAME
//
//   MeasureFallTime
//
//  Author:                      21-JAN-2003      Richard B. Johnson
//
// DESCRIPTION
//
//   This routine will calculate the fall time of the first
//   falling edge in the specified waveform data array.
//
// INPUTS
//
//   Pointer to data array in volts
//   Length of data array
//   Sample rate in Hz
//   LO reference voltage (in percent (0->100)).
//   HI reference voltage (in percent (0->100)).
//
// OUTPUTS
//
//   Result value, in Seconds
//
double MSL::MeasureFallTime( double * pdData, long nLength, double dRate, double dLoRefVolt, double dHiRefVolt)
{
    int start, stop, nr, i;
    double *fp, pos_peak, neg_peak, span;
    nr = (int) nLength;
//
//  Set reference, relative to the peak.
//
    pos_peak = MeasurePosPeak(pdData, nLength);  // Get the peak voltage
    neg_peak = MeasureNegPeak(pdData, nLength);
    span = pos_peak - neg_peak;
    span *= pcent;
    dHiRefVolt = neg_peak + (span * dHiRefVolt);
    dLoRefVolt = neg_peak + (span * dLoRefVolt);

//
//  Start searching from the positive peak
//
    i = sig.TimeToPosRef(pdData, dHiRefVolt, nr);
    nr -= i;
    fp = pdData + i;

//
//  Find where we first are less than the high value.
//
    for(i = start = 0; i< nr; i++, fp++)
    {
        if(*fp <= dHiRefVolt)
        {
             start = i;
             break;
        }
    }
//
//  Find where we are less than the low value.
//
    for(stop = (int) nLength; i< nr; i++, fp++)
    {
        if(*fp < dLoRefVolt)
        {
             stop = i;
             break;
        }
    }
    i = stop - start;  // Number of samples between
    return (double)i/dRate;
}
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-
//
// METHOD NAME
//
//   MeasureFrequency
//
//  Author:                      22-JAN-2003      Richard B. Johnson
//
// DESCRIPTION
//
//   This routine will calculate the frequency of the specified
//   waveform data array.  The frequency is determined by finding
//   the period from the first edge to the nth edge afterwards.
//   N = 1 will return the frequency of a regular repetitive waveform.
//
// INPUTS
//
//   Pointer to data array in volts
//   Length of data array
//   Sample rate in Hz
//   Number of pulses in a burst
//   Reference voltage (in percent (0->100))
//
// OUTPUTS
//
//   Result value, in Hz
//
double MSL::MeasureFrequency( double * pdData, long nLength, double dRate, long nBurst, double dRefVolt)
{
    return  1.0 / MeasurePeriod(pdData, nLength, dRate, nBurst, dRefVolt);
}
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-
//
// METHOD NAME
//
//   MeasurePeriod
//
//  Author:                      22-JAN-2003      Richard B. Johnson
//
// DESCRIPTION
//
//   This routine will calculate the period from the first edge to the
//   nth edge afterwards.  N = 1 will return the period of a regular
//   repetitive waveform.
//
// INPUTS
//
//   Pointer to data array in volts
//   Length of data array
//   Sample rate in Hz
//   Number of pulses in a burst
//   Reference voltage (in percent (0->100))
//
//
// OUTPUTS
//
//   Result value, in Seconds
//   In the event, we don't get the two zero-crossings we need, the
//   return value is the length of the array times the data rate.
//
//
double MSL::MeasurePeriod( double * pdData, long nLength, double dRate, long nBurst, double dRefVolt)
{
    double pos_peak, neg_peak, span, cmp, *fp;
    int i, start, up, *ip, av, nr;
    nr = (int) nBurst + 1;


    if((ip = new int [nr]) == NULL)
        return 0.0;

	DEB(printf(" percent = %f\n",  pcent));
    DEB(printf("  pdData = %p\n",  pdData));
    DEB(printf(" nLength = %ld\n", nLength));
    DEB(printf("   dRate = %f\n", dRate));
    DEB(printf("  nBurst = %ld\n", nBurst));
    DEB(printf("dRefVolt = %f\n", dRefVolt));
    pos_peak = MeasurePosPeak(pdData, nLength);  // Get pos peak voltage
    neg_peak = MeasureNegPeak(pdData, nLength);  // Get neg peak voltage
    DEB(printf("pos_peak = %f\n", pos_peak));
    DEB(printf("neg_peak = %f\n", neg_peak));
    span = pos_peak - neg_peak;                  // Should be a pos value
    span *= pcent;                               // Intervals in percent 
    dRefVolt = neg_peak + (span * dRefVolt);
    cmp   = dRefVolt + HYST;
    DEB(printf("     cmp = %f\n", cmp));
    start = 0;
    up    = FALSE;
    fp    = pdData;
//
//  Record the time (array index) for each pair of crossings. If we
//  get to the end of the burst-length, we are done.
//
    for(i=0; i< (int)nLength; i++)
    {
        if(*fp++ >= cmp)
        {
             if(up == FALSE)
             {
                 up = TRUE;
                 ip[start++] = i;
                 if(start == nr)
                     break;
                 cmp = dRefVolt - HYST;
             }
        }
        else
        {
            cmp = dRefVolt + HYST;
            up = FALSE;
        }
    }
//
//  Average the difference in time for each of the crossings.
//
    for(i = 1, av = 0;  i < nr; i++)
    {
        av += (ip[i] - ip[i-1]);
        DEB(printf("Up at %d\n", ip[i]));
    }
    av /= nr-1;
    DEB(printf("Ave %d\n", av));
    delete[] ip;
    if(av == 0)
        return dRate * (double) nLength;  // Return period of whole array 
    return (double)av / dRate;            // Return the period 
}
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-
//
// METHOD NAME
//
//   MeasureRMSVolt
//
//  Author:                      22-JAN-2003      Richard B. Johnson
//
// DESCRIPTION
//
//   This routine will calculate the DC voltage of a DC signal.
//   The Hi voltage will be measured of a step signal.
//   The RMS average of the specified waveform data array will be
//   calculated for all other signal types.
//
// INPUTS
//
//   Pointer to data array in volts
//   Length of data array
//   Signal type to measure
//
// OUTPUTS
//
//   Result value, in Volts
//
double MSL::MeasureRMSVolt( double * pdData, long nLength, enum ATE_SIGNAL_TYPE eSignalType )
{
    eSignalType = eSignalType;
    return sig.ArrayRMS(pdData, (int) nLength);
}
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-
//
// METHOD NAME
//
//   MeasurePeakToPeak
//
//  Author:                      22-JAN-2003      Richard B. Johnson
//
// DESCRIPTION
//
//   For pulsed DC and square wave signals this will calculate the
//   delta between the Hi voltage level and the Lo voltage level.
//   All other signal types will measure the delta between the most
//   positive value to the most negative value of the specified
//   waveform data array.
//
// INPUTS
//
//   Pointer to data array in volts
//   Length of data array
//   Signal type to measure
//
// OUTPUTS
//
//   Result value, in Volts
//
double MSL::MeasurePeakToPeak( double * pdData, long nLength, enum ATE_SIGNAL_TYPE eSignalType )
{
    eSignalType = eSignalType;
    return MeasurePosPeak(pdData, nLength) - MeasureNegPeak(pdData, nLength);
}
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-
//
// METHOD NAME
//
//   MeasurePosPeak
//
//  Author:                      22-JAN-2003      Richard B. Johnson
//
// DESCRIPTION
//
//   This routine will calculate the most positive voltage
//   of the specified waveform data array.
//
// INPUTS
//
//   Pointer to data array in volts
//   Length of data array
//
// OUTPUTS
//
//   Result value, in Volts
//

#define IF_MORE(n) if(pdData[n] > greater) greater = pdData[n]

double MSL::MeasurePosPeak( double * pdData, long nLength )
{
    double greater = *pdData;
#ifdef UNROLL
    while(nLength >= 0x100)
    {
        nLength -= 0x100;
        pdData  += 0x100;
ALIGN;
        IF_MORE(-0x100);
        IF_MORE(-0x0ff);
        IF_MORE(-0x0fe);
        IF_MORE(-0x0fd);
        IF_MORE(-0x0fc);
        IF_MORE(-0x0fb);
        IF_MORE(-0x0fa);
        IF_MORE(-0x0f9);
        IF_MORE(-0x0f8);
        IF_MORE(-0x0f7);
        IF_MORE(-0x0f6);
        IF_MORE(-0x0f5);
        IF_MORE(-0x0f4);
        IF_MORE(-0x0f3);
        IF_MORE(-0x0f2);
        IF_MORE(-0x0f1);
        IF_MORE(-0x0f0);
        IF_MORE(-0x0ef);
        IF_MORE(-0x0ee);
        IF_MORE(-0x0ed);
        IF_MORE(-0x0ec);
        IF_MORE(-0x0eb);
        IF_MORE(-0x0ea);
        IF_MORE(-0x0e9);
        IF_MORE(-0x0e8);
        IF_MORE(-0x0e7);
        IF_MORE(-0x0e6);
        IF_MORE(-0x0e5);
        IF_MORE(-0x0e4);
        IF_MORE(-0x0e3);
        IF_MORE(-0x0e2);
        IF_MORE(-0x0e1);
        IF_MORE(-0x0e0);
        IF_MORE(-0x0df);
        IF_MORE(-0x0de);
        IF_MORE(-0x0dd);
        IF_MORE(-0x0dc);
        IF_MORE(-0x0db);
        IF_MORE(-0x0da);
        IF_MORE(-0x0d9);
        IF_MORE(-0x0d8);
        IF_MORE(-0x0d7);
        IF_MORE(-0x0d6);
        IF_MORE(-0x0d5);
        IF_MORE(-0x0d4);
        IF_MORE(-0x0d3);
        IF_MORE(-0x0d2);
        IF_MORE(-0x0d1);
        IF_MORE(-0x0d0);
        IF_MORE(-0x0cf);
        IF_MORE(-0x0ce);
        IF_MORE(-0x0cd);
        IF_MORE(-0x0cc);
        IF_MORE(-0x0cb);
        IF_MORE(-0x0ca);
        IF_MORE(-0x0c9);
        IF_MORE(-0x0c8);
        IF_MORE(-0x0c7);
        IF_MORE(-0x0c6);
        IF_MORE(-0x0c5);
        IF_MORE(-0x0c4);
        IF_MORE(-0x0c3);
        IF_MORE(-0x0c2);
        IF_MORE(-0x0c1);
        IF_MORE(-0x0c0);
        IF_MORE(-0x0bf);
        IF_MORE(-0x0be);
        IF_MORE(-0x0bd);
        IF_MORE(-0x0bc);
        IF_MORE(-0x0bb);
        IF_MORE(-0x0ba);
        IF_MORE(-0x0b9);
        IF_MORE(-0x0b8);
        IF_MORE(-0x0b7);
        IF_MORE(-0x0b6);
        IF_MORE(-0x0b5);
        IF_MORE(-0x0b4);
        IF_MORE(-0x0b3);
        IF_MORE(-0x0b2);
        IF_MORE(-0x0b1);
        IF_MORE(-0x0b0);
        IF_MORE(-0x0af);
        IF_MORE(-0x0ae);
        IF_MORE(-0x0ad);
        IF_MORE(-0x0ac);
        IF_MORE(-0x0ab);
        IF_MORE(-0x0aa);
        IF_MORE(-0x0a9);
        IF_MORE(-0x0a8);
        IF_MORE(-0x0a7);
        IF_MORE(-0x0a6);
        IF_MORE(-0x0a5);
        IF_MORE(-0x0a4);
        IF_MORE(-0x0a3);
        IF_MORE(-0x0a2);
        IF_MORE(-0x0a1);
        IF_MORE(-0x0a0);
        IF_MORE(-0x09f);
        IF_MORE(-0x09e);
        IF_MORE(-0x09d);
        IF_MORE(-0x09c);
        IF_MORE(-0x09b);
        IF_MORE(-0x09a);
        IF_MORE(-0x099);
        IF_MORE(-0x098);
        IF_MORE(-0x097);
        IF_MORE(-0x096);
        IF_MORE(-0x095);
        IF_MORE(-0x094);
        IF_MORE(-0x093);
        IF_MORE(-0x092);
        IF_MORE(-0x091);
        IF_MORE(-0x090);
        IF_MORE(-0x08f);
        IF_MORE(-0x08e);
        IF_MORE(-0x08d);
        IF_MORE(-0x08c);
        IF_MORE(-0x08b);
        IF_MORE(-0x08a);
        IF_MORE(-0x089);
        IF_MORE(-0x088);
        IF_MORE(-0x087);
        IF_MORE(-0x086);
        IF_MORE(-0x085);
        IF_MORE(-0x084);
        IF_MORE(-0x083);
        IF_MORE(-0x082);
        IF_MORE(-0x081);
        IF_MORE(-0x080);
        IF_MORE(-0x07f);
        IF_MORE(-0x07e);
        IF_MORE(-0x07d);
        IF_MORE(-0x07c);
        IF_MORE(-0x07b);
        IF_MORE(-0x07a);
        IF_MORE(-0x079);
        IF_MORE(-0x078);
        IF_MORE(-0x077);
        IF_MORE(-0x076);
        IF_MORE(-0x075);
        IF_MORE(-0x074);
        IF_MORE(-0x073);
        IF_MORE(-0x072);
        IF_MORE(-0x071);
        IF_MORE(-0x070);
        IF_MORE(-0x06f);
        IF_MORE(-0x06e);
        IF_MORE(-0x06d);
        IF_MORE(-0x06c);
        IF_MORE(-0x06b);
        IF_MORE(-0x06a);
        IF_MORE(-0x069);
        IF_MORE(-0x068);
        IF_MORE(-0x067);
        IF_MORE(-0x066);
        IF_MORE(-0x065);
        IF_MORE(-0x064);
        IF_MORE(-0x063);
        IF_MORE(-0x062);
        IF_MORE(-0x061);
        IF_MORE(-0x060);
        IF_MORE(-0x05f);
        IF_MORE(-0x05e);
        IF_MORE(-0x05d);
        IF_MORE(-0x05c);
        IF_MORE(-0x05b);
        IF_MORE(-0x05a);
        IF_MORE(-0x059);
        IF_MORE(-0x058);
        IF_MORE(-0x057);
        IF_MORE(-0x056);
        IF_MORE(-0x055);
        IF_MORE(-0x054);
        IF_MORE(-0x053);
        IF_MORE(-0x052);
        IF_MORE(-0x051);
        IF_MORE(-0x050);
        IF_MORE(-0x04f);
        IF_MORE(-0x04e);
        IF_MORE(-0x04d);
        IF_MORE(-0x04c);
        IF_MORE(-0x04b);
        IF_MORE(-0x04a);
        IF_MORE(-0x049);
        IF_MORE(-0x048);
        IF_MORE(-0x047);
        IF_MORE(-0x046);
        IF_MORE(-0x045);
        IF_MORE(-0x044);
        IF_MORE(-0x043);
        IF_MORE(-0x042);
        IF_MORE(-0x041);
        IF_MORE(-0x040);
        IF_MORE(-0x03f);
        IF_MORE(-0x03e);
        IF_MORE(-0x03d);
        IF_MORE(-0x03c);
        IF_MORE(-0x03b);
        IF_MORE(-0x03a);
        IF_MORE(-0x039);
        IF_MORE(-0x038);
        IF_MORE(-0x037);
        IF_MORE(-0x036);
        IF_MORE(-0x035);
        IF_MORE(-0x034);
        IF_MORE(-0x033);
        IF_MORE(-0x032);
        IF_MORE(-0x031);
        IF_MORE(-0x030);
        IF_MORE(-0x02f);
        IF_MORE(-0x02e);
        IF_MORE(-0x02d);
        IF_MORE(-0x02c);
        IF_MORE(-0x02b);
        IF_MORE(-0x02a);
        IF_MORE(-0x029);
        IF_MORE(-0x028);
        IF_MORE(-0x027);
        IF_MORE(-0x026);
        IF_MORE(-0x025);
        IF_MORE(-0x024);
        IF_MORE(-0x023);
        IF_MORE(-0x022);
        IF_MORE(-0x021);
        IF_MORE(-0x020);
        IF_MORE(-0x01f);
        IF_MORE(-0x01e);
        IF_MORE(-0x01d);
        IF_MORE(-0x01c);
        IF_MORE(-0x01b);
        IF_MORE(-0x01a);
        IF_MORE(-0x019);
        IF_MORE(-0x018);
        IF_MORE(-0x017);
        IF_MORE(-0x016);
        IF_MORE(-0x015);
        IF_MORE(-0x014);
        IF_MORE(-0x013);
        IF_MORE(-0x012);
        IF_MORE(-0x011);
        IF_MORE(-0x010);
        IF_MORE(-0x00f);
        IF_MORE(-0x00e);
        IF_MORE(-0x00d);
        IF_MORE(-0x00c);
        IF_MORE(-0x00b);
        IF_MORE(-0x00a);
        IF_MORE(-0x009);
        IF_MORE(-0x008);
        IF_MORE(-0x007);
        IF_MORE(-0x006);
        IF_MORE(-0x005);
        IF_MORE(-0x004);
        IF_MORE(-0x003);
        IF_MORE(-0x002);
        IF_MORE(-0x001);
    }
    while(nLength >= 0x10)
    {
        nLength -= 0x10;
        pdData  += 0x10;
        IF_MORE(-0x10);
        IF_MORE(-0x0f);
        IF_MORE(-0x0e);
        IF_MORE(-0x0d);
        IF_MORE(-0x0c);
        IF_MORE(-0x0b);
        IF_MORE(-0x0a);
        IF_MORE(-0x09);
        IF_MORE(-0x08);
        IF_MORE(-0x07);
        IF_MORE(-0x06);
        IF_MORE(-0x05);
        IF_MORE(-0x04);
        IF_MORE(-0x03);
        IF_MORE(-0x02);
        IF_MORE(-0x01);
    }
#endif
    while(nLength--)
    {
        if(*pdData > greater) greater = *pdData;
        pdData++;
    }
    return greater;
}
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-
//
// METHOD NAME
//
//   MeasureNegPeak
//
//  Author:                      22-JAN-2003      Richard B. Johnson
//
// DESCRIPTION
//
//   This routine will calculate the most negative voltage
//   of the specified waveform data array.
//
// INPUTS
//
//   Pointer to data array in volts
//   Length of data array
//
// OUTPUTS
//
//   Result value, in Volts
//

#define IF_LESS(n) if(pdData[n] < lesser) lesser = pdData[n]

double MSL::MeasureNegPeak( double * pdData, long nLength )
{
    double lesser = *pdData;
#ifdef UNROLL
    while(nLength >= 0x100)
    {
        nLength -= 0x100;
        pdData  += 0x100;
ALIGN;
        IF_LESS(-0x100);
        IF_LESS(-0x0ff);
        IF_LESS(-0x0fe);
        IF_LESS(-0x0fd);
        IF_LESS(-0x0fc);
        IF_LESS(-0x0fb);
        IF_LESS(-0x0fa);
        IF_LESS(-0x0f9);
        IF_LESS(-0x0f8);
        IF_LESS(-0x0f7);
        IF_LESS(-0x0f6);
        IF_LESS(-0x0f5);
        IF_LESS(-0x0f4);
        IF_LESS(-0x0f3);
        IF_LESS(-0x0f2);
        IF_LESS(-0x0f1);
        IF_LESS(-0x0f0);
        IF_LESS(-0x0ef);
        IF_LESS(-0x0ee);
        IF_LESS(-0x0ed);
        IF_LESS(-0x0ec);
        IF_LESS(-0x0eb);
        IF_LESS(-0x0ea);
        IF_LESS(-0x0e9);
        IF_LESS(-0x0e8);
        IF_LESS(-0x0e7);
        IF_LESS(-0x0e6);
        IF_LESS(-0x0e5);
        IF_LESS(-0x0e4);
        IF_LESS(-0x0e3);
        IF_LESS(-0x0e2);
        IF_LESS(-0x0e1);
        IF_LESS(-0x0e0);
        IF_LESS(-0x0df);
        IF_LESS(-0x0de);
        IF_LESS(-0x0dd);
        IF_LESS(-0x0dc);
        IF_LESS(-0x0db);
        IF_LESS(-0x0da);
        IF_LESS(-0x0d9);
        IF_LESS(-0x0d8);
        IF_LESS(-0x0d7);
        IF_LESS(-0x0d6);
        IF_LESS(-0x0d5);
        IF_LESS(-0x0d4);
        IF_LESS(-0x0d3);
        IF_LESS(-0x0d2);
        IF_LESS(-0x0d1);
        IF_LESS(-0x0d0);
        IF_LESS(-0x0cf);
        IF_LESS(-0x0ce);
        IF_LESS(-0x0cd);
        IF_LESS(-0x0cc);
        IF_LESS(-0x0cb);
        IF_LESS(-0x0ca);
        IF_LESS(-0x0c9);
        IF_LESS(-0x0c8);
        IF_LESS(-0x0c7);
        IF_LESS(-0x0c6);
        IF_LESS(-0x0c5);
        IF_LESS(-0x0c4);
        IF_LESS(-0x0c3);
        IF_LESS(-0x0c2);
        IF_LESS(-0x0c1);
        IF_LESS(-0x0c0);
        IF_LESS(-0x0bf);
        IF_LESS(-0x0be);
        IF_LESS(-0x0bd);
        IF_LESS(-0x0bc);
        IF_LESS(-0x0bb);
        IF_LESS(-0x0ba);
        IF_LESS(-0x0b9);
        IF_LESS(-0x0b8);
        IF_LESS(-0x0b7);
        IF_LESS(-0x0b6);
        IF_LESS(-0x0b5);
        IF_LESS(-0x0b4);
        IF_LESS(-0x0b3);
        IF_LESS(-0x0b2);
        IF_LESS(-0x0b1);
        IF_LESS(-0x0b0);
        IF_LESS(-0x0af);
        IF_LESS(-0x0ae);
        IF_LESS(-0x0ad);
        IF_LESS(-0x0ac);
        IF_LESS(-0x0ab);
        IF_LESS(-0x0aa);
        IF_LESS(-0x0a9);
        IF_LESS(-0x0a8);
        IF_LESS(-0x0a7);
        IF_LESS(-0x0a6);
        IF_LESS(-0x0a5);
        IF_LESS(-0x0a4);
        IF_LESS(-0x0a3);
        IF_LESS(-0x0a2);
        IF_LESS(-0x0a1);
        IF_LESS(-0x0a0);
        IF_LESS(-0x09f);
        IF_LESS(-0x09e);
        IF_LESS(-0x09d);
        IF_LESS(-0x09c);
        IF_LESS(-0x09b);
        IF_LESS(-0x09a);
        IF_LESS(-0x099);
        IF_LESS(-0x098);
        IF_LESS(-0x097);
        IF_LESS(-0x096);
        IF_LESS(-0x095);
        IF_LESS(-0x094);
        IF_LESS(-0x093);
        IF_LESS(-0x092);
        IF_LESS(-0x091);
        IF_LESS(-0x090);
        IF_LESS(-0x08f);
        IF_LESS(-0x08e);
        IF_LESS(-0x08d);
        IF_LESS(-0x08c);
        IF_LESS(-0x08b);
        IF_LESS(-0x08a);
        IF_LESS(-0x089);
        IF_LESS(-0x088);
        IF_LESS(-0x087);
        IF_LESS(-0x086);
        IF_LESS(-0x085);
        IF_LESS(-0x084);
        IF_LESS(-0x083);
        IF_LESS(-0x082);
        IF_LESS(-0x081);
        IF_LESS(-0x080);
        IF_LESS(-0x07f);
        IF_LESS(-0x07e);
        IF_LESS(-0x07d);
        IF_LESS(-0x07c);
        IF_LESS(-0x07b);
        IF_LESS(-0x07a);
        IF_LESS(-0x079);
        IF_LESS(-0x078);
        IF_LESS(-0x077);
        IF_LESS(-0x076);
        IF_LESS(-0x075);
        IF_LESS(-0x074);
        IF_LESS(-0x073);
        IF_LESS(-0x072);
        IF_LESS(-0x071);
        IF_LESS(-0x070);
        IF_LESS(-0x06f);
        IF_LESS(-0x06e);
        IF_LESS(-0x06d);
        IF_LESS(-0x06c);
        IF_LESS(-0x06b);
        IF_LESS(-0x06a);
        IF_LESS(-0x069);
        IF_LESS(-0x068);
        IF_LESS(-0x067);
        IF_LESS(-0x066);
        IF_LESS(-0x065);
        IF_LESS(-0x064);
        IF_LESS(-0x063);
        IF_LESS(-0x062);
        IF_LESS(-0x061);
        IF_LESS(-0x060);
        IF_LESS(-0x05f);
        IF_LESS(-0x05e);
        IF_LESS(-0x05d);
        IF_LESS(-0x05c);
        IF_LESS(-0x05b);
        IF_LESS(-0x05a);
        IF_LESS(-0x059);
        IF_LESS(-0x058);
        IF_LESS(-0x057);
        IF_LESS(-0x056);
        IF_LESS(-0x055);
        IF_LESS(-0x054);
        IF_LESS(-0x053);
        IF_LESS(-0x052);
        IF_LESS(-0x051);
        IF_LESS(-0x050);
        IF_LESS(-0x04f);
        IF_LESS(-0x04e);
        IF_LESS(-0x04d);
        IF_LESS(-0x04c);
        IF_LESS(-0x04b);
        IF_LESS(-0x04a);
        IF_LESS(-0x049);
        IF_LESS(-0x048);
        IF_LESS(-0x047);
        IF_LESS(-0x046);
        IF_LESS(-0x045);
        IF_LESS(-0x044);
        IF_LESS(-0x043);
        IF_LESS(-0x042);
        IF_LESS(-0x041);
        IF_LESS(-0x040);
        IF_LESS(-0x03f);
        IF_LESS(-0x03e);
        IF_LESS(-0x03d);
        IF_LESS(-0x03c);
        IF_LESS(-0x03b);
        IF_LESS(-0x03a);
        IF_LESS(-0x039);
        IF_LESS(-0x038);
        IF_LESS(-0x037);
        IF_LESS(-0x036);
        IF_LESS(-0x035);
        IF_LESS(-0x034);
        IF_LESS(-0x033);
        IF_LESS(-0x032);
        IF_LESS(-0x031);
        IF_LESS(-0x030);
        IF_LESS(-0x02f);
        IF_LESS(-0x02e);
        IF_LESS(-0x02d);
        IF_LESS(-0x02c);
        IF_LESS(-0x02b);
        IF_LESS(-0x02a);
        IF_LESS(-0x029);
        IF_LESS(-0x028);
        IF_LESS(-0x027);
        IF_LESS(-0x026);
        IF_LESS(-0x025);
        IF_LESS(-0x024);
        IF_LESS(-0x023);
        IF_LESS(-0x022);
        IF_LESS(-0x021);
        IF_LESS(-0x020);
        IF_LESS(-0x01f);
        IF_LESS(-0x01e);
        IF_LESS(-0x01d);
        IF_LESS(-0x01c);
        IF_LESS(-0x01b);
        IF_LESS(-0x01a);
        IF_LESS(-0x019);
        IF_LESS(-0x018);
        IF_LESS(-0x017);
        IF_LESS(-0x016);
        IF_LESS(-0x015);
        IF_LESS(-0x014);
        IF_LESS(-0x013);
        IF_LESS(-0x012);
        IF_LESS(-0x011);
        IF_LESS(-0x010);
        IF_LESS(-0x00f);
        IF_LESS(-0x00e);
        IF_LESS(-0x00d);
        IF_LESS(-0x00c);
        IF_LESS(-0x00b);
        IF_LESS(-0x00a);
        IF_LESS(-0x009);
        IF_LESS(-0x008);
        IF_LESS(-0x007);
        IF_LESS(-0x006);
        IF_LESS(-0x005);
        IF_LESS(-0x004);
        IF_LESS(-0x003);
        IF_LESS(-0x002);
        IF_LESS(-0x001);
    }
    while(nLength >= 0x10)
    {
        nLength -= 0x10;
        pdData  += 0x10;
        IF_LESS(-0x10);
        IF_LESS(-0x0f);
        IF_LESS(-0x0e);
        IF_LESS(-0x0d);
        IF_LESS(-0x0c);
        IF_LESS(-0x0b);
        IF_LESS(-0x0a);
        IF_LESS(-0x09);
        IF_LESS(-0x08);
        IF_LESS(-0x07);
        IF_LESS(-0x06);
        IF_LESS(-0x05);
        IF_LESS(-0x04);
        IF_LESS(-0x03);
        IF_LESS(-0x02);
        IF_LESS(-0x01);
    }
#endif
    while(nLength--)
    {
        if(*pdData < lesser) lesser = *pdData;
        pdData++;
    }
    return lesser;
}
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-
//
// METHOD NAME
//
//   MeasurePulseHiVoltage
//
//  Author:                      22-JAN-2003      Richard B. Johnson
//
// DESCRIPTION
//
//   This routine will calculate the pulse HI voltage of the specified
//   waveform data array.  The signal is assumed to be digital.
//
// INPUTS
//
//   Pointer to data array in volts
//   Length of data array
//
// OUTPUTS
//
//   Result value, in Volts
//
double MSL::MeasurePulseHiVoltage( double * pdData, long nLength, enum ATE_SIGNAL_TYPE eSignalType )
{
    eSignalType = eSignalType;
    return MeasurePosPeak(pdData, nLength);
}
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-
//
// METHOD NAME
//
//   MeasurePulseLoVoltge
//
//  Author:                      22-JAN-2003      Richard B. Johnson
//
// DESCRIPTION
//
//   This routine will calculate the pulse LO voltage of the specified
//   waveform data array.  The signal is assumed to be digital.
//
// INPUTS
//
//   Pointer to data array in volts
//   Length of data array
//
// OUTPUTS
//
//   Result value, in Volts
//
double MSL::MeasurePulseLoVoltage( double * pdData, long nLength, enum ATE_SIGNAL_TYPE eSignalType )
{
    eSignalType = eSignalType;
    return MeasureNegPeak(pdData, nLength);
}
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-
//
// METHOD NAME
//
//   MeasureDCVolt
//
//  Author:                      22-JAN-2003      Richard B. Johnson
//
// DESCRIPTION
//
//   This routine will calculate the average voltage of the specified
//   waveform data array.
//
// INPUTS
//
//   Pointer to data array in volts
//   Length of data array
//
// OUTPUTS
//
//   Result value, in Volts
//
double MSL::MeasureDCVolt( double * pdData, long nLength )
{
    double *dp, retval;
    size_t len = (size_t) nLength;
    if((dp = new double [len]) == NULL)
        return 0.0;
    memcpy(dp, pdData, len * sizeof(double));
    sig.Window(dp, SIG::WINDOW_TYPE_RCOS, len);
    retval = sig.MeasMean(dp, len);
    delete[] dp;
    return retval;
}
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-
//
// METHOD NAME
//
//   MeasurePulsePosWidth
//
//  Author:                      24-JAN-2003      Richard B. Johnson
//
// DESCRIPTION
//
//   This routine will calculate the positive pulse width of the
//   first cycle in the specified waveform data array.
//
// INPUTS
//
//   Pointer to data array in volts
//   Length of data array
//   Sample rate in Hz
//   Reference voltage (0->100%)
//
// OUTPUTS
//
//   Result value, in Seconds
//
double MSL::MeasurePulsePosWidth( double * pdData, long nLength,
                             double dRate, double dRefVolt)
{
    double peak;
    int i, start, nr;
    nr = (int) nLength;
    peak = MeasurePosPeak(pdData, nLength);  // Get the peak voltage
    dRefVolt = peak * dRefVolt * pcent;
    for(i=0; i< nr; i++, pdData++)
        if(dRefVolt < *pdData)
            break;
    for(start = i; i< nr; i++, pdData++)
        if(dRefVolt > *pdData)
            break;
    i -= start;
    return (double)i/dRate;
}
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-
//
// METHOD NAME
//
//   MeasurePulseNegWidth
//
//  Author:                      24-JAN-2003      Richard B. Johnson
//
//
// DESCRIPTION
//
//   This routine will calculate the negative pulse width of the
//   first cycle in the specified waveform data array.
//
// INPUTS
//
//   Pointer to data array in volts
//   Length of data array
//   Sample rate in Hz
//   Reference voltage (0->100%)
//
// OUTPUTS
//
//   Result value, in Seconds
//
double MSL::MeasurePulseNegWidth( double * pdData, long nLength, double dRate, double dRefVolt)
{
    double peak;
    int i, start, nr;
    nr = (int) nLength;
    peak = MeasureNegPeak(pdData, nLength);  // Get the peak voltage
    dRefVolt = peak * dRefVolt * pcent;
    for(i=0; i< nr; i++, pdData++)
        if(dRefVolt > *pdData)
            break;
    for(start = i; i< nr; i++, pdData++)
        if(dRefVolt < *pdData)
            break;
    i -= start;
    return (double) i * dRate;
}
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-
//
// METHOD NAME
//
//   MeasureDutyCyclePos
//
//  Author:                      24-JAN-2003      Richard B. Johnson
//
// DESCRIPTION
//
//   This routine will calculate the duty cycle of the specified
//   waveform data array.  Only the first cycle will be analyzed.
//
// INPUTS
//
//   Pointer to data array in volts
//   Length of data array
//   Reference voltage (0->100%)
//
// OUTPUTS
//
//   Result value, in percent
//
double MSL::MeasureDutyCyclePos( double * pdData, long nLength, double dRefVolt)
{
    double pos_peak, neg_peak, span;
    int i, start, stop, nr;
    nr = (int) nLength;
    pos_peak = MeasurePosPeak(pdData, nLength);  // Get pos peak voltage
    neg_peak = MeasureNegPeak(pdData, nLength);  // Get neg peak voltage
    span = pos_peak - neg_peak;                  // Should be a pos value
    span *= pcent;                               // Intervals in percent
    dRefVolt = neg_peak + (span * dRefVolt);

    i = sig.TimeToReference(pdData, dRefVolt, nLength);
    nr -= i;
    pdData += i;

    for(i = start = 0; i< nr; i++, pdData++)
        if(dRefVolt < *pdData)
            break;
    for(start = i; i< nr; i++, pdData++)
        if(dRefVolt > *pdData)
            break;
    for(stop = i; i< nr; i++, pdData++)
        if(dRefVolt < *pdData)
            break;
    if((i - start) == 0) return 0.0;
    return ((double)(stop-start)/(double)(i - start) * hcent);
}
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-
//
// METHOD NAME
//
//   MeasureDutyCycleNeg
//
//  Author:                      24-JAN-2003      Richard B. Johnson
//
// DESCRIPTION
//
//   This routine will calculate the duty cycle of the specified
//   waveform data array and subtract that value from 100.0.  Only
//   the first cycle will be analyzed.
//
// INPUTS
//
//   Pointer to data array in volts
//   Length of data array
//   Reference voltage, if not specified the 50% voltage is used
//
// OUTPUTS
//
//   Result value, in percent
//
double MSL::MeasureDutyCycleNeg( double * pdData, long nLength, double dRefVolt)
{
    double pos_peak, neg_peak, span;
    int i, start, stop, nr;
    nr = (int) nLength;
    pos_peak = MeasurePosPeak(pdData, nLength);  // Get pos peak voltage
    neg_peak = MeasureNegPeak(pdData, nLength);  // Get neg peak voltage
    span = pos_peak - neg_peak;                  // Should be a pos value
    span *= pcent;                               // Intervals in percent
    dRefVolt = neg_peak + (span * dRefVolt);

    i = sig.TimeToReference(pdData, dRefVolt, nLength);
    nr -= i;
    pdData += i;

    for(i = start = 0; i< nr; i++, pdData++)
        if(dRefVolt > *pdData)
            break;
    for(start = i; i< nr; i++, pdData++)
        if(dRefVolt < *pdData)
            break;
    for(stop = i; i< nr; i++, pdData++)
        if(dRefVolt > *pdData)
            break;
   if((i - start) == 0) return 0.0;
    return ((double)(stop-start)/(double)(i - start) * hcent);
}
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-
//
// METHOD NAME
//
//   MeasurePulseAmplitude
//
//  Author:                      24-JAN-2003      Richard B. Johnson
//
// DESCRIPTION
//
//   This routine will calculate the delta from the pulse LO voltage
//   to the pulse HI voltage of the specified waveform data array.
//
// INPUTS
//
//   Pointer to data array in volts
//   Length of data array
//
// OUTPUTS
//
//   Result value, in Volts
//
double MSL::MeasurePulseAmplitude( double * pdData, long nLength, enum ATE_SIGNAL_TYPE eSignalType )
{
    return MeasurePeakToPeak(pdData, nLength, eSignalType);
}
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-
//
// METHOD NAME
//
//   MeasureCycleACVolt
//
//  Author:                      24-JAN-2003      Richard B. Johnson
//
// DESCRIPTION
//
//   This routine will calculate the RMS voltage of the first cycle of the
//   specified waveform data array.
//
// INPUTS
//
//   Pointer to data array in volts
//   Length of data array
//   Reference voltage (0->100%)
//
// OUTPUTS
//
//   Result value, in Volts
//
double MSL::MeasureCycleACVolt( double * pdData, long nLength, double dRefVolt)
{
    double pos_peak, neg_peak, span, *begin;
    int i, start, stop, nr;
    nr = (int) nLength;
    pos_peak = MeasurePosPeak(pdData, nLength);  // Get pos peak voltage
    neg_peak = MeasureNegPeak(pdData, nLength);  // Get neg peak voltage
    span = pos_peak - neg_peak;                  // Should be a pos value
    span *= pcent;                               // Intervals in percent
    dRefVolt = neg_peak + (span * dRefVolt);

    i = sig.TimeToReference(pdData, dRefVolt, nLength);
    nr -= i;
    pdData += i;

    for(i=0, start = 0; i< nr; i++, pdData++)
        if(dRefVolt < *pdData)
            break;
    for(start = i, begin = pdData; i< nr; i++, pdData++)
        if(dRefVolt > *pdData)
            break;
    for(stop = i; i< nr; i++, pdData++)
        if(dRefVolt < *pdData)
            break;
    return MeasureRMSVolt(begin,(long)(i - start), SIGNAL_AC);
}
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-
//
// METHOD NAME
//
//   MeasureCycleDCVolt
//
//  Author:                      24-JAN-2003      Richard B. Johnson
//
// DESCRIPTION
//
//   This routine will calculate the average voltage of the first cycle of
//   the specified waveform data array.
//
// INPUTS
//
//   Pointer to data array in volts
//   Length of data array
//   Reference voltage (0->100%)
//
// OUTPUTS
//
//   Result value, in Volts
//
double MSL::MeasureCycleDCVolt( double * pdData, long nLength, double dRefVolt)
{
    double pos_peak, neg_peak, span, *begin;
    int i, start, stop, nr;
    nr = (int) nLength;
    pos_peak = MeasurePosPeak(pdData, nLength);  // Get pos peak voltage
    neg_peak = MeasureNegPeak(pdData, nLength);  // Get neg peak voltage 
    span = pos_peak - neg_peak;                  // Should be a pos value
    span *= pcent;                               // Intervals in percent
    dRefVolt = neg_peak + (span * dRefVolt);

    i = sig.TimeToReference(pdData, dRefVolt, nLength);
    nr -= i;
    pdData += i;

    for(i=0, start = 0; i< nr; i++, pdData++)
        if(dRefVolt < *pdData)
            break;
    for(start = i, begin = pdData; i< nr; i++, pdData++)
        if(dRefVolt > *pdData)
            break;
    for(stop = i; i< nr; i++, pdData++)
        if(dRefVolt < *pdData)
            break;
    return sig.MeasMean(begin, (i - start));
}
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-
//
// METHOD NAME
//
//   MeasureDCOffset
//
//  Author:                      24-JAN-2003      Richard B. Johnson
//
// DESCRIPTION
//
//   For pulsed DC signals this routine will calculate the pulse Lo
//   voltage.
//
//   For square wave signals this routine will calculate the average
//   of the pulse Hi voltage and the pulse Lo voltage.
//
//   For a step signal this routine will calculate the step Lo voltage.
//   For all other signal types this routine will calculate the difference
//   of the maximum positive and maximum negative voltages. This really
//   should do the duty-cycle calculations and might in the future.
//
// INPUTS
//
//   Pointer to data array in volts
//   Length of data array
//   Signal type to measure
//
// OUTPUTS
//   Result value, in Volts
//
double MSL::MeasureDCOffset( double * pdData, long nLength, enum ATE_SIGNAL_TYPE eSignalType )
{
    switch(eSignalType)
    {
    //  return MeasureDCVolt(pdData, nLength);
    case SIGNAL_DC:
    case SIGNAL_DC_AC_COMP_FREQ:
    case SIGNAL_FREQUENCY:
    case SIGNAL_PULSED_DC:
    case SIGNAL_PULSED_DC_TIME:
        return MeasureNegPeak(pdData, nLength);
        break;
    case SIGNAL_AC:
    case SIGNAL_AC_MATH:
    case SIGNAL_AC_REF:
    case SIGNAL_BURST:
    case SIGNAL_RAMP:
    case SIGNAL_RAMP_TIME:
    case SIGNAL_SQUARE:
    case SIGNAL_SQUARE_TIME:
    case SIGNAL_STEP:
    case SIGNAL_TRIANGLE:
    case SIGNAL_TRIANGLE_TIME:
    case SIGNAL_WAVEFORM:
        return (MeasurePosPeak(pdData, nLength) + MeasureNegPeak(pdData, nLength))/2.0;
       break;
   default:
       break;
    }
    return 0.0;
}

#ifdef AVG_METHOD
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-
//
// METHOD NAME
//
//   MeasureOverShoot
//
//  Author:                      27-JAN-2003      Richard B. Johnson
//
// DESCRIPTION
//
//   This routine will calculate the delta from the pulse HI voltage
//   to the peak HI voltage of the specified waveform data array.
//
//            | <-- Overshoot      |
//            |___________         |__________
//            |          |         |          |
//            |          |         |          |
//            |          |         |          |
// ___________|          |_________|          |___________
//
//
//
// INPUTS
//
//   Pointer to data array in volts
//   Length of data array
//
// OUTPUTS
//
//   Result value, in percent
//

double MSL::MeasureOverShoot( double * pdData, long nLength, enum ATE_SIGNAL_TYPE eSignalType )
{
    double peak, top, half, *dp;
    int nr, glitch, zero;
    eSignalType = eSignalType;

    if((dp = (double *) malloc((size_t)nLength * sizeof(double))) == NULL)
        return 0.0;
    nr = (int) nLength;
    memcpy(dp, pdData, nr * sizeof(double));
    half   = (MeasurePosPeak(dp, nr) + MeasureNegPeak(dp, nr)) / 2.0;
    SubConst(dp, half, nr);               // Subtract the offset
    peak   = MeasurePosPeak(dp, nr);      // Get the peak voltage
    glitch = TimeToPosRef(dp, peak, nr);  // Find the peak bin
    zero   = TimeToNegRef(&dp[glitch], 0.0, nr - glitch);
    zero >>= 1;                           // Cut top pulse in half
    top    = MeasMean(&dp[glitch + zero], zero);
    free(dp);
    return (peak - top) * hcent / (2.0 * (top + (peak - top)));

}
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-
#else
//
// METHOD NAME
//
//   MeasureOverShoot
//
//  Author:                      6-MAR-2003      C. Higgins
//
// DESCRIPTION
//
//   This routine will calculate the delta from the maximum voltage
//   of pulse to the peak HI voltage of the specified waveform data array.
//
//       The result is returned as a percentage.
//       Calculated using the following: (Max - High)/Amplitude x 100% where:
//                      Max = positive peak voltage
//                      High = voltage representing 100% reference level
//                      Amplitude = voltage at 100% ref. level - voltage at 0% ref. level
//
//
//            | <-- Overshoot      |
//            |___________         |__________
//            |          |         |          |
//            |          |         |          |
//            |          |         |          |
// ___________|          |_________|          |___________
//
//
//
// INPUTS
//
//   Pointer to data array in volts
//   Length of data array
//
// OUTPUTS
//
//   Result value, in percent

/////////////////////////////////////////////////////////////////////////////
double MSL::MeasureOverShoot( double * pdData, long nLength, enum ATE_SIGNAL_TYPE eSignalType )
{
        #define NBINS  1000

        long hist[NBINS+1] = {0},
                hist_peak, i;
        double max, min, high, low, slope, b, amp;
        int index_high = 0,
                index_low = 0;
//
//      Get pos & neg peaks
//
        max = MeasurePosPeak(pdData, nLength);
        min = MeasureNegPeak(pdData,  nLength);
//
//      Calculate parameters for linear transform
//
        if(max - min == 0.0) return 0.0;
        slope = (double)NBINS/(max - min);
        b = (double)NBINS - slope * max;
//
//      Create histogram 
//
        for(i = 0; i < nLength; i++)
        {
                hist[(int)(slope * pdData[i] + b)]++;
        }

//
//      Search negative half of histogram for peaks
//
        hist_peak = 0;
        for(i = 0; i < NBINS/2; i++)
        {
                if(hist[i] > hist_peak)
                {
                        hist_peak = hist[i];
                        index_low = i;
                }
        }

//
//      Search positive half of histogram for peaks
//
        hist_peak = 0;
        for(i = NBINS/2; i <= NBINS; i++)
        {
                if(hist[i] > hist_peak)
                {
                        hist_peak = hist[i];
                        index_high = i;
                }
        }
//
//      Convert index back to voltage
//
        high = ((double)index_high - b)/slope;
        low = ((double)index_low - b)/slope;
        amp = high - low;

        return ((max-high)/amp) * 100.0;
}

#endif
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-
//
// METHOD NAME
//
//   MeasureUnderShoot
//
//  Author:                      27-JAN-2003      Richard B. Johnson
//
//
//            ____________          __________
//            |          |         |          |
//            |          |         |          |
//            |          |         |          |
// ___________|          |_________|          |___________
//                       |                    | <-   Undershoot
// DESCRIPTION
//
//   This routine will calculate the delta from the pulse LO voltage
//   to the peak LO voltage of the specified waveform data array.
//
// INPUTS
//
//   Pointer to data array in volts
//   Length of data array
//
// OUTPUTS
//
//   Result value, in percent
/////////////////////////////////////////////////////////////////////////////
double MSL::MeasureUnderShoot( double * pdData, long nLength, enum ATE_SIGNAL_TYPE eSignalType )
{
    double result, *dp;
    if((dp = new double [nLength]) == NULL)
        return 0.0;
    memcpy(dp, pdData, (size_t)nLength * sizeof(double));
    InvertWaveform(dp, nLength);
    result = MeasureOverShoot(dp, nLength, eSignalType);
    delete[] dp;
    return result;
}
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-
//
// METHOD NAME
//
//   MeasurePreShoot
//
// DESCRIPTION
//
//   This routine will calculate the delta from the pulse LO voltage
//   to the peak LO voltage of the specified waveform data array.
//
// INPUTS
//
//   Pointer to data array in volts
//   Length of data array
//
// OUTPUTS
//
//   Result value, in Volts
/////////////////////////////////////////////////////////////////////////////
double MSL::MeasurePreShoot( double * pdData, long nLength, enum ATE_SIGNAL_TYPE eSignalType )
{
    pdData      = pdData;
    nLength     = nLength;
    eSignalType = eSignalType;
    return 0.0;
}
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-
//
// METHOD NAME
//
//   MeasurePhase
//
//  Author:                      25-JAN-2003      Richard B. Johnson
//
// DESCRIPTION
//
//   This routine will find the first edge of pdData1 and the corresponding
//   edge in pdData2.  The number of samples from the edge of pdData2 is
//   subtracted from the edge in pdData1.  This value is divided by the
//   number of samples between the first edge in pdData1 and the next
//   occurrence of the same slope edge in pdData1 and multiplied by 360.
//
// INPUTS
//
//   Pointer to start of data array1
//   Pointer to start of data array2
//   Max length of array
//   Reference voltage (0->100%).
//
// OUTPUTS
//
//   Result value, in Degrees
/////////////////////////////////////////////////////////////////////////////
double MSL::MeasurePhase( double * pdData1, double * pdData2, long nLength, double dRefVolt)
{
    double peak;
    int i, cross, bins,  nr;
    nr = (int) nLength;
    peak = MeasurePosPeak(pdData1, nLength);  // Get the peak voltage
    dRefVolt = peak * dRefVolt * pcent;
//
//  Find where it crosses the reference voltage the first time.
//
    for(i=0; i< nr; i++, pdData1++)
        if(dRefVolt < *pdData1)
            break;
//
//  Okay, record that sample then continue until it falls through
//  that reference voltage.
//
    for(cross = i; i< nr; i++, pdData1++)
        if(dRefVolt > *pdData1)
            break;
//
//  Okay, continue until it crosses the reference voltage the second
//  time. Record that sample interval. That represents 360 degrees
//  of phase change.
//
    for(; i< nr; i++, pdData1++)
        if(dRefVolt < *pdData1)
            break;
    bins = i - cross;
//
//  Find where second sample crosses the reference voltage the first time.
//
    for(i=0; i< nr; i++, pdData2++)
        if(dRefVolt < *pdData2)
            break;
    return ((double)i - (double)cross) * turn / (double) bins;
}
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-
//
// METHOD NAME
//
//   MeasureTHD
//
//  Author:                      30-JAN-2003      Richard B. Johnson
//
// DESCRIPTION
//
//   This routine will calculate the power at frequency and then take the
//   ratio of the next 7 harmonics with the sum of the 7 harmonics and
//   power at frequency.
//
// INPUTS
//
//   Pointer to start of data array
//   Frequency of our primary signal
//   Sample rate
//   Max length of array
//
// OUTPUTS
//
//   Result value, in Percent
//
double MSL::MeasureTHD( double * pdData, double dFreq, double dRate, long nLength )
{
    double *dp, retval, carrier, harm, freq;
    int bins;
    size_t len;
    dFreq = dFreq;
    dRate = dRate;
    retval = 0.0;
    len = (size_t) nLength;
    if((dp = new double [len]) == NULL)
        return retval;
    freq = sig.do_FFT(dp, pdData, SIG::WINDOW_TYPE_WEED, len);
//
//  Protect against too long a record (noise, etc).
//
    if((((size_t)(freq * 8.0 + PAD) * sizeof(double)) > len) || (freq < ZERO))
    {
        delete[] dp;
        return retval;
    }
//
//  Protect against zero frequency (DC) and retrieve the correct
//  number of bins at each frequency. We include all the bins that
//  will be 1/4 the fundamental or greater (1/2 power points).
//
    if((bins = (int) (freq + PAD)) != 0)
    {
#ifdef REJECT_NOISE
        carrier = dp[bins] / 4.0;      // P = E^2 / R 
        while(carrier < dp[bins])      // Find 1/2 power points
            bins++;
        bins--;
        bins -= (int)freq;             // Subtract starting point
        bins |= 1;                     // Make an odd number
#endif
        carrier = sig.get_bins(dp, (int)(freq + PAD), bins);
        harm  = sig.get_bins(dp, (int)((freq * 2.0) + PAD), bins);
        harm += sig.get_bins(dp, (int)((freq * 3.0) + PAD), bins);
        harm += sig.get_bins(dp, (int)((freq * 4.0) + PAD), bins);
        harm += sig.get_bins(dp, (int)((freq * 5.0) + PAD), bins);
        harm += sig.get_bins(dp, (int)((freq * 6.0) + PAD), bins);
        harm += sig.get_bins(dp, (int)((freq * 7.0) + PAD), bins);
        harm += sig.get_bins(dp, (int)((freq * 8.0) + PAD), bins);
        retval = (harm / carrier) * hcent;
    }
    delete[] dp;
    return retval;
}
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-
//
// METHOD NAME
//
//   SqrtSumSqr
//
//  Author:                      25-JUL-2008      Richard B. Johnson
//
// DESCRIPTION
//
//   Calculate the square-root of the sum of the squares from data in the
//   two input arrays and leave the result in the output array.
//
// INPUTS
//
//   Pointer to start of data array PdData1
//   Pointer to start of data array PdData2
//   Pointer to start of output data array pdData0
//   Max length of array
//
// OUTPUTS
//
//   Result value, in the output array, pdData0
//

void MSL::SqrtSumSqr(double *pdData0, double *pdData1, double *pdData2, long nLength)
{

	double *sqr1 = new double [nLength];
	double *sqr2 = new double [nLength];
	double *sum0 = new double [nLength];

	sig.SqurArray(sqr1, pdData1, nLength);
	sig.SqurArray(sqr2, pdData2, nLength);
	sig.AddArray(sum0,  sqr1, sqr2, nLength);
    sig.SqrtArray(pdData0, sum0, nLength);

	delete[] sqr1;
	delete[] sqr2;
	delete[] sum0;

}

//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-
//
// METHOD NAME
//
//  FiltBySum
//
//  Author:                      25-JUL-2008      Richard B. Johnson
//
// DESCRIPTION
//
//   Filter signals by summing and dividing the result by a coefficient
//   leaving the result in the output array.
//
// INPUTS
//
//   Pointer to start of data array PdData1
//   Pointer to start of data array PdData2
//   Pointer to start of output data array pdData0
//   Max length of array
//
// OUTPUTS
//
//   Result value, in the output array, pdData0
//

void MSL::FiltBySum(double *pdData0, double *pdData1, double *pdData2, double coef, long nLength)
{

	sig.AddArray(pdData0,  pdData1, pdData2, nLength);
    sig.DivConst(pdData0,  coef, nLength);

}

//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= E N D =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-




