70 lines
2.3 KiB
Python
Executable File
70 lines
2.3 KiB
Python
Executable File
#!/usr/bin/env python
|
|
from gnuradio import gr, gru, blks2
|
|
from gnuradio.eng_option import eng_option
|
|
from optparse import OptionParser
|
|
|
|
"""
|
|
simple frequency demodulator for captured P25 C4FM signals
|
|
|
|
input: complex sample captured by USRP
|
|
output: real baseband sample at 48 ksps
|
|
"""
|
|
|
|
class my_top_block(gr.top_block):
|
|
def __init__(self, options):
|
|
gr.top_block.__init__(self)
|
|
|
|
bandwidth = 12.5e3
|
|
symbol_rate = 4800
|
|
|
|
output_sample_rate = options.samples_per_symbol * symbol_rate
|
|
lcm = gru.lcm(options.sample_rate, output_sample_rate)
|
|
intrp = int(lcm // options.sample_rate)
|
|
decim = int(lcm // output_sample_rate)
|
|
|
|
if options.input_file == '-':
|
|
src = gr.file_descriptor_source(gr.sizeof_gr_complex, 0)
|
|
else:
|
|
src = gr.file_source(gr.sizeof_gr_complex, options.input_file)
|
|
|
|
ddc_coeffs = \
|
|
gr.firdes.low_pass (1.0,
|
|
options.sample_rate,
|
|
bandwidth/2,
|
|
bandwidth/2,
|
|
gr.firdes.WIN_HANN)
|
|
ddc = gr.freq_xlating_fir_filter_ccf (1,ddc_coeffs,-options.frequency,options.sample_rate)
|
|
resampler = blks2.rational_resampler_ccc(intrp, decim, None, None)
|
|
qdemod = gr.quadrature_demod_cf(1.0)
|
|
|
|
if options.output_file == '-':
|
|
sink = gr.file_descriptor_sink(gr.sizeof_float, 1)
|
|
else:
|
|
sink = gr.file_sink(gr.sizeof_float, options.output_file)
|
|
|
|
if options.invert:
|
|
inverter = gr.multiply_const_ff(-1.0)
|
|
self.connect(src,ddc,resampler,qdemod,inverter,sink)
|
|
else:
|
|
self.connect(src,ddc,resampler,qdemod,sink)
|
|
|
|
def main():
|
|
parser = OptionParser(option_class=eng_option)
|
|
parser.add_option("-i", "--input-file", type="string", default="in.dat", help="specify the input file")
|
|
parser.add_option("-o", "--output-file", type="string", default="demod.dat", help="specify the output file")
|
|
parser.add_option("-r", "--sample-rate", type="eng_float", default=500e3, help="sample rate of input file", metavar="Hz")
|
|
parser.add_option("-f", "--frequency", type="eng_float", default=0, help="frequency of signal to demodulate", metavar="Hz")
|
|
parser.add_option("-s", "--samples-per-symbol", type="int", default=10, help="samples per symbol in output file")
|
|
parser.add_option("-a", "--invert", action="store_true", dest="invert", default=False, help="invert output")
|
|
|
|
(options, args) = parser.parse_args()
|
|
|
|
tb = my_top_block(options)
|
|
try:
|
|
tb.run()
|
|
except KeyboardInterrupt:
|
|
pass
|
|
|
|
if __name__ == "__main__":
|
|
main()
|