Main Page | Namespace List | Class Hierarchy | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

VrPointSink.h

Go to the documentation of this file.
00001 /* -*- Mode: c++ -*- 00002 * 00003 * Copyright 1999 Massachusetts Institute of Technology 00004 * 00005 * Permission to use, copy, modify, distribute, and sell this software and its 00006 * documentation for any purpose is hereby granted without fee, provided that 00007 * the above copyright notice appear in all copies and that both that 00008 * copyright notice and this permission notice appear in supporting 00009 * documentation, and that the name of M.I.T. not be used in advertising or 00010 * publicity pertaining to distribution of the software without specific, 00011 * written prior permission. M.I.T. makes no representations about the 00012 * suitability of this software for any purpose. It is provided "as is" 00013 * without express or implied warranty. 00014 * 00015 */ 00016 00017 /* 00018 * Interface to a Virtual Radio sink connected to a GUI for a constellation plot. 00019 * VrPointSink inherits from VrSink, whereas VrGUI inherits from QWidget. 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; // number of points to plot 00052 VrPointSink(VrGUILayout *layout, 00053 int arg_min, int arg_max, int arg_nPoints = maxnPoints, int arg_no_wait = 0); 00054 //void ~VrPointSink(); 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; // number of x-axis divisions 00059 00060 private: 00061 double tpd; // time per x-axis division (microseconds) 00062 double samplingFrequency; // samples/microsecond 00063 int samplesAvailable; // for work procedure 00064 int skipWork; 00065 int skipIncrement; 00066 int skipBetween; 00067 int nPoints; // max number of points to plot 00068 int current_nPoints; // number of points to plot 00069 int run; 00070 00071 VrGUIPlot *display; 00072 int ymin, ymax; // possible range of sample values 00073 int xmin, xmax; // possible range of sample values 00074 VrComplex sampleValue; // value of last sample 00075 double trigger; // amplitude to trigger new display 00076 00077 PointSinkState state; // how next sample will be used 00078 PointSinkState prevState; // how last sample was used 00079 // TRIGGER_SETTING, TRIGGER_WAITING 00080 double maxAmplitude; // base for setting new trigger 00081 int triggerCount; // samples to check before resetting trigger 00082 // DISPLAYING 00083 int nextPoint; // index of next point to generate for graph 00084 double *xValues; 00085 double *yValues; 00086 int no_wait; 00087 int first_time_collect; 00088 00089 // void setTrigger(iType *i[]); 00090 // void findTrigger(iType *i[]); 00091 void collectData(VrComplex *i[]); 00092 void skipData(VrComplex *i[]); 00093 00094 }; 00095 00096 /***************************************************************************** 00097 * Implementation of template (C++ requires it to be in .h file). 00098 ****************************************************************************/ 00099 00100 00101 /* 00102 * Creates a new VrPointSink. 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 //trigger = ymax/TRIGGER_SENSITIVITY; // set high to force recomputation 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 * Records maximum amplitude of signal seen in TRIGGER_SAMPLES settings. 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 * If triggerCount > 0, gets the next sample and compares it with both the 00181 * last sample and the trigger. Sets the state to DISPLAYING if it is 00182 * greater than both. Sets the state to TRIGGER_SETTING if triggerCount = 0. 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 * Acquires the next point to plot on the graph. Displays the graph when 00207 * all points are acquired. 00208 */ 00209 void 00210 VrPointSink::collectData(VrComplex *i[]) { 00211 //cout << "collect data: " << nextPoint << " " << current_nPoints << endl; 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 // Fix: have source skip proper number of values instead of using a loop 00223 while (skipWork > 0) { 00224 if (samplesAvailable-- <= 0) return; 00225 sampleValue = *i[0]++; // Fix: eliminate loop? just bump counter? 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); // mlw 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 // else 00257 // printf (stderr, "setPoints %d exceeds max %d\n", arg_nPoints, nPoints); 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 // Fix: tell the scheduler to ignore some number of samples 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

Generated on Wed Aug 4 02:22:05 2004 for GNU Radio by doxygen 1.3.8