
#include "testdatagenerator.h"

#include <math.h>

#include "rep_fpga_interface.h"

#define FRQ(x_) (x_)

struct sig_fmt_t
{
    enum { max_ch=12, max_samples=2048};

    unsigned int ch;
    unsigned int num_samples;

    char samples[max_ch][max_samples];
};

class AdTestDataGenerator::Implementation
{
public:
    float cwFrequency;
    float cwLevel;
    float cwJitter;
    float phaseJitter;
    float noiseFrequency;
    float noiseLevel;
    float acq_time;
    unsigned int samples;
    unsigned int ch;

    Implementation():
        cwFrequency(5),
        cwLevel(1),
        cwJitter(0),
        phaseJitter(0.1),
        noiseFrequency(10),
        noiseLevel(0.2),
        samples(2048),
        ch(1)
    {
    }

    void generate(char* data)
    {
        static float jitter=0;
        static float phJitter=0;

        float dt=1.0f/float(samples);
        float t=0;
        float nl=cwLevel*noiseLevel;
        float level=1+nl;
        float scale=127.0f/level;
        float f=cwFrequency+jitter;
        jitter+=0.1;
        if (jitter>cwJitter)
            jitter=0;

        t=dt*phJitter;
        phJitter+=phaseJitter;
        if (phJitter>(samples/2))
            phJitter=0;

        for(unsigned int i=0; i<samples; ++i)
        {
            //yc1=cos(2*pi*ff*t+ph)+1j*sin(2*pi*ff*t+ph)
            float v=cos(2*M_PI*f*t);
            float n=nl*cos(2*M_PI*noiseFrequency*t);
            float s=v+n;
            char d=s*scale;
            data[i]=d;
            t+=dt;
        }
    }
};



AdTestDataGenerator::AdTestDataGenerator(QObject *parent):
    TestDataGenerator(parent),
    p_(*new Implementation)
{
    setObjectName("AdTstWaveform");
    m_name="AD";
}

AdTestDataGenerator::~AdTestDataGenerator()
{
    delete &p_;
}

unsigned int AdTestDataGenerator::formatMarker() const
{
    return 0x5771414L;
}

bool AdTestDataGenerator::completed() const
{
    return false;
}

int AdTestDataGenerator::numberOfBatches() const
{
    return 0;
}

unsigned int AdTestDataGenerator::generateNextBatch(void *data, unsigned int max_data_size, const RepFpgaProgramData *cfg)
{
    //sig_fmt_t& out=*reinterpret_cast<sig_fmt_t*>(data);
    //out.ch=1;
    //out.num_samples=p_.samples;
    //p_.generate(&out.samples[0][0]);
    RepFpgaSignal& s=*reinterpret_cast<RepFpgaSignal*>(data);

    if (max_data_size<sizeof s)
        return 0;

    //s.msgHeader=cfg->msgHeader;
    //s.msgHeader.len=sizeof s;
    s.fpgaHeader.dspHeader=cfg->dspHeader;
    s.fpgaHeader.acq_channel=RepFpgaSignalHeaderData::acq_ch_sum;
    s.fpgaHeader.signal_format=RepFpgaSignalHeaderData::sig_fmt_sweep;

    unsigned int rbins=s.fpgaHeader.dspHeader.rbins;
    if (rbins>2048)
        rbins=2048;

    s.fpgaHeader.dspHeader.rbins=2048;
    p_.generate((char*)s.data);

    return sizeof s;
}

float AdTestDataGenerator::noiseFrequency() const
{
    return p_.noiseFrequency;
}
void AdTestDataGenerator::setNoiseFrequency(float f)
{
    p_.noiseFrequency=f;
}

float AdTestDataGenerator::noiseLevel() const
{
    return p_.noiseLevel;
}

void AdTestDataGenerator::setNoiseLevel(float v)
{
    p_.noiseLevel=v;
}

float AdTestDataGenerator::phaseJitter() const
{
    return p_.phaseJitter;
}
void AdTestDataGenerator::setPhaseJitter(float v)
{
    p_.phaseJitter=v;
}

float AdTestDataGenerator::cwFrequency() const
{
    return p_.cwFrequency;
}

void AdTestDataGenerator::setCwFrequency(float f)
{
    p_.cwFrequency=f;
}

float AdTestDataGenerator::cwJitter() const
{
    return p_.cwJitter;
}

void AdTestDataGenerator::setCwJitter(float v)
{
    p_.cwJitter=v;
}

float AdTestDataGenerator::spuriousFrequency() const
{
    return 0;
}

void AdTestDataGenerator::setSpuriousFrequency(float)
{
}
