[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Discuss-gnuradio] AM demodulation
From: |
Martin Dvh |
Subject: |
[Discuss-gnuradio] AM demodulation |
Date: |
Fri, 24 Dec 2004 17:59:31 +0100 |
User-agent: |
Mozilla Thunderbird 0.8 (X11/20040926) |
I am trying to build an AM receiver with gnuradio.
Can anybody tell me how to do this (example)?
So far I found and did the following:
In the WIKI I find that building an AM detector "is easy", but not how
to do it.
On the mailinglist archive I found that using an absolute value followed
by a low-pass filter should do the job.
The current version of gnuradio has no absolute value block so I build a
gr_abs_cc block.
I also tried using the gr_mult functionality.
(Multiply the signal with itsself, this gives a squared value which
should also do for AM)
The multiply with itsself does seem to work although it is quite an
processorintensive option.
The abs value works "sort of", maybe I got the values for the low-pass
filter or the decimation wrong (I used some settings of the FMdemod example)
I get a high beep through every signal (even if there is no signal, just
noise)
Has anybody any experience with AM reception using gnuradio and what did
You use.
attached is the gr_abs_cc I build, and the am_receiver.py which uses it.
It takes the absolute value of a complex signal. The absolute value of a
float signal would be much less processor intensive but I have not
build that yet.
The relevant part in my AM_receiver.py
(input is 50 Msps followed by a channel filter and decimator (decimate
by 512)
def build_pipeline (fg, quad_rate, audio_decimation):
'''Given a flow_graph, fg, construct a pipeline
for demodulating a narrowband AM signal. The
input is the downconverteed complex baseband
signal. The output is the demodulated audio.
build_pipeline returns a two element tuple
containing the input and output endpoints.
'''
audio_rate = quad_rate / audio_decimation
# input: complex; output: float
# fm_demod = gr.quadrature_demod_cf (volume*fm_demod_gain)
# HERE IS THE DEMODULATOR:
am_demod = gr.abs_cf()
# compute FIR filter taps for audio filter
width_of_transition_band = audio_rate / 32
audio_coeffs = \
gr.firdes.low_pass (
1.0, # gain
quad_rate, # sampling rate
audio_rate/2 - width_of_transition_band,
width_of_transition_band,
gr.firdes.WIN_HAMMING)
# input: float; output: float
audio_filter = gr.fir_filter_fff (audio_decimation,
audio_coeffs)
fg.connect (am_demod, audio_filter)
return ((am_demod, 0), (audio_filter, 0))
#!/usr/bin/env python
import math
from gnuradio import gr
from gnuradio import audio
import sys
from gnuradio import mc4020
from gnuradio import v4ltuner
def high_speed_adc (fg, input_rate): #My own driver for my own hacked bttv card
to have functionality similar to mc4020, ofcourse you can use your own high
speed ADC source or a software generated signal
return mc4020.source (input_rate,mc4020.BTTV_EXTEND_RAW_LINES |
mc4020.BTTV_NOGAP, "/dev/video0");
# return a gr.flow_graph
#
def build_chan_filter(freq,input_rate,cfir_decimation):
# compute FIR filter taps for channel selection
channel_coeffs = \
gr.firdes.low_pass (
1.0, # gain
input_rate, # sampling rate
250e3, #250e3, low pass cutoff freq
1e6,#800e3, #8*100e3, width of trans. band
gr.firdes.WIN_HAMMING)
# input: short; output: complex
chan_filter1 = \
gr.freq_xlating_fir_filter_scf (
cfir_decimation,
channel_coeffs,
freq, # 1st station freq
input_rate)
return chan_filter1
def build_graph (src,freq1,
input_rate,cfir_decimation,audio_decimation,chan_filter1):
quad_rate = input_rate / cfir_decimation
audio_rate = quad_rate / audio_decimation
(head1, tail1) = \
build_pipeline (fg, quad_rate,
audio_decimation)
# sound card as final sink
audio_sink = audio.sink (int (audio_rate))
# now wire it all together
fg.connect (src, chan_filter1)
fg.connect (chan_filter1, head1)
fg.connect (tail1, (audio_sink, 0))
return fg
def build_pipeline (fg, quad_rate, audio_decimation):
'''Given a flow_graph, fg, construct a pipeline
for demodulating a broadcast FM signal. The
input is the downconverteed complex baseband
signal. The output is the demodulated audio.
build_pipeline returns a two element tuple
containing the input and output endpoints.
'''
# fm_demod_gain = 2200.0/32768.0
audio_rate = quad_rate / audio_decimation
# volume = 2.0
# input: complex; output: float
#fm_demod = \
# gr.quadrature_demod_cf (volume*fm_demod_gain)
# HERE IS THE AM DEMODULATOR:
am_demod = gr.abs_cf()
# compute FIR filter taps for audio filter
width_of_transition_band = audio_rate / 32
audio_coeffs = \
gr.firdes.low_pass (
1.0, # gain
quad_rate, # sampling rate
audio_rate/2 - width_of_transition_band,
width_of_transition_band,
gr.firdes.WIN_HAMMING)
# input: float; output: float
audio_filter = \
gr.fir_filter_fff (audio_decimation,
audio_coeffs)
fg.connect (am_demod, audio_filter)
return ((am_demod, 0), (audio_filter, 0))
if __name__ == '__main__':
#f1 = float (sys.argv[1:][0])
nargs = len (sys.argv[1:])
#freq1 = IFfreq
#tunerfreq = RFfreq
if nargs == 1:
freq1 = float (sys.argv[1:][0]) * 1e6
elif nargs == 2:
freq1 = float (sys.argv[1:][0]) * 1e6
tunerfreq=float (sys.argv[1:][1]) * 1e6
else:
sys.stderr.write ('usage: am_receiver.py IFfreq RFfreq\n')
sys.stderr.write ('frequencies in MHz\n')
sys.exit (1)
input_rate=int(50000000) #50 Msps # int(50000000.0 *
674*1024*50/35468950)
rate_fact = 1.0 # (674.0*1024*50)/35468950
#orig FM cfir_decimation = 125
#orig FM audio_decimation = 5
cfir_decimation = 512
audio_decimation = 8
fg = gr.flow_graph ()
# use high speed ADC as input source
src = high_speed_adc (fg, input_rate)
chan_filter1=build_chan_filter(int(freq1*rate_fact),input_rate,cfir_decimation)
fg2=build_graph(src,freq1*rate_fact,input_rate,cfir_decimation,audio_decimation,chan_filter1)
actualtunerfreq=src.set_RF_freq(tunerfreq)
freq1=freq1+(tunerfreq - actualtunerfreq)
print(tunerfreq);
print(actualtunerfreq);
print(freq1);
letter=""
fg2.start () # fork thread(s) and return
while (letter!="x"):
#print(freq1)
letter=raw_input ( 'Press x Enter to quit: ')
if letter=="'":
tunerfreq+=100000
elif letter==";":
tunerfreq-=100000
elif letter==">":
tunerfreq+=10000
elif letter=="<":
tunerfreq-=10000
elif letter==".":
tunerfreq+=1000
elif letter==",":
tunerfreq-=1000
else:
tunerfreq+=10000
print(tunerfreq)
print(src.set_RF_freq(tunerfreq))
#chan_filter1.set_center_freq( int(freq1*rate_fact) )
fg2.stop ()
print "The end!"
/* -*- c++ -*- */
/*
* Copyright 2004 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
* GNU Radio 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 2, or (at your option)
* any later version.
*
* GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <gr_abs_cf.h>
#include <gr_io_signature.h>
gr_abs_cf::gr_abs_cf ():
gr_sync_block ("abs_cf",
gr_make_io_signature (1, 1, sizeof (gr_complex)),
gr_make_io_signature (1, 1, sizeof (float)))
{
}
gr_abs_cf_sptr
gr_make_abs_cf ()
{
return gr_abs_cf_sptr (new gr_abs_cf ());
}
int
gr_abs_cf::work (int noutput_items,
gr_vector_const_void_star & input_items,
gr_vector_void_star & output_items)
{
gr_complex *in = (gr_complex *) input_items[0];
float *out = (float *) output_items[0];
int i;
for ( i = 0; i < noutput_items-3; i+=4)//stride=4
{
out[i] = abs (in[i]);
out[i+1]=abs (in[i+1]);
out[i+2]=abs (in[i+2]);
out[i+3]=abs (in[i+3]);
}
for (; i < noutput_items; i++) //tail section
{
out[i] = abs (in[i]);
}
return noutput_items;
}
/* -*- c++ -*- */
/*
* Copyright 2004 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
* GNU Radio 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 2, or (at your option)
* any later version.
*
* GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef INCLUDED_GR_ABS_CF_H
#define INCLUDED_GR_ABS_CF_H
#include <gr_sync_block.h>
class gr_abs_cf;
typedef
boost::shared_ptr <
gr_abs_cf >
gr_abs_cf_sptr;
gr_abs_cf_sptr
gr_make_abs_cf ();
/*!
* \brief abs: compute absolute value, can be used for envelope AM demodulator:
complex in, complex out
* \ingroup block
*/
class
gr_abs_cf:
public
gr_sync_block
{
friend gr_abs_cf_sptr
gr_make_abs_cf ();
gr_abs_cf ();
public:
int
work (int noutput_items,
gr_vector_const_void_star & input_items,
gr_vector_void_star & output_items);
};
#endif /* INCLUDED_GR_ABS_CF_H */
/* -*- c++ -*- */
/*
* Copyright 2004 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
* GNU Radio 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 2, or (at your option)
* any later version.
*
* GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
GR_SWIG_BLOCK_MAGIC (gr, abs_cf)
gr_abs_cf_sptr gr_make_abs_cf ( );
class gr_abs_cf : public gr_sync_block
{
gr_abs_cf ( );
};
- [Discuss-gnuradio] AM demodulation,
Martin Dvh <=