discuss-gnuradio
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Discuss-gnuradio] fm, vector_source


From: Eric Blossom
Subject: Re: [Discuss-gnuradio] fm, vector_source
Date: Fri, 24 Sep 2004 23:20:23 -0700
User-agent: Mutt/1.4.1i

On Fri, Sep 24, 2004 at 05:28:25PM -0400, cswiger wrote:
> Hello -
> 
> Q: How is gr.frequency_modulator_fc() used? I see it takes
> a 'sensitivity' arg, a float signal in and produces a complex out.
> What is being frequency modulated how?
> 

Hi Chuck,

Great questions!  Let's take a look at the guts of frequency_modulator_fc.h

/*!
 * \brief Frequency modulator block
 * \ingroup block
 */
class gr_frequency_modulator_fc : public gr_sync_block
{
  double        d_sensitivity;
  double        d_phase;

  friend gr_frequency_modulator_fc_sptr
  gr_make_frequency_modulator_fc (double sensitivity);

  gr_frequency_modulator_fc (double sensitivity);

 public:

  int work (int noutput_items,
            gr_vector_const_void_star &input_items,
            gr_vector_void_star &output_items);
};

>From the class header we can see that there are only two instance
variables, d_sensitivity and d_phase.  d_phase serves as a "phase
accumulator."  It represents the current phase of a numerically
controlled oscillator.

If we were generating a constant frequency complex sinusoid, on each
iteration, we'd add a constant to d_phase and then use that value as
the input to the sine and cosine functions.  This would give us the
classic "rotating phasor".  In our case we want to vary the output
frequency as some function of the input signal.

For Phase Modulation (PM) the phase is directly proportional to the
modulating signal (I'm using foo[i] to indicate the value at sample
time[i], where in[i] is the i'th input sample.)

    phase[i] = sensitivity * in[i]

For Frequency Modulation (FM) the phase is proportional to the
integral of the modulating signal over all time (-inf to now)

    phase[i] = sensitivity * integral (in[i])

In the discrete time world, an integral is just an addition.
sensitivity is a constant, so we're free to move it into the
integral.

    phase[i] = integral (sensitivity * in[i])

We implement the integral with the phase accumulator d_phase.  
If our input units were volts, then the sensitivity constant would have
units of radians/volt-second.

Concepts to remember:
  (1) the derivative of phase WRT time is frequency (radians/sec)
  (2) the integral of frequency over time is phase (radians)

Looking at the work routine below, we see a direct implementation of
these ideas.  We keep a running phase that is adjusted at each sample
time by the sensitivity * the current input sample.  We use the
resulting phase to compute the value of sine and cosine, and then use
those values as the imaginary and real parts of the result.


int
gr_frequency_modulator_fc::work (int noutput_items,
                                 gr_vector_const_void_star &input_items,
                                 gr_vector_void_star &output_items)
{
  const float *in = (const float *) input_items[0];
  gr_complex *out = (gr_complex *) output_items[0];

  for (int i = 0; i < noutput_items; i++){
    d_phase = d_phase + d_sensitivity * in[i];
    float oi, oq;
    gr_sincosf (d_phase, &oq, &oi);
    out[i] = gr_complex (oi, oq);
  }

  return noutput_items;
}


"Digital and Analog Communication Systems, 5th Ed." by Leon Couch has a
clear discussion of these concepts in section 5-6.  ISBN 0-13-522583-3


If you look in CVS, gnuradio-examples/python/usrp1/fm_tx4.py
implements a four channel FM transmitter.  [Each instance of the
pipeline ought to have a "pre-emphasis filter", but that's just an
IIR.  The output is perfectly intelligible without it.]

Eric




reply via email to

[Prev in Thread] Current Thread [Next in Thread]