/*******************************************************************************
* 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;
}