00001
00002
00003
00004
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;
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
00045 char* data_ptr, *cur_data_ptr;
00046
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
00077
00078
00079 size -= samples_per_bit;
00080
00081 if(!sync_mode){
00082 input_symbol = *i[0]++;
00083
00084
00085 if ((skip_count++) == skip_length-1){
00086
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 }
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
00224
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
00252 symbol_count = 0;
00253 data_ptr = new char[MAX_SYMBOLS];
00254 cur_data_ptr = data_ptr;
00255
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
00289
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
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