From 26645da7613da2c50675f2059c70811354a334a3 Mon Sep 17 00:00:00 2001 From: tvoid Date: Fri, 11 Apr 2008 08:23:48 -0600 Subject: -modified offset tuning to call only on good SCH -added burst_ff_single (from testing, unbuilt) -add complex capture in burst_sink_c -gsm_scan.py: added options for realtime, fusb settings - add auto offset adjustment for file input --- gsm-tvoid/src/lib/gsm_burst.cc | 28 ++++---- gsm-tvoid/src/lib/gsm_burst.h | 27 +++---- gsm-tvoid/src/lib/gsm_burst_ff.cc | 2 +- gsm-tvoid/src/lib/gsm_burst_ff_single.cc | 118 +++++++++++++++++++++++++++++++ gsm-tvoid/src/lib/gsm_burst_ff_single.h | 31 ++++++++ gsm-tvoid/src/lib/gsm_burst_sink_c.cc | 31 +++++--- gsm-tvoid/src/lib/gsm_burst_sink_c.h | 4 ++ 7 files changed, 206 insertions(+), 35 deletions(-) create mode 100755 gsm-tvoid/src/lib/gsm_burst_ff_single.cc create mode 100755 gsm-tvoid/src/lib/gsm_burst_ff_single.h (limited to 'gsm-tvoid/src/lib') diff --git a/gsm-tvoid/src/lib/gsm_burst.cc b/gsm-tvoid/src/lib/gsm_burst.cc index 3bef146..eb44bb4 100755 --- a/gsm-tvoid/src/lib/gsm_burst.cc +++ b/gsm-tvoid/src/lib/gsm_burst.cc @@ -621,8 +621,9 @@ int gsm_burst::get_burst(void) case PARTIAL_SCH: d_sync_state = WAIT_SCH; break; - case SCH: - d_sync_state = SYNCHRONIZED; + //case SCH: + //let the burst type switch handle this so it knows if new or old sync + // d_sync_state = SYNCHRONIZED; break; default: break; @@ -648,17 +649,6 @@ int gsm_burst::get_burst(void) d_fcch_count++; calc_freq_offset(); - -#ifndef TEST_TUNE_TIMING - if (p_tuner) { - if (SYNCHRONIZED == d_sync_state) - p_tuner->calleval(BURST_CB_ADJ_OFFSET); - else - p_tuner->calleval(BURST_CB_SYNC_OFFSET); - - } -#endif - d_ts = 0; break; case PARTIAL_SCH: @@ -668,6 +658,18 @@ int gsm_burst::get_burst(void) d_ts = 0; //TODO: check this break; case SCH: +#ifndef TEST_TUNE_TIMING + //TODO: it would be better to adjust tuning on first FCCH (for better SCH detection), + // but tuning can run away with false FCCHs + // Some logic to retune back to original offset on false FCCH might work + if (p_tuner) { + if (SYNCHRONIZED == d_sync_state) + p_tuner->calleval(BURST_CB_ADJ_OFFSET); + else + p_tuner->calleval(BURST_CB_SYNC_OFFSET); + + } +#endif d_burst_count++; d_sch_count++; d_last_sch = d_burst_count; diff --git a/gsm-tvoid/src/lib/gsm_burst.h b/gsm-tvoid/src/lib/gsm_burst.h index d6ab381..2e482d0 100755 --- a/gsm-tvoid/src/lib/gsm_burst.h +++ b/gsm-tvoid/src/lib/gsm_burst.h @@ -134,24 +134,25 @@ protected: BURST_TYPE get_sch_burst(void); BURST_TYPE get_norm_burst(void); - void shift_burst(int); - void calc_freq_offset(void); - void equalize(void); - float correlate_pattern(const float *,const int,const int,const int); - void diff_decode_burst(void); + virtual void shift_burst(int); + void calc_freq_offset(void); + virtual void equalize(void); + float correlate_pattern(const float *,const int,const int,const int); + void diff_decode_burst(void); - void sync_reset(void); + void sync_reset(void); - void print_bits(const float *data,int length); - void print_hex(const unsigned char *data,int length); - void soft2hardbit(char *dst, const float *data, int len); - void print_burst(void); + void print_bits(const float *data,int length); + void print_hex(const unsigned char *data,int length); - void diff_encode(const float *in,float *out,int length,float lastbit = 1.0); - void diff_decode(const float *in,float *out,int length,float lastbit = 1.0); + void soft2hardbit(char *dst, const float *data, int len); //need this? + void print_burst(void); + + void diff_encode(const float *in,float *out,int length,float lastbit = 1.0); + void diff_decode(const float *in,float *out,int length,float lastbit = 1.0); public: - ~gsm_burst (); + virtual ~gsm_burst (); ////// General Stats //TODO: Maybe there should be a burst_stats class? diff --git a/gsm-tvoid/src/lib/gsm_burst_ff.cc b/gsm-tvoid/src/lib/gsm_burst_ff.cc index 89b513f..dd449f1 100755 --- a/gsm-tvoid/src/lib/gsm_burst_ff.cc +++ b/gsm-tvoid/src/lib/gsm_burst_ff.cc @@ -38,7 +38,7 @@ void gsm_burst_ff::forecast (int noutput_items, gr_vector_int &ninput_items_requ { unsigned ninputs = ninput_items_required.size (); for (unsigned i = 0; i < ninputs; i++) - ninput_items_required[i] = noutput_items * BBUF_SIZE + history(); + ninput_items_required[i] = noutput_items * BBUF_SIZE; } diff --git a/gsm-tvoid/src/lib/gsm_burst_ff_single.cc b/gsm-tvoid/src/lib/gsm_burst_ff_single.cc new file mode 100755 index 0000000..ff6c354 --- /dev/null +++ b/gsm-tvoid/src/lib/gsm_burst_ff_single.cc @@ -0,0 +1,118 @@ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include + +gsm_burst_ff_sptr gsm_make_burst_ff (gr_feval_ll *t) +{ + return gsm_burst_ff_sptr (new gsm_burst_ff(t)); +} + +static const int MIN_IN = 1; // minimum number of input streams +static const int MAX_IN = 1; // maximum number of input streams +static const int MIN_OUT = 0; // minimum number of output streams +static const int MAX_OUT = 1; // maximum number of output streams + +gsm_burst_ff::gsm_burst_ff (gr_feval_ll *t) : + gsm_burst(t), + gr_block( "burst_ff", + gr_make_io_signature (MIN_IN, MAX_IN, sizeof (float)), +// gr_make_io_signature (MIN_OUT, MAX_OUT, USEFUL_BITS * sizeof (float))) + gr_make_io_signature (0, 0, 0)) +// gr_make_io_signature (MIN_OUT, MAX_OUT, sizeof (float))) +{ + + set_history(1); + +} + +gsm_burst_ff::~gsm_burst_ff () +{ +} + +/* +void gsm_burst_ff::forecast (int noutput_items, gr_vector_int &ninput_items_required) +{ + unsigned ninputs = ninput_items_required.size (); + for (unsigned i = 0; i < ninputs; i++) + ninput_items_required[i] = noutput_items * BBUF_SIZE + history(); +} +*/ + +int gsm_burst_ff::general_work (int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) +{ + const float *in = (const float *) input_items[0]; + float *out = (float *) output_items[0]; + + int ii=0; + //int rval = 0; //default to no output + int rval = noutput_items; //default to no output + + //int do_output = output_items.size() > 0 ? 1 : 0; + int do_output = 0; + + int n_input = ninput_items[0]; +// fprintf(stderr,"out=%8.8x/#i=%d/#o=%d",(unsigned)out,n_input,noutput_items); +// fprintf(stderr,"#i=%d/#o=%d",n_input,noutput_items); + +// while (( rval < noutput_items) && ( ii < n_input ) ) { + while ( ii < n_input ) { + + assert(d_bbuf_pos <= BBUF_SIZE ); + + if (d_bbuf_pos >= 0) //could have been offset negative. TODO: perhaps better just to add some slack to the buffer + d_burst_buffer[d_bbuf_pos] = in[ii]; + + d_bbuf_pos++; + + if ( d_bbuf_pos >= BBUF_SIZE ) { + + if (get_burst()) { + //found a burst, send to output + if (do_output) { + //ensure that output data is in range + int b = d_burst_start; + if (b < 0) + b = 0; + else if (b >= 2 * MAX_CORR_DIST) + b = 2 * MAX_CORR_DIST - 1; + + memcpy(out+rval*USEFUL_BITS, d_burst_buffer + b, USEFUL_BITS*sizeof(float)); + } + //rval++; + //rval += USEFUL_BITS*sizeof(float); + + switch ( d_clock_options & QB_MASK ) { + case QB_QUARTER: //Can't do this in the FF version + case QB_FULL04: //extra bit on timeslot 0 & 4 + if (!(d_ts%4)) + d_bbuf_pos--; + break; + case QB_NONE: //don't adjust for quarter bits at all + default: + break; + } + + d_last_burst_s_count = d_sample_count; + + } + } + d_sample_count++; + ii++; + } + +// fprintf(stderr,"/ii=%d/rval=%d\n",ii,rval); + + consume_each (ii); + + return rval; +} diff --git a/gsm-tvoid/src/lib/gsm_burst_ff_single.h b/gsm-tvoid/src/lib/gsm_burst_ff_single.h new file mode 100755 index 0000000..553fe65 --- /dev/null +++ b/gsm-tvoid/src/lib/gsm_burst_ff_single.h @@ -0,0 +1,31 @@ +#ifndef INCLUDED_GSM_BURST_FF_H +#define INCLUDED_GSM_BURST_FF_H + +#include +#include + +class gsm_burst_ff; + +typedef boost::shared_ptr gsm_burst_ff_sptr; + +gsm_burst_ff_sptr gsm_make_burst_ff(gr_feval_ll *); + +class gsm_burst_ff : public gr_block, public gsm_burst +{ +private: + + friend gsm_burst_ff_sptr gsm_make_burst_ff(gr_feval_ll *); + gsm_burst_ff(gr_feval_ll *t); + +public: + ~gsm_burst_ff (); + +// void forecast (int noutput_items, gr_vector_int &ninput_items_required); + + int general_work ( int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); +}; + +#endif /* INCLUDED_GSM_BURST_FF_H */ diff --git a/gsm-tvoid/src/lib/gsm_burst_sink_c.cc b/gsm-tvoid/src/lib/gsm_burst_sink_c.cc index 103c09f..58787bb 100755 --- a/gsm-tvoid/src/lib/gsm_burst_sink_c.cc +++ b/gsm-tvoid/src/lib/gsm_burst_sink_c.cc @@ -49,7 +49,26 @@ gsm_burst_sink_c::~gsm_burst_sink_c () delete d_interp; } +void gsm_burst_sink_c::shift_burst(int shift_bits) +{ + //fprintf(stderr,"sft:%d\n",shift_bits); + + assert(shift_bits >= 0); + assert(shift_bits < BBUF_SIZE ); + + gr_complex *p_src = d_complex_burst + shift_bits; + gr_complex *p_dst = d_complex_burst; + int num = BBUF_SIZE - shift_bits; + + memmove(p_dst,p_src,num * sizeof(gr_complex)); //need memmove because of overlap + //DON'T adjust the buffer positions, the superclass method will do that... + //d_bbuf_pos -= shift_bits; + //call the parent method to shift the float version + gsm_burst::shift_burst(shift_bits); +} + +//TODO: put everything but GR stuff in a common complex type class (share w/ gsm_burst_cf) int gsm_burst_sink_c::work(int noutput_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) @@ -61,15 +80,9 @@ int gsm_burst_sink_c::work(int noutput_items, assert( d_ii >= 0 ); -// while (( rval < noutput_items) && ( ii < ni ) ) { while ( d_ii < noutput_items ) { -// while ( oo++ < noutput_items ) { //clock symbols - //TODO: this is very basic and can be improved. Need tracking... - //TODO: use burst_start offsets as timing feedback - //TODO: save complex samples for Viterbi EQ - - //from m&m + gr_complex sample = d_interp->interpolate (&in[d_ii], d_mu); gr_complex conjprod = sample * conj(d_last_sample); @@ -80,8 +93,10 @@ int gsm_burst_sink_c::work(int noutput_items, #if 1 assert(d_bbuf_pos <= BBUF_SIZE ); - if (d_bbuf_pos >= 0) //could be negative offset from burst alignment. TODO: perhaps better just to add some padding to the buffer + if (d_bbuf_pos >= 0) { //could be negative offset from burst alignment. TODO: perhaps better just to add some padding to the buffer d_burst_buffer[d_bbuf_pos] = diff_angle; + d_complex_burst[d_bbuf_pos] = sample; + } d_bbuf_pos++; diff --git a/gsm-tvoid/src/lib/gsm_burst_sink_c.h b/gsm-tvoid/src/lib/gsm_burst_sink_c.h index 5918dc6..1197a2c 100755 --- a/gsm-tvoid/src/lib/gsm_burst_sink_c.h +++ b/gsm-tvoid/src/lib/gsm_burst_sink_c.h @@ -30,6 +30,10 @@ private: int d_ii; //save index between work calls for interp advance gri_mmse_fir_interpolator_cc *d_interp; //sub-sample interpolator from GR + + gr_complex d_complex_burst[BBUF_SIZE]; + + void shift_burst(int shift_bits); public: ~gsm_burst_sink_c (); -- cgit v1.2.3