forked from gnuradio/gnuradio
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfm_demod.py
81 lines (65 loc) · 2.7 KB
/
fm_demod.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#!/usr/bin/env python
#
# Copyright 2013 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
# SPDX-License-Identifier: GPL-3.0-or-later
#
#
from gnuradio import gr
from gnuradio import blocks
from gnuradio import filter
from gnuradio import analog
from gnuradio import audio
from gnuradio.filter import firdes
from gnuradio.fft import window
import sys
import math
# Create a top_block
class build_graph(gr.top_block):
def __init__(self):
gr.top_block.__init__(self)
input_rate = 200e3 # rate of a broadcast FM station
audio_rate = 44.1e3 # Rate we send the signal to the speaker
# resample from the output of the demodulator to the rate of
# the audio sink.
resamp_rate = audio_rate / input_rate
# use a file as a dummy source. Replace this with a real radio
# receiver to capture signals over-the-air.
src = blocks.file_source(gr.sizeof_gr_complex, "dummy.dat", True)
# Set the demodulator using the same deviation as the receiver.
max_dev = 75e3
fm_demod_gain = input_rate / (2 * math.pi * max_dev / 8.0)
fm_demod = analog.quadrature_demod_cf(fm_demod_gain)
# Create a filter for the resampler and filter the audio
# signal to 15 kHz. The nfilts is the number of filters in the
# arbitrary resampler. It logically operates at a rate of
# nfilts*input_rate, so we make those adjustments when
# building the filter.
volume = 0.20
nfilts = 32
resamp_taps = firdes.low_pass_2(volume * nfilts, # gain
nfilts * input_rate, # sampling rate
15e3, # low pass cutoff freq
1e3, # width of trans. band
60, # stop band attenuaton
window.WIN_KAISER)
# Build the resampler and filter
resamp_filter = filter.pfb_arb_resampler_fff(resamp_rate,
resamp_taps, nfilts)
# sound card as final sink You may have to add a specific
# device name as a second argument here, something like
# "pulse" if using pulse audio or "plughw:0,0".
audio_sink = audio.sink(int(audio_rate))
# now wire it all together
self.connect(src, fm_demod)
self.connect(fm_demod, resamp_filter)
self.connect(resamp_filter, (audio_sink, 0))
def main(args):
tb = build_graph()
tb.start() # fork thread and return
input('Press Enter to quit: ')
tb.stop()
if __name__ == '__main__':
main(sys.argv[1:])