00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef _VRCOMPLEXPLOTSINK_H_
00018 #define _VRCOMPLEXPLOTSINK_H_
00019
00020 #define PLOT 1
00021 #define PARTIAL_PLOT 0
00022 #define TWO 0
00023
00024 #include <stdio.h>
00025 #include "VrSkippingSink.h"
00026 #include "VrGUI.h"
00027
00028 #define MAX_SYMBOLS 100000
00029 #define SQR_HISTORY_OFFSET 20
00030 #define VRCOMPLEX_nPoints 100
00031 class VrComplexPlotSink : public VrSkippingSink<VrComplex> {
00032 protected:
00033 int sync_version;
00034 VrPulse<char,char> *sync_pointer;
00035 float timeDuration, slice;
00036 float pos_threshold, high_pos_threshold, low_pos_threshold;
00037 float neg_threshold, high_neg_threshold, low_neg_threshold;
00038 int size;
00039 VrGUILayout *layout;
00040 VrGUIPlot *display;
00041 int current_point_index;
00042 int N, flip, flip_c, plot, plot_count, symb_count, symbol_sync;
00043 VrComplex sum, old_conj;
00044 VrComplex sqr_hist[2*SQR_HISTORY_OFFSET], *current_sqr, *last_sqr;
00045 int data_ready_flag;
00046
00047 VrComplex *correlation_input, temp;
00048 int old_drf, oversample_interval, log_oversample_factor;
00049 int correlate_interval, input_size, corr_calc;
00050 double xValues[VRCOMPLEX_nPoints], yValues[VRCOMPLEX_nPoints];
00051
00052
00053 char *data_ptr, *cur_data_ptr;
00054
00055 public:
00056 VrComplexPlotSink(VrGUILayout *arg_layout, VrPulse<char, char>*, float td, int s);
00057 virtual ~VrComplexPlotSink() {}
00058 virtual const char *name() { return "VrComplexPlotSink"; }
00059 virtual void initialize();
00060 virtual int work3(VrSampleRange output,
00061 VrSampleRange inputs[], void *i[]);
00062 float getTimeDuration() {return timeDuration;}
00063 void setTimeDuration(float t) {
00064 timeDuration = t;
00065 history = ((int)(getInputSamplingFrequencyN(0) * timeDuration));
00066 }
00067 int getSize() {return size;}
00068 void setSize(int s) {size = s;}
00069 void do_correlation(int,int);
00070 char symbol_decision(float);
00071 void init_plot();
00072 void point_plot(VrComplex);
00073 void finish_plot();
00074
00075 char* getRcvdData(){ cur_data_ptr = data_ptr; return data_ptr;}
00076
00077 };
00078
00079 int
00080 VrComplexPlotSink::work3(VrSampleRange output,
00081 VrSampleRange inputs[], void *ai[])
00082 {
00083 VrComplex **i = (VrComplex **)ai;
00084 int size = output.size;
00085 int length=0;
00086 VrComplex temp, est_theta;
00087
00088 if (data_ready_flag) {
00089 cout << "Corr" << endl;
00090 display->clear();
00091 do_correlation(4,6);
00092 data_ready_flag = 0;
00093 getchar();
00094 }
00095 #if (PLOT | PARTIAL_PLOT)
00096 init_plot();
00097 #endif
00098 symbol_sync=1;
00099 if (symbol_sync) {
00100 while (size-- > 0) {
00101 length = history;
00102 while(length-- > 0) {
00103 temp = *i[0]++;
00104 *current_sqr = temp * temp;
00105 *(current_sqr-SQR_HISTORY_OFFSET) = temp * temp;
00106 sum = sum + *current_sqr - *(current_sqr-N);
00107 current_sqr++;
00108 if (current_sqr == last_sqr) current_sqr -= SQR_HISTORY_OFFSET;
00109 est_theta = sqrt ( sum / sqrt((real(sum)*real(sum) + imag(sum)*imag(sum))));
00110 if (real(old_conj*est_theta)<0) flip = -flip;
00111 old_conj = VrComplex(real(est_theta), -imag(est_theta));
00112
00113 if (flip <0) temp = -temp;
00114 slice = real(temp);
00115 symb_count++;
00116 if (symb_count%100000 == 0) cout << "100K" << endl;
00117 if (!sync_version) {
00118 if (symb_count == 10){
00119 cout << "try out high res " << endl;
00120 data_ready_flag = 0;
00121 sync_pointer -> start_oversampling(8, 6, 10,
00122 correlation_input, &data_ready_flag);
00123 }
00124 #if PULSE_VERSION && 0
00125 if (data_ready_flag == 1 && old_drf == 0) {
00126 cout << "Corr lag " << symb_count-corr_calc << endl;
00127 old_drf = 1;
00128 }
00129 if (symb_count%correlate_interval == 10) {
00130 cout << "Correlation" << endl;
00131 data_ready_flag = 0;
00132 old_drf = 0;
00133 sync_pointer -> start_oversampling(oversample_interval, log_oversample_factor,
00134 correlation_input, &data_ready_flag);
00135 cout << data_ready_flag << endl;
00136 corr_calc = symb_count;
00137 }
00138 #endif
00139 }
00140 #if LOG_SYMBOLS
00141 if (cur_data_ptr < &data_ptr[MAX_SYMBOLS])
00142 *cur_data_ptr++ = symbol_decision(-slice);
00143 #endif
00144 #if (PLOT | PARTIAL_PLOT)
00145 point_plot(temp);
00146 #endif
00147 }
00148 #if (PLOT | PARTIAL_PLOT)
00149 finish_plot();
00150 #endif
00151 }
00152 }
00153 else {
00154
00155 }
00156 return output.size;
00157 }
00158
00159 #if 0
00160 void
00161 VrComplexPlotSink::get_initial_sync()
00162 {
00163 data_ready_flag = 0;
00164 old_drf = 0;
00165 sync_pointer -> start_oversampling(oversample_interval, log_oversample_factor,
00166 correlation_input, &data_ready_flag);
00167 }
00168 #endif
00169
00170 char
00171 VrComplexPlotSink::symbol_decision(float slice)
00172 {
00173 char symbol;
00174 #ifdef EIGHT
00175 #define OUTER (slice > 0)
00176 #define MID (slice > pos_threshold)
00177 #define INNER (slice > high_pos_threshold)
00178 #define INNER2 (slice > low_pos_threshold)
00179 #else
00180 #define OUTER (1)
00181 #define INNER2 (slice > neg_threshold)
00182 #ifdef TWO
00183 #define MID (1)
00184 #define INNER (slice > 0)
00185 #else
00186 #define MID (slice > 0)
00187 #define INNER (slice > pos_threshold)
00188 #endif
00189 #endif
00190 if (OUTER)
00191 if (MID)
00192 if (INNER)
00193 symbol = 0x00;
00194 else symbol = 0x01;
00195 else
00196 if (INNER2)
00197 symbol = 0x02;
00198 else symbol = 0x03;
00199 else
00200 if (slice>neg_threshold)
00201 if (slice>high_neg_threshold) symbol = 0x04;
00202 else symbol = 0x05;
00203 else
00204 if (slice> low_neg_threshold) symbol = 0x06;
00205 else symbol = 0x07;
00206
00207 return symbol;
00208 }
00209
00210 void
00211 VrComplexPlotSink::do_correlation(int N, int B)
00212 {
00213 printf ("start do_correlation\n");
00214
00215 int tmp1, flip_c;
00216 float sum1;
00217 VrComplex sum;
00218 VrComplex correction, old_correction;
00219
00220 #if 0
00221 init_plot();
00222 for (int tmp = 0 ; tmp < N * (1 << B); tmp ++){
00223 point_plot( *(correlation_input+tmp) * (*(correlation_input+tmp)));
00224 }
00225 finish_plot();
00226 getchar();
00227 fprintf(fd,"plot [%d:%d][%d:%d] \"-\" w l\n",-size, size, -size, size);
00228 for (int tmp = 0 ; tmp < N * (1 << B); tmp ++){
00229 point_plot( *(correlation_input+tmp) * (*(correlation_input+tmp)));
00230 }
00231 finish_plot();
00232 getchar();
00233 #endif
00234
00235 #if 1
00236
00237 old_correction = VrComplex();
00238 flip_c =1;
00239
00240 sum = 0;
00241 for (int tmp = 0 ; tmp < oversample_interval * (1 << log_oversample_factor); tmp ++){
00242 sum += *(correlation_input+tmp) * (*(correlation_input+tmp));
00243 }
00244 cout << 180.0 / M_PI * arg(sqrt(sum)) << endl;
00245
00246 correction = sqrt ( sum / sqrt((real(sum)*real(sum) + imag(sum)*imag(sum))));
00247 cout << 180.0 / M_PI * arg((correction)) << endl;
00248
00249 for (int tmp = 0 ; tmp < (oversample_interval-8) * (1 << log_oversample_factor); tmp ++){
00250 sum1 = 0;
00251 for (tmp1 =0 ; tmp1 < 2 * (1 << log_oversample_factor); tmp1 ++)
00252 sum1 += real(*(correlation_input+tmp+tmp1) * correction);
00253 for (; tmp1 < 6 * (1 << log_oversample_factor); tmp1 ++)
00254 sum1 -= real(*(correlation_input+tmp+tmp1) * correction);
00255 for (; tmp1 < 8 * (1 << log_oversample_factor); tmp1 ++)
00256 sum1 += real(*(correlation_input+tmp+tmp1) * correction);
00257
00258 if (real(old_correction*correction)<0) flip_c = -flip_c;
00259 old_correction = VrComplex(real(correction), -imag(correction));
00260 temp = *(correlation_input+tmp) * VrComplex(real(correction), -imag(correction));
00261 if (flip_c <0) correction = -correction;
00262
00263 if (tmp < VRCOMPLEX_nPoints) {
00264 xValues[tmp] = tmp;
00265 yValues[tmp] = 2*sum1/8.0/(float)(1 << log_oversample_factor);
00266 }
00267 }
00268 display->data(xValues, yValues, VRCOMPLEX_nPoints);
00269 #endif
00270
00271 }
00272
00273 void
00274 VrComplexPlotSink::finish_plot()
00275 {
00276 #if PARTIAL_PLOT
00277 plot_count++;
00278 #endif
00279 display->data(xValues, yValues, VRCOMPLEX_nPoints);
00280 current_point_index = 0;
00281 }
00282 void
00283 VrComplexPlotSink::point_plot(VrComplex point)
00284 {
00285 if (current_point_index < VRCOMPLEX_nPoints) {
00286 #if PLOT
00287 xValues[current_point_index] = real(point);
00288 yValues[current_point_index++] = imag(point);
00289 #endif
00290 #if PARTIAL_PLOT
00291 if (plot) {
00292 xValues[current_point_index] = real(point);
00293 yValues[current_point_index++] = imag(point);
00294 }
00295 #endif
00296 }
00297 }
00298
00299 void
00300 VrComplexPlotSink::init_plot()
00301 {
00302 #if PLOT
00303 plot =1;
00304 #endif
00305 #if PARTIAL_PLOT
00306 plot = (plot_count%50 ==0);
00307 #endif
00308 current_point_index = 0;
00309 }
00310
00311 void
00312 VrComplexPlotSink::initialize()
00313 {
00314 float dummy;
00315
00316 increment = (int)(getInputSamplingFrequencyN(0) * timeDuration);
00317 history = increment;
00318 current_sqr = &sqr_hist[SQR_HISTORY_OFFSET];
00319 last_sqr = current_sqr + SQR_HISTORY_OFFSET;
00320 old_conj = VrComplex();
00321 flip =1;
00322 plot_count =0;
00323 symb_count = 0;
00324
00325 N = 5;
00326 for (int i = 0; i<2*SQR_HISTORY_OFFSET; i++)
00327 sqr_hist[i] = VrComplex();
00328 if (sync_version) {
00329 sync_pointer -> setSymbol_Timing((float)0.0);
00330 dummy = sync_pointer -> getSymbol_Period();
00331 sync_pointer -> setSymbol_Period(dummy*1.0);
00332 }
00333 else {
00334 log_oversample_factor = 4;
00335 oversample_interval = 60;
00336 correlate_interval = 2000;
00337 input_size = (1 << log_oversample_factor) * oversample_interval;
00338 correlation_input = (VrComplex *) new VrComplex[input_size];
00339 }
00340
00341 data_ptr = new char[MAX_SYMBOLS];
00342 cur_data_ptr = data_ptr;
00343
00344 pos_threshold = 0.7;
00345 neg_threshold = -0.7;
00346 high_pos_threshold = 1.1;
00347 low_pos_threshold = 0.4;
00348 high_neg_threshold = -0.4;
00349 low_neg_threshold = -1.1;
00350 }
00351
00352 VrComplexPlotSink::VrComplexPlotSink(VrGUILayout *arg_layout, VrPulse<char,char> *filter, float td, int s)
00353 :sync_pointer(filter),timeDuration(td),size(s)
00354 {
00355 data_ready_flag = 0;
00356 sync_version = sync_pointer->version();
00357 layout = arg_layout;
00358 display = new VrGUIPlot(layout, "real part", "imag part", 0, -size*2, size*2, -size, size, VRCOMPLEX_nPoints,
00359 10 );
00360 }
00361 #endif