00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
#ifndef _VRPULSECORRELATOR_H_
00019
#define _VRPULSECORRELATOR_H_
00020
00021
#include <VrDecimatingSigProc.h>
00022
00023
#if defined (ENABLE_MMX)
00024
#include <VrMMX.h>
00025
#endif
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #define PRECISION_BITS 12
00040
00041
template<
class iType>
00042 class VrPulseCorrelator :
public VrDecimatingSigProc<iType,VrComplex> {
00043
protected:
00044 int num_taps,
bump;
00045 int shift_bits,
max_sample_count,
sample_count,
high_res,
middle_offset,
samples_per_symbol;
00046 int *
all_done,
high_res_start,
high_res_waiting;
00047 VrComplex*
taps;
00048 VrComplex phase_correction,
phase_corr_incr, *
over_sampled_result,
small_corr_incr;
00049 long time;
00050 int symbol_boundary,
symbol_period,
pointer_incr,
old_output_loc,
new_output_loc;
00051 float center_freq,
gain;
00052
void buildFilter_complex();
00053
#if defined (ENABLE_MMX)
00054
mmxTaps* processedTaps;
00055
#endif
00056
public:
00057 virtual const char *
name() {
return "VrPulseCorrelator"; }
00058
virtual int work(
VrSampleRange output,
VrComplex *o[],
00059
VrSampleRange inputs[],
iType *i[]);
00060
virtual void initialize();
00061
int setCenter_Freq(
float);
00062
int setNumber_Taps(
int);
00063
00064
float getSymbol_Period();
00065
int setSymbol_Period(
float);
00066
int setSymbol_Timing(
float);
00067
void start_oversampling(
int,
int,
int,
VrComplex*,
int*);
00068
VrPulseCorrelator(
int n,
float d,
const int t[],
const float f[],
00069
const float g[]);
00070
VrPulseCorrelator(
float d,
int t,
float f,
float g);
00071
~VrPulseCorrelator();
00072 int version() {
return 0; };
00073 };
00074
00075
template<
class iType>
int
00076 VrPulseCorrelator<iType>::work(
VrSampleRange output,
VrComplex *o[],
00077
VrSampleRange inputs[],
iType *i[])
00078 {
00079
unsigned int size = output.
size;
00080
VrComplex result = 0;
00081
int output_offset = 0;
00082
00083 cout <<
" enter Work in filter" << endl;
00084
for (
int i=0;i<size;) {
00085
00086
00087
00088
00089
if (
high_res_waiting & (
high_res_start-- == 0)) {
00090
high_res = 1;
00091
high_res_waiting = 0;
00092 }
00093
if (
high_res) {
00094
if (
sample_count == 1)
symbol_boundary +=
symbol_period;
00095
if (
sample_count % (1 <<
shift_bits) == 0)
symbol_boundary += symbol_period;
00096 output_offset = (
sample_count % (1 <<
shift_bits)) * (symbol_period >>
shift_bits);
00097
new_output_loc = (
symbol_boundary + output_offset) >>
PRECISION_BITS;
00098 }
else {
00099
symbol_boundary +=
symbol_period;
00100
new_output_loc = (
symbol_boundary + (symbol_period/2)) >>
PRECISION_BITS;
00101 }
00102
00103
pointer_incr =
new_output_loc -
old_output_loc;
00104
if (
pointer_incr <0) {
00105
00106
pointer_incr += (1 << (32-
PRECISION_BITS));
00107 }
00108
00109 old_output_loc =
new_output_loc;
00110
00111
if (
bump != 0) {
00112
symbol_boundary +=
bump;
00113 cout <<
"Bumping pointer " << (
float) (bump) / (
float)(1<<
PRECISION_BITS) << endl;
00114 bump =0;
00115 }
00116
00117 result = 0;
00118
00119
00120
iType *inputArray = i[0]+history+(-
num_taps+1);
00121
00122
#if defined (ENABLE_MMX)
00123
if(processedTaps->mmxReady())
00124 result = processedTaps->mmxCVDProduct(inputArray);
00125
else {
00126
VrComplex *taps_tmp =
taps;
00127
for (
int j=0; j <
num_taps; j++)
00128 result += taps_tmp[j] * inputArray[j];
00129 }
00130
#else
00131
VrComplex *taps_tmp =
taps;
00132
for (
int j=0; j <
num_taps; j++)
00133 result += taps_tmp[j] * inputArray[j];
00134
#endif
00135
00136
00137
if (
center_freq != 0.0) {
00138
if (
high_res){
00139
phase_correction *=
small_corr_incr;
00140 }
else {
00141
phase_correction *=
phase_corr_incr;
00142 }
00143 result *=
phase_correction;
00144 }
00145
if (
high_res) {
00146
over_sampled_result[
sample_count-1] = result;
00147
if ((
sample_count -
middle_offset) %
samples_per_symbol == 0) {
00148 i++;
00149 *o[0]++ = result;
00150 }
00151
sample_count++;
00152
if (
sample_count ==
max_sample_count) {
00153
sample_count = 1;
00154
high_res = 0;
00155 *
all_done = 1;
00156 }
00157 }
else {
00158 i++;
00159 *o[0]++ = result;
00160 }
00161 i[0] +=
pointer_incr;
00162 }
00163 cout <<
" leave Work in filter" << endl;
00164
return output.
size;
00165 }
00166
00167
template<
class iType>
void
00168 VrPulseCorrelator<iType>::buildFilter_complex(){
00169
int inSampFreq;
00170
int index;
00171
float N =
num_taps, a=0.0;
00172
float M = N-1;
00173
00174 inSampFreq =
getInputSamplingFrequencyN(0);
00175
00176
if (
center_freq == 0.0){
00177
00178
00179
00180
00181
for ( index=0 ; index < num_taps ; index++) {
00182
taps[index] =
gain*
VrComplex((0.54-0.46*
cos(2*M_PI*index/(M))));
00183 }
00184 }
else {
00185
00186 a = 2*M_PI*
center_freq / (
float)inSampFreq;
00187
for ( index=0 ; index < num_taps ; index++) {
00188
00189
taps[index] =
VrComplex(
gain*
cos(a*index)*(0.54-0.46*
cos(2*M_PI*index/(M))),
00190
gain*(-1)*
sin(a*index)*(0.54-0.46*
cos(2*M_PI*index/(M))));
00191
00192 }
00193
phase_corr_incr =
VrComplex(
cos(a*(
float)decimation),
00194 (-1)*
sin(a*(
float)decimation));
00195 }
00196
00197 a = a * ((
float)(
symbol_period) / (
float)((
int)1 <<
PRECISION_BITS));
00198
VrComplex temp =
VrComplex(
cos(a),(-1)*
sin(a));
00199
phase_corr_incr = temp;
00200
00201
#if defined (ENABLE_MMX)
00202
if(processedTaps!=
NULL)
00203
delete processedTaps;
00204 processedTaps=
new mmxTaps(
taps,num_taps);
00205
#endif
00206
}
00207
00208
template<
class iType>
00209 VrPulseCorrelator<iType>::VrPulseCorrelator(
float per,
int t,
float freq,
float g)
00210 :
VrDecimatingSigProc<
iType,
VrComplex>(1,(int) per)
00211 {
00212
00213
symbol_period = (
int) (per * (
float)(1 <<
PRECISION_BITS));
00214
symbol_boundary = 0;
00215
old_output_loc = (
symbol_period >>1) >>
PRECISION_BITS;
00216
bump = 0;
00217
00218
00219
num_taps = t;
00220
phase_correction =
VrComplex(1,0);
00221
phase_corr_incr = VrComplex(1,0);
00222
center_freq = freq;
00223
gain = g;
00224
#if defined (ENABLE_MMX)
00225
processedTaps=
NULL;
00226
#endif
00227
}
00228
00229
template<
class iType>
00230 void VrPulseCorrelator<iType>::initialize()
00231 {
00232
taps=
new VrComplex[
num_taps];
00233
buildFilter_complex();
00234
00235
00236
int max_num_taps =
num_taps;
00237 setHistory(max_num_taps);
00238
high_res_waiting = 0;
00239 }
00240
00241
template<
class iType>
00242 int VrPulseCorrelator<iType>::setCenter_Freq(
float cf)
00243 {
00244
center_freq = cf;
00245
buildFilter_complex();
00246
return 1;
00247 }
00248
00249
template<
class iType>
00250 int VrPulseCorrelator<iType>::setNumber_Taps(
int numT)
00251 {
00252
num_taps = numT;
00253
delete taps;
00254
taps=
new VrComplex[
num_taps];
00255
00256
00257 setHistory(
num_taps);
00258
buildFilter_complex();
00259
return 1;
00260 }
00261
00262
template<
class iType>
00263 float VrPulseCorrelator<iType>::getSymbol_Period()
00264 {
00265
00266
return (
float)
symbol_period /(
float)(1 <<
PRECISION_BITS) / (
float)
getInputSamplingFrequencyN(0);
00267 }
00268
00269
template<
class iType>
00270 int VrPulseCorrelator<iType>::setSymbol_Period(
float period)
00271 {
00272
00273
symbol_period = (
int)(period * (
float)(1 <<
PRECISION_BITS) * (
float)
getInputSamplingFrequencyN(0));
00274 cout <<
" Set period to " << (
double)
symbol_period / (
double)(1 <<
PRECISION_BITS) << endl;
00275
return 1;
00276 }
00277
00278
template<
class iType>
00279 int VrPulseCorrelator<iType>::setSymbol_Timing(
float fraction)
00280 {
00281
00282
00283
bump = (
int)( fraction * (
float)
symbol_period);
00284
return 1;
00285 }
00286
00287
template<
class iType>
00288 void VrPulseCorrelator<iType>::start_oversampling(
int N,
int B,
int wait,
VrComplex *output_ptr,
00289
int *done_flag)
00290 {
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
shift_bits = B;
00302
max_sample_count = N * (1 <<
shift_bits);
00303
high_res_start = wait;
00304
high_res_waiting = 1;
00305
sample_count = 1;
00306
high_res = 0;
00307
00308
over_sampled_result = output_ptr;
00309
middle_offset = (1 << (
shift_bits-1))+1;
00310
samples_per_symbol = (1 <<
shift_bits);
00311
all_done = done_flag;
00312 *
all_done = 0;
00313
00314
float arg = 2*M_PI*
center_freq / (
float)
getInputSamplingFrequencyN(0);
00315
small_corr_incr =
VrComplex(
cos(
arg*(
float)
symbol_period / (
float)(1 << (
PRECISION_BITS+B))),
00316 (-1)*
sin(
arg*(
float)
symbol_period / (
float)(1 <<
PRECISION_BITS+B)));
00317 }
00318
00319
template<
class iType>
00320 VrPulseCorrelator<iType>::~VrPulseCorrelator()
00321 {
00322
delete taps;
00323
#if defined (ENABLE_MMX)
00324
delete processedTaps;
00325
#endif
00326
}
00327
#endif