00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef _VRPOINTSINK_H_
00023 #define _VRPOINTSINK_H_
00024
00025 #include <VrSink.h>
00026 #include "VrGUI.h"
00027
00028 #define DEBUG1 0
00029 #define DEBUG2 0
00030
00031 extern "C" {
00032 #include <dlfcn.h>
00033 #include <float.h>
00034 #include <math.h>
00035 }
00036
00037 #define XAXIS_NAME "In-phase"
00038 #define YAXIS_NAME "Quadrature"
00039
00040 enum PointSinkState { TRIGGER_SETTING, TRIGGER_WAITING, DISPLAYING, SKIPPING };
00041
00042 class VrPointSink : public VrSink<VrComplex> {
00043
00044 public:
00045 virtual const char *name() { return "VrPointSink"; }
00046 virtual void initialize();
00047 void clear() {display->clear(); }
00048 void set_persistent(int arg_persistent) {display->set_persistent(arg_persistent); }
00049 virtual int work(VrSampleRange output,
00050 VrSampleRange inputs[], void *i[]);
00051 static const int maxnPoints = 1000;
00052 VrPointSink(VrGUILayout *layout,
00053 int arg_min, int arg_max, int arg_nPoints = maxnPoints, int arg_no_wait = 0);
00054
00055 void setRun(int r) {run = r;};
00056 void setSkip(int arg_inc, int arg_between);
00057 void setPoints(int arg_nPoints);
00058 static const int divisions = 10;
00059
00060 private:
00061 double tpd;
00062 double samplingFrequency;
00063 int samplesAvailable;
00064 int skipWork;
00065 int skipIncrement;
00066 int skipBetween;
00067 int nPoints;
00068 int current_nPoints;
00069 int run;
00070
00071 VrGUIPlot *display;
00072 int ymin, ymax;
00073 int xmin, xmax;
00074 VrComplex sampleValue;
00075 double trigger;
00076
00077 PointSinkState state;
00078 PointSinkState prevState;
00079
00080 double maxAmplitude;
00081 int triggerCount;
00082
00083 int nextPoint;
00084 double *xValues;
00085 double *yValues;
00086 int no_wait;
00087 int first_time_collect;
00088
00089
00090
00091 void collectData(VrComplex *i[]);
00092 void skipData(VrComplex *i[]);
00093
00094 };
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104 VrPointSink::VrPointSink(VrGUILayout *layout,
00105 int arg_min, int arg_max, int arg_nPoints, int arg_no_wait)
00106 {
00107 nPoints = arg_nPoints;
00108 current_nPoints = nPoints;
00109 yValues = new double[nPoints+1];
00110 xValues = new double[nPoints];
00111 no_wait = arg_no_wait;
00112 ymin = arg_min;
00113 ymax = arg_max;
00114 xmin = 3*arg_min/2;
00115 xmax = 3*arg_max/2;
00116
00117 display = new VrGUIPlot (layout, XAXIS_NAME, YAXIS_NAME, 0,
00118 xmin, xmax, ymin, ymax, nPoints, divisions);
00119 setOptimalSize(nPoints);
00120 }
00121
00122 void
00123 VrPointSink::initialize()
00124 {
00125 samplingFrequency = getInputSamplingFrequencyN(0)/1000000;
00126 setSkip(1,0);
00127 run =1 ;
00128 }
00129
00130 int
00131 VrPointSink::work(VrSampleRange output,
00132 VrSampleRange inputs[], void *ai[])
00133 {
00134 VrComplex **i = (VrComplex **)ai;
00135 sync(output.index);
00136 samplesAvailable = output.size;
00137 while (samplesAvailable > 0) {
00138 switch (state) {
00139 case TRIGGER_SETTING:
00140 break;
00141 case TRIGGER_WAITING:
00142 break;
00143 case DISPLAYING:
00144 collectData(i);
00145 break;
00146 case SKIPPING:
00147 skipData(i);
00148 break;
00149 }
00150 }
00151 return output.size;
00152 }
00153
00154 #if 0
00155
00156
00157
00158 void
00159 VrPointSink::setTrigger(iType *i[]) {
00160 if (prevState != state) {
00161 #if DEBUG1
00162 cerr << "Setting trigger value." << endl;
00163 #endif
00164 prevState = state;
00165 triggerCount = TRIGGER_SAMPLES;
00166 maxAmplitude = (double)ymin;
00167 }
00168 if (triggerCount-- <= 0) {
00169 trigger = TRIGGER_SENSITIVITY*maxAmplitude;
00170 state = TRIGGER_WAITING;
00171 } else {
00172
00173 sampleValue = (int)*i[0]++;
00174 samplesAvailable--;
00175 if (sampleValue > maxAmplitude) maxAmplitude = (double)sampleValue;
00176 }
00177 }
00178
00179
00180
00181
00182
00183
00184 void
00185 VrPointSink::findTrigger(iType *i[]) {
00186 if (prevState != state) {
00187 #if DEBUG1
00188 cerr << "Waiting for trigger value." << endl;
00189 #endif
00190 prevState = state;
00191 triggerCount = TRIGGER_SAMPLES;
00192 sampleValue = ymax;
00193 }
00194 if (triggerCount-- <= 0) {
00195 state = TRIGGER_SETTING;
00196 } else {
00197 int lastValue = sampleValue;
00198 sampleValue = (int)*i[0]++;
00199 samplesAvailable--;
00200 if (sampleValue > trigger && sampleValue > lastValue) state = DISPLAYING;
00201 }
00202 }
00203 #endif
00204
00205
00206
00207
00208
00209 void
00210 VrPointSink::collectData(VrComplex *i[]) {
00211
00212 if (first_time_collect) {
00213 #if DEBUG1
00214 cerr << "Acquiring data." << endl;
00215 #endif
00216 prevState = state;
00217 nextPoint = 0;
00218 skipWork = skipIncrement + skipBetween;
00219 first_time_collect = 0;
00220 }
00221 if (nextPoint <= current_nPoints) {
00222
00223 while (skipWork > 0) {
00224 if (samplesAvailable-- <= 0) return;
00225 sampleValue = *i[0]++;
00226 skipWork--;
00227 }
00228 xValues[nextPoint] = real(sampleValue);
00229 yValues[nextPoint++] = imag(sampleValue);
00230 skipWork = skipIncrement;
00231 }
00232 if (nextPoint >= current_nPoints) {
00233 if (run) display->data(xValues, yValues, current_nPoints);
00234 first_time_collect = 1;
00235 if (!no_wait)
00236 state = SKIPPING;
00237 }
00238 }
00239 void
00240 VrPointSink::setSkip(int arg_inc, int arg_between)
00241 {
00242 skipIncrement = arg_inc;
00243 skipBetween = arg_between;
00244
00245 state = TRIGGER_WAITING;
00246 if (no_wait)
00247 state = DISPLAYING;
00248 first_time_collect = 1;
00249 triggerCount = 0;
00250 }
00251 void
00252 VrPointSink::setPoints(int arg_nPoints)
00253 {
00254 if (arg_nPoints < nPoints)
00255 current_nPoints = arg_nPoints;
00256
00257
00258 }
00259
00260 void
00261 VrPointSink::skipData(VrComplex *i[]) {
00262 if (prevState != state) {
00263 prevState = state;
00264 #if DEBUG1
00265 cerr << "Skipping data." << endl;
00266 #endif
00267 }
00268 state = TRIGGER_WAITING;
00269
00270 }
00271 #if 0
00272
00273 void
00274 VrPointSink::~VrPointSink()
00275 {
00276 delete[] xValues;
00277 delete[] yValues;
00278 }
00279
00280 #endif
00281 #endif
00282
00283
00284
00285