waveform.h 6.65 KiB
#pragma once
#include "external/Eigen/Dense"
#include <string>
#include <set>
typedef Eigen::Vector<int16_t, Eigen::Dynamic> EigenVectorXi16;
/**
* @brief class for array waveform generation
*/
class ArrayWaveform {
private:
void* pDataBuffer; // points to a page aligned mem location where data is stored
int64_t dataLen; // length of waveform
struct WaveformParam {
unsigned long samplingRate;
unsigned long freqResolution;
Eigen::VectorXd freqTones;
Eigen::VectorXd phases;
Eigen::VectorXd amplitudes;
};
WaveformParam wfmParam;
/**
* @brief allocates a page-aligned memory buffer for waveform data
*
* @param bytes number of bytes to allocate
*/
void bindBuffer(int64_t bytes);
/**
* @brief frees pDataBuffer
*/
void unbindBuffer();
/**
* @brief generate a static frequency segment
*
* @param timeSeries reference to an array filled with timestamps
* @param f frequency
* @param initPhase initial phase
* @param amp amplitude
* @return ending phase of the segment
*/
double setStaticSegment(
Eigen::Ref<Eigen::VectorXd> timeSeries,
double f,
double initPhase,
double amp
);
/**
* @brief generate a dynamic frequency segment
*
* @param timeSeries reference to an array filled with timestamps
* @param fInit initial frequency
* @param fFinal final frequency
* @param initPhase initial phase
* @param amp amplitude
* @return end phase of the segment
*/
double setMovingSegment(
Eigen::Ref<Eigen::VectorXd> timeSeries,
double fInit,
double fFinal,
double initPhase,
double amp
);
public:
/**
* @brief default constructor, all private members are set to 0/nullptr
*/
ArrayWaveform();
/**
* @brief default destructor, calls unbindBuffer
*/
~ArrayWaveform();
/**
* @brief get the pointer to data buffer
*
* @return void* pointer to data buffer, nullptr if uninitialized
*/
void* getDataBuffer();
/**
* @brief get number of samples in current waveform
*
* @return int64_t number of samples
*/
int64_t getDataLen();
/**
* @brief set sampling rate
*
* @param sr sampling rate (Hz)
*/
void setSamplingRate(ulong sr);
/**
* @brief get sampling rate
*
* @return sampling rate (Hz)
*/
ulong getSamplingRate();
/**
* @brief set freqeuncy resolution
*
* @param fr frequency resolution (Hz)
*/
void setFreqResolution(ulong fr);
/**
* @brief get frequency resolution
*
* @return frequency resolution (Hz)
*/
ulong getFreqResolution();
/**
* @brief set array frequency tone
*
* @param centerFreq center frequency of array (Hz)
* @param freqSpacing freqeuncy spacing in the array (Hz)
* @param numTones total number of tones to generate
*/
void setFreqTone(
int centerFreq,
int freqSpacing,
int numTones
);
/**
* @brief set array frequency tone
*
* @param tones vector of frequency tones (Hz)
*/
void setFreqTone(const std::vector<int>& tones);
/**
* @brief get array frequency tone
*
* @return std::vector<double> vector of frequency tones (Hz)
*/
std::vector<double> getFreqTone();
/**
* @brief set intial phase of all tones
*
* @param phases range: [0 - 2pi)
*/
void setPhase(const std::vector<double>& phases);
/**
* @brief get intial phase of all tones
* @return vector of phases
*/
std::vector<double> getPhase();
/**
* @brief set amplitudes of all tones
*
* @param amplitudes range: [0, 2^15-1]
*/
void setAmplitude(const std::vector<double>& amplitudes);
/**
* @brief get amplitudes of all tones
*
* @return vector of amplitudes
*/
std::vector<double> getAmplitude();
/**
* @brief Set phases to 0 and amplitudes to 2000
*/
void setDefaultParam();
/**
* @brief save current waveform parameters to csv file
* csv has format:
* ----- col 0 | col 1 | ...
* row 0 samplignRate | |
* row 1 freqResolution | |
* row 2 freqTones[0] | freqTones[1] | ...
* row 3 phases[0] | phases[1] | ...
* row 4 amplitudes[0] | amplitudes[1] | ... */
void saveParam(std::string fileName);
/**
* @brief load waveform parameters from file
*
* @param fileName name of file to load from, must be of .csv
*/
void loadParam(std::string fileName);
/**
* @brief debugging helper to print current waveform parameters
*/
void printParam();
/**
* @brief get minimum data length that fulfills rounding
* requirements
* @param samplingRate sampling rate (Hz)
* @param freqResolution frequency resolution (Hz)
* @return number of samples
*/
ulong getMinSampleLen(ulong samplingRate, ulong freqResolution);
/**
* @brief get data length close to speficifed time and also
* fulfills rounding requirements
*
* @param tau time (s)
* @param samplingRate sampling rate (Hz)
* @param freqResolution frequency resolution (Hz)
* @return number of samples
*/
ulong getSampleLen(
double tau,
ulong samplingRate,
ulong freqResolution
);
/**
* @brief generate a static frequency waveform from current set
* of parameters
*
* @return std::pair(pDataBuffer: void*, dataLength: int64_t)
*/
std::pair<void*, int64_t> getStaticWaveform();
/**
* @brief generate a tricky-trick waveform from current set of
* parameters
*
* @param siteIndex index of array sites to perform tricky-trick
* @param df frequency to move by (Hz)
* @param tauMove moving time (s)
* @param tauStay wait time (s)
* @return std::pair(pDataBuffer: void*, dataLength: int64_t)
*/
std::pair<void*, int64_t> getTrickWaveform(
std::set<int> siteIndex,
double df,
double tauMove=0,
double tauStay=0
);
/**
* @brief save currently generated waveform to csv file
* csv has format:
* ----- col 0 | col 1 | col 2 | ...
* row 0 data0 | data1 | data2 | ...
* @param fileName name of file to save to, must be of .csv
*/
void saveWaveform(std::string fileName);
};
/**
* @brief class for arbitrary waveform generation
* @todo do this
*/
class ArbitraryWaveform {};