Main Page | Namespace List | Class Hierarchy | Class List | 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 Wed Aug 4 02:22:05 2004 for GNU Radio by doxygen 1.3.8