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