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

VrComplexPlotSink.h

Go to the documentation of this file.
00001 /* -*- Mode: c++ -*-
00002  *
00003  *  Copyright 1997 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 #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 //#if PULSE_VERSION
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 //#endif /* PULSE_VERSION */
00052 //jca #if LOG_SYMBOLS
00053   char *data_ptr, *cur_data_ptr;
00054 //jca #endif
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 //jca #if LOG_SYMBOLS
00075   char* getRcvdData(){ cur_data_ptr = data_ptr; return data_ptr;}
00076 //jca #endif
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) {        /* PULSE_VERSION */
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                 //                      temp = temp * VrComplex(real(est_theta), -imag(est_theta));
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) {    /* PULSE_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                 }                                       /* PULSE_VERSION */
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       } /* while (length-- > 0) */
00148 #if (PLOT | PARTIAL_PLOT)
00149       finish_plot();
00150 #endif
00151     } /* while (size-- > 0) */
00152   }
00153   else {                /* if !symbol_sync */
00154     //    get_initial_sync();
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 /* !EIGHT */
00180 #define OUTER (1)
00181 #define INNER2 (slice > neg_threshold)
00182 #ifdef TWO
00183 #define MID (1)
00184 #define INNER (slice > 0)
00185 #else /* !TWO */
00186 #define MID (slice > 0)
00187 #define INNER (slice > pos_threshold)
00188 #endif /* TWO */
00189 #endif /* EIGHT */
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   //      cout <<  (int)(symbol);
00207   return symbol;
00208 }
00209 
00210 void
00211 VrComplexPlotSink::do_correlation(int N, int B) /* PULSE_VERSION */
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   //correction = VrComplex( cos( arg(sqrt(sum))), sin( arg(sqrt(sum))));
00246   correction = sqrt ( sum / sqrt((real(sum)*real(sum) + imag(sum)*imag(sum))));
00247   cout << 180.0 / M_PI * arg((correction)) << endl;
00248   //    sum = 0;
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) {           /* 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 {                                        /* PULSE_VERSION */
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 //jca #if LOG_SYMBOLS
00341   data_ptr = new char[MAX_SYMBOLS];
00342   cur_data_ptr = data_ptr;
00343 //jca #endif
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 /* divisions*/);
00360 }
00361 #endif

Generated on Tue Mar 15 23:47:08 2005 for GNU Radio by  doxygen 1.4.0