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

VrDigMod.h

Go to the documentation of this file.
00001 /* -*- Mode: c++ -*- 
00002  *
00003  *
00004  *     Digital Modulator: QAM, PAM, BPSK 
00005  */
00006 
00007 
00008 #ifndef _VRDIGMOD_H_
00009 #define _VRDIGMOD_H_
00010 
00011 #include <VrInterpolatingSigProc.h>
00012 
00013 #define TAP_RANGE            1024.0 //  = 2^TAP_RANGE_EXP 
00014 #define TAP_RANGE_EXP          10
00015 #define SYMBOL_FOR_ONE          1
00016 #define MAX_SYMBOLS        100000
00017 #define LOG_SYMBOLS             0
00018 
00019 int power(int base,int exp){ 
00020   int result=1; 
00021   for (int i=0; i< exp; i++)
00022     result *= base;
00023   return result;
00024 } 
00025 
00026 template<class iType,class oType> 
00027 class VrDigMod : public VrInterpolatingSigProc<iType,oType> {
00028 protected:
00029   int samples_per_bit, k, num_symbols, fr_mult, freq_band, bit_rate;  /* num_symbols = a power of 2 */
00030   float center_freq, amplitude;                     
00031   float sym_phase[32], sym_ampl[32], alpha;
00032   unsigned int last_k_symb, buffer_mask;
00033   int custom_symbols;
00034   oType* wavetable;
00035   int sync_count, skip_count, sync_length, skip_length, sync_mode;
00036   int sync_high, sync_low;
00037   iType *sync_symbol;
00038   double* p_t;
00039   unsigned int buffer_length;
00040   virtual void initialize();
00041   virtual void inc_place_symbol(int[]);
00042   virtual void calc_prototype();
00043   virtual void fill_wavetable(double*);
00044 //jca #if LOG_SYMBOLS
00045   char* data_ptr, *cur_data_ptr;
00046 //jca #endif
00047   int symbol_count;
00048 public:   
00049   virtual const char *name() { return "VrDigMod"; }
00050   virtual void change_constellation(float, float, int, int, float*, float*,int);
00051   virtual void set_sync_symbols(int, int);
00052   virtual int work(VrSampleRange output, void *o[],
00053                    VrSampleRange inputs[], void *i[]);
00054   char* getOriginal() {symbol_count = 0;
00055         cur_data_ptr = data_ptr;
00056         return data_ptr;
00057         };
00058   int getNumSymbols() {return symbol_count;};
00059   VrDigMod(int, float, float);
00060   VrDigMod(int, float, float, int, float[], float[]);
00061   VrDigMod(int, float, float, int, float[], float[], int, float, int);
00062 };
00063 
00064 template<class iType,class oType> int
00065 VrDigMod<iType,oType>::work(VrSampleRange output, void *ao[],
00066                                 VrSampleRange inputs[], void *ai[])
00067 {
00068   iType **i = (iType **)ai;
00069   oType **o = (oType **)ao;
00070   int size = output.size;
00071   iType input_symbol; 
00072   oType *output_ptr;
00073   int j;
00074 
00075   while (size > 0) {
00076     //size -= samples_per_bit;
00077     // this code assumes that input_symbols is in range: [0..(num_symbols-1)]
00078         //    input_symbol = *i[0]++;
00079       size -= samples_per_bit;
00080 
00081     if(!sync_mode){
00082       input_symbol = *i[0]++;
00083       //      size -= samples_per_bit;
00084       //cout << skip_count << endl;
00085       if ((skip_count++) == skip_length-1){
00086         //cout << "start sync soon" << endl;
00087         sync_mode = 1;
00088         skip_count = 0;
00089       }
00090     } else {
00091       input_symbol = *(sync_symbol+sync_count++);
00092       if (sync_count==sync_length){
00093         sync_mode = 0;
00094         sync_count = 0;
00095       } 
00096     }
00097 
00098 #if LOG_SYMBOLS
00099         if (cur_data_ptr < &data_ptr[MAX_SYMBOLS])
00100         *cur_data_ptr++ = input_symbol;
00101     symbol_count++;
00102 #endif
00103 if (input_symbol < 0 || input_symbol >= num_symbols) {
00104 printf ("bad input symbol %d (max %d)\n", input_symbol, num_symbols);
00105 input_symbol = 0;
00106 }
00107     last_k_symb = ((last_k_symb * num_symbols) + (input_symbol)) & buffer_mask;
00108 if ((last_k_symb+1) * samples_per_bit > buffer_length) {
00109 printf ("index too large (%d+1) * %d = %d (max %d)\n", last_k_symb, samples_per_bit,
00110 (last_k_symb+1) * samples_per_bit, buffer_length);
00111 }
00112 
00113     output_ptr = wavetable + (last_k_symb * samples_per_bit); 
00114         j = samples_per_bit;
00115     while (j--)
00116                 *o[0]++= *output_ptr++;    
00117   } /* while (size-- > 0) */
00118   return output.size;
00119 }
00120 
00121 template<class iType,class oType> void
00122 VrDigMod<iType,oType>::inc_place_symbol(int place_symbol[])
00123 {
00124 
00125   place_symbol[0]++;
00126   for(int i=0;i<k-1;i++)
00127     if(place_symbol[i]==num_symbols){
00128       place_symbol[i]=0;
00129       place_symbol[i+1]++;
00130     }
00131 }
00132 
00133 template<class iType,class oType> void
00134 VrDigMod<iType,oType>::calc_prototype()
00135 {
00136   
00137   float time, Tb, Ts, fr_c;
00138   int bit_rate, out_sample_rate, tmp_i;
00139   const double pi = (double) M_PI;
00140   float tmp_a, tmp_p;
00141 
00142   cout << "Calc_prototype..." << endl;
00143   bit_rate = (int)getInputSamplingFrequencyN(0);
00144   out_sample_rate = (int)getSamplingFrequency();
00145 
00146   Tb = 1/ (double) bit_rate;
00147   Ts = 1/ (double) out_sample_rate;
00148   fr_c = freq_band * fr_mult * getInputSamplingFrequencyN(0);
00149 
00150   for (int symbol=0; symbol < num_symbols; symbol++){
00151     for (int i=0;i< k; i++){
00152       for (int j=0;j< samples_per_bit; j++){
00153 
00154         time = ((-1)*k/2*Tb) + (Ts/2) + (Ts* ((double)(i*samples_per_bit) +(double)j));
00155 
00156     tmp_i = (symbol*k+i)*samples_per_bit+j;
00157     tmp_a = sym_ampl[symbol] ;
00158     tmp_p = sym_phase[symbol] ;
00159 
00160 #if 1
00161     p_t[tmp_i] = (double) (tmp_a
00162                 * (cos(2*pi*fr_c*time+tmp_p))
00163                 * (sin(pi*time/Tb)/(pi*time/Tb))
00164                 * (cos(alpha*pi*time/Tb)/(1-((2*alpha*time/Tb)*(2*alpha*time/Tb)))) );
00165 #endif
00166 
00167 #if 0
00168         cout << "symbol: " << symbol << "    i: " << i << "    j: " << j << "  " <<
00169                  (double) p_t[(symbol*k+i)*samples_per_bit+j] << endl;
00170         cout << (double) p_t[(symbol*k+i)*samples_per_bit+j] << endl;
00171 #endif
00172       }
00173     }
00174   }
00175 }
00176 
00177 template<class iType,class oType> void
00178 VrDigMod<iType,oType>::fill_wavetable(double* proto)
00179 {  
00180   float temp;
00181   int *place_symbol;
00182 
00183   place_symbol = new int[k];
00184   for(int i=0;i<k;i++){ place_symbol[i]=0;} 
00185   printf("Fill wavetable...\n");
00186 
00187   for (int i=0;i<power(num_symbols,k);i++){
00188     for (int m=0;m<samples_per_bit;m++){
00189       temp =0.0;
00190       
00191       for (int n=0;n<k;n++){
00192 #if 0
00193                 cout << i << " " << m << " " << n << "     " << place_symbol[3] << " " << place_symbol[2] << " "
00194                         << place_symbol[1] << " " << place_symbol[0] << " " << endl;
00195 #endif
00196                 temp+= proto[((place_symbol[n]*k+n)*samples_per_bit)+m];
00197       }
00198       wavetable[(i)*samples_per_bit+m] = (oType) (amplitude * temp);
00199     }
00200     inc_place_symbol(place_symbol);
00201   }
00202 }
00203 
00204 template<class iType,class oType> void
00205 VrDigMod<iType,oType>::initialize()
00206 {
00207   int num_buffers;
00208 
00209   printf("Inititalize...\n");
00210   if (!custom_symbols){
00211     num_symbols = 4;
00212     sym_phase[0] =  0; sym_phase[1] =  0; sym_phase[2] =  0; sym_phase[3] =  0;
00213     sym_ampl[0]  =  -1.0; sym_ampl[1]  =  -1.0/3.0; sym_ampl[2]  =  1.0/3.0; sym_ampl[3]  =  1.0;
00214   }    
00215   last_k_symb = 0;
00216     
00217   buffer_mask = 0;
00218   num_buffers = power(num_symbols,k);
00219   buffer_mask = (unsigned int) num_buffers-1;  
00220 
00221   cout << "memory: " << k << "  buffers: " << num_buffers << "  mask: " << buffer_mask << endl;
00222 
00223   /* allocate and create prototype and wavetable */
00224   /* p_t will hold prototype pulse for EACH symbol over entire k-interval period*/ 
00225 
00226   p_t = new double[num_symbols*k*samples_per_bit];
00227   cout << "p_t is " << num_symbols << " x " << k << " x " << samples_per_bit << endl;
00228   calc_prototype();
00229   
00230   buffer_length = num_buffers * samples_per_bit;
00231   wavetable = new oType[buffer_length];
00232   fill_wavetable(p_t);
00233   cout << "wavetable buffer: " << sizeof(oType)*buffer_length << " bytes" << endl; 
00234 
00235   sync_count = 0;
00236   skip_count = 0;
00237   skip_length = 42;
00238   sync_length = 8;
00239   sync_mode = 1;
00240   sync_symbol = new iType[sync_length];
00241   
00242   sync_symbol[0] = 0;
00243   sync_symbol[1] = 0;
00244   sync_symbol[2] = 7;
00245   sync_symbol[3] = 7;
00246   sync_symbol[4] = 7;
00247   sync_symbol[5] = 7;
00248   sync_symbol[6] = 0;
00249   sync_symbol[7] = 0;
00250 
00251 //jca #if LOG_SYMBOLS
00252   symbol_count = 0;
00253   data_ptr = new char[MAX_SYMBOLS]; 
00254   cur_data_ptr = data_ptr;
00255 //jca #endif
00256 }
00257 
00258 
00259 template<class iType,class oType> void
00260 VrDigMod<iType,oType>::change_constellation(float alph, float a, int new_ns, int new_k,
00261                                             float sym_phs[], float sym_amp[], int fr_band)
00262 {
00263   int num_buffers;
00264 
00265   delete wavetable;
00266   delete p_t;
00267 
00268   freq_band = fr_band; 
00269   k = new_k;
00270   num_symbols = new_ns;
00271   printf("num symbols: %d\n",num_symbols);
00272   alpha = alph;
00273   amplitude = a;
00274 
00275   for (int i=0;i<num_symbols;i++){
00276     sym_phase[i] = sym_phs[i];
00277     sym_ampl[i] = sym_amp[i];
00278     printf(" symbol phase: %f    symbol amplitude: %f \n ",sym_phase[i],sym_ampl[i]);
00279   }
00280   last_k_symb = 0;
00281     
00282   buffer_mask = 0;
00283   num_buffers = power(num_symbols,k);
00284   buffer_mask = (unsigned int) num_buffers-1;  
00285 
00286   cout << "memory: " << k << "  buffers: " << num_buffers << "  mask: " << buffer_mask << endl;
00287 
00288   /* allocate and create prototype and wavetable */
00289   /* p_t will hold prototype pulse for EACH symbol over entire k-interval period*/ 
00290 
00291   p_t = new double[num_symbols*k*samples_per_bit];
00292   cout << "p_t is " << num_symbols << " x " << k << " x " << samples_per_bit << endl;
00293   calc_prototype();
00294   
00295   buffer_length = num_buffers * samples_per_bit;
00296   wavetable = new oType[buffer_length];
00297   fill_wavetable(p_t);
00298   cout << "wavetable buffer: " << sizeof(oType)*buffer_length << " bytes" << endl; 
00299 
00300 //jca #if LOG_SYMBOLS
00301   symbol_count = 0;
00302   data_ptr = new char[MAX_SYMBOLS]; 
00303   cur_data_ptr = data_ptr;
00304 }
00305 
00306 template<class iType,class oType> void 
00307 VrDigMod<iType,oType>::set_sync_symbols(int l, int h){
00308 
00309   sync_symbol[0] = l;
00310   sync_symbol[1] = l;
00311   sync_symbol[2] = h;
00312   sync_symbol[3] = h;
00313   sync_symbol[4] = h;
00314   sync_symbol[5] = h;
00315   sync_symbol[6] = l;
00316   sync_symbol[7] = l;
00317 }
00318 
00319 
00320 template<class iType,class oType> 
00321 VrDigMod<iType,oType>::VrDigMod(int i, float fc, float a)
00322   :VrInterpolatingSigProc<iType, oType>(1, i), center_freq(fc), amplitude(a)
00323 {
00324   custom_symbols = 0;
00325   samples_per_bit = interp;
00326   setOutputSize(samples_per_bit);
00327   k = 4;
00328   alpha = 0.3;
00329   fr_mult = 0;
00330   freq_band = 1;
00331 }
00332 
00333 template<class iType,class oType> 
00334 VrDigMod<iType,oType>::VrDigMod(int i, float fc, float a, int num_sym, float sym_phs[], float sym_amp[])
00335   :VrInterpolatingSigProc<iType, oType>(1, i), center_freq(fc), amplitude(a)
00336 {
00337   custom_symbols = 1;
00338   num_symbols = num_sym;
00339   printf("num symbols: %d\n",num_symbols);
00340   for (int i=0;i<num_symbols;i++){
00341     sym_phase[i] = sym_phs[i];
00342     sym_ampl[i] = sym_amp[i];
00343     printf(" symbol phase: %f    symbol amplitude: %f \n ",sym_phase[i],sym_ampl[i]);
00344   }
00345   samples_per_bit = interp;
00346   setOutputSize(samples_per_bit);
00347   k = 6;
00348   alpha = 0.3;
00349   fr_mult = 0;
00350   freq_band = 1;
00351   printf(" Done initialize!\n");
00352 }
00353 
00354 template<class iType,class oType> 
00355 VrDigMod<iType,oType>::VrDigMod(int i, float fc, float am, int num_sym, float sym_phs[], float sym_amp[], int K, float a, int fr)
00356   :VrInterpolatingSigProc<iType, oType>(1, i), k(K), center_freq(fc), amplitude(am),  alpha(a)
00357 {
00358   custom_symbols = 1;
00359   num_symbols = num_sym;
00360   printf("num symbols: %d\n",num_symbols);
00361   for (int i=0;i<num_symbols;i++){
00362     sym_phase[i] = sym_phs[i];
00363     sym_ampl[i] = sym_amp[i];
00364     printf(" symbol phase: %f    symbol amplitude: %f \n ",sym_phase[i],sym_ampl[i]);
00365   }
00366   samples_per_bit = interp;
00367   setOutputSize(samples_per_bit);
00368   fr_mult = fr;
00369   freq_band = 1;
00370 }
00371 #endif

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