diff options
Diffstat (limited to 'gr-dtv/lib/atsc/atsc_equalizer_impl.cc')
-rw-r--r-- | gr-dtv/lib/atsc/atsc_equalizer_impl.cc | 89 |
1 files changed, 68 insertions, 21 deletions
diff --git a/gr-dtv/lib/atsc/atsc_equalizer_impl.cc b/gr-dtv/lib/atsc/atsc_equalizer_impl.cc index c804be6dc7..de01cea6f2 100644 --- a/gr-dtv/lib/atsc/atsc_equalizer_impl.cc +++ b/gr-dtv/lib/atsc/atsc_equalizer_impl.cc @@ -28,6 +28,7 @@ #include "atsc_types.h" #include "atsc_pnXXX_impl.h" #include <gnuradio/io_signature.h> +#include <volk/volk.h> namespace gr { namespace dtv { @@ -76,23 +77,42 @@ namespace gr { init_field_sync_common(training_sequence1, 0); init_field_sync_common(training_sequence2, 1); - for (int i = 0; i < NTAPS; i++) - d_taps[i] = 0.0; + d_taps.resize(NTAPS, 0.0f); d_buff_not_filled = true; + + const int alignment_multiple = + volk_get_alignment() / sizeof(float); + set_alignment(std::max(1, alignment_multiple)); } atsc_equalizer_impl::~atsc_equalizer_impl() { } + std::vector<float> + atsc_equalizer_impl::taps() const + { + return d_taps; + } + + std::vector<float> + atsc_equalizer_impl::data() const + { + std::vector<float> ret(&data_mem2[0], &data_mem2[ATSC_DATA_SEGMENT_LENGTH-1]); + return ret; + } + void - atsc_equalizer_impl::filterN(const float *input_samples, float *output_samples, int nsamples) + atsc_equalizer_impl::filterN(const float *input_samples, + float *output_samples, + int nsamples) { for (int j = 0; j < nsamples; j++) { output_samples[j] = 0; - for(int i = 0; i < NTAPS; i++) - output_samples[j] += d_taps[i] * input_samples[j + i]; + volk_32f_x2_dot_prod_32f(&output_samples[j], + &input_samples[j], + &d_taps[0], NTAPS); } } @@ -107,14 +127,16 @@ namespace gr { for(int j = 0; j < nsamples; j++) { output_samples[j] = 0; - for( int i = 0; i < NTAPS; i++ ) - output_samples[j] += d_taps[i] * input_samples[j + i]; + volk_32f_x2_dot_prod_32f(&output_samples[j], + &input_samples[j], + &d_taps[0], NTAPS); - double e = output_samples[j] - training_pattern[j]; + float e = output_samples[j] - training_pattern[j]; // update taps... - for( int i = 0; i < NTAPS; i++ ) - d_taps[i] -= BETA * e * (double)(input_samples[j + i]); + float tmp_taps[NTAPS]; + volk_32f_s32f_multiply_32f(tmp_taps, &input_samples[j], BETA*e, NTAPS); + volk_32f_x2_subtract_32f(&d_taps[0], &d_taps[0], tmp_taps, NTAPS); } } @@ -131,8 +153,8 @@ namespace gr { int i = 0; if(d_buff_not_filled) { - for(int j = 0; j < ATSC_DATA_SEGMENT_LENGTH; j++) - data_mem[NPRETAPS + j] = in[i].data[j]; + memcpy(&data_mem[NPRETAPS], in[i].data, + ATSC_DATA_SEGMENT_LENGTH*sizeof(float)); d_flags = in[i].pli._flags; d_segno = in[i].pli._segno; d_buff_not_filled = false; @@ -141,8 +163,8 @@ namespace gr { for (; i < noutput_items; i++) { - for(int j = 0; j < NTAPS - NPRETAPS; j++) - data_mem[ATSC_DATA_SEGMENT_LENGTH + NPRETAPS + j] = in[i].data[j]; + memcpy(&data_mem[ATSC_DATA_SEGMENT_LENGTH + NPRETAPS], in[i].data, + (NTAPS - NPRETAPS)*sizeof(float)); if(d_segno == -1) { if(d_flags & 0x0010) { @@ -157,19 +179,18 @@ namespace gr { else { filterN(data_mem, data_mem2, ATSC_DATA_SEGMENT_LENGTH); - for(int j = 0; j < ATSC_DATA_SEGMENT_LENGTH; j++) - out[output_produced].data[j] = data_mem2[j]; + memcpy(out[output_produced].data, data_mem2, + ATSC_DATA_SEGMENT_LENGTH*sizeof(float)); out[output_produced].pli._flags = d_flags; out[output_produced].pli._segno = d_segno; output_produced++; } - for( int j = 0; j < NPRETAPS; j++ ) - data_mem[j] = data_mem[ATSC_DATA_SEGMENT_LENGTH + j]; - - for(int j = 0; j < ATSC_DATA_SEGMENT_LENGTH; j++) - data_mem[NPRETAPS + j] = in[i].data[j]; + memcpy(data_mem, &data_mem[ATSC_DATA_SEGMENT_LENGTH], + NPRETAPS*sizeof(float)); + memcpy(&data_mem[NPRETAPS], in[i].data, + ATSC_DATA_SEGMENT_LENGTH*sizeof(float)); d_flags = in[i].pli._flags; d_segno = in[i].pli._segno; @@ -179,5 +200,31 @@ namespace gr { return output_produced; } + void + atsc_equalizer_impl::setup_rpc() + { +#ifdef GR_CTRLPORT + add_rpc_variable( + rpcbasic_sptr(new rpcbasic_register_get<atsc_equalizer, std::vector<float> >( + alias(), "taps", + &atsc_equalizer::taps, + pmt::make_f32vector(1,-10), + pmt::make_f32vector(1,10), + pmt::make_f32vector(1,0), + "", "Equalizer Taps", RPC_PRIVLVL_MIN, + DISPTIME))); + + add_rpc_variable( + rpcbasic_sptr(new rpcbasic_register_get<atsc_equalizer, std::vector<float> >( + alias(), "data", + &atsc_equalizer::data, + pmt::make_f32vector(1,-10), + pmt::make_f32vector(1,10), + pmt::make_f32vector(1,0), + "", "Post-equalizer Data", RPC_PRIVLVL_MIN, + DISPTIME))); +#endif /* GR_CTRLPORT */ + } + } /* namespace dtv */ } /* namespace gr */ |