/******************************************************************************* * SigGen.cpp Signal Generator classes * T.Barnaby, BEAM Ltd, 2006-09-12 * updated by D.Korchagin, CERN AB-BI-SW, 2007-08-31 ******************************************************************************* */ #include <SigGen.h> #include <math.h> #include <time.h> #ifndef __Lynx__ #else #define round(x) ((x)>=0?(long)((x)+0.5):(long)((x)-0.5)) #endif #define DEBUG 0 #if DEBUG #define dprintf(fmt, a...) printf(fmt, ##a); #else #define dprintf(fmt, a...) #endif BSignal::BSignal(int id, int numSamples, int numRepeat, int nextId){ int i; this->id = id; this->numSamples = numSamples; this->numRepeat = numRepeat; this->nextId = nextId; for(i = 0; i < NumChannels; i++){ data[i] = new Sample[this->numSamples]; memset(data[i], 0, this->numSamples * sizeof(Sample)); } } BSignal::BSignal(const BSignal& sig){ int i; id = sig.id; numSamples = sig.numSamples; numRepeat = sig.numRepeat; nextId = sig.nextId; for(i = 0; i < NumChannels; i++){ data[i] = new Sample[this->numSamples]; memcpy(data[i], sig.data[i], this->numSamples * sizeof(Sample)); } } BSignal::~BSignal(){ int i; for(i = 0; i < NumChannels; i++){ delete [] data[i]; } } BSignal& BSignal::operator=(const BSignal& sig){ int i; id = sig.id; numSamples = sig.numSamples; numRepeat = sig.numRepeat; nextId = sig.nextId; for(i = 0; i < NumChannels; i++){ delete [] data[i]; } for(i = 0; i < NumChannels; i++){ data[i] = new Sample[this->numSamples]; memcpy(data[i], sig.data[i], this->numSamples * sizeof(Sample)); } return *this; } SigGen::SigGen(){ osampleRate = 48000; ox = 0; } SigGen::~SigGen(){ } BError SigGen::config(double sampleRate){ BError err; osampleRate = sampleRate; ox = 0; return err; } BError SigGen::generate(Sample* data, int numSamples){ BError err; return err; } SigGenSine::SigGenSine(){ } SigGenSine::~SigGenSine(){ } BError SigGenSine::config(double sampleRate, double freq, double amplitude){ BError err; SigGen::config(sampleRate); ofreq = freq; oamplitude = amplitude; return err; } BError SigGenSine::generate(Sample* data, int numSamples){ BError err; int i; for(i = 0; i < numSamples; i++, ox++){ data[i] = oamplitude * sin(ox * 2.0 * M_PI * ofreq / osampleRate); } return err; } SigGenSquare::SigGenSquare(){ } SigGenSquare::~SigGenSquare(){ } BError SigGenSquare::config(double sampleRate, double freq, double amplitude, double offset){ BError err; SigGen::config(sampleRate); ofreq = freq; oamplitude = amplitude; ooffset = offset; return err; } BError SigGenSquare::generate(Sample* data, int numSamples){ BError err; int i; for(i = 0; i < numSamples; i++, ox++){ if(sin(ox * 2.0 * M_PI * ofreq / osampleRate) > 0.1) data[i] = ooffset + oamplitude; else data[i] = ooffset - oamplitude; } return err; } SigGenNoise::SigGenNoise(){ } SigGenNoise::~SigGenNoise(){ } BError SigGenNoise::config(double sampleRate, double amplitude){ BError err; SigGen::config(sampleRate); oamplitude = amplitude; return err; } BError SigGenNoise::generate(Sample* data, int numSamples){ BError err; int i; for(i = 0; i < numSamples; i++, ox++){ data[i] = oamplitude * double(rand() - (RAND_MAX / 2)) / (RAND_MAX / 2); } return err; } SigGenPulse::SigGenPulse(){ } SigGenPulse::~SigGenPulse(){ } BError SigGenPulse::config(double sampleRate, double freq, double amplitude, double onTime, double startTime){ BError err; SigGen::config(sampleRate); ofreq = freq; oamplitude = amplitude; oonTime = onTime; ostartTime = startTime; return err; } BError SigGenPulse::generate(Sample* data, int numSamples){ BError err; int i; int x; int xRepeat; int xStart; int xEnd; xRepeat = int(round(osampleRate / ofreq)); x = ox % xRepeat; xStart = int(ostartTime * osampleRate); xEnd = xStart + int(oonTime * osampleRate); for(i = 0; i < numSamples; i++, ox++, x++){ if(((x % xRepeat) >= xStart) && ((x % xRepeat) < xEnd)) data[i] = oamplitude; else data[i] = 0; } return err; } SigGenBeam::SigGenBeam(){ oharmonic = 0; oblr = 0; oreduce = 0; } SigGenBeam::~SigGenBeam(){ } BError SigGenBeam::config(double sampleRate, double fref, int harmonic, int bunchSet, double reduce, int blr, double amplitude){ BError err; SigGen::config(sampleRate); oharmonic = harmonic; oamplitude = amplitude; ofref = fref; oblr = blr; obunchSet = bunchSet; oreduce = reduce; return err; } BError SigGenBeam::generate(Sample* data, int numSamples){ BError err; int i; double sigma; double d,t,y,b=0; int bunch; double m = 1.0; d = 1/ofref/oharmonic; sigma = 300.0e-9 / oharmonic; // Get start conditions right for repetative output b = 0.126144; for(i = 0; i < numSamples; i++, ox++){ t = fmod((double)ox/osampleRate, (double)1/ofref) - 0.5 / ofref; y = 0; for(bunch = 0; bunch < oharmonic; bunch++){ if(obunchSet & (1 << bunch)){ if(oreduce){ m = 1.0 - ((bunch * (1.0 - oreduce)) / oharmonic); } y += m * exp(-0.5 * pow((t + (oharmonic/2 - bunch - 0.5) * d) / sigma, 2.0)); } } if(oblr) b = 0; else b = 0.99 * b + 0.01 * y; // Baseline // data[i] = oamplitude * 0.05 * oharmonic * (y - b); data[i] = oamplitude * (y - b); } // printf("BaseLine: %f Fref: %f\n", b, ofref); return err; } BError SigGenBeam::generateIntegrated(Sample* data, int numSamples){ BError err; int i; int bunch; int nbunches = 0; for(i = 0; i < oharmonic; i++){ if(obunchSet & (1 << i)){ nbunches++; } } for(i = 0; i < numSamples; i++, ox++){ bunch = ox % nbunches; data[i] = oamplitude / (bunch + 1); } return err; }