From 7d02410b88d90514ad4ffd38224fb6256aa85a2d Mon Sep 17 00:00:00 2001 From: LongHairedHacker Date: Fri, 5 Apr 2019 23:33:45 +0200 Subject: [PATCH] Added flowgraph --- apps/flowgraphs/CMakeLists.txt | 6 +- apps/flowgraphs/satnogs_sstv_pd120_demod.py | 448 ++++++++++++ apps/flowgraphs/sstv_pd120_demod.grc | 766 ++++++++++++++++++++ 3 files changed, 1218 insertions(+), 2 deletions(-) create mode 100755 apps/flowgraphs/satnogs_sstv_pd120_demod.py create mode 100644 apps/flowgraphs/sstv_pd120_demod.grc diff --git a/apps/flowgraphs/CMakeLists.txt b/apps/flowgraphs/CMakeLists.txt index 55b509f..afa03c8 100644 --- a/apps/flowgraphs/CMakeLists.txt +++ b/apps/flowgraphs/CMakeLists.txt @@ -26,10 +26,11 @@ set(flowgraphs example_flowgraph.grc fsk_ax25.grc iq_receiver.grc + sstv_pd120_demod.grc ) message(“Compiling GRC SatNOGS flowgraphs…”) foreach(grc_file ${flowgraphs}) - + message("Compiling " ${grc_file}) execute_process(COMMAND grcc ${grc_file} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} @@ -44,5 +45,6 @@ GR_PYTHON_INSTALL( satnogs_example_flowgraph.py satnogs_fsk_ax25.py satnogs_iq_receiver.py + satnogs_sstv_pd120_demod.py DESTINATION bin -) \ No newline at end of file +) diff --git a/apps/flowgraphs/satnogs_sstv_pd120_demod.py b/apps/flowgraphs/satnogs_sstv_pd120_demod.py new file mode 100755 index 0000000..327d971 --- /dev/null +++ b/apps/flowgraphs/satnogs_sstv_pd120_demod.py @@ -0,0 +1,448 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +# +# SPDX-License-Identifier: GPL-3.0 +# +# GNU Radio Python Flow Graph +# Title: SSTV PD120 decoder +# Author: Manolis Surligas, George Vardakis, Sebastian Schumb +# Description: SSTV PD120 decoder with automatic image synchronization +# GNU Radio version: 3.8.0.0 + +from gnuradio import analog +from gnuradio import filter +from gnuradio.filter import firdes +from gnuradio import gr +import sys +import signal +from argparse import ArgumentParser +from gnuradio.eng_arg import eng_float, intx +from gnuradio import eng_notation +from gnuradio.filter import pfb +import satnogs +import soapy + +class satnogs_sstv_pd120_demod(gr.top_block): + + def __init__(self, antenna='', bw=0.0, decoded_data_file_path='/tmp/.satnogs/data/data', dev_args='', doppler_correction_per_sec=20, enable_iq_dump=0, file_path='test.wav', flip_images=0, gain=0.0, iq_file_path='/tmp/iq.dat', lo_offset=100e3, rigctl_port=4532, rx_freq=100e6, samp_rate_rx=0.0, soapy_rx_device='driver=invalid', sync=1, udp_IP='127.0.0.1', udp_port=16887, waterfall_file_path='/tmp/waterfall.dat'): + gr.top_block.__init__(self, "SSTV PD120 decoder") + + ################################################## + # Parameters + ################################################## + self.antenna = antenna + self.bw = bw + self.decoded_data_file_path = decoded_data_file_path + self.dev_args = dev_args + self.doppler_correction_per_sec = doppler_correction_per_sec + self.enable_iq_dump = enable_iq_dump + self.file_path = file_path + self.flip_images = flip_images + self.gain = gain + self.iq_file_path = iq_file_path + self.lo_offset = lo_offset + self.rigctl_port = rigctl_port + self.rx_freq = rx_freq + self.samp_rate_rx = samp_rate_rx + self.soapy_rx_device = soapy_rx_device + self.sync = sync + self.udp_IP = udp_IP + self.udp_port = udp_port + self.waterfall_file_path = waterfall_file_path + + ################################################## + # Variables + ################################################## + self.intermediate_samp_rate = intermediate_samp_rate = int(4*4160*4 / 5) + self.audio_samp_rate = audio_samp_rate = 48000 + + ################################################## + # Blocks + ################################################## + self.soapy_source_0 = None + if "custom" == 'custom': + dev = soapy_rx_device + else: + dev = 'driver=' + "custom" + if "custom" == 'sdrplay': + f = 'if_mode=' + "Zero-IF" + ',' + 'agc_setpoint=' + str("-30") + ',' + 'biasT_ctrl=' + "True".lower() + ',' + 'rfnotch_ctrl=' + "False".lower() + ',' + 'dabnotch_ctrl=' + "False".lower() + ',' + str(dev_args) + f = f.replace('\"', '') + f = f.replace("\\'", '') + f = f.strip(',') + self.soapy_source_0 = soapy.source(1, dev, f, samp_rate_rx, "fc32") + else: + self.soapy_source_0 = soapy.source(1, dev, dev_args, samp_rate_rx, "fc32") + + if 0 != 0: + self.soapy_source_0.set_master_clock_rate(0) + + if len('') > 0: + self.soapy_source_0.set_clock_source('') + + # Set up dc offsets + if "custom" != 'uhd': + if (self.soapy_source_0.hasDCOffset(0)): + self.soapy_source_0.set_dc_offset(0,0,False == 'True') + + if (self.soapy_source_0.hasDCOffset(1)): + self.soapy_source_0.set_dc_offset(1,0,False == 'True') + + # Setup IQ Balance + if "custom" != 'uhd': + if (self.soapy_source_0.hasIQBalance(0)): + self.soapy_source_0.set_iq_balance(0,0) + + if (self.soapy_source_0.hasIQBalance(1)): + self.soapy_source_0.set_iq_balance(1,0) + + # Setup Frequency correction + if (self.soapy_source_0.hasFrequencyCorrection(0)): + self.soapy_source_0.set_frequency_correction(0,0) + + if (self.soapy_source_0.hasFrequencyCorrection(1)): + self.soapy_source_0.set_frequency_correction(1,0) + + self.soapy_source_0.set_gain_mode(0,False) + self.soapy_source_0.set_gain_mode(1,False) + + self.soapy_source_0.set_frequency(0, rx_freq - lo_offset) + self.soapy_source_0.set_frequency(1, 0) + + # Made antenna sanity check more generic + antList = self.soapy_source_0.listAntennas(0) + + if len(antList) > 1: + # If we have more than 1 possible antenna + if len(antenna) == 0 or antenna not in antList: + print("ERROR: Please define ant0 to an allowed antenna name.") + strAntList = str(antList).lstrip('(').rstrip(')').rstrip(',') + print("Allowed antennas: " + strAntList) + exit(0) + + self.soapy_source_0.set_antenna(0,antenna) + + if 1 > 1: + antList = self.soapy_source_0.listAntennas(1) + # If we have more than 1 possible antenna + if len(antList) > 1: + if len('RX2') == 0 or 'RX2' not in antList: + print("ERROR: Please define ant1 to an allowed antenna name.") + strAntList = str(antList).lstrip('(').rstrip(')').rstrip(',') + print("Allowed antennas: " + strAntList) + exit(0) + + self.soapy_source_0.set_antenna(1,'RX2') + + self.soapy_source_0.set_overall_gain(0,gain, False ) + self.soapy_source_0.set_overall_gain(1,10, True ) + + # Prevent some weird double-gain setting issues for systems with an overall_gain setting + # noticed weird behavior with uhd + if "custom" == 'uhd' or "custom" == 'sidekiq' or "custom" == 'bladerf' or "custom" == 'lime': + self.soapy_source_0.set_gain(0,"PGA", 24, False ) + self.soapy_source_0.set_gain(1,"PGA", 24, True ) + else: + if "custom" == 'custom': + # If we're here and we're custom, let's still call overall gain + self.soapy_source_0.set_overall_gain(0,gain, False ) + self.soapy_source_0.set_overall_gain(1,10, True ) + + self.soapy_source_0.set_gain(0,"LNA", 10, False ) + self.soapy_source_0.set_gain(1,"LNA", 10, True ) + self.soapy_source_0.set_gain(0,"TIA", 0, False ) + self.soapy_source_0.set_gain(1,"TIA", 0, True ) + self.soapy_source_0.set_gain(0,"MIX", 10, False ) + self.soapy_source_0.set_gain(1,"MIX", 10, True ) + self.soapy_source_0.set_gain(0,"VGA", 10, False ) + self.soapy_source_0.set_gain(1,"VGA", 10, True ) + # Only rtl-sdr uses TUNER, so just ch0 + self.soapy_source_0.set_gain(0,"TUNER", 10, False ) + # Only hackrf uses "AMP", so just ch0 + self.soapy_source_0.set_gain(0,"AMP", 0, False ) + # Only sdrplay uses IFGR so just ch0 for each + self.soapy_source_0.set_gain(0,"IFGR", 59, False ) + self.soapy_source_0.set_gain(0,"RFGR", 9, False ) + self.satnogs_waterfall_sink_0_0 = satnogs.waterfall_sink(4*4160*4, rx_freq, 10, 1024, waterfall_file_path, 1) + self.satnogs_tcp_rigctl_msg_source_0 = satnogs.tcp_rigctl_msg_source("127.0.0.1", rigctl_port, False, int(1000.0/doppler_correction_per_sec) + 1, 1500) + self.satnogs_sstv_pd120_sink_0 = satnogs.sstv_pd120_sink(decoded_data_file_path) + self.satnogs_ogg_encoder_0 = satnogs.ogg_encoder(file_path, audio_samp_rate, 0.8) + self.satnogs_iq_sink_0_0 = satnogs.iq_sink(16768, iq_file_path, False, enable_iq_dump) + self.satnogs_doppler_compensation_0 = satnogs.doppler_compensation(samp_rate_rx, rx_freq, lo_offset, 4*4160*4, 1) + self.rational_resampler_xxx_0 = filter.rational_resampler_fff( + interpolation=5263, + decimation=intermediate_samp_rate, + taps=None, + fractional_bw=None) + self.pfb_arb_resampler_xxx_0 = pfb.arb_resampler_fff( + audio_samp_rate / (4*4160*4), + taps=None, + flt_size=32) + self.pfb_arb_resampler_xxx_0.declare_sample_delay(0) + self.low_pass_filter_0_0_0 = filter.fir_filter_fff( + 1, + firdes.low_pass( + 1, + intermediate_samp_rate, + 1500, + 1000, + firdes.WIN_HAMMING, + 6.76)) + self.low_pass_filter_0_0 = filter.fir_filter_ccf( + 1, + firdes.low_pass( + 1, + 4*4160*4, + 4*4160*1.1, + 1e3, + firdes.WIN_HAMMING, + 6.76)) + self.hilbert_fc_0 = filter.hilbert_fc(65, firdes.WIN_HAMMING, 6.76) + self.freq_xlating_fir_filter_xxx_0_0 = filter.freq_xlating_fir_filter_ccc(5, [63], 1750, (4*4160*4 )) + self.analog_wfm_rcv_0 = analog.wfm_rcv( + quad_rate=4*4160*4, + audio_decimation=1, + ) + self.analog_nbfm_rx_0 = analog.nbfm_rx( + audio_rate=intermediate_samp_rate, + quad_rate=intermediate_samp_rate, + tau=75e-6, + max_dev=600, + ) + + + + ################################################## + # Connections + ################################################## + self.msg_connect((self.satnogs_tcp_rigctl_msg_source_0, 'freq'), (self.satnogs_doppler_compensation_0, 'doppler')) + self.connect((self.analog_nbfm_rx_0, 0), (self.low_pass_filter_0_0_0, 0)) + self.connect((self.analog_wfm_rcv_0, 0), (self.hilbert_fc_0, 0)) + self.connect((self.analog_wfm_rcv_0, 0), (self.pfb_arb_resampler_xxx_0, 0)) + self.connect((self.freq_xlating_fir_filter_xxx_0_0, 0), (self.analog_nbfm_rx_0, 0)) + self.connect((self.hilbert_fc_0, 0), (self.freq_xlating_fir_filter_xxx_0_0, 0)) + self.connect((self.low_pass_filter_0_0, 0), (self.analog_wfm_rcv_0, 0)) + self.connect((self.low_pass_filter_0_0_0, 0), (self.rational_resampler_xxx_0, 0)) + self.connect((self.pfb_arb_resampler_xxx_0, 0), (self.satnogs_ogg_encoder_0, 0)) + self.connect((self.rational_resampler_xxx_0, 0), (self.satnogs_sstv_pd120_sink_0, 0)) + self.connect((self.satnogs_doppler_compensation_0, 0), (self.low_pass_filter_0_0, 0)) + self.connect((self.satnogs_doppler_compensation_0, 0), (self.satnogs_iq_sink_0_0, 0)) + self.connect((self.satnogs_doppler_compensation_0, 0), (self.satnogs_waterfall_sink_0_0, 0)) + self.connect((self.soapy_source_0, 0), (self.satnogs_doppler_compensation_0, 0)) + + def get_antenna(self): + return self.antenna + + def set_antenna(self, antenna): + self.antenna = antenna + self.soapy_source_0.set_antenna(0,self.antenna) + + def get_bw(self): + return self.bw + + def set_bw(self, bw): + self.bw = bw + self.soapy_source_0.set_bandwidth(0,self.bw) + + def get_decoded_data_file_path(self): + return self.decoded_data_file_path + + def set_decoded_data_file_path(self, decoded_data_file_path): + self.decoded_data_file_path = decoded_data_file_path + + def get_dev_args(self): + return self.dev_args + + def set_dev_args(self, dev_args): + self.dev_args = dev_args + + def get_doppler_correction_per_sec(self): + return self.doppler_correction_per_sec + + def set_doppler_correction_per_sec(self, doppler_correction_per_sec): + self.doppler_correction_per_sec = doppler_correction_per_sec + + def get_enable_iq_dump(self): + return self.enable_iq_dump + + def set_enable_iq_dump(self, enable_iq_dump): + self.enable_iq_dump = enable_iq_dump + + def get_file_path(self): + return self.file_path + + def set_file_path(self, file_path): + self.file_path = file_path + + def get_flip_images(self): + return self.flip_images + + def set_flip_images(self, flip_images): + self.flip_images = flip_images + + def get_gain(self): + return self.gain + + def set_gain(self, gain): + self.gain = gain + self.soapy_source_0.set_overall_gain(0,self.gain, False ) + + def get_iq_file_path(self): + return self.iq_file_path + + def set_iq_file_path(self, iq_file_path): + self.iq_file_path = iq_file_path + + def get_lo_offset(self): + return self.lo_offset + + def set_lo_offset(self, lo_offset): + self.lo_offset = lo_offset + self.soapy_source_0.set_frequency(0, self.rx_freq - self.lo_offset) + + def get_rigctl_port(self): + return self.rigctl_port + + def set_rigctl_port(self, rigctl_port): + self.rigctl_port = rigctl_port + + def get_rx_freq(self): + return self.rx_freq + + def set_rx_freq(self, rx_freq): + self.rx_freq = rx_freq + self.soapy_source_0.set_frequency(0, self.rx_freq - self.lo_offset) + + def get_samp_rate_rx(self): + return self.samp_rate_rx + + def set_samp_rate_rx(self, samp_rate_rx): + self.samp_rate_rx = samp_rate_rx + + def get_soapy_rx_device(self): + return self.soapy_rx_device + + def set_soapy_rx_device(self, soapy_rx_device): + self.soapy_rx_device = soapy_rx_device + + def get_sync(self): + return self.sync + + def set_sync(self, sync): + self.sync = sync + + def get_udp_IP(self): + return self.udp_IP + + def set_udp_IP(self, udp_IP): + self.udp_IP = udp_IP + + def get_udp_port(self): + return self.udp_port + + def set_udp_port(self, udp_port): + self.udp_port = udp_port + + def get_waterfall_file_path(self): + return self.waterfall_file_path + + def set_waterfall_file_path(self, waterfall_file_path): + self.waterfall_file_path = waterfall_file_path + + def get_intermediate_samp_rate(self): + return self.intermediate_samp_rate + + def set_intermediate_samp_rate(self, intermediate_samp_rate): + self.intermediate_samp_rate = intermediate_samp_rate + self.low_pass_filter_0_0_0.set_taps(firdes.low_pass(1, self.intermediate_samp_rate, 1500, 1000, firdes.WIN_HAMMING, 6.76)) + + def get_audio_samp_rate(self): + return self.audio_samp_rate + + def set_audio_samp_rate(self, audio_samp_rate): + self.audio_samp_rate = audio_samp_rate + self.pfb_arb_resampler_xxx_0.set_rate(self.audio_samp_rate / (4*4160*4)) + + +def argument_parser(): + description = 'SSTV PD120 decoder with automatic image synchronization' + parser = ArgumentParser(description=description) + parser.add_argument( + "--antenna", dest="antenna", type=str, default='', + help="Set antenna [default=%(default)r]") + parser.add_argument( + "--bw", dest="bw", type=eng_float, default="0.0", + help="Set Bandwidth [default=%(default)r]") + parser.add_argument( + "--decoded-data-file-path", dest="decoded_data_file_path", type=str, default='/tmp/.satnogs/data/data', + help="Set decoded_data_file_path [default=%(default)r]") + parser.add_argument( + "--dev-args", dest="dev_args", type=str, default='', + help="Set Device arguments [default=%(default)r]") + parser.add_argument( + "--doppler-correction-per-sec", dest="doppler_correction_per_sec", type=intx, default=20, + help="Set doppler_correction_per_sec [default=%(default)r]") + parser.add_argument( + "--enable-iq-dump", dest="enable_iq_dump", type=intx, default=0, + help="Set enable_iq_dump [default=%(default)r]") + parser.add_argument( + "--file-path", dest="file_path", type=str, default='test.wav', + help="Set file_path [default=%(default)r]") + parser.add_argument( + "--flip-images", dest="flip_images", type=intx, default=0, + help="Set flip_images [default=%(default)r]") + parser.add_argument( + "--gain", dest="gain", type=eng_float, default="0.0", + help="Set gain [default=%(default)r]") + parser.add_argument( + "--iq-file-path", dest="iq_file_path", type=str, default='/tmp/iq.dat', + help="Set iq_file_path [default=%(default)r]") + parser.add_argument( + "--lo-offset", dest="lo_offset", type=eng_float, default="100.0k", + help="Set lo_offset [default=%(default)r]") + parser.add_argument( + "--rigctl-port", dest="rigctl_port", type=intx, default=4532, + help="Set rigctl_port [default=%(default)r]") + parser.add_argument( + "--rx-freq", dest="rx_freq", type=eng_float, default="100.0M", + help="Set rx_freq [default=%(default)r]") + parser.add_argument( + "--samp-rate-rx", dest="samp_rate_rx", type=eng_float, default="0.0", + help="Set Device Sampling rate [default=%(default)r]") + parser.add_argument( + "--soapy-rx-device", dest="soapy_rx_device", type=str, default='driver=invalid', + help="Set soapy_rx_device [default=%(default)r]") + parser.add_argument( + "--sync", dest="sync", type=intx, default=1, + help="Set sync [default=%(default)r]") + parser.add_argument( + "--udp-IP", dest="udp_IP", type=str, default='127.0.0.1', + help="Set udp_IP [default=%(default)r]") + parser.add_argument( + "--udp-port", dest="udp_port", type=intx, default=16887, + help="Set udp_port [default=%(default)r]") + parser.add_argument( + "--waterfall-file-path", dest="waterfall_file_path", type=str, default='/tmp/waterfall.dat', + help="Set waterfall_file_path [default=%(default)r]") + return parser + + +def main(top_block_cls=satnogs_sstv_pd120_demod, options=None): + if options is None: + options = argument_parser().parse_args() + tb = top_block_cls(antenna=options.antenna, bw=options.bw, decoded_data_file_path=options.decoded_data_file_path, dev_args=options.dev_args, doppler_correction_per_sec=options.doppler_correction_per_sec, enable_iq_dump=options.enable_iq_dump, file_path=options.file_path, flip_images=options.flip_images, gain=options.gain, iq_file_path=options.iq_file_path, lo_offset=options.lo_offset, rigctl_port=options.rigctl_port, rx_freq=options.rx_freq, samp_rate_rx=options.samp_rate_rx, soapy_rx_device=options.soapy_rx_device, sync=options.sync, udp_IP=options.udp_IP, udp_port=options.udp_port, waterfall_file_path=options.waterfall_file_path) + + def sig_handler(sig=None, frame=None): + tb.stop() + tb.wait() + sys.exit(0) + + signal.signal(signal.SIGINT, sig_handler) + signal.signal(signal.SIGTERM, sig_handler) + + tb.start() + tb.wait() + + +if __name__ == '__main__': + main() diff --git a/apps/flowgraphs/sstv_pd120_demod.grc b/apps/flowgraphs/sstv_pd120_demod.grc new file mode 100644 index 0000000..6ee42a8 --- /dev/null +++ b/apps/flowgraphs/sstv_pd120_demod.grc @@ -0,0 +1,766 @@ +options: + parameters: + author: Manolis Surligas, George Vardakis, Sebastian Schumb + category: '[GRC Hier Blocks]' + cmake_opt: '' + comment: '' + copyright: '' + description: SSTV PD120 decoder with automatic image synchronization + gen_cmake: 'On' + gen_linking: dynamic + generate_options: no_gui + hier_block_src_path: '.:' + id: satnogs_sstv_pd120_demod + max_nouts: '0' + output_language: python + placement: (0,0) + qt_qss_theme: '' + realtime_scheduling: '' + run: 'True' + run_command: '{python} -u {filename}' + run_options: run + sizing_mode: fixed + thread_safe_setters: '' + title: SSTV PD120 decoder + window_size: 2048,1080 + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [8, 8] + rotation: 0 + state: enabled + +blocks: +- name: audio_samp_rate + id: variable + parameters: + comment: '' + value: '48000' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [1056, 12.0] + rotation: 0 + state: enabled +- name: intermediate_samp_rate + id: variable + parameters: + comment: '' + value: int(4*4160*4 / 5) + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [1048, 644.0] + rotation: 0 + state: true +- name: analog_nbfm_rx_0 + id: analog_nbfm_rx + parameters: + affinity: '' + alias: '' + audio_rate: intermediate_samp_rate + comment: '' + max_dev: '600' + maxoutbuf: '0' + minoutbuf: '0' + quad_rate: intermediate_samp_rate + tau: 75e-6 + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [1272, 524.0] + rotation: 0 + state: enabled +- name: analog_wfm_rcv_0 + id: analog_wfm_rcv + parameters: + affinity: '' + alias: '' + audio_decimation: '1' + comment: '' + maxoutbuf: '0' + minoutbuf: '0' + quad_rate: 4*4160*4 + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [464, 524.0] + rotation: 0 + state: enabled +- name: antenna + id: parameter + parameters: + alias: '' + comment: '' + hide: none + label: '' + short_id: '' + type: str + value: '' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [792, 12.0] + rotation: 0 + state: enabled +- name: bw + id: parameter + parameters: + alias: '' + comment: 'The bandwidth should configure RF filters on some devices. + + Set to 0.0 for automatic calculation.' + hide: none + label: Bandwidth + short_id: '' + type: eng_float + value: '0.0' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [952, 12.0] + rotation: 0 + state: enabled +- name: decoded_data_file_path + id: parameter + parameters: + alias: '' + comment: '' + hide: none + label: '' + short_id: '' + type: str + value: /tmp/.satnogs/data/data + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [16, 764.0] + rotation: 0 + state: enabled +- name: dev_args + id: parameter + parameters: + alias: '' + comment: '' + hide: none + label: Device arguments + short_id: '' + type: str + value: '' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [336, 12.0] + rotation: 0 + state: enabled +- name: doppler_correction_per_sec + id: parameter + parameters: + alias: '' + comment: '' + hide: none + label: '' + short_id: '' + type: intx + value: '20' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [176, 764.0] + rotation: 0 + state: enabled +- name: enable_iq_dump + id: parameter + parameters: + alias: '' + comment: '' + hide: none + label: '' + short_id: '' + type: intx + value: '0' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [272, 684.0] + rotation: 0 + state: enabled +- name: file_path + id: parameter + parameters: + alias: '' + comment: '' + hide: none + label: '' + short_id: '' + type: str + value: test.wav + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [160, 684.0] + rotation: 180 + state: enabled +- name: flip_images + id: parameter + parameters: + alias: '' + comment: '' + hide: none + label: '' + short_id: '' + type: intx + value: '0' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [1176, 12.0] + rotation: 0 + state: enabled +- name: freq_xlating_fir_filter_xxx_0_0 + id: freq_xlating_fir_filter_xxx + parameters: + affinity: '' + alias: '' + center_freq: '1750' + comment: '' + decim: '5' + maxoutbuf: '0' + minoutbuf: '0' + samp_rate: (4*4160*4 ) + taps: '63' + type: ccc + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [1040, 524.0] + rotation: 0 + state: enabled +- name: gain + id: parameter + parameters: + alias: '' + comment: '' + hide: none + label: '' + short_id: '' + type: eng_float + value: '0.0' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [880, 12.0] + rotation: 0 + state: enabled +- name: hilbert_fc_0 + id: hilbert_fc + parameters: + affinity: '' + alias: '' + beta: '6.76' + comment: '' + maxoutbuf: '0' + minoutbuf: '0' + num_taps: '65' + win: firdes.WIN_HAMMING + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [792, 532.0] + rotation: 0 + state: enabled +- name: iq_file_path + id: parameter + parameters: + alias: '' + comment: '' + hide: none + label: '' + short_id: '' + type: str + value: /tmp/iq.dat + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [400, 684.0] + rotation: 0 + state: enabled +- name: lo_offset + id: parameter + parameters: + alias: '' + comment: 'To avoid the SDR carrier at the DC + + we shift the LO a little further' + hide: none + label: '' + short_id: '' + type: eng_float + value: 100e3 + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [704, 12.0] + rotation: 0 + state: enabled +- name: low_pass_filter_0_0 + id: low_pass_filter + parameters: + affinity: '' + alias: '' + beta: '6.76' + comment: "Perform a relaxed filter to increase \nthe performance of the auto frequency\n\ + correction" + cutoff_freq: 4*4160*1.1 + decim: '1' + gain: '1' + interp: '1' + maxoutbuf: '0' + minoutbuf: '0' + samp_rate: 4*4160*4 + type: fir_filter_ccf + width: 1e3 + win: firdes.WIN_HAMMING + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [264, 484.0] + rotation: 0 + state: enabled +- name: low_pass_filter_0_0_0 + id: low_pass_filter + parameters: + affinity: '' + alias: '' + beta: '6.76' + comment: '' + cutoff_freq: '1500' + decim: '1' + gain: '1' + interp: '1' + maxoutbuf: '0' + minoutbuf: '0' + samp_rate: intermediate_samp_rate + type: fir_filter_fff + width: '1000' + win: firdes.WIN_HAMMING + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [1480, 500.0] + rotation: 0 + state: enabled +- name: pfb_arb_resampler_xxx_0 + id: pfb_arb_resampler_xxx + parameters: + affinity: '' + alias: '' + atten: '100' + comment: '' + maxoutbuf: '0' + minoutbuf: '0' + nfilts: '32' + rrate: audio_samp_rate / (4*4160*4) + samp_delay: '0' + taps: '' + type: fff + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [728, 380.0] + rotation: 0 + state: true +- name: rational_resampler_xxx_0 + id: rational_resampler_xxx + parameters: + affinity: '' + alias: '' + comment: '' + decim: intermediate_samp_rate + fbw: '0' + interp: '5263' + maxoutbuf: '0' + minoutbuf: '0' + taps: '' + type: fff + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [1664, 524.0] + rotation: 0 + state: enabled +- name: rigctl_port + id: parameter + parameters: + alias: '' + comment: '' + hide: none + label: '' + short_id: '' + type: intx + value: '4532' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [344, 764.0] + rotation: 0 + state: enabled +- name: rx_freq + id: parameter + parameters: + alias: '' + comment: '' + hide: none + label: '' + short_id: '' + type: eng_float + value: 100e6 + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [624, 12.0] + rotation: 0 + state: enabled +- name: samp_rate_rx + id: parameter + parameters: + alias: '' + comment: '' + hide: none + label: Device Sampling rate + short_id: '' + type: eng_float + value: '0.0' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [472, 12.0] + rotation: 0 + state: enabled +- name: satnogs_doppler_compensation_0 + id: satnogs_doppler_compensation + parameters: + affinity: '' + alias: '' + comment: '' + compensate: '1' + lo_offset: lo_offset + maxoutbuf: '0' + minoutbuf: '0' + out_samp_rate: 4*4160*4 + samp_rate: samp_rate_rx + sat_freq: rx_freq + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [464, 132.0] + rotation: 0 + state: true +- name: satnogs_iq_sink_0_0 + id: satnogs_iq_sink + parameters: + activate: enable_iq_dump + affinity: '' + alias: '' + append: 'False' + comment: '' + filename: iq_file_path + scale: '16768' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [16, 588.0] + rotation: 180 + state: enabled +- name: satnogs_ogg_encoder_0 + id: satnogs_ogg_encoder + parameters: + affinity: '' + alias: '' + comment: '' + filename: file_path + quality: '0.8' + samp_rate: audio_samp_rate + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [1024, 388.0] + rotation: 0 + state: enabled +- name: satnogs_sstv_pd120_sink_0 + id: satnogs_sstv_pd120_sink + parameters: + affinity: '' + alias: '' + comment: '' + filename_png: decoded_data_file_path + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [1848, 540.0] + rotation: 0 + state: enabled +- name: satnogs_tcp_rigctl_msg_source_0 + id: satnogs_tcp_rigctl_msg_source + parameters: + addr: '"127.0.0.1"' + affinity: '' + alias: '' + comment: '' + interval: int(1000.0/doppler_correction_per_sec) + 1 + maxoutbuf: '0' + minoutbuf: '0' + mode: 'False' + mtu: '1500' + port: rigctl_port + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [208, 244.0] + rotation: 0 + state: enabled +- name: satnogs_waterfall_sink_0_0 + id: satnogs_waterfall_sink + parameters: + affinity: '' + alias: '' + center_freq: rx_freq + comment: '' + fft_size: '1024' + filename: waterfall_file_path + mode: '1' + rps: '10' + samp_rate: 4*4160*4 + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [16, 404.0] + rotation: 180 + state: enabled +- name: soapy_rx_device + id: parameter + parameters: + alias: '' + comment: '' + hide: none + label: '' + short_id: '' + type: str + value: driver=invalid + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [216, 12.0] + rotation: 0 + state: enabled +- name: soapy_source_0 + id: soapy_source + parameters: + affinity: '' + alias: '' + amp_gain0: '0' + ant0: antenna + ant1: RX2 + args: dev_args + balance0: '0' + balance1: '0' + bw0: bw + bw1: '0' + center_freq0: rx_freq - lo_offset + center_freq1: '0' + clock_rate: '0' + clock_source: '' + comment: '' + correction0: '0' + correction1: '0' + dc_offset0: '0' + dc_offset1: '0' + dc_offset_auto_mode0: 'False' + dc_offset_auto_mode1: 'False' + dev: soapy_rx_device + devname: custom + gain_auto_mode0: 'False' + gain_auto_mode1: 'False' + ifgr_gain: '59' + lna_gain0: '10' + lna_gain1: '10' + manual_gain0: 'False' + manual_gain1: 'True' + maxoutbuf: '0' + minoutbuf: '0' + mix_gain0: '10' + mix_gain1: '10' + nchan: '1' + nco_freq0: '0' + nco_freq1: '0' + overall_gain0: gain + overall_gain1: '10' + pga_gain0: '24' + pga_gain1: '24' + rfgr_gain: '9' + samp_rate: samp_rate_rx + sdrplay_agc_setpoint: '-30' + sdrplay_biastee: 'True' + sdrplay_dabnotch: 'False' + sdrplay_if_mode: Zero-IF + sdrplay_rfnotch: 'False' + tia_gain0: '0' + tia_gain1: '0' + tuner_gain0: '10' + tuner_gain1: '10' + type: fc32 + vga_gain0: '10' + vga_gain1: '10' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [208, 108.0] + rotation: 0 + state: true +- name: sync + id: parameter + parameters: + alias: '' + comment: '' + hide: none + label: '' + short_id: '' + type: intx + value: '1' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [1264, 12.0] + rotation: 0 + state: enabled +- name: udp_IP + id: parameter + parameters: + alias: '' + comment: '' + hide: none + label: '' + short_id: '' + type: str + value: 127.0.0.1 + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [512, 684.0] + rotation: 0 + state: enabled +- name: udp_port + id: parameter + parameters: + alias: '' + comment: '' + hide: none + label: '' + short_id: '' + type: intx + value: '16887' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [440, 764.0] + rotation: 0 + state: enabled +- name: virtual_sink_0 + id: virtual_sink + parameters: + alias: '' + comment: '' + stream_id: doppler_corrected + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [768, 164.0] + rotation: 0 + state: true +- name: virtual_source_0 + id: virtual_source + parameters: + alias: '' + comment: '' + stream_id: doppler_corrected + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [16, 532.0] + rotation: 0 + state: true +- name: waterfall_file_path + id: parameter + parameters: + alias: '' + comment: '' + hide: none + label: '' + short_id: '' + type: str + value: /tmp/waterfall.dat + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [16, 684.0] + rotation: 0 + state: enabled + +connections: +- [analog_nbfm_rx_0, '0', low_pass_filter_0_0_0, '0'] +- [analog_wfm_rcv_0, '0', hilbert_fc_0, '0'] +- [analog_wfm_rcv_0, '0', pfb_arb_resampler_xxx_0, '0'] +- [freq_xlating_fir_filter_xxx_0_0, '0', analog_nbfm_rx_0, '0'] +- [hilbert_fc_0, '0', freq_xlating_fir_filter_xxx_0_0, '0'] +- [low_pass_filter_0_0, '0', analog_wfm_rcv_0, '0'] +- [low_pass_filter_0_0_0, '0', rational_resampler_xxx_0, '0'] +- [pfb_arb_resampler_xxx_0, '0', satnogs_ogg_encoder_0, '0'] +- [rational_resampler_xxx_0, '0', satnogs_sstv_pd120_sink_0, '0'] +- [satnogs_doppler_compensation_0, '0', virtual_sink_0, '0'] +- [satnogs_tcp_rigctl_msg_source_0, freq, satnogs_doppler_compensation_0, doppler] +- [soapy_source_0, '0', satnogs_doppler_compensation_0, '0'] +- [virtual_source_0, '0', low_pass_filter_0_0, '0'] +- [virtual_source_0, '0', satnogs_iq_sink_0_0, '0'] +- [virtual_source_0, '0', satnogs_waterfall_sink_0_0, '0'] + +metadata: + file_format: 1