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