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