diff options
author | piotr <Piotr Krysik pkrysik@elka.pw.edu.pl> | 2014-08-06 14:10:56 +0200 |
---|---|---|
committer | piotr <Piotr Krysik pkrysik@elka.pw.edu.pl> | 2014-08-06 14:10:56 +0200 |
commit | 4089c1a7f3dbadf024b160667ebbd273d77984dd (patch) | |
tree | 2575805a52cd6c542a4e0911553c0114a94944a8 /lib | |
parent | 969ecbcb4cf780673866a07abfc7a96ff86cd6f9 (diff) |
Added new blocks for clock freqeuncy correction
Diffstat (limited to 'lib')
-rw-r--r-- | lib/CMakeLists.txt | 3 | ||||
-rw-r--r-- | lib/misc_utils/controlled_const_source_f_impl.cc | 86 | ||||
-rw-r--r-- | lib/misc_utils/controlled_const_source_f_impl.h | 51 | ||||
-rw-r--r-- | lib/misc_utils/controlled_rotator_cc_impl.cc | 107 | ||||
-rw-r--r-- | lib/misc_utils/controlled_rotator_cc_impl.h | 53 | ||||
-rw-r--r-- | lib/receiver/receiver_impl.cc | 108 | ||||
-rw-r--r-- | lib/receiver/receiver_impl.h | 19 |
7 files changed, 363 insertions, 64 deletions
diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 5a730b9..e4ed842 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -35,6 +35,9 @@ list(APPEND gsm_sources decoding/control_channels_decoder_impl.cc decoding/cch.c decoding/fire_crc.c + misc_utils/controlled_rotator_cc_impl.cc + misc_utils/controlled_const_source_f_impl.cc + misc_utils/message_printer_impl.cc ) add_library(gnuradio-gsm SHARED ${gsm_sources}) diff --git a/lib/misc_utils/controlled_const_source_f_impl.cc b/lib/misc_utils/controlled_const_source_f_impl.cc new file mode 100644 index 0000000..d58f04f --- /dev/null +++ b/lib/misc_utils/controlled_const_source_f_impl.cc @@ -0,0 +1,86 @@ +/* -*- c++ -*- */ +/* + * Copyright 2014 <+YOU OR YOUR COMPANY+>. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <gnuradio/io_signature.h> +#include "controlled_const_source_f_impl.h" + +namespace gr { + namespace gsm { + + controlled_const_source_f::sptr + controlled_const_source_f::make(float constant) + { + return gnuradio::get_initial_sptr + (new controlled_const_source_f_impl(constant)); + } + + void controlled_const_source_f_impl::set_constant_msg(pmt::pmt_t msg){ + if(pmt::is_real(msg)){ + set_constant(pmt::to_double(msg)); + } + } + + /* + * The private constructor + */ + controlled_const_source_f_impl::controlled_const_source_f_impl(float constant) + : gr::sync_block("controlled_const_source_f", + gr::io_signature::make(0, 0, 0), + gr::io_signature::make(1, 1, sizeof(float))) + { + set_constant(constant); + message_port_register_in(pmt::mp("constant_msg")); + set_msg_handler(pmt::mp("constant_msg"), boost::bind(&controlled_const_source_f_impl::set_constant_msg, this, _1)); + } + + /* + * Our virtual destructor. + */ + controlled_const_source_f_impl::~controlled_const_source_f_impl() + { + } + + int + controlled_const_source_f_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + float *optr = (float*)output_items[0]; + float t; + + t = d_constant; + std::fill_n(optr, noutput_items, t); + + return noutput_items; + } + + void controlled_const_source_f_impl::set_constant(float constant){ + d_constant = constant; + } + + + + } /* namespace gsm */ +} /* namespace gr */ + diff --git a/lib/misc_utils/controlled_const_source_f_impl.h b/lib/misc_utils/controlled_const_source_f_impl.h new file mode 100644 index 0000000..2abe812 --- /dev/null +++ b/lib/misc_utils/controlled_const_source_f_impl.h @@ -0,0 +1,51 @@ +/* -*- c++ -*- */ +/* + * Copyright 2014 <+YOU OR YOUR COMPANY+>. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GSM_CONTROLLED_CONST_SOURCE_F_IMPL_H +#define INCLUDED_GSM_CONTROLLED_CONST_SOURCE_F_IMPL_H + +#include <gsm/controlled_const_source_f.h> + +namespace gr { + namespace gsm { + + class controlled_const_source_f_impl : public controlled_const_source_f + { + private: + float d_constant; + void set_constant_msg(pmt::pmt_t msg); + + public: + controlled_const_source_f_impl(float constant); + ~controlled_const_source_f_impl(); + + // Where all the action really happens + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + + virtual void set_constant(float constant); + }; + + } // namespace gsm +} // namespace gr + +#endif /* INCLUDED_GSM_CONTROLLED_CONST_SOURCE_F_IMPL_H */ + diff --git a/lib/misc_utils/controlled_rotator_cc_impl.cc b/lib/misc_utils/controlled_rotator_cc_impl.cc new file mode 100644 index 0000000..39fafb0 --- /dev/null +++ b/lib/misc_utils/controlled_rotator_cc_impl.cc @@ -0,0 +1,107 @@ +/* -*- c++ -*- */ +/* + * Copyright 2014 <+YOU OR YOUR COMPANY+>. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <gnuradio/io_signature.h> +#include "controlled_rotator_cc_impl.h" +#include <gnuradio/blocks/rotator_cc.h> +#include <math.h> + +namespace gr { + namespace gsm { + + controlled_rotator_cc::sptr + controlled_rotator_cc::make(double phase_inc, double samp_rate) + { + return gnuradio::get_initial_sptr + (new controlled_rotator_cc_impl(phase_inc, samp_rate)); + } + + /* + * The private constructor + */ + controlled_rotator_cc_impl::controlled_rotator_cc_impl(double phase_inc, double samp_rate) + : gr::sync_block("controlled_rotator_cc", + gr::io_signature::make2(1, 2, sizeof(gr_complex), sizeof(float)), + gr::io_signature::make(1, 1, sizeof(gr_complex))) + { + set_phase_inc(phase_inc); + set_samp_rate(samp_rate); + } + + /* + * Our virtual destructor. + */ + controlled_rotator_cc_impl::~controlled_rotator_cc_impl() + { + } + + void + controlled_rotator_cc_impl::set_phase_inc(double phase_inc) + { + d_phase_inc = phase_inc; + d_r.set_phase_incr( exp(gr_complex(0, (double)phase_inc)) ); + } + + void + controlled_rotator_cc_impl::set_samp_rate(double samp_rate) + { + d_samp_rate = samp_rate; + } + + int + controlled_rotator_cc_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + const gr_complex *in = (const gr_complex *)input_items[0]; + gr_complex *out = (gr_complex *)output_items[0]; + + if(input_items.size() == 2) { + int ii=0; + const float *pp = (const float *)input_items[1]; + + while(ii < noutput_items){ + //look for different values on phase increment control input + if(d_phase_inc != (*pp)){ + set_phase_inc(*(pp)); //set new value of phase increment + + float freq_offset_setting = (*(pp) / (2*M_PI)) * d_samp_rate; //send stream tag with a new value of the frequency offset + int offset = nitems_written(0); + pmt::pmt_t key = pmt::string_to_symbol("setting_freq_offset"); + pmt::pmt_t value = pmt::from_double(freq_offset_setting); + add_item_tag(0,offset, key, value); + + break; + } + pp++; + ii++; + } + } + d_r.rotateN(out, in, noutput_items); + return noutput_items; + } + + } /* namespace gsm */ +} /* namespace gr */ + diff --git a/lib/misc_utils/controlled_rotator_cc_impl.h b/lib/misc_utils/controlled_rotator_cc_impl.h new file mode 100644 index 0000000..2dbad6c --- /dev/null +++ b/lib/misc_utils/controlled_rotator_cc_impl.h @@ -0,0 +1,53 @@ +/* -*- c++ -*- */ +/* + * Copyright 2014 <+YOU OR YOUR COMPANY+>. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GSM_CONTROLLED_ROTATOR_CC_IMPL_H +#define INCLUDED_GSM_CONTROLLED_ROTATOR_CC_IMPL_H + +#include <gsm/controlled_rotator_cc.h> +#include <gnuradio/blocks/rotator.h> + +namespace gr { + namespace gsm { + + class controlled_rotator_cc_impl : public controlled_rotator_cc + { + private: + gr_complex d_phase_inc; + double d_samp_rate; + blocks::rotator d_r; + + public: + controlled_rotator_cc_impl(double phase_inc, double samp_rate); + ~controlled_rotator_cc_impl(); + + virtual void set_phase_inc(double phase_inc); + virtual void set_samp_rate(double samp_rate); + // Where all the action really happens + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } // namespace gsm +} // namespace gr + +#endif /* INCLUDED_GSM_CONTROLLED_ROTATOR_CC_IMPL_H */ + diff --git a/lib/receiver/receiver_impl.cc b/lib/receiver/receiver_impl.cc index 500113e..c333ccf 100644 --- a/lib/receiver/receiver_impl.cc +++ b/lib/receiver/receiver_impl.cc @@ -71,7 +71,7 @@ receiver_impl::receiver_impl(feval_dd * tuner, int osr, int arfcn) d_tuner(tuner), d_counter(0), d_fcch_start_pos(0), - d_freq_offset(0), + d_freq_offset_setting(0), d_state(first_fcch_search), d_burst_nr(osr), d_failed_sch(0), @@ -79,7 +79,7 @@ receiver_impl::receiver_impl(feval_dd * tuner, int osr, int arfcn) d_signal_dbm(-120) { int i; - //set_output_multiple(floor((TS_BITS + 2 * GUARD_PERIOD) * d_OSR)); //don't send samples to the receiver until there are at least samples for one + //don't send samples to the receiver until there are at least samples for one set_output_multiple(floor((TS_BITS + 2 * GUARD_PERIOD) * d_OSR)); // burst and two gurad periods (one gurard period is an arbitrary overlap) gmsk_mapper(SYNC_BITS, N_SYNC_BITS, d_sch_training_seq, gr_complex(0.0, -1.0)); for (i = 0; i < TRAIN_SEQ_NUM; i++) @@ -89,11 +89,10 @@ receiver_impl::receiver_impl(feval_dd * tuner, int osr, int arfcn) gmsk_mapper(train_seq[i], N_TRAIN_BITS, d_norm_training_seq[i], startpoint); } message_port_register_out(pmt::mp("bursts")); + message_port_register_out(pmt::mp("measurements")); configure_receiver(); //configure the receiver - tell it where to find which burst type } - - /* * Our virtual destructor. */ @@ -106,19 +105,44 @@ receiver_impl::work(int noutput_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) { - //std::cout << noutput_items << std::endl; const gr_complex *input = (const gr_complex *) input_items[0]; - + std::vector<tag_t> freq_offset_tags; + uint64_t start = nitems_read(0); + uint64_t stop = start + noutput_items; + + pmt::pmt_t key = pmt::string_to_symbol("setting_freq_offset"); + get_tags_in_range(freq_offset_tags, 0, start, stop, key); + bool freq_offset_tag_in_fcch = false; + uint64_t tag_offset=-1; //-1 - just some clearly invalid value + + if(!freq_offset_tags.empty()){ + tag_t freq_offset_tag = freq_offset_tags[0]; + tag_offset = freq_offset_tag.offset - start; + + burst_type b_type = d_channel_conf.get_burst_type(d_burst_nr); + if(d_state == synchronized && b_type == fcch_burst){ + uint64_t last_sample_nr = ceil((GUARD_PERIOD + 2.0 * TAIL_BITS + 156.25) * d_OSR) + 1; + if(tag_offset < last_sample_nr){ + DCOUT("Freq change inside FCCH burst!!!!!!!!!!!!!!"); + freq_offset_tag_in_fcch = true; + } + d_freq_offset_setting = pmt::to_double(freq_offset_tag.value); + } else { + d_freq_offset_setting = pmt::to_double(freq_offset_tag.value); + } + } + switch (d_state) { //bootstrapping case first_fcch_search: DCOUT("FCCH search"); - if (find_fcch_burst(input, noutput_items)) //find frequency correction burst in the input buffer + double freq_offset_tmp; + if (find_fcch_burst(input, noutput_items, freq_offset_tmp)) //find frequency correction burst in the input buffer { - //set_frequency(d_freq_offset); //if fcch search is successful set frequency offset - DCOUT("Freq offset " << d_freq_offset); - DCOUT("PPM: " << d_freq_offset/940e6); + pmt::pmt_t msg = pmt::make_tuple(pmt::mp("freq_offset"),pmt::from_double(freq_offset_tmp-d_freq_offset_setting),pmt::mp("first_fcch_search")); + message_port_pub(pmt::mp("measurements"), msg); + d_state = next_fcch_search; } else @@ -130,15 +154,12 @@ receiver_impl::work(int noutput_items, case next_fcch_search: //this state is used because it takes some time (a bunch of buffered samples) { DCOUT("NEXT FCCH search"); - d_prev_freq_offset = d_freq_offset; //before previous set_frequqency cause change - if (find_fcch_burst(input, noutput_items)) + double freq_offset_tmp; + if (find_fcch_burst(input, noutput_items,freq_offset_tmp)) { - if (abs(d_prev_freq_offset - d_freq_offset) > FCCH_MAX_FREQ_OFFSET) - { - //set_frequency(d_freq_offset); //call set_frequncy only frequency offset change is greater than some value - //COUT("Freq offset " << d_freq_offset); - DCOUT("PPM: " << d_freq_offset/940); - } + pmt::pmt_t msg = pmt::make_tuple(pmt::mp("freq_offset"),pmt::from_double(freq_offset_tmp-d_freq_offset_setting),pmt::mp("next_fcch_search")); + message_port_pub(pmt::mp("measurements"), msg); + d_state = sch_search; } else @@ -148,7 +169,6 @@ receiver_impl::work(int noutput_items, break; } - case sch_search: { DCOUT("SCH search"); @@ -206,30 +226,24 @@ receiver_impl::work(int noutput_items, { const unsigned first_sample = ceil((GUARD_PERIOD + 2 * TAIL_BITS) * d_OSR) + 1; const unsigned last_sample = first_sample + USEFUL_BITS * d_OSR - TAIL_BITS * d_OSR; - double freq_offset = compute_freq_offset(input, first_sample, last_sample); //extract frequency offset from it + double freq_offset_tmp = compute_freq_offset(input, first_sample, last_sample); //extract frequency offset from it - d_freq_offset_vals.push_front(freq_offset); send_burst(d_burst_nr, fc_fb, b_type); - if (d_freq_offset_vals.size() >= 10) - { - double sum = std::accumulate(d_freq_offset_vals.begin(), d_freq_offset_vals.end(), 0); - double mean_offset = sum / d_freq_offset_vals.size(); //compute mean - d_freq_offset_vals.clear(); - DCOUT("mean offset" << mean_offset/940); - if (abs(mean_offset) > FCCH_MAX_FREQ_OFFSET) - { - //d_freq_offset -= mean_offset; //and adjust frequency if it have changed beyond - //set_frequency(d_freq_offset); //some limit - DCOUT("Adjusting frequency, new frequency offset: " << d_freq_offset << "\n"); - } - } + pmt::pmt_t msg = pmt::make_tuple(pmt::mp("freq_offset"),pmt::from_double(freq_offset_tmp-d_freq_offset_setting),pmt::mp("synchronized")); + message_port_pub(pmt::mp("measurements"), msg); } break; case sch_burst: //if it's SCH burst { int t1, t2, t3, d_ncc, d_bcc; burst_start = get_sch_chan_imp_resp(input, &channel_imp_resp[0]); //get channel impulse response + + if(d_prev_burst_start != burst_start){ + d_prev_burst_start = burst_start; + DCOUT("burst start" << burst_start); + } + detect_burst(input, &channel_imp_resp[0], burst_start, output_binary); //MLSE detection of bits send_burst(d_burst_nr, output_binary, b_type); if (decode_sch(&output_binary[3], &t1, &t2, &t3, &d_ncc, &d_bcc) == 0) //and decode SCH data @@ -247,10 +261,9 @@ receiver_impl::work(int noutput_items, if (d_failed_sch >= MAX_SCH_ERRORS) { d_state = next_fcch_search; - d_freq_offset_vals.clear(); - d_freq_offset=0; - //set_frequency(0); - COUT("Re-Synchronization!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); + pmt::pmt_t msg = pmt::make_tuple(pmt::mp("freq_offset"),pmt::from_double(0.0),pmt::mp("sync_loss")); + message_port_pub(pmt::mp("measurements"), msg); + DCOUT("Re-Synchronization!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); } } } @@ -268,9 +281,7 @@ receiver_impl::work(int noutput_items, { unsigned int normal_burst_start; float dummy_corr_max, normal_corr_max; - DCOUT("Dummy"); get_norm_chan_imp_resp(input, &channel_imp_resp[0], &dummy_corr_max, TS_DUMMY); - DCOUT("Normal"); normal_burst_start = get_norm_chan_imp_resp(input, &channel_imp_resp[0], &normal_corr_max, d_bcc); DCOUT("normal_corr_max: " << normal_corr_max << " dummy_corr_max:" << dummy_corr_max); @@ -305,8 +316,7 @@ receiver_impl::work(int noutput_items, return 0; } - -bool receiver_impl::find_fcch_burst(const gr_complex *input, const int nitems) +bool receiver_impl::find_fcch_burst(const gr_complex *input, const int nitems, double & computed_freq_offset) { circular_buffer_float phase_diff_buffer(FCCH_HITS_NEEDED * d_OSR); //circular buffer used to scan throug signal to find //best match for FCCH burst @@ -451,10 +461,8 @@ bool receiver_impl::find_fcch_burst(const gr_complex *input, const int nitems) //compute frequency offset double phase_offset = best_sum / FCCH_HITS_NEEDED; - double freq_offset = phase_offset * 1625000.0 / (12.0 * M_PI); - //d_freq_offset -= freq_offset; - d_freq_offset = freq_offset; - DCOUT("freq_offset: " << d_freq_offset); + double freq_offset = phase_offset * 1625000.0/6 / (2 * M_PI); //1625000.0/6 - GMSK symbol rate in GSM + computed_freq_offset = freq_offset; end = true; result = true; @@ -623,7 +631,6 @@ void receiver_impl::detect_burst(const gr_complex * input, gr_complex * chan_imp } } -//TODO consider placing this funtion in a separate class for signal processing void receiver_impl::gmsk_mapper(const unsigned char * input, int nitems, gr_complex * gmsk_output, gr_complex start_point) { gr_complex j = gr_complex(0.0, 1.0); @@ -645,7 +652,6 @@ void receiver_impl::gmsk_mapper(const unsigned char * input, int nitems, gr_comp } } -//TODO consider use of some generalized function for correlation and placing it in a separate class for signal processing gr_complex receiver_impl::correlate_sequence(const gr_complex * sequence, int length, const gr_complex * input) { gr_complex result(0.0, 0.0); @@ -662,7 +668,6 @@ gr_complex receiver_impl::correlate_sequence(const gr_complex * sequence, int le } //computes autocorrelation for positive arguments -//TODO consider placing this funtion in a separate class for signal processing inline void receiver_impl::autocorrelation(const gr_complex * input, gr_complex * out, int nitems) { int i, k; @@ -676,7 +681,6 @@ inline void receiver_impl::autocorrelation(const gr_complex * input, gr_complex } } -//TODO consider use of some generalized function for filtering and placing it in a separate class for signal processing inline void receiver_impl::mafi(const gr_complex * input, int nitems, gr_complex * filter, int filter_length, gr_complex * output) { int ii = 0, n, a; @@ -698,7 +702,6 @@ inline void receiver_impl::mafi(const gr_complex * input, int nitems, gr_complex } } -//TODO: get_norm_chan_imp_resp is similar to get_sch_chan_imp_resp - consider joining this two functions //especially computations of strongest_window_nr int receiver_impl::get_norm_chan_imp_resp(const gr_complex *input, gr_complex * chan_imp_resp, float *corr_max, int bcc) { @@ -774,8 +777,6 @@ int receiver_impl::get_norm_chan_imp_resp(const gr_complex *input, gr_complex * DCOUT("strongest_window_nr_new: " << strongest_window_nr); burst_start = search_start_pos + strongest_window_nr - TRAIN_POS * d_OSR; //compute first sample posiiton which corresponds to the first sample of the impulse response - //TRAIN_POS=3+57+1+6 - //TODO: describe this part in detail in documentation as this is crucial part for synchronization DCOUT("burst_start: " << burst_start); return burst_start; @@ -845,7 +846,6 @@ void receiver_impl::configure_receiver() void receiver_impl::set_arfcn(int arfcn) //!! { d_arfcn = arfcn; -// std::cout << "set arfcn:"<<arfcn << std::endl; } void receiver_impl::reset() diff --git a/lib/receiver/receiver_impl.h b/lib/receiver/receiver_impl.h index d3083b2..76ad40b 100644 --- a/lib/receiver/receiver_impl.h +++ b/lib/receiver/receiver_impl.h @@ -34,6 +34,7 @@ namespace gr { class receiver_impl : public receiver { private: + int d_prev_burst_start; //!! /**@name Configuration of the receiver */ //@{ const int d_OSR; ///< oversampling ratio @@ -59,8 +60,8 @@ namespace gr { /**@name Variables used to store result of the find_fcch_burst fuction */ //@{ unsigned d_fcch_start_pos; ///< position of the first sample of the fcch burst - float d_freq_offset; ///< frequency offset of the received signal - float d_prev_freq_offset; //!!! +// float d_freq_offset; ///< frequency offset of the received signal + float d_freq_offset_setting; ///< frequency offset set in frequency shifter located upstream //@} std::list<double> d_freq_offset_vals; @@ -89,19 +90,19 @@ namespace gr { /** Function whis is used to search a FCCH burst and to compute frequency offset before * "synchronized" state of the receiver * - * TODO: Describe the FCCH search algorithm in the documentation * @param input vector with input signal * @param nitems number of samples in the input vector * @return */ - bool find_fcch_burst(const gr_complex *input, const int nitems); + bool find_fcch_burst(const gr_complex *input, const int nitems, double & computed_freq_offset); /** Computes frequency offset from FCCH burst samples * - * @param input vector with input samples - * @param first_sample number of the first sample of the FCCH busrt - * @param last_sample number of the last sample of the FCCH busrt - * @return frequency offset + * @param[in] input vector with input samples + * @param[in] first_sample number of the first sample of the FCCH busrt + * @param[in] last_sample number of the last sample of the FCCH busrt + * @param[out] computed_freq_offset contains frequency offset estimate if FCCH burst was located + * @return true if frequency offset was faound */ double compute_freq_offset(const gr_complex * input, unsigned first_sample, unsigned last_sample); @@ -206,8 +207,6 @@ namespace gr { receiver_impl(feval_dd * tuner, int osr, int arfcn); ~receiver_impl(); -// void forecast(int noutput_items, gr_vector_int &ninput_items_required); - int work(int noutput_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items); virtual void set_arfcn(int arfcn); virtual void reset(); |