From d5a115453516aa1cda446b22b2228513f36a4e76 Mon Sep 17 00:00:00 2001 From: Mark Jessop Date: Sun, 17 Sep 2017 14:21:19 +0930 Subject: [PATCH 1/4] NOAA decoder speedups, via surligas. --- .../satellites/noaa_apt_decoder.grc | 42 ++++++------ .../satellites/satnogs_noaa_apt_decoder.py | 65 +++++++++---------- 2 files changed, 53 insertions(+), 54 deletions(-) diff --git a/apps/flowgraphs/satellites/noaa_apt_decoder.grc b/apps/flowgraphs/satellites/noaa_apt_decoder.grc index f8f3334..714bc7c 100644 --- a/apps/flowgraphs/satellites/noaa_apt_decoder.grc +++ b/apps/flowgraphs/satellites/noaa_apt_decoder.grc @@ -1,5 +1,5 @@ - + Mon Apr 10 23:26:02 2017 @@ -136,7 +136,7 @@ in acceptable levels especially for embedded devices. value - 4 + 2 @@ -151,7 +151,7 @@ in acceptable levels especially for embedded devices. cutoff_freq - 0.2 + 0.4 _enabled @@ -286,7 +286,7 @@ TX sampling rate value - satnogs.hw_rx_settings[rx_sdr_device]['samp_rate'] + 250e3 @@ -313,7 +313,7 @@ TX sampling rate _coordinate - (935, 123) + (968, 124) _rotation @@ -423,7 +423,7 @@ TX sampling rate high_cutoff_freq - 4.2e3 + 3.7e3 id @@ -435,7 +435,7 @@ TX sampling rate low_cutoff_freq - 500 + 700 maxoutbuf @@ -451,7 +451,7 @@ TX sampling rate width - 200 + 1e3 win @@ -740,7 +740,7 @@ TX sampling rate _coordinate - (718, 115) + (760, 116) _rotation @@ -838,7 +838,7 @@ TX sampling rate _enabled - True + 1 _coordinate @@ -2626,7 +2626,7 @@ we shift the LO a little further _enabled - True + 1 fbw @@ -2685,7 +2685,7 @@ we shift the LO a little further _enabled - True + 1 fbw @@ -2799,11 +2799,11 @@ we shift the LO a little further decim - int(samp_rate_rx/ ( first_stage_decimation * int(samp_rate_rx/ first_stage_decimation / initial_bandwidth)) / audio_decimation) + int(samp_rate_rx /first_stage_decimation) _enabled - True + 1 fbw @@ -2811,7 +2811,7 @@ we shift the LO a little further _coordinate - (896, 232) + (992, 232) _rotation @@ -3034,7 +3034,7 @@ we shift the LO a little further _coordinate - (471, 119) + (528, 120) _rotation @@ -3081,7 +3081,7 @@ we shift the LO a little further _enabled - True + 1 filename @@ -3089,7 +3089,7 @@ we shift the LO a little further _coordinate - (1112, 236) + (1224, 236) _rotation @@ -3124,7 +3124,7 @@ we shift the LO a little further _enabled - True + 1 flip @@ -3132,7 +3132,7 @@ we shift the LO a little further _coordinate - (520, 320) + (568, 320) _rotation @@ -3226,7 +3226,7 @@ we shift the LO a little further _coordinate - (223, 47) + (176, 88) _rotation diff --git a/apps/flowgraphs/satellites/satnogs_noaa_apt_decoder.py b/apps/flowgraphs/satellites/satnogs_noaa_apt_decoder.py index eb90877..567cde9 100755 --- a/apps/flowgraphs/satellites/satnogs_noaa_apt_decoder.py +++ b/apps/flowgraphs/satellites/satnogs_noaa_apt_decoder.py @@ -5,7 +5,7 @@ # Title: NOAA APT Decoder # Author: Manolis Surligas, George Vardakis # Description: A NOAA APT Decoder with automatic image synchronization -# Generated: Wed Aug 9 18:06:52 2017 +# Generated: Sun Sep 17 04:44:10 2017 ################################################## from gnuradio import analog @@ -52,15 +52,15 @@ class satnogs_noaa_apt_decoder(gr.top_block): ################################################## # Variables ################################################## - self.samp_rate_rx = samp_rate_rx = satnogs.hw_rx_settings[rx_sdr_device]['samp_rate'] - self.first_stage_decimation = first_stage_decimation = 4 - + self.samp_rate_rx = samp_rate_rx = 250e3 + self.first_stage_decimation = first_stage_decimation = 2 + self.noaa_filter_taps = noaa_filter_taps = firdes.low_pass(1.0, samp_rate_rx /first_stage_decimation, 16.5e3, 4e3, firdes.WIN_HAMMING, 6.76) - + self.initial_bandwidth = initial_bandwidth = 100e3 - - self.first_stage_filter_taps = first_stage_filter_taps = firdes.low_pass(1.0, 1.0, 0.2, 0.1, firdes.WIN_HAMMING, 6.76) - + + self.first_stage_filter_taps = first_stage_filter_taps = firdes.low_pass(1.0, 1.0, 0.4, 0.1, firdes.WIN_HAMMING, 6.76) + self.audio_decimation = audio_decimation = 2 ################################################## @@ -74,7 +74,7 @@ class satnogs_noaa_apt_decoder(gr.top_block): self.satnogs_coarse_doppler_correction_cc_0 = satnogs.coarse_doppler_correction_cc(rx_freq, samp_rate_rx /first_stage_decimation) self.rational_resampler_xxx_2 = filter.rational_resampler_ccc( interpolation=48000, - decimation=int(samp_rate_rx/ ( first_stage_decimation * int(samp_rate_rx/ first_stage_decimation / initial_bandwidth)) / audio_decimation), + decimation=int(samp_rate_rx /first_stage_decimation), taps=None, fractional_bw=None, ) @@ -108,7 +108,7 @@ class satnogs_noaa_apt_decoder(gr.top_block): self.osmosdr_source_0.set_bb_gain(satnogs.handle_rx_bb_gain(rx_sdr_device, bb_gain), 0) self.osmosdr_source_0.set_antenna(satnogs.handle_rx_antenna(rx_sdr_device, antenna), 0) self.osmosdr_source_0.set_bandwidth(samp_rate_rx, 0) - + self.hilbert_fc_0 = filter.hilbert_fc(65, firdes.WIN_HAMMING, 6.76) self.freq_xlating_fir_filter_xxx_0 = filter.freq_xlating_fir_filter_ccc(first_stage_decimation, (first_stage_filter_taps), lo_offset, samp_rate_rx) self.fir_filter_xxx_1 = filter.fir_filter_fff(2, ([0.5, 0.5])) @@ -117,7 +117,7 @@ class satnogs_noaa_apt_decoder(gr.top_block): self.fft_filter_xxx_0.declare_sample_delay(0) self.blocks_complex_to_mag_0 = blocks.complex_to_mag(1) self.band_pass_filter_0 = filter.fir_filter_fff(1, firdes.band_pass( - 6, samp_rate_rx/ ( first_stage_decimation * int(samp_rate_rx/ first_stage_decimation / initial_bandwidth)) / audio_decimation, 500, 4.2e3, 200, firdes.WIN_HAMMING, 6.76)) + 6, samp_rate_rx/ ( first_stage_decimation * int(samp_rate_rx/ first_stage_decimation / initial_bandwidth)) / audio_decimation, 700, 3.7e3, 1e3, firdes.WIN_HAMMING, 6.76)) self.analog_wfm_rcv_0 = analog.wfm_rcv( quad_rate=samp_rate_rx/ ( first_stage_decimation * int(samp_rate_rx/ first_stage_decimation / initial_bandwidth)), audio_decimation=audio_decimation, @@ -126,23 +126,23 @@ class satnogs_noaa_apt_decoder(gr.top_block): ################################################## # Connections ################################################## - self.msg_connect((self.satnogs_tcp_rigctl_msg_source_0, 'freq'), (self.satnogs_coarse_doppler_correction_cc_0, 'freq')) - self.connect((self.analog_wfm_rcv_0, 0), (self.band_pass_filter_0, 0)) - self.connect((self.analog_wfm_rcv_0, 0), (self.rational_resampler_xxx_1, 0)) - self.connect((self.band_pass_filter_0, 0), (self.fir_filter_xxx_1, 0)) - self.connect((self.blocks_complex_to_mag_0, 0), (self.rational_resampler_xxx_0_0, 0)) - self.connect((self.fft_filter_xxx_0, 0), (self.analog_wfm_rcv_0, 0)) - self.connect((self.fft_filter_xxx_0, 0), (self.rational_resampler_xxx_2, 0)) - self.connect((self.fir_filter_xxx_1, 0), (self.rational_resampler_xxx_0, 0)) - self.connect((self.freq_xlating_fir_filter_xxx_0, 0), (self.satnogs_coarse_doppler_correction_cc_0, 0)) - self.connect((self.hilbert_fc_0, 0), (self.blocks_complex_to_mag_0, 0)) - self.connect((self.osmosdr_source_0, 0), (self.freq_xlating_fir_filter_xxx_0, 0)) - self.connect((self.rational_resampler_xxx_0, 0), (self.hilbert_fc_0, 0)) - self.connect((self.rational_resampler_xxx_0_0, 0), (self.satnogs_noaa_apt_sink_0, 0)) - self.connect((self.rational_resampler_xxx_1, 0), (self.satnogs_ogg_encoder_0, 0)) - self.connect((self.rational_resampler_xxx_2, 0), (self.satnogs_iq_sink_0, 0)) - self.connect((self.satnogs_coarse_doppler_correction_cc_0, 0), (self.fft_filter_xxx_0, 0)) - self.connect((self.satnogs_coarse_doppler_correction_cc_0, 0), (self.satnogs_waterfall_sink_0, 0)) + self.msg_connect((self.satnogs_tcp_rigctl_msg_source_0, 'freq'), (self.satnogs_coarse_doppler_correction_cc_0, 'freq')) + self.connect((self.analog_wfm_rcv_0, 0), (self.band_pass_filter_0, 0)) + self.connect((self.analog_wfm_rcv_0, 0), (self.rational_resampler_xxx_1, 0)) + self.connect((self.band_pass_filter_0, 0), (self.fir_filter_xxx_1, 0)) + self.connect((self.blocks_complex_to_mag_0, 0), (self.rational_resampler_xxx_0_0, 0)) + self.connect((self.fft_filter_xxx_0, 0), (self.analog_wfm_rcv_0, 0)) + self.connect((self.fft_filter_xxx_0, 0), (self.rational_resampler_xxx_2, 0)) + self.connect((self.fir_filter_xxx_1, 0), (self.rational_resampler_xxx_0, 0)) + self.connect((self.freq_xlating_fir_filter_xxx_0, 0), (self.satnogs_coarse_doppler_correction_cc_0, 0)) + self.connect((self.hilbert_fc_0, 0), (self.blocks_complex_to_mag_0, 0)) + self.connect((self.osmosdr_source_0, 0), (self.freq_xlating_fir_filter_xxx_0, 0)) + self.connect((self.rational_resampler_xxx_0, 0), (self.hilbert_fc_0, 0)) + self.connect((self.rational_resampler_xxx_0_0, 0), (self.satnogs_noaa_apt_sink_0, 0)) + self.connect((self.rational_resampler_xxx_1, 0), (self.satnogs_ogg_encoder_0, 0)) + self.connect((self.rational_resampler_xxx_2, 0), (self.satnogs_iq_sink_0, 0)) + self.connect((self.satnogs_coarse_doppler_correction_cc_0, 0), (self.fft_filter_xxx_0, 0)) + self.connect((self.satnogs_coarse_doppler_correction_cc_0, 0), (self.satnogs_waterfall_sink_0, 0)) def get_antenna(self): return self.antenna @@ -248,7 +248,6 @@ class satnogs_noaa_apt_decoder(gr.top_block): def set_rx_sdr_device(self, rx_sdr_device): self.rx_sdr_device = rx_sdr_device - self.set_samp_rate_rx(satnogs.hw_rx_settings[self.rx_sdr_device]['samp_rate']) self.osmosdr_source_0.set_gain(satnogs.handle_rx_rf_gain(self.rx_sdr_device, self.rf_gain), 0) self.osmosdr_source_0.set_if_gain(satnogs.handle_rx_if_gain(self.rx_sdr_device, self.if_gain), 0) self.osmosdr_source_0.set_bb_gain(satnogs.handle_rx_bb_gain(self.rx_sdr_device, self.bb_gain), 0) @@ -279,14 +278,14 @@ class satnogs_noaa_apt_decoder(gr.top_block): self.samp_rate_rx = samp_rate_rx self.osmosdr_source_0.set_sample_rate(self.samp_rate_rx) self.osmosdr_source_0.set_bandwidth(self.samp_rate_rx, 0) - self.band_pass_filter_0.set_taps(firdes.band_pass(6, self.samp_rate_rx/ ( self.first_stage_decimation * int(self.samp_rate_rx/ self.first_stage_decimation / self.initial_bandwidth)) / self.audio_decimation, 500, 4.2e3, 200, firdes.WIN_HAMMING, 6.76)) + self.band_pass_filter_0.set_taps(firdes.band_pass(6, self.samp_rate_rx/ ( self.first_stage_decimation * int(self.samp_rate_rx/ self.first_stage_decimation / self.initial_bandwidth)) / self.audio_decimation, 700, 3.7e3, 1e3, firdes.WIN_HAMMING, 6.76)) def get_first_stage_decimation(self): return self.first_stage_decimation def set_first_stage_decimation(self, first_stage_decimation): self.first_stage_decimation = first_stage_decimation - self.band_pass_filter_0.set_taps(firdes.band_pass(6, self.samp_rate_rx/ ( self.first_stage_decimation * int(self.samp_rate_rx/ self.first_stage_decimation / self.initial_bandwidth)) / self.audio_decimation, 500, 4.2e3, 200, firdes.WIN_HAMMING, 6.76)) + self.band_pass_filter_0.set_taps(firdes.band_pass(6, self.samp_rate_rx/ ( self.first_stage_decimation * int(self.samp_rate_rx/ self.first_stage_decimation / self.initial_bandwidth)) / self.audio_decimation, 700, 3.7e3, 1e3, firdes.WIN_HAMMING, 6.76)) def get_noaa_filter_taps(self): return self.noaa_filter_taps @@ -300,7 +299,7 @@ class satnogs_noaa_apt_decoder(gr.top_block): def set_initial_bandwidth(self, initial_bandwidth): self.initial_bandwidth = initial_bandwidth - self.band_pass_filter_0.set_taps(firdes.band_pass(6, self.samp_rate_rx/ ( self.first_stage_decimation * int(self.samp_rate_rx/ self.first_stage_decimation / self.initial_bandwidth)) / self.audio_decimation, 500, 4.2e3, 200, firdes.WIN_HAMMING, 6.76)) + self.band_pass_filter_0.set_taps(firdes.band_pass(6, self.samp_rate_rx/ ( self.first_stage_decimation * int(self.samp_rate_rx/ self.first_stage_decimation / self.initial_bandwidth)) / self.audio_decimation, 700, 3.7e3, 1e3, firdes.WIN_HAMMING, 6.76)) def get_first_stage_filter_taps(self): return self.first_stage_filter_taps @@ -314,7 +313,7 @@ class satnogs_noaa_apt_decoder(gr.top_block): def set_audio_decimation(self, audio_decimation): self.audio_decimation = audio_decimation - self.band_pass_filter_0.set_taps(firdes.band_pass(6, self.samp_rate_rx/ ( self.first_stage_decimation * int(self.samp_rate_rx/ self.first_stage_decimation / self.initial_bandwidth)) / self.audio_decimation, 500, 4.2e3, 200, firdes.WIN_HAMMING, 6.76)) + self.band_pass_filter_0.set_taps(firdes.band_pass(6, self.samp_rate_rx/ ( self.first_stage_decimation * int(self.samp_rate_rx/ self.first_stage_decimation / self.initial_bandwidth)) / self.audio_decimation, 700, 3.7e3, 1e3, firdes.WIN_HAMMING, 6.76)) def argument_parser(): From 21b4f7e2de9c080017a1b4677f41c56613796fcb Mon Sep 17 00:00:00 2001 From: Mark Jessop Date: Sun, 17 Sep 2017 14:44:22 +0930 Subject: [PATCH 2/4] FM demod with 16 kHz channel filter + local UDP (port 7355) output. --- apps/flowgraphs/fm_demod.grc | 204 +++++++++++++++++++++++++++- apps/flowgraphs/satnogs_fm_demod.py | 33 +++-- 2 files changed, 221 insertions(+), 16 deletions(-) diff --git a/apps/flowgraphs/fm_demod.grc b/apps/flowgraphs/fm_demod.grc index 6397991..3f57494 100644 --- a/apps/flowgraphs/fm_demod.grc +++ b/apps/flowgraphs/fm_demod.grc @@ -1,5 +1,5 @@ - + Thu May 5 00:22:45 2016 @@ -369,7 +369,7 @@ TX sampling rate _coordinate - (1085, 410) + (864, 412) _rotation @@ -537,6 +537,108 @@ TX sampling rate ccc + + blocks_float_to_short + + alias + + + + comment + + + + affinity + + + + _enabled + True + + + _coordinate + (696, 532) + + + _rotation + 180 + + + id + blocks_float_to_short_0 + + + maxoutbuf + 0 + + + minoutbuf + 0 + + + scale + 32767 + + + vlen + 1 + + + + blocks_udp_sink + + alias + + + + comment + + + + affinity + + + + ipaddr + 127.0.0.1 + + + port + 7355 + + + _enabled + True + + + _coordinate + (384, 512) + + + _rotation + 180 + + + id + blocks_udp_sink_0 + + + type + short + + + psize + 1472 + + + eof + False + + + vlen + 1 + + parameter @@ -941,6 +1043,82 @@ we shift the LO a little further 100e3 + + low_pass_filter + + beta + 6.76 + + + alias + + + + comment + 16 kHz filter width, about right +for a standard 5 kHz Dev FM signal. + + + affinity + + + + cutoff_freq + 8000 + + + decim + 1 + + + _enabled + True + + + type + fir_filter_ccf + + + _coordinate + (1064, 368) + + + _rotation + 180 + + + gain + 1 + + + id + low_pass_filter_0 + + + interp + 1 + + + maxoutbuf + 0 + + + minoutbuf + 0 + + + samp_rate + audio_samp_rate + + + width + 3000 + + + win + firdes.WIN_HAMMING + + osmosdr_source @@ -2681,7 +2859,7 @@ we shift the LO a little further _coordinate - (877, 394) + (432, 396) _rotation @@ -2857,6 +3035,12 @@ we shift the LO a little further /tmp/waterfall.dat + + analog_quadrature_demod_cf_0 + blocks_float_to_short_0 + 0 + 0 + analog_quadrature_demod_cf_0 satnogs_ogg_encoder_0 @@ -2865,7 +3049,7 @@ we shift the LO a little further blks2_rational_resampler_xxx_1 - analog_quadrature_demod_cf_0 + low_pass_filter_0 0 0 @@ -2881,12 +3065,24 @@ we shift the LO a little further 0 0 + + blocks_float_to_short_0 + blocks_udp_sink_0 + 0 + 0 + freq_xlating_fir_filter_xxx_0 blks2_rational_resampler_xxx_1 0 0 + + low_pass_filter_0 + analog_quadrature_demod_cf_0 + 0 + 0 + osmosdr_source_0 satnogs_coarse_doppler_correction_cc_0 diff --git a/apps/flowgraphs/satnogs_fm_demod.py b/apps/flowgraphs/satnogs_fm_demod.py index cbbe1e7..8bd3d19 100755 --- a/apps/flowgraphs/satnogs_fm_demod.py +++ b/apps/flowgraphs/satnogs_fm_demod.py @@ -5,10 +5,11 @@ # Title: FM Generic Demodulation # Author: Manolis Surligas (surligas@gmail.com) # Description: A generic FM demodulation block -# Generated: Wed Aug 9 13:41:22 2017 +# Generated: Sun Sep 17 05:13:50 2017 ################################################## from gnuradio import analog +from gnuradio import blocks from gnuradio import eng_notation from gnuradio import filter from gnuradio import gr @@ -51,9 +52,9 @@ class satnogs_fm_demod(gr.top_block): ################################################## self.samp_rate_rx = samp_rate_rx = satnogs.hw_rx_settings[rx_sdr_device]['samp_rate'] self.xlate_filter_taps = xlate_filter_taps = firdes.low_pass(1, samp_rate_rx, 125000, 25000, firdes.WIN_HAMMING, 6.76) - + self.taps = taps = firdes.low_pass(12.0, samp_rate_rx, 100e3, 60000, firdes.WIN_HAMMING, 6.76) - + self.filter_rate = filter_rate = 250000 self.deviation = deviation = 5000 self.audio_samp_rate = audio_samp_rate = 48000 @@ -79,8 +80,12 @@ class satnogs_fm_demod(gr.top_block): self.osmosdr_source_0.set_bb_gain(satnogs.handle_rx_bb_gain(rx_sdr_device, bb_gain), 0) self.osmosdr_source_0.set_antenna(satnogs.handle_rx_antenna(rx_sdr_device, antenna), 0) self.osmosdr_source_0.set_bandwidth(samp_rate_rx, 0) - + + self.low_pass_filter_0 = filter.fir_filter_ccf(1, firdes.low_pass( + 1, audio_samp_rate, 8000, 3000, firdes.WIN_HAMMING, 6.76)) self.freq_xlating_fir_filter_xxx_0 = filter.freq_xlating_fir_filter_ccc(int(samp_rate_rx/filter_rate), (xlate_filter_taps), lo_offset, samp_rate_rx) + self.blocks_udp_sink_0 = blocks.udp_sink(gr.sizeof_short*1, '127.0.0.1', 7355, 1472, False) + self.blocks_float_to_short_0 = blocks.float_to_short(1, 32767) self.blks2_rational_resampler_xxx_1 = filter.rational_resampler_ccc( interpolation=24, decimation=125, @@ -92,14 +97,17 @@ class satnogs_fm_demod(gr.top_block): ################################################## # Connections ################################################## - self.msg_connect((self.satnogs_tcp_rigctl_msg_source_0, 'freq'), (self.satnogs_coarse_doppler_correction_cc_0, 'freq')) - self.connect((self.analog_quadrature_demod_cf_0, 0), (self.satnogs_ogg_encoder_0, 0)) - self.connect((self.blks2_rational_resampler_xxx_1, 0), (self.analog_quadrature_demod_cf_0, 0)) - self.connect((self.blks2_rational_resampler_xxx_1, 0), (self.satnogs_iq_sink_0, 0)) - self.connect((self.blks2_rational_resampler_xxx_1, 0), (self.satnogs_waterfall_sink_0, 0)) - self.connect((self.freq_xlating_fir_filter_xxx_0, 0), (self.blks2_rational_resampler_xxx_1, 0)) - self.connect((self.osmosdr_source_0, 0), (self.satnogs_coarse_doppler_correction_cc_0, 0)) - self.connect((self.satnogs_coarse_doppler_correction_cc_0, 0), (self.freq_xlating_fir_filter_xxx_0, 0)) + self.msg_connect((self.satnogs_tcp_rigctl_msg_source_0, 'freq'), (self.satnogs_coarse_doppler_correction_cc_0, 'freq')) + self.connect((self.analog_quadrature_demod_cf_0, 0), (self.blocks_float_to_short_0, 0)) + self.connect((self.analog_quadrature_demod_cf_0, 0), (self.satnogs_ogg_encoder_0, 0)) + self.connect((self.blks2_rational_resampler_xxx_1, 0), (self.low_pass_filter_0, 0)) + self.connect((self.blks2_rational_resampler_xxx_1, 0), (self.satnogs_iq_sink_0, 0)) + self.connect((self.blks2_rational_resampler_xxx_1, 0), (self.satnogs_waterfall_sink_0, 0)) + self.connect((self.blocks_float_to_short_0, 0), (self.blocks_udp_sink_0, 0)) + self.connect((self.freq_xlating_fir_filter_xxx_0, 0), (self.blks2_rational_resampler_xxx_1, 0)) + self.connect((self.low_pass_filter_0, 0), (self.analog_quadrature_demod_cf_0, 0)) + self.connect((self.osmosdr_source_0, 0), (self.satnogs_coarse_doppler_correction_cc_0, 0)) + self.connect((self.satnogs_coarse_doppler_correction_cc_0, 0), (self.freq_xlating_fir_filter_xxx_0, 0)) def get_antenna(self): return self.antenna @@ -252,6 +260,7 @@ class satnogs_fm_demod(gr.top_block): def set_audio_samp_rate(self, audio_samp_rate): self.audio_samp_rate = audio_samp_rate + self.low_pass_filter_0.set_taps(firdes.low_pass(1, self.audio_samp_rate, 8000, 3000, firdes.WIN_HAMMING, 6.76)) self.analog_quadrature_demod_cf_0.set_gain((2*math.pi*self.deviation)/self.audio_samp_rate) def get_audio_gain(self): From 0a6325613f6e64d1be07e6fa43f606c8728ba501 Mon Sep 17 00:00:00 2001 From: Mark Jessop Date: Thu, 21 Sep 2017 20:20:32 +0930 Subject: [PATCH 3/4] Updated fm_demod to calculate filter width using Carson's rule. --- apps/flowgraphs/fm_demod.grc | 151 ++++++---------------------- apps/flowgraphs/satnogs_fm_demod.py | 20 ++-- 2 files changed, 45 insertions(+), 126 deletions(-) diff --git a/apps/flowgraphs/fm_demod.grc b/apps/flowgraphs/fm_demod.grc index 3f57494..e215a9e 100644 --- a/apps/flowgraphs/fm_demod.grc +++ b/apps/flowgraphs/fm_demod.grc @@ -178,7 +178,7 @@ SDR received samples _coordinate - (781, 865) + (928, 1028) _rotation @@ -220,6 +220,33 @@ SDR received samples 250000 + + variable + + comment + + + + _enabled + True + + + _coordinate + (1040, 1028) + + + _rotation + 0 + + + id + max_modulation_freq + + + value + 3000 + + variable @@ -537,108 +564,6 @@ TX sampling rate ccc - - blocks_float_to_short - - alias - - - - comment - - - - affinity - - - - _enabled - True - - - _coordinate - (696, 532) - - - _rotation - 180 - - - id - blocks_float_to_short_0 - - - maxoutbuf - 0 - - - minoutbuf - 0 - - - scale - 32767 - - - vlen - 1 - - - - blocks_udp_sink - - alias - - - - comment - - - - affinity - - - - ipaddr - 127.0.0.1 - - - port - 7355 - - - _enabled - True - - - _coordinate - (384, 512) - - - _rotation - 180 - - - id - blocks_udp_sink_0 - - - type - short - - - psize - 1472 - - - eof - False - - - vlen - 1 - - parameter @@ -1055,8 +980,10 @@ we shift the LO a little further comment - 16 kHz filter width, about right -for a standard 5 kHz Dev FM signal. + Using the Carson bandwidth rule for filter width: +width = 2*(deviation + max_modulation_freq). +For the majority of FM transmissions we can expect +max_modulation_freq = 3000 affinity @@ -1064,7 +991,7 @@ for a standard 5 kHz Dev FM signal. cutoff_freq - 8000 + deviation+max_modulation_freq decim @@ -3035,12 +2962,6 @@ for a standard 5 kHz Dev FM signal. /tmp/waterfall.dat - - analog_quadrature_demod_cf_0 - blocks_float_to_short_0 - 0 - 0 - analog_quadrature_demod_cf_0 satnogs_ogg_encoder_0 @@ -3065,12 +2986,6 @@ for a standard 5 kHz Dev FM signal. 0 0 - - blocks_float_to_short_0 - blocks_udp_sink_0 - 0 - 0 - freq_xlating_fir_filter_xxx_0 blks2_rational_resampler_xxx_1 diff --git a/apps/flowgraphs/satnogs_fm_demod.py b/apps/flowgraphs/satnogs_fm_demod.py index 8bd3d19..0b6ef0b 100755 --- a/apps/flowgraphs/satnogs_fm_demod.py +++ b/apps/flowgraphs/satnogs_fm_demod.py @@ -5,11 +5,10 @@ # Title: FM Generic Demodulation # Author: Manolis Surligas (surligas@gmail.com) # Description: A generic FM demodulation block -# Generated: Sun Sep 17 05:13:50 2017 +# Generated: Thu Sep 21 10:50:12 2017 ################################################## from gnuradio import analog -from gnuradio import blocks from gnuradio import eng_notation from gnuradio import filter from gnuradio import gr @@ -55,6 +54,7 @@ class satnogs_fm_demod(gr.top_block): self.taps = taps = firdes.low_pass(12.0, samp_rate_rx, 100e3, 60000, firdes.WIN_HAMMING, 6.76) + self.max_modulation_freq = max_modulation_freq = 3000 self.filter_rate = filter_rate = 250000 self.deviation = deviation = 5000 self.audio_samp_rate = audio_samp_rate = 48000 @@ -82,10 +82,8 @@ class satnogs_fm_demod(gr.top_block): self.osmosdr_source_0.set_bandwidth(samp_rate_rx, 0) self.low_pass_filter_0 = filter.fir_filter_ccf(1, firdes.low_pass( - 1, audio_samp_rate, 8000, 3000, firdes.WIN_HAMMING, 6.76)) + 1, audio_samp_rate, deviation+max_modulation_freq, 3000, firdes.WIN_HAMMING, 6.76)) self.freq_xlating_fir_filter_xxx_0 = filter.freq_xlating_fir_filter_ccc(int(samp_rate_rx/filter_rate), (xlate_filter_taps), lo_offset, samp_rate_rx) - self.blocks_udp_sink_0 = blocks.udp_sink(gr.sizeof_short*1, '127.0.0.1', 7355, 1472, False) - self.blocks_float_to_short_0 = blocks.float_to_short(1, 32767) self.blks2_rational_resampler_xxx_1 = filter.rational_resampler_ccc( interpolation=24, decimation=125, @@ -98,12 +96,10 @@ class satnogs_fm_demod(gr.top_block): # Connections ################################################## self.msg_connect((self.satnogs_tcp_rigctl_msg_source_0, 'freq'), (self.satnogs_coarse_doppler_correction_cc_0, 'freq')) - self.connect((self.analog_quadrature_demod_cf_0, 0), (self.blocks_float_to_short_0, 0)) self.connect((self.analog_quadrature_demod_cf_0, 0), (self.satnogs_ogg_encoder_0, 0)) self.connect((self.blks2_rational_resampler_xxx_1, 0), (self.low_pass_filter_0, 0)) self.connect((self.blks2_rational_resampler_xxx_1, 0), (self.satnogs_iq_sink_0, 0)) self.connect((self.blks2_rational_resampler_xxx_1, 0), (self.satnogs_waterfall_sink_0, 0)) - self.connect((self.blocks_float_to_short_0, 0), (self.blocks_udp_sink_0, 0)) self.connect((self.freq_xlating_fir_filter_xxx_0, 0), (self.blks2_rational_resampler_xxx_1, 0)) self.connect((self.low_pass_filter_0, 0), (self.analog_quadrature_demod_cf_0, 0)) self.connect((self.osmosdr_source_0, 0), (self.satnogs_coarse_doppler_correction_cc_0, 0)) @@ -242,6 +238,13 @@ class satnogs_fm_demod(gr.top_block): def set_taps(self, taps): self.taps = taps + def get_max_modulation_freq(self): + return self.max_modulation_freq + + def set_max_modulation_freq(self, max_modulation_freq): + self.max_modulation_freq = max_modulation_freq + self.low_pass_filter_0.set_taps(firdes.low_pass(1, self.audio_samp_rate, self.deviation+self.max_modulation_freq, 3000, firdes.WIN_HAMMING, 6.76)) + def get_filter_rate(self): return self.filter_rate @@ -253,6 +256,7 @@ class satnogs_fm_demod(gr.top_block): def set_deviation(self, deviation): self.deviation = deviation + self.low_pass_filter_0.set_taps(firdes.low_pass(1, self.audio_samp_rate, self.deviation+self.max_modulation_freq, 3000, firdes.WIN_HAMMING, 6.76)) self.analog_quadrature_demod_cf_0.set_gain((2*math.pi*self.deviation)/self.audio_samp_rate) def get_audio_samp_rate(self): @@ -260,7 +264,7 @@ class satnogs_fm_demod(gr.top_block): def set_audio_samp_rate(self, audio_samp_rate): self.audio_samp_rate = audio_samp_rate - self.low_pass_filter_0.set_taps(firdes.low_pass(1, self.audio_samp_rate, 8000, 3000, firdes.WIN_HAMMING, 6.76)) + self.low_pass_filter_0.set_taps(firdes.low_pass(1, self.audio_samp_rate, self.deviation+self.max_modulation_freq, 3000, firdes.WIN_HAMMING, 6.76)) self.analog_quadrature_demod_cf_0.set_gain((2*math.pi*self.deviation)/self.audio_samp_rate) def get_audio_gain(self): From 6b4f5936619084ed4452601b5e63f4d0f2f3589b Mon Sep 17 00:00:00 2001 From: Mark Jessop Date: Thu, 21 Sep 2017 20:36:31 +0930 Subject: [PATCH 4/4] Revert NOAA decoder to master --- .../satellites/noaa_apt_decoder.grc | 42 ++++++------ .../satellites/satnogs_noaa_apt_decoder.py | 65 ++++++++++--------- 2 files changed, 54 insertions(+), 53 deletions(-) diff --git a/apps/flowgraphs/satellites/noaa_apt_decoder.grc b/apps/flowgraphs/satellites/noaa_apt_decoder.grc index 714bc7c..f8f3334 100644 --- a/apps/flowgraphs/satellites/noaa_apt_decoder.grc +++ b/apps/flowgraphs/satellites/noaa_apt_decoder.grc @@ -1,5 +1,5 @@ - + Mon Apr 10 23:26:02 2017 @@ -136,7 +136,7 @@ in acceptable levels especially for embedded devices. value - 2 + 4 @@ -151,7 +151,7 @@ in acceptable levels especially for embedded devices. cutoff_freq - 0.4 + 0.2 _enabled @@ -286,7 +286,7 @@ TX sampling rate value - 250e3 + satnogs.hw_rx_settings[rx_sdr_device]['samp_rate'] @@ -313,7 +313,7 @@ TX sampling rate _coordinate - (968, 124) + (935, 123) _rotation @@ -423,7 +423,7 @@ TX sampling rate high_cutoff_freq - 3.7e3 + 4.2e3 id @@ -435,7 +435,7 @@ TX sampling rate low_cutoff_freq - 700 + 500 maxoutbuf @@ -451,7 +451,7 @@ TX sampling rate width - 1e3 + 200 win @@ -740,7 +740,7 @@ TX sampling rate _coordinate - (760, 116) + (718, 115) _rotation @@ -838,7 +838,7 @@ TX sampling rate _enabled - 1 + True _coordinate @@ -2626,7 +2626,7 @@ we shift the LO a little further _enabled - 1 + True fbw @@ -2685,7 +2685,7 @@ we shift the LO a little further _enabled - 1 + True fbw @@ -2799,11 +2799,11 @@ we shift the LO a little further decim - int(samp_rate_rx /first_stage_decimation) + int(samp_rate_rx/ ( first_stage_decimation * int(samp_rate_rx/ first_stage_decimation / initial_bandwidth)) / audio_decimation) _enabled - 1 + True fbw @@ -2811,7 +2811,7 @@ we shift the LO a little further _coordinate - (992, 232) + (896, 232) _rotation @@ -3034,7 +3034,7 @@ we shift the LO a little further _coordinate - (528, 120) + (471, 119) _rotation @@ -3081,7 +3081,7 @@ we shift the LO a little further _enabled - 1 + True filename @@ -3089,7 +3089,7 @@ we shift the LO a little further _coordinate - (1224, 236) + (1112, 236) _rotation @@ -3124,7 +3124,7 @@ we shift the LO a little further _enabled - 1 + True flip @@ -3132,7 +3132,7 @@ we shift the LO a little further _coordinate - (568, 320) + (520, 320) _rotation @@ -3226,7 +3226,7 @@ we shift the LO a little further _coordinate - (176, 88) + (223, 47) _rotation diff --git a/apps/flowgraphs/satellites/satnogs_noaa_apt_decoder.py b/apps/flowgraphs/satellites/satnogs_noaa_apt_decoder.py index 567cde9..eb90877 100755 --- a/apps/flowgraphs/satellites/satnogs_noaa_apt_decoder.py +++ b/apps/flowgraphs/satellites/satnogs_noaa_apt_decoder.py @@ -5,7 +5,7 @@ # Title: NOAA APT Decoder # Author: Manolis Surligas, George Vardakis # Description: A NOAA APT Decoder with automatic image synchronization -# Generated: Sun Sep 17 04:44:10 2017 +# Generated: Wed Aug 9 18:06:52 2017 ################################################## from gnuradio import analog @@ -52,15 +52,15 @@ class satnogs_noaa_apt_decoder(gr.top_block): ################################################## # Variables ################################################## - self.samp_rate_rx = samp_rate_rx = 250e3 - self.first_stage_decimation = first_stage_decimation = 2 - + self.samp_rate_rx = samp_rate_rx = satnogs.hw_rx_settings[rx_sdr_device]['samp_rate'] + self.first_stage_decimation = first_stage_decimation = 4 + self.noaa_filter_taps = noaa_filter_taps = firdes.low_pass(1.0, samp_rate_rx /first_stage_decimation, 16.5e3, 4e3, firdes.WIN_HAMMING, 6.76) - + self.initial_bandwidth = initial_bandwidth = 100e3 - - self.first_stage_filter_taps = first_stage_filter_taps = firdes.low_pass(1.0, 1.0, 0.4, 0.1, firdes.WIN_HAMMING, 6.76) - + + self.first_stage_filter_taps = first_stage_filter_taps = firdes.low_pass(1.0, 1.0, 0.2, 0.1, firdes.WIN_HAMMING, 6.76) + self.audio_decimation = audio_decimation = 2 ################################################## @@ -74,7 +74,7 @@ class satnogs_noaa_apt_decoder(gr.top_block): self.satnogs_coarse_doppler_correction_cc_0 = satnogs.coarse_doppler_correction_cc(rx_freq, samp_rate_rx /first_stage_decimation) self.rational_resampler_xxx_2 = filter.rational_resampler_ccc( interpolation=48000, - decimation=int(samp_rate_rx /first_stage_decimation), + decimation=int(samp_rate_rx/ ( first_stage_decimation * int(samp_rate_rx/ first_stage_decimation / initial_bandwidth)) / audio_decimation), taps=None, fractional_bw=None, ) @@ -108,7 +108,7 @@ class satnogs_noaa_apt_decoder(gr.top_block): self.osmosdr_source_0.set_bb_gain(satnogs.handle_rx_bb_gain(rx_sdr_device, bb_gain), 0) self.osmosdr_source_0.set_antenna(satnogs.handle_rx_antenna(rx_sdr_device, antenna), 0) self.osmosdr_source_0.set_bandwidth(samp_rate_rx, 0) - + self.hilbert_fc_0 = filter.hilbert_fc(65, firdes.WIN_HAMMING, 6.76) self.freq_xlating_fir_filter_xxx_0 = filter.freq_xlating_fir_filter_ccc(first_stage_decimation, (first_stage_filter_taps), lo_offset, samp_rate_rx) self.fir_filter_xxx_1 = filter.fir_filter_fff(2, ([0.5, 0.5])) @@ -117,7 +117,7 @@ class satnogs_noaa_apt_decoder(gr.top_block): self.fft_filter_xxx_0.declare_sample_delay(0) self.blocks_complex_to_mag_0 = blocks.complex_to_mag(1) self.band_pass_filter_0 = filter.fir_filter_fff(1, firdes.band_pass( - 6, samp_rate_rx/ ( first_stage_decimation * int(samp_rate_rx/ first_stage_decimation / initial_bandwidth)) / audio_decimation, 700, 3.7e3, 1e3, firdes.WIN_HAMMING, 6.76)) + 6, samp_rate_rx/ ( first_stage_decimation * int(samp_rate_rx/ first_stage_decimation / initial_bandwidth)) / audio_decimation, 500, 4.2e3, 200, firdes.WIN_HAMMING, 6.76)) self.analog_wfm_rcv_0 = analog.wfm_rcv( quad_rate=samp_rate_rx/ ( first_stage_decimation * int(samp_rate_rx/ first_stage_decimation / initial_bandwidth)), audio_decimation=audio_decimation, @@ -126,23 +126,23 @@ class satnogs_noaa_apt_decoder(gr.top_block): ################################################## # Connections ################################################## - self.msg_connect((self.satnogs_tcp_rigctl_msg_source_0, 'freq'), (self.satnogs_coarse_doppler_correction_cc_0, 'freq')) - self.connect((self.analog_wfm_rcv_0, 0), (self.band_pass_filter_0, 0)) - self.connect((self.analog_wfm_rcv_0, 0), (self.rational_resampler_xxx_1, 0)) - self.connect((self.band_pass_filter_0, 0), (self.fir_filter_xxx_1, 0)) - self.connect((self.blocks_complex_to_mag_0, 0), (self.rational_resampler_xxx_0_0, 0)) - self.connect((self.fft_filter_xxx_0, 0), (self.analog_wfm_rcv_0, 0)) - self.connect((self.fft_filter_xxx_0, 0), (self.rational_resampler_xxx_2, 0)) - self.connect((self.fir_filter_xxx_1, 0), (self.rational_resampler_xxx_0, 0)) - self.connect((self.freq_xlating_fir_filter_xxx_0, 0), (self.satnogs_coarse_doppler_correction_cc_0, 0)) - self.connect((self.hilbert_fc_0, 0), (self.blocks_complex_to_mag_0, 0)) - self.connect((self.osmosdr_source_0, 0), (self.freq_xlating_fir_filter_xxx_0, 0)) - self.connect((self.rational_resampler_xxx_0, 0), (self.hilbert_fc_0, 0)) - self.connect((self.rational_resampler_xxx_0_0, 0), (self.satnogs_noaa_apt_sink_0, 0)) - self.connect((self.rational_resampler_xxx_1, 0), (self.satnogs_ogg_encoder_0, 0)) - self.connect((self.rational_resampler_xxx_2, 0), (self.satnogs_iq_sink_0, 0)) - self.connect((self.satnogs_coarse_doppler_correction_cc_0, 0), (self.fft_filter_xxx_0, 0)) - self.connect((self.satnogs_coarse_doppler_correction_cc_0, 0), (self.satnogs_waterfall_sink_0, 0)) + self.msg_connect((self.satnogs_tcp_rigctl_msg_source_0, 'freq'), (self.satnogs_coarse_doppler_correction_cc_0, 'freq')) + self.connect((self.analog_wfm_rcv_0, 0), (self.band_pass_filter_0, 0)) + self.connect((self.analog_wfm_rcv_0, 0), (self.rational_resampler_xxx_1, 0)) + self.connect((self.band_pass_filter_0, 0), (self.fir_filter_xxx_1, 0)) + self.connect((self.blocks_complex_to_mag_0, 0), (self.rational_resampler_xxx_0_0, 0)) + self.connect((self.fft_filter_xxx_0, 0), (self.analog_wfm_rcv_0, 0)) + self.connect((self.fft_filter_xxx_0, 0), (self.rational_resampler_xxx_2, 0)) + self.connect((self.fir_filter_xxx_1, 0), (self.rational_resampler_xxx_0, 0)) + self.connect((self.freq_xlating_fir_filter_xxx_0, 0), (self.satnogs_coarse_doppler_correction_cc_0, 0)) + self.connect((self.hilbert_fc_0, 0), (self.blocks_complex_to_mag_0, 0)) + self.connect((self.osmosdr_source_0, 0), (self.freq_xlating_fir_filter_xxx_0, 0)) + self.connect((self.rational_resampler_xxx_0, 0), (self.hilbert_fc_0, 0)) + self.connect((self.rational_resampler_xxx_0_0, 0), (self.satnogs_noaa_apt_sink_0, 0)) + self.connect((self.rational_resampler_xxx_1, 0), (self.satnogs_ogg_encoder_0, 0)) + self.connect((self.rational_resampler_xxx_2, 0), (self.satnogs_iq_sink_0, 0)) + self.connect((self.satnogs_coarse_doppler_correction_cc_0, 0), (self.fft_filter_xxx_0, 0)) + self.connect((self.satnogs_coarse_doppler_correction_cc_0, 0), (self.satnogs_waterfall_sink_0, 0)) def get_antenna(self): return self.antenna @@ -248,6 +248,7 @@ class satnogs_noaa_apt_decoder(gr.top_block): def set_rx_sdr_device(self, rx_sdr_device): self.rx_sdr_device = rx_sdr_device + self.set_samp_rate_rx(satnogs.hw_rx_settings[self.rx_sdr_device]['samp_rate']) self.osmosdr_source_0.set_gain(satnogs.handle_rx_rf_gain(self.rx_sdr_device, self.rf_gain), 0) self.osmosdr_source_0.set_if_gain(satnogs.handle_rx_if_gain(self.rx_sdr_device, self.if_gain), 0) self.osmosdr_source_0.set_bb_gain(satnogs.handle_rx_bb_gain(self.rx_sdr_device, self.bb_gain), 0) @@ -278,14 +279,14 @@ class satnogs_noaa_apt_decoder(gr.top_block): self.samp_rate_rx = samp_rate_rx self.osmosdr_source_0.set_sample_rate(self.samp_rate_rx) self.osmosdr_source_0.set_bandwidth(self.samp_rate_rx, 0) - self.band_pass_filter_0.set_taps(firdes.band_pass(6, self.samp_rate_rx/ ( self.first_stage_decimation * int(self.samp_rate_rx/ self.first_stage_decimation / self.initial_bandwidth)) / self.audio_decimation, 700, 3.7e3, 1e3, firdes.WIN_HAMMING, 6.76)) + self.band_pass_filter_0.set_taps(firdes.band_pass(6, self.samp_rate_rx/ ( self.first_stage_decimation * int(self.samp_rate_rx/ self.first_stage_decimation / self.initial_bandwidth)) / self.audio_decimation, 500, 4.2e3, 200, firdes.WIN_HAMMING, 6.76)) def get_first_stage_decimation(self): return self.first_stage_decimation def set_first_stage_decimation(self, first_stage_decimation): self.first_stage_decimation = first_stage_decimation - self.band_pass_filter_0.set_taps(firdes.band_pass(6, self.samp_rate_rx/ ( self.first_stage_decimation * int(self.samp_rate_rx/ self.first_stage_decimation / self.initial_bandwidth)) / self.audio_decimation, 700, 3.7e3, 1e3, firdes.WIN_HAMMING, 6.76)) + self.band_pass_filter_0.set_taps(firdes.band_pass(6, self.samp_rate_rx/ ( self.first_stage_decimation * int(self.samp_rate_rx/ self.first_stage_decimation / self.initial_bandwidth)) / self.audio_decimation, 500, 4.2e3, 200, firdes.WIN_HAMMING, 6.76)) def get_noaa_filter_taps(self): return self.noaa_filter_taps @@ -299,7 +300,7 @@ class satnogs_noaa_apt_decoder(gr.top_block): def set_initial_bandwidth(self, initial_bandwidth): self.initial_bandwidth = initial_bandwidth - self.band_pass_filter_0.set_taps(firdes.band_pass(6, self.samp_rate_rx/ ( self.first_stage_decimation * int(self.samp_rate_rx/ self.first_stage_decimation / self.initial_bandwidth)) / self.audio_decimation, 700, 3.7e3, 1e3, firdes.WIN_HAMMING, 6.76)) + self.band_pass_filter_0.set_taps(firdes.band_pass(6, self.samp_rate_rx/ ( self.first_stage_decimation * int(self.samp_rate_rx/ self.first_stage_decimation / self.initial_bandwidth)) / self.audio_decimation, 500, 4.2e3, 200, firdes.WIN_HAMMING, 6.76)) def get_first_stage_filter_taps(self): return self.first_stage_filter_taps @@ -313,7 +314,7 @@ class satnogs_noaa_apt_decoder(gr.top_block): def set_audio_decimation(self, audio_decimation): self.audio_decimation = audio_decimation - self.band_pass_filter_0.set_taps(firdes.band_pass(6, self.samp_rate_rx/ ( self.first_stage_decimation * int(self.samp_rate_rx/ self.first_stage_decimation / self.initial_bandwidth)) / self.audio_decimation, 700, 3.7e3, 1e3, firdes.WIN_HAMMING, 6.76)) + self.band_pass_filter_0.set_taps(firdes.band_pass(6, self.samp_rate_rx/ ( self.first_stage_decimation * int(self.samp_rate_rx/ self.first_stage_decimation / self.initial_bandwidth)) / self.audio_decimation, 500, 4.2e3, 200, firdes.WIN_HAMMING, 6.76)) def argument_parser():