diff --git a/apps/flowgraphs/cw_decoder.grc b/apps/flowgraphs/cw_decoder.grc
index 87eec52..b1a9146 100644
--- a/apps/flowgraphs/cw_decoder.grc
+++ b/apps/flowgraphs/cw_decoder.grc
@@ -116,6 +116,123 @@
48000
+
+ variable
+
+ comment
+
+
+
+ _enabled
+ 1
+
+
+ _coordinate
+ (455, 35)
+
+
+ _rotation
+ 0
+
+
+ id
+ dec
+
+
+ value
+ 8
+
+
+
+ variable
+
+ comment
+
+
+
+ _enabled
+ 1
+
+
+ _coordinate
+ (359, 35)
+
+
+ _rotation
+ 0
+
+
+ id
+ dot_samples
+
+
+ value
+ int((1.2 / wpm) / (1.0 / (audio_samp_rate / 10.0)))
+
+
+
+ analog_agc2_xx
+
+ attack_rate
+ 1e-4
+
+
+ alias
+
+
+
+ comment
+
+
+
+ affinity
+
+
+
+ decay_rate
+ 1e-4
+
+
+ _enabled
+ 1
+
+
+ _coordinate
+ (567, 283)
+
+
+ _rotation
+ 0
+
+
+ gain
+ 1.0
+
+
+ id
+ analog_agc2_xx_0
+
+
+ max_gain
+ 65536
+
+
+ maxoutbuf
+ 0
+
+
+ minoutbuf
+ 0
+
+
+ reference
+ 1.0
+
+
+ type
+ complex
+
+
analog_agc2_xx
@@ -179,65 +296,6 @@
complex
-
- analog_agc_xx
-
- alias
-
-
-
- comment
-
-
-
- affinity
-
-
-
- _enabled
- 1
-
-
- _coordinate
- (1372, 339)
-
-
- _rotation
- 0
-
-
- gain
- 1.0
-
-
- id
- analog_agc_xx_0
-
-
- max_gain
- 65536
-
-
- maxoutbuf
- 0
-
-
- minoutbuf
- 0
-
-
- rate
- 1e-3
-
-
- reference
- 1.0
-
-
- type
- float
-
-
analog_pll_carriertracking_cc
@@ -258,7 +316,7 @@
_coordinate
- (960, 348)
+ (919, 299)
_rotation
@@ -270,11 +328,11 @@
w
- 2*math.pi/400.0
+ 2*math.pi/100
max_freq
- 2*math.pi*2e3/audio_samp_rate
+ 2*math.pi*2500
maxoutbuf
@@ -282,7 +340,7 @@
min_freq
- -2*math.pi*2e3/audio_samp_rate
+ -2*math.pi*2500
minoutbuf
@@ -496,7 +554,7 @@ tone. This tone is typically 1 kHz.
- blocks_complex_to_mag_squared
+ blocks_complex_to_mag
alias
@@ -515,15 +573,15 @@ tone. This tone is typically 1 kHz.
_coordinate
- (1168, 368)
+ (1630, 479)
_rotation
- 0
+ 180
id
- blocks_complex_to_mag_squared_0
+ blocks_complex_to_mag_0
maxoutbuf
@@ -581,6 +639,104 @@ tone. This tone is typically 1 kHz.
1
+
+ blocks_delay
+
+ alias
+
+
+
+ comment
+
+
+
+ affinity
+
+
+
+ delay
+ int(dot_samples)/dec
+
+
+ _enabled
+ 1
+
+
+ _coordinate
+ (1302, 403)
+
+
+ _rotation
+ 0
+
+
+ id
+ blocks_delay_0
+
+
+ maxoutbuf
+ 0
+
+
+ minoutbuf
+ 0
+
+
+ num_ports
+ 1
+
+
+ type
+ complex
+
+
+ vlen
+ 1
+
+
+
+ blocks_multiply_conjugate_cc
+
+ alias
+
+
+
+ comment
+
+
+
+ affinity
+
+
+
+ _enabled
+ 1
+
+
+ _coordinate
+ (1358, 311)
+
+
+ _rotation
+ 0
+
+
+ id
+ blocks_multiply_conjugate_cc_0
+
+
+ maxoutbuf
+ 0
+
+
+ minoutbuf
+ 0
+
+
+ vlen
+ 1
+
+
blocks_multiply_xx
@@ -910,6 +1066,61 @@ tone. This tone is typically 1 kHz.
test.txt
+
+ fir_filter_xxx
+
+ alias
+
+
+
+ comment
+
+
+
+ affinity
+
+
+
+ decim
+ 1
+
+
+ _enabled
+ True
+
+
+ _coordinate
+ (1574, 315)
+
+
+ _rotation
+ 0
+
+
+ id
+ fir_filter_xxx_0
+
+
+ maxoutbuf
+ 0
+
+
+ minoutbuf
+ 0
+
+
+ samp_delay
+ 0
+
+
+ taps
+ [1.0] * (int(dot_samples)/dec)
+
+
+ type
+ ccc
+
+
parameter
@@ -1134,7 +1345,7 @@ we shift the LO a little further
cutoff_freq
- 2e3
+ 200
decim
@@ -1150,7 +1361,7 @@ we shift the LO a little further
_coordinate
- (1268, 179)
+ (1102, 267)
_rotation
@@ -1178,11 +1389,11 @@ we shift the LO a little further
samp_rate
- audio_samp_rate
+ audio_samp_rate/10
width
- 1e3
+ 0.1e3
win
@@ -1201,7 +1412,7 @@ we shift the LO a little further
comment
- Output samplerate: 20k / 4 = 5k
+
affinity
@@ -1209,11 +1420,11 @@ we shift the LO a little further
cutoff_freq
- 100
+ 2500
decim
- 4
+ 10
_enabled
@@ -1221,19 +1432,19 @@ we shift the LO a little further
type
- fir_filter_fff
+ fir_filter_ccf
_coordinate
- (1584, 420)
+ (743, 267)
_rotation
- 180
+ 0
gain
- 4
+ 1
id
@@ -1257,7 +1468,82 @@ we shift the LO a little further
width
- 100
+ 0.4e3
+
+
+ win
+ firdes.WIN_HAMMING
+
+
+
+ low_pass_filter
+
+ beta
+ 6.76
+
+
+ alias
+
+
+
+ comment
+
+
+
+ affinity
+
+
+
+ cutoff_freq
+ 2500
+
+
+ decim
+ 1
+
+
+ _enabled
+ True
+
+
+ type
+ fir_filter_ccf
+
+
+ _coordinate
+ (1310, 155)
+
+
+ _rotation
+ 0
+
+
+ gain
+ 1
+
+
+ id
+ low_pass_filter_0_0_0
+
+
+ interp
+ 1
+
+
+ maxoutbuf
+ 0
+
+
+ minoutbuf
+ 0
+
+
+ samp_rate
+ audio_samp_rate
+
+
+ width
+ 0.8e3
win
@@ -3067,7 +3353,7 @@ we shift the LO a little further
satnogs_cw_to_symbol
threshold
- 0.4
+ 2.0
alias
@@ -3079,7 +3365,7 @@ we shift the LO a little further
conf_level
- 0.75
+ 0.90
affinity
@@ -3091,12 +3377,16 @@ we shift the LO a little further
_coordinate
- (1336, 460)
+ (1206, 459)
_rotation
180
+
+ hysteresis
+ dot_samples/dec
+
id
satnogs_cw_to_symbol_0
@@ -3111,7 +3401,7 @@ we shift the LO a little further
sampling_rate
- audio_samp_rate/4
+ audio_samp_rate/10.0
wpm
@@ -3224,7 +3514,7 @@ we shift the LO a little further
_coordinate
- (952, 444)
+ (951, 483)
_rotation
@@ -3639,21 +3929,21 @@ we shift the LO a little further
20
+
+ analog_agc2_xx_0
+ low_pass_filter_0_0
+ 0
+ 0
+
analog_agc2_xx_0_0
blocks_multiply_xx_0
0
1
-
- analog_agc_xx_0
- low_pass_filter_0_0
- 0
- 0
-
analog_pll_carriertracking_cc_0
- blocks_complex_to_mag_squared_0
+ low_pass_filter_0
0
0
@@ -3664,8 +3954,8 @@ we shift the LO a little further
0
- blocks_complex_to_mag_squared_0
- analog_agc_xx_0
+ blocks_complex_to_mag_0
+ satnogs_cw_to_symbol_0
0
0
@@ -3675,6 +3965,18 @@ we shift the LO a little further
0
0
+
+ blocks_delay_0
+ blocks_multiply_conjugate_cc_0
+ 0
+ 1
+
+
+ blocks_multiply_conjugate_cc_0
+ fir_filter_xxx_0
+ 0
+ 0
+
blocks_multiply_xx_0
blocks_complex_to_real_0
@@ -3688,20 +3990,32 @@ we shift the LO a little further
0
- low_pass_filter_0
- analog_agc2_xx_0_0
+ fir_filter_xxx_0
+ blocks_complex_to_mag_0
0
0
low_pass_filter_0
- analog_pll_carriertracking_cc_0
+ blocks_delay_0
+ 0
+ 0
+
+
+ low_pass_filter_0
+ blocks_multiply_conjugate_cc_0
0
0
low_pass_filter_0_0
- satnogs_cw_to_symbol_0
+ analog_pll_carriertracking_cc_0
+ 0
+ 0
+
+
+ low_pass_filter_0_0_0
+ analog_agc2_xx_0_0
0
0
@@ -3713,7 +4027,13 @@ we shift the LO a little further
pfb_arb_resampler_xxx_0
- low_pass_filter_0
+ analog_agc2_xx_0
+ 0
+ 0
+
+
+ pfb_arb_resampler_xxx_0
+ low_pass_filter_0_0_0
0
0
diff --git a/apps/flowgraphs/fsk_ax25.grc b/apps/flowgraphs/fsk_ax25.grc
index e389e60..f19499e 100644
--- a/apps/flowgraphs/fsk_ax25.grc
+++ b/apps/flowgraphs/fsk_ax25.grc
@@ -136,7 +136,7 @@
_coordinate
- (1248, 196)
+ (1190, 411)
_rotation
@@ -179,7 +179,7 @@
_coordinate
- (992, 316)
+ (1030, 195)
_rotation
@@ -406,7 +406,7 @@
_coordinate
- (1432, 188)
+ (1390, 403)
_rotation
@@ -457,7 +457,7 @@
_coordinate
- (1208, 308)
+ (1206, 187)
_rotation
@@ -641,7 +641,7 @@
_coordinate
- (1616, 164)
+ (1590, 379)
_rotation
@@ -677,7 +677,7 @@
omega
- 2
+ 4
type
@@ -998,6 +998,81 @@ we shift the LO a little further
100e3
+
+ low_pass_filter
+
+ beta
+ 6.76
+
+
+ alias
+
+
+
+ comment
+
+
+
+ affinity
+
+
+
+ cutoff_freq
+ baudrate / 2 + 1500
+
+
+ decim
+ 1
+
+
+ _enabled
+ True
+
+
+ type
+ fir_filter_ccf
+
+
+ _coordinate
+ (1007, 363)
+
+
+ _rotation
+ 0
+
+
+ gain
+ 1
+
+
+ id
+ low_pass_filter_0
+
+
+ interp
+ 1
+
+
+ maxoutbuf
+ 0
+
+
+ minoutbuf
+ 0
+
+
+ samp_rate
+ 4.0 * baudrate
+
+
+ width
+ 1000
+
+
+ win
+ firdes.WIN_HAMMING
+
+
osmosdr_source
@@ -2457,7 +2532,7 @@ we shift the LO a little further
atten
- 100
+ 60
taps
@@ -2488,7 +2563,7 @@ we shift the LO a little further
_coordinate
- (984, 172)
+ (727, 275)
_rotation
@@ -2512,7 +2587,7 @@ we shift the LO a little further
rrate
- (2.0*baudrate)/audio_samp_rate
+ (4.0*baudrate)/satnogs.handle_samp_rate_rx(rx_sdr_device, samp_rate_rx)
samp_delay
@@ -2520,7 +2595,7 @@ we shift the LO a little further
atten
- 100
+ 60
taps
@@ -3088,7 +3163,7 @@ we shift the LO a little further
_coordinate
- (1384, 300)
+ (1382, 179)
_rotation
@@ -3500,6 +3575,12 @@ we shift the LO a little further
0
0
+
+ low_pass_filter_0
+ analog_quadrature_demod_cf_0_0
+ 0
+ 0
+
osmosdr_source_0
blocks_rotator_cc_0
@@ -3512,12 +3593,6 @@ we shift the LO a little further
0
0
-
- pfb_arb_resampler_xxx_0
- pfb_arb_resampler_xxx_0_0
- 0
- 0
-
pfb_arb_resampler_xxx_0
satnogs_iq_sink_0
@@ -3532,7 +3607,7 @@ we shift the LO a little further
pfb_arb_resampler_xxx_0_0
- analog_quadrature_demod_cf_0_0
+ low_pass_filter_0
0
0
@@ -3566,6 +3641,12 @@ we shift the LO a little further
0
0
+
+ satnogs_coarse_doppler_correction_cc_0
+ pfb_arb_resampler_xxx_0_0
+ 0
+ 0
+
satnogs_quad_demod_filter_ff_0
digital_binary_slicer_fb_0
diff --git a/apps/flowgraphs/msk_ax25.grc b/apps/flowgraphs/msk_ax25.grc
index 321727f..0db7bf8 100644
--- a/apps/flowgraphs/msk_ax25.grc
+++ b/apps/flowgraphs/msk_ax25.grc
@@ -136,7 +136,7 @@
_coordinate
- (1248, 196)
+ (1214, 419)
_rotation
@@ -406,7 +406,7 @@
_coordinate
- (1432, 188)
+ (1430, 411)
_rotation
@@ -641,7 +641,7 @@
_coordinate
- (1616, 164)
+ (1614, 387)
_rotation
@@ -677,7 +677,7 @@
omega
- 2
+ 4
type
@@ -998,6 +998,81 @@ we shift the LO a little further
100e3
+
+ low_pass_filter
+
+ beta
+ 6.76
+
+
+ alias
+
+
+
+ comment
+
+
+
+ affinity
+
+
+
+ cutoff_freq
+ baudrate / 2 + 1500
+
+
+ decim
+ 1
+
+
+ _enabled
+ True
+
+
+ type
+ fir_filter_ccf
+
+
+ _coordinate
+ (1022, 371)
+
+
+ _rotation
+ 0
+
+
+ gain
+ 1
+
+
+ id
+ low_pass_filter_0
+
+
+ interp
+ 1
+
+
+ maxoutbuf
+ 0
+
+
+ minoutbuf
+ 0
+
+
+ samp_rate
+ 4.0 * baudrate
+
+
+ width
+ 1000
+
+
+ win
+ firdes.WIN_HAMMING
+
+
osmosdr_source
@@ -2488,7 +2563,7 @@ we shift the LO a little further
_coordinate
- (984, 172)
+ (735, 395)
_rotation
@@ -2496,7 +2571,7 @@ we shift the LO a little further
id
- pfb_arb_resampler_xxx_0_0
+ pfb_arb_resampler_xxx_0_0_0
maxoutbuf
@@ -2512,7 +2587,7 @@ we shift the LO a little further
rrate
- (2.0*baudrate)/audio_samp_rate
+ (4.0*baudrate)/satnogs.handle_samp_rate_rx(rx_sdr_device, samp_rate_rx)
samp_delay
@@ -2520,7 +2595,7 @@ we shift the LO a little further
atten
- 100
+ 60
taps
@@ -3500,6 +3575,12 @@ we shift the LO a little further
0
0
+
+ low_pass_filter_0
+ analog_quadrature_demod_cf_0_0
+ 0
+ 0
+
osmosdr_source_0
blocks_rotator_cc_0
@@ -3512,12 +3593,6 @@ we shift the LO a little further
0
0
-
- pfb_arb_resampler_xxx_0
- pfb_arb_resampler_xxx_0_0
- 0
- 0
-
pfb_arb_resampler_xxx_0
satnogs_iq_sink_0
@@ -3531,8 +3606,8 @@ we shift the LO a little further
0
- pfb_arb_resampler_xxx_0_0
- analog_quadrature_demod_cf_0_0
+ pfb_arb_resampler_xxx_0_0_0
+ low_pass_filter_0
0
0
@@ -3566,6 +3641,12 @@ we shift the LO a little further
0
0
+
+ satnogs_coarse_doppler_correction_cc_0
+ pfb_arb_resampler_xxx_0_0_0
+ 0
+ 0
+
satnogs_quad_demod_filter_ff_0
digital_binary_slicer_fb_0
diff --git a/apps/flowgraphs/satnogs_cw_decoder.py b/apps/flowgraphs/satnogs_cw_decoder.py
index 630ba3c..4c3af5b 100755
--- a/apps/flowgraphs/satnogs_cw_decoder.py
+++ b/apps/flowgraphs/satnogs_cw_decoder.py
@@ -5,7 +5,7 @@
# Title: CW Decoder
# Author: Manolis Surligas (surligas@gmail.com)
# Description: A CW (Morse) Decoder
-# Generated: Sun Aug 19 21:56:19 2018
+# Generated: Sun Jan 6 13:47:58 2019
##################################################
from gnuradio import analog
@@ -25,7 +25,7 @@ import time
class satnogs_cw_decoder(gr.top_block):
- def __init__(self, antenna=satnogs.not_set_antenna, bb_gain=satnogs.not_set_rx_bb_gain, bfo_freq=1e3, decoded_data_file_path='/tmp/.satnogs/data/data', dev_args=satnogs.not_set_dev_args, doppler_correction_per_sec=1000, enable_iq_dump=0, file_path='test.txt', if_gain=satnogs.not_set_rx_if_gain, iq_file_path='/tmp/iq.dat', lo_offset=100e3, ppm=0, rf_gain=satnogs.not_set_rx_rf_gain, rigctl_port=4532, rx_freq=100e6, rx_sdr_device='usrpb200', udp_IP='127.0.0.1', udp_port=16887, waterfall_file_path='/tmp/waterfall.dat', wpm=20, samp_rate_rx=satnogs.not_set_samp_rate_rx):
+ def __init__(self, antenna=satnogs.not_set_antenna, bb_gain=satnogs.not_set_rx_bb_gain, bfo_freq=1e3, decoded_data_file_path='/tmp/.satnogs/data/data', dev_args=satnogs.not_set_dev_args, doppler_correction_per_sec=1000, enable_iq_dump=0, file_path='test.txt', if_gain=satnogs.not_set_rx_if_gain, iq_file_path='/tmp/iq.dat', lo_offset=100e3, ppm=0, rf_gain=satnogs.not_set_rx_rf_gain, rigctl_port=4532, rx_freq=100e6, rx_sdr_device='usrpb200', samp_rate_rx=satnogs.not_set_samp_rate_rx, udp_IP='127.0.0.1', udp_port=16887, waterfall_file_path='/tmp/waterfall.dat', wpm=20):
gr.top_block.__init__(self, "CW Decoder")
##################################################
@@ -47,16 +47,18 @@ class satnogs_cw_decoder(gr.top_block):
self.rigctl_port = rigctl_port
self.rx_freq = rx_freq
self.rx_sdr_device = rx_sdr_device
+ self.samp_rate_rx = samp_rate_rx
self.udp_IP = udp_IP
self.udp_port = udp_port
self.waterfall_file_path = waterfall_file_path
self.wpm = wpm
- self.samp_rate_rx = samp_rate_rx
##################################################
# Variables
##################################################
self.audio_samp_rate = audio_samp_rate = 48000
+ self.dot_samples = dot_samples = int((1.2 / wpm) / (1.0 / (audio_samp_rate / 10.0)))
+ self.dec = dec = 8
##################################################
# Blocks
@@ -68,7 +70,7 @@ class satnogs_cw_decoder(gr.top_block):
self.satnogs_morse_decoder_0 = satnogs.morse_decoder(ord('#'), 3)
self.satnogs_iq_sink_0 = satnogs.iq_sink(16768, iq_file_path, False, enable_iq_dump)
self.satnogs_frame_file_sink_0_0 = satnogs.frame_file_sink(decoded_data_file_path, 0)
- self.satnogs_cw_to_symbol_0 = satnogs.cw_to_symbol(audio_samp_rate/4, 0.4, 0.75, wpm)
+ self.satnogs_cw_to_symbol_0 = satnogs.cw_to_symbol(audio_samp_rate/10.0, 2.0, 0.90, wpm, dot_samples/dec)
self.satnogs_coarse_doppler_correction_cc_0 = satnogs.coarse_doppler_correction_cc(rx_freq, satnogs.handle_samp_rate_rx(rx_sdr_device, samp_rate_rx))
self.pfb_arb_resampler_xxx_0 = pfb.arb_resampler_ccf(
audio_samp_rate/satnogs.handle_samp_rate_rx(rx_sdr_device, samp_rate_rx),
@@ -89,20 +91,26 @@ class satnogs_cw_decoder(gr.top_block):
self.osmosdr_source_0.set_antenna(satnogs.handle_rx_antenna(rx_sdr_device, antenna), 0)
self.osmosdr_source_0.set_bandwidth(satnogs.handle_samp_rate_rx(rx_sdr_device, samp_rate_rx), 0)
- self.low_pass_filter_0_0 = filter.fir_filter_fff(4, firdes.low_pass(
- 4, audio_samp_rate, 100, 100, firdes.WIN_HAMMING, 6.76))
+ self.low_pass_filter_0_0_0 = filter.fir_filter_ccf(1, firdes.low_pass(
+ 1, audio_samp_rate, 2500, 0.8e3, firdes.WIN_HAMMING, 6.76))
+ self.low_pass_filter_0_0 = filter.fir_filter_ccf(10, firdes.low_pass(
+ 1, audio_samp_rate, 2500, 0.4e3, firdes.WIN_HAMMING, 6.76))
self.low_pass_filter_0 = filter.fir_filter_ccf(1, firdes.low_pass(
- 1, audio_samp_rate, 2e3, 1e3, firdes.WIN_HAMMING, 6.76))
+ 1, audio_samp_rate/10, 200, 0.1e3, firdes.WIN_HAMMING, 6.76))
+ self.fir_filter_xxx_0 = filter.fir_filter_ccc(1, ([1.0] * (int(dot_samples)/dec)))
+ self.fir_filter_xxx_0.declare_sample_delay(0)
self.blocks_rotator_cc_0 = blocks.rotator_cc(-2.0 * math.pi * (lo_offset / satnogs.handle_samp_rate_rx(rx_sdr_device, samp_rate_rx)))
self.blocks_multiply_xx_0 = blocks.multiply_vcc(1)
+ self.blocks_multiply_conjugate_cc_0 = blocks.multiply_conjugate_cc(1)
+ self.blocks_delay_0 = blocks.delay(gr.sizeof_gr_complex*1, int(dot_samples)/dec)
self.blocks_complex_to_real_0 = blocks.complex_to_real(1)
- self.blocks_complex_to_mag_squared_0 = blocks.complex_to_mag_squared(1)
+ self.blocks_complex_to_mag_0 = blocks.complex_to_mag(1)
self.analog_sig_source_x_0 = analog.sig_source_c(audio_samp_rate, analog.GR_COS_WAVE, bfo_freq, 1, 0)
- self.analog_pll_carriertracking_cc_0 = analog.pll_carriertracking_cc(2*math.pi/400.0, 2*math.pi*2e3/audio_samp_rate, -2*math.pi*2e3/audio_samp_rate)
- self.analog_agc_xx_0 = analog.agc_ff(1e-3, 1.0, 1.0)
- self.analog_agc_xx_0.set_max_gain(65536)
+ self.analog_pll_carriertracking_cc_0 = analog.pll_carriertracking_cc(2*math.pi/100, 2*math.pi*2500, -2*math.pi*2500)
self.analog_agc2_xx_0_0 = analog.agc2_cc(0.01, 0.001, 0.015, 0.0)
self.analog_agc2_xx_0_0.set_max_gain(65536)
+ self.analog_agc2_xx_0 = analog.agc2_cc(1e-4, 1e-4, 1.0, 1.0)
+ self.analog_agc2_xx_0.set_max_gain(65536)
@@ -113,19 +121,24 @@ class satnogs_cw_decoder(gr.top_block):
self.msg_connect((self.satnogs_morse_decoder_0, 'out'), (self.satnogs_frame_file_sink_0_0, 'frame'))
self.msg_connect((self.satnogs_morse_decoder_0, 'out'), (self.satnogs_udp_msg_sink_0_0, 'in'))
self.msg_connect((self.satnogs_tcp_rigctl_msg_source_0, 'freq'), (self.satnogs_coarse_doppler_correction_cc_0, 'freq'))
+ self.connect((self.analog_agc2_xx_0, 0), (self.low_pass_filter_0_0, 0))
self.connect((self.analog_agc2_xx_0_0, 0), (self.blocks_multiply_xx_0, 1))
- self.connect((self.analog_agc_xx_0, 0), (self.low_pass_filter_0_0, 0))
- self.connect((self.analog_pll_carriertracking_cc_0, 0), (self.blocks_complex_to_mag_squared_0, 0))
+ self.connect((self.analog_pll_carriertracking_cc_0, 0), (self.low_pass_filter_0, 0))
self.connect((self.analog_sig_source_x_0, 0), (self.blocks_multiply_xx_0, 0))
- self.connect((self.blocks_complex_to_mag_squared_0, 0), (self.analog_agc_xx_0, 0))
+ self.connect((self.blocks_complex_to_mag_0, 0), (self.satnogs_cw_to_symbol_0, 0))
self.connect((self.blocks_complex_to_real_0, 0), (self.satnogs_ogg_encoder_0, 0))
+ self.connect((self.blocks_delay_0, 0), (self.blocks_multiply_conjugate_cc_0, 1))
+ self.connect((self.blocks_multiply_conjugate_cc_0, 0), (self.fir_filter_xxx_0, 0))
self.connect((self.blocks_multiply_xx_0, 0), (self.blocks_complex_to_real_0, 0))
self.connect((self.blocks_rotator_cc_0, 0), (self.satnogs_coarse_doppler_correction_cc_0, 0))
- self.connect((self.low_pass_filter_0, 0), (self.analog_agc2_xx_0_0, 0))
- self.connect((self.low_pass_filter_0, 0), (self.analog_pll_carriertracking_cc_0, 0))
- self.connect((self.low_pass_filter_0_0, 0), (self.satnogs_cw_to_symbol_0, 0))
+ self.connect((self.fir_filter_xxx_0, 0), (self.blocks_complex_to_mag_0, 0))
+ self.connect((self.low_pass_filter_0, 0), (self.blocks_delay_0, 0))
+ self.connect((self.low_pass_filter_0, 0), (self.blocks_multiply_conjugate_cc_0, 0))
+ self.connect((self.low_pass_filter_0_0, 0), (self.analog_pll_carriertracking_cc_0, 0))
+ self.connect((self.low_pass_filter_0_0_0, 0), (self.analog_agc2_xx_0_0, 0))
self.connect((self.osmosdr_source_0, 0), (self.blocks_rotator_cc_0, 0))
- self.connect((self.pfb_arb_resampler_xxx_0, 0), (self.low_pass_filter_0, 0))
+ self.connect((self.pfb_arb_resampler_xxx_0, 0), (self.analog_agc2_xx_0, 0))
+ self.connect((self.pfb_arb_resampler_xxx_0, 0), (self.low_pass_filter_0_0_0, 0))
self.connect((self.pfb_arb_resampler_xxx_0, 0), (self.satnogs_iq_sink_0, 0))
self.connect((self.pfb_arb_resampler_xxx_0, 0), (self.satnogs_waterfall_sink_0, 0))
self.connect((self.satnogs_coarse_doppler_correction_cc_0, 0), (self.pfb_arb_resampler_xxx_0, 0))
@@ -244,6 +257,16 @@ class satnogs_cw_decoder(gr.top_block):
self.osmosdr_source_0.set_bandwidth(satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx), 0)
self.blocks_rotator_cc_0.set_phase_inc(-2.0 * math.pi * (self.lo_offset / satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx)))
+ 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
+ self.pfb_arb_resampler_xxx_0.set_rate(self.audio_samp_rate/satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx))
+ self.osmosdr_source_0.set_sample_rate(satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx))
+ self.osmosdr_source_0.set_bandwidth(satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx), 0)
+ self.blocks_rotator_cc_0.set_phase_inc(-2.0 * math.pi * (self.lo_offset / satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx)))
+
def get_udp_IP(self):
return self.udp_IP
@@ -267,28 +290,35 @@ class satnogs_cw_decoder(gr.top_block):
def set_wpm(self, wpm):
self.wpm = wpm
-
- 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
- self.pfb_arb_resampler_xxx_0.set_rate(self.audio_samp_rate/satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx))
- self.osmosdr_source_0.set_sample_rate(satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx))
- self.osmosdr_source_0.set_bandwidth(satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx), 0)
- self.blocks_rotator_cc_0.set_phase_inc(-2.0 * math.pi * (self.lo_offset / satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx)))
+ self.set_dot_samples(int((1.2 / self.wpm) / (1.0 / (self.audio_samp_rate / 10.0))))
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.set_dot_samples(int((1.2 / self.wpm) / (1.0 / (self.audio_samp_rate / 10.0))))
self.pfb_arb_resampler_xxx_0.set_rate(self.audio_samp_rate/satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx))
- self.low_pass_filter_0_0.set_taps(firdes.low_pass(4, self.audio_samp_rate, 100, 100, firdes.WIN_HAMMING, 6.76))
- self.low_pass_filter_0.set_taps(firdes.low_pass(1, self.audio_samp_rate, 2e3, 1e3, firdes.WIN_HAMMING, 6.76))
+ self.low_pass_filter_0_0_0.set_taps(firdes.low_pass(1, self.audio_samp_rate, 2500, 0.8e3, firdes.WIN_HAMMING, 6.76))
+ self.low_pass_filter_0_0.set_taps(firdes.low_pass(1, self.audio_samp_rate, 2500, 0.4e3, firdes.WIN_HAMMING, 6.76))
+ self.low_pass_filter_0.set_taps(firdes.low_pass(1, self.audio_samp_rate/10, 200, 0.1e3, firdes.WIN_HAMMING, 6.76))
self.analog_sig_source_x_0.set_sampling_freq(self.audio_samp_rate)
- self.analog_pll_carriertracking_cc_0.set_max_freq(2*math.pi*2e3/self.audio_samp_rate)
- self.analog_pll_carriertracking_cc_0.set_min_freq(-2*math.pi*2e3/self.audio_samp_rate)
+
+ def get_dot_samples(self):
+ return self.dot_samples
+
+ def set_dot_samples(self, dot_samples):
+ self.dot_samples = dot_samples
+ self.fir_filter_xxx_0.set_taps(([1.0] * (int(self.dot_samples)/self.dec)))
+ self.blocks_delay_0.set_dly(int(self.dot_samples)/self.dec)
+
+ def get_dec(self):
+ return self.dec
+
+ def set_dec(self, dec):
+ self.dec = dec
+ self.fir_filter_xxx_0.set_taps(([1.0] * (int(self.dot_samples)/self.dec)))
+ self.blocks_delay_0.set_dly(int(self.dot_samples)/self.dec)
def argument_parser():
@@ -342,6 +372,9 @@ def argument_parser():
parser.add_option(
"", "--rx-sdr-device", dest="rx_sdr_device", type="string", default='usrpb200',
help="Set rx_sdr_device [default=%default]")
+ parser.add_option(
+ "", "--samp-rate-rx", dest="samp_rate_rx", type="eng_float", default=eng_notation.num_to_str(satnogs.not_set_samp_rate_rx),
+ help="Set samp_rate_rx [default=%default]")
parser.add_option(
"", "--udp-IP", dest="udp_IP", type="string", default='127.0.0.1',
help="Set udp_IP [default=%default]")
@@ -354,9 +387,6 @@ def argument_parser():
parser.add_option(
"", "--wpm", dest="wpm", type="intx", default=20,
help="Set wpm [default=%default]")
- parser.add_option(
- "", "--samp-rate-rx", dest="samp_rate_rx", type="eng_float", default=eng_notation.num_to_str(satnogs.not_set_samp_rate_rx),
- help="Set samp_rate_rx [default=%default]")
return parser
@@ -364,7 +394,7 @@ def main(top_block_cls=satnogs_cw_decoder, options=None):
if options is None:
options, _ = argument_parser().parse_args()
- tb = top_block_cls(antenna=options.antenna, bb_gain=options.bb_gain, bfo_freq=options.bfo_freq, 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, if_gain=options.if_gain, iq_file_path=options.iq_file_path, lo_offset=options.lo_offset, ppm=options.ppm, rf_gain=options.rf_gain, rigctl_port=options.rigctl_port, rx_freq=options.rx_freq, rx_sdr_device=options.rx_sdr_device, udp_IP=options.udp_IP, udp_port=options.udp_port, waterfall_file_path=options.waterfall_file_path, wpm=options.wpm, samp_rate_rx=options.samp_rate_rx)
+ tb = top_block_cls(antenna=options.antenna, bb_gain=options.bb_gain, bfo_freq=options.bfo_freq, 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, if_gain=options.if_gain, iq_file_path=options.iq_file_path, lo_offset=options.lo_offset, ppm=options.ppm, rf_gain=options.rf_gain, rigctl_port=options.rigctl_port, rx_freq=options.rx_freq, rx_sdr_device=options.rx_sdr_device, samp_rate_rx=options.samp_rate_rx, udp_IP=options.udp_IP, udp_port=options.udp_port, waterfall_file_path=options.waterfall_file_path, wpm=options.wpm)
tb.start()
tb.wait()
diff --git a/apps/flowgraphs/satnogs_fsk_ax25.py b/apps/flowgraphs/satnogs_fsk_ax25.py
index 780b1f4..acdef68 100755
--- a/apps/flowgraphs/satnogs_fsk_ax25.py
+++ b/apps/flowgraphs/satnogs_fsk_ax25.py
@@ -5,7 +5,7 @@
# Title: satnogs_fsk_ax25
# Author: Manolis Surligas (surligas@gmail.com)
# Description: Generic FSK AX.25 decoder
-# Generated: Fri Aug 17 00:38:04 2018
+# Generated: Sun Jan 6 14:19:34 2019
##################################################
from gnuradio import analog
@@ -72,7 +72,7 @@ class satnogs_fsk_ax25(gr.top_block):
self.satnogs_ax25_decoder_bm_0_0 = satnogs.ax25_decoder_bm('GND', 0, True, False, 1024)
self.satnogs_ax25_decoder_bm_0 = satnogs.ax25_decoder_bm('GND', 0, True, True, 1024)
self.pfb_arb_resampler_xxx_0_0 = pfb.arb_resampler_ccf(
- (2.0*baudrate)/audio_samp_rate,
+ (4.0*baudrate)/satnogs.handle_samp_rate_rx(rx_sdr_device, samp_rate_rx),
taps=None,
flt_size=32)
self.pfb_arb_resampler_xxx_0_0.declare_sample_delay(0)
@@ -96,7 +96,9 @@ class satnogs_fsk_ax25(gr.top_block):
self.osmosdr_source_0.set_antenna(satnogs.handle_rx_antenna(rx_sdr_device, antenna), 0)
self.osmosdr_source_0.set_bandwidth(satnogs.handle_samp_rate_rx(rx_sdr_device, samp_rate_rx), 0)
- self.digital_clock_recovery_mm_xx_0 = digital.clock_recovery_mm_ff(2, 0.25*0.175*0.175, 0.5, 0.175, 0.005)
+ self.low_pass_filter_0 = filter.fir_filter_ccf(1, firdes.low_pass(
+ 1, 4.0 * baudrate, baudrate / 2 + 1500, 1000, firdes.WIN_HAMMING, 6.76))
+ self.digital_clock_recovery_mm_xx_0 = digital.clock_recovery_mm_ff(4, 0.25*0.175*0.175, 0.5, 0.175, 0.005)
self.digital_binary_slicer_fb_0 = digital.binary_slicer_fb()
self.dc_blocker_xx_0_0 = filter.dc_blocker_ff(1024, True)
self.dc_blocker_xx_0 = filter.dc_blocker_ff(1024, True)
@@ -122,13 +124,14 @@ class satnogs_fsk_ax25(gr.top_block):
self.connect((self.digital_binary_slicer_fb_0, 0), (self.satnogs_ax25_decoder_bm_0, 0))
self.connect((self.digital_binary_slicer_fb_0, 0), (self.satnogs_ax25_decoder_bm_0_0, 0))
self.connect((self.digital_clock_recovery_mm_xx_0, 0), (self.satnogs_quad_demod_filter_ff_0, 0))
+ self.connect((self.low_pass_filter_0, 0), (self.analog_quadrature_demod_cf_0_0, 0))
self.connect((self.osmosdr_source_0, 0), (self.blocks_rotator_cc_0, 0))
self.connect((self.pfb_arb_resampler_xxx_0, 0), (self.analog_quadrature_demod_cf_0_0_0, 0))
- self.connect((self.pfb_arb_resampler_xxx_0, 0), (self.pfb_arb_resampler_xxx_0_0, 0))
self.connect((self.pfb_arb_resampler_xxx_0, 0), (self.satnogs_iq_sink_0, 0))
self.connect((self.pfb_arb_resampler_xxx_0, 0), (self.satnogs_waterfall_sink_0, 0))
- self.connect((self.pfb_arb_resampler_xxx_0_0, 0), (self.analog_quadrature_demod_cf_0_0, 0))
+ self.connect((self.pfb_arb_resampler_xxx_0_0, 0), (self.low_pass_filter_0, 0))
self.connect((self.satnogs_coarse_doppler_correction_cc_0, 0), (self.pfb_arb_resampler_xxx_0, 0))
+ self.connect((self.satnogs_coarse_doppler_correction_cc_0, 0), (self.pfb_arb_resampler_xxx_0_0, 0))
self.connect((self.satnogs_quad_demod_filter_ff_0, 0), (self.digital_binary_slicer_fb_0, 0))
def get_antenna(self):
@@ -143,7 +146,8 @@ class satnogs_fsk_ax25(gr.top_block):
def set_baudrate(self, baudrate):
self.baudrate = baudrate
- self.pfb_arb_resampler_xxx_0_0.set_rate((2.0*self.baudrate)/self.audio_samp_rate)
+ self.pfb_arb_resampler_xxx_0_0.set_rate((4.0*self.baudrate)/satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx))
+ self.low_pass_filter_0.set_taps(firdes.low_pass(1, 4.0 * self.baudrate, self.baudrate / 2 + 1500, 1000, firdes.WIN_HAMMING, 6.76))
def get_bb_gain(self):
return self.bb_gain
@@ -236,6 +240,7 @@ class satnogs_fsk_ax25(gr.top_block):
def set_rx_sdr_device(self, rx_sdr_device):
self.rx_sdr_device = rx_sdr_device
+ self.pfb_arb_resampler_xxx_0_0.set_rate((4.0*self.baudrate)/satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx))
self.pfb_arb_resampler_xxx_0.set_rate(self.audio_samp_rate/satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx))
self.osmosdr_source_0.set_sample_rate(satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx))
self.osmosdr_source_0.set_gain(satnogs.handle_rx_rf_gain(self.rx_sdr_device, self.rf_gain), 0)
@@ -250,6 +255,7 @@ class satnogs_fsk_ax25(gr.top_block):
def set_samp_rate_rx(self, samp_rate_rx):
self.samp_rate_rx = samp_rate_rx
+ self.pfb_arb_resampler_xxx_0_0.set_rate((4.0*self.baudrate)/satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx))
self.pfb_arb_resampler_xxx_0.set_rate(self.audio_samp_rate/satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx))
self.osmosdr_source_0.set_sample_rate(satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx))
self.osmosdr_source_0.set_bandwidth(satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx), 0)
@@ -278,7 +284,6 @@ class satnogs_fsk_ax25(gr.top_block):
def set_audio_samp_rate(self, audio_samp_rate):
self.audio_samp_rate = audio_samp_rate
- self.pfb_arb_resampler_xxx_0_0.set_rate((2.0*self.baudrate)/self.audio_samp_rate)
self.pfb_arb_resampler_xxx_0.set_rate(self.audio_samp_rate/satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx))
diff --git a/apps/flowgraphs/satnogs_msk_ax25.py b/apps/flowgraphs/satnogs_msk_ax25.py
index 09fe10c..7d12bf6 100755
--- a/apps/flowgraphs/satnogs_msk_ax25.py
+++ b/apps/flowgraphs/satnogs_msk_ax25.py
@@ -5,7 +5,7 @@
# Title: satnogs_msk_ax25
# Author: Manolis Surligas (surligas@gmail.com)
# Description: Generic MSK AX.25 decoder
-# Generated: Fri Aug 17 00:38:15 2018
+# Generated: Sun Jan 6 14:17:55 2019
##################################################
from gnuradio import analog
@@ -71,11 +71,11 @@ class satnogs_msk_ax25(gr.top_block):
self.satnogs_coarse_doppler_correction_cc_0 = satnogs.coarse_doppler_correction_cc(rx_freq, satnogs.handle_samp_rate_rx(rx_sdr_device, samp_rate_rx))
self.satnogs_ax25_decoder_bm_0_0 = satnogs.ax25_decoder_bm('GND', 0, True, False, 1024)
self.satnogs_ax25_decoder_bm_0 = satnogs.ax25_decoder_bm('GND', 0, True, True, 1024)
- self.pfb_arb_resampler_xxx_0_0 = pfb.arb_resampler_ccf(
- (2.0*baudrate)/audio_samp_rate,
+ self.pfb_arb_resampler_xxx_0_0_0 = pfb.arb_resampler_ccf(
+ (4.0*baudrate)/satnogs.handle_samp_rate_rx(rx_sdr_device, samp_rate_rx),
taps=None,
flt_size=32)
- self.pfb_arb_resampler_xxx_0_0.declare_sample_delay(0)
+ self.pfb_arb_resampler_xxx_0_0_0.declare_sample_delay(0)
self.pfb_arb_resampler_xxx_0 = pfb.arb_resampler_ccf(
audio_samp_rate/satnogs.handle_samp_rate_rx(rx_sdr_device, samp_rate_rx),
@@ -96,7 +96,9 @@ class satnogs_msk_ax25(gr.top_block):
self.osmosdr_source_0.set_antenna(satnogs.handle_rx_antenna(rx_sdr_device, antenna), 0)
self.osmosdr_source_0.set_bandwidth(satnogs.handle_samp_rate_rx(rx_sdr_device, samp_rate_rx), 0)
- self.digital_clock_recovery_mm_xx_0 = digital.clock_recovery_mm_ff(2, 0.25*0.175*0.175, 0.5, 0.175, 0.005)
+ self.low_pass_filter_0 = filter.fir_filter_ccf(1, firdes.low_pass(
+ 1, 4.0 * baudrate, baudrate / 2 + 1500, 1000, firdes.WIN_HAMMING, 6.76))
+ self.digital_clock_recovery_mm_xx_0 = digital.clock_recovery_mm_ff(4, 0.25*0.175*0.175, 0.5, 0.175, 0.005)
self.digital_binary_slicer_fb_0 = digital.binary_slicer_fb()
self.dc_blocker_xx_0_0 = filter.dc_blocker_ff(1024, True)
self.dc_blocker_xx_0 = filter.dc_blocker_ff(1024, True)
@@ -122,13 +124,14 @@ class satnogs_msk_ax25(gr.top_block):
self.connect((self.digital_binary_slicer_fb_0, 0), (self.satnogs_ax25_decoder_bm_0, 0))
self.connect((self.digital_binary_slicer_fb_0, 0), (self.satnogs_ax25_decoder_bm_0_0, 0))
self.connect((self.digital_clock_recovery_mm_xx_0, 0), (self.satnogs_quad_demod_filter_ff_0, 0))
+ self.connect((self.low_pass_filter_0, 0), (self.analog_quadrature_demod_cf_0_0, 0))
self.connect((self.osmosdr_source_0, 0), (self.blocks_rotator_cc_0, 0))
self.connect((self.pfb_arb_resampler_xxx_0, 0), (self.analog_quadrature_demod_cf_0_0_0, 0))
- self.connect((self.pfb_arb_resampler_xxx_0, 0), (self.pfb_arb_resampler_xxx_0_0, 0))
self.connect((self.pfb_arb_resampler_xxx_0, 0), (self.satnogs_iq_sink_0, 0))
self.connect((self.pfb_arb_resampler_xxx_0, 0), (self.satnogs_waterfall_sink_0, 0))
- self.connect((self.pfb_arb_resampler_xxx_0_0, 0), (self.analog_quadrature_demod_cf_0_0, 0))
+ self.connect((self.pfb_arb_resampler_xxx_0_0_0, 0), (self.low_pass_filter_0, 0))
self.connect((self.satnogs_coarse_doppler_correction_cc_0, 0), (self.pfb_arb_resampler_xxx_0, 0))
+ self.connect((self.satnogs_coarse_doppler_correction_cc_0, 0), (self.pfb_arb_resampler_xxx_0_0_0, 0))
self.connect((self.satnogs_quad_demod_filter_ff_0, 0), (self.digital_binary_slicer_fb_0, 0))
def get_antenna(self):
@@ -143,7 +146,8 @@ class satnogs_msk_ax25(gr.top_block):
def set_baudrate(self, baudrate):
self.baudrate = baudrate
- self.pfb_arb_resampler_xxx_0_0.set_rate((2.0*self.baudrate)/self.audio_samp_rate)
+ self.pfb_arb_resampler_xxx_0_0_0.set_rate((4.0*self.baudrate)/satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx))
+ self.low_pass_filter_0.set_taps(firdes.low_pass(1, 4.0 * self.baudrate, self.baudrate / 2 + 1500, 1000, firdes.WIN_HAMMING, 6.76))
def get_bb_gain(self):
return self.bb_gain
@@ -236,6 +240,7 @@ class satnogs_msk_ax25(gr.top_block):
def set_rx_sdr_device(self, rx_sdr_device):
self.rx_sdr_device = rx_sdr_device
+ self.pfb_arb_resampler_xxx_0_0_0.set_rate((4.0*self.baudrate)/satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx))
self.pfb_arb_resampler_xxx_0.set_rate(self.audio_samp_rate/satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx))
self.osmosdr_source_0.set_sample_rate(satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx))
self.osmosdr_source_0.set_gain(satnogs.handle_rx_rf_gain(self.rx_sdr_device, self.rf_gain), 0)
@@ -250,6 +255,7 @@ class satnogs_msk_ax25(gr.top_block):
def set_samp_rate_rx(self, samp_rate_rx):
self.samp_rate_rx = samp_rate_rx
+ self.pfb_arb_resampler_xxx_0_0_0.set_rate((4.0*self.baudrate)/satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx))
self.pfb_arb_resampler_xxx_0.set_rate(self.audio_samp_rate/satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx))
self.osmosdr_source_0.set_sample_rate(satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx))
self.osmosdr_source_0.set_bandwidth(satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx), 0)
@@ -278,7 +284,6 @@ class satnogs_msk_ax25(gr.top_block):
def set_audio_samp_rate(self, audio_samp_rate):
self.audio_samp_rate = audio_samp_rate
- self.pfb_arb_resampler_xxx_0_0.set_rate((2.0*self.baudrate)/self.audio_samp_rate)
self.pfb_arb_resampler_xxx_0.set_rate(self.audio_samp_rate/satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx))
diff --git a/apps/flowgraphs/satnogs_sstv_pd120_demod.py b/apps/flowgraphs/satnogs_sstv_pd120_demod.py
index 6315b41..30c17c0 100755
--- a/apps/flowgraphs/satnogs_sstv_pd120_demod.py
+++ b/apps/flowgraphs/satnogs_sstv_pd120_demod.py
@@ -5,9 +5,10 @@
# Title: SSTV PD120 Demodulation
# Author: Sebastian Schumb (sebastian@sebastains-site.de)
# Description: A PD120 SSTV demodulator
-# Generated: Fri Apr 5 23:30:50 2019
+# GNU Radio version: 3.7.13.5
##################################################
+
from gnuradio import analog
from gnuradio import eng_notation
from gnuradio import filter
@@ -91,6 +92,7 @@ class satnogs_sstv_pd120_demod(gr.top_block):
1, 12000, 1500, 1000, firdes.WIN_HAMMING, 6.76))
self.low_pass_filter_0 = filter.fir_filter_ccf(1, firdes.low_pass(
1, audio_samp_rate, deviation+max_modulation_freq, 3000, 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(4, (63, ), 1750, audio_samp_rate)
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.blks2_rational_resampler_xxx_1 = filter.rational_resampler_ccc(
@@ -114,14 +116,15 @@ class satnogs_sstv_pd120_demod(gr.top_block):
##################################################
self.msg_connect((self.satnogs_tcp_rigctl_msg_source_0, 'freq'), (self.satnogs_coarse_doppler_correction_cc_0, 'freq'))
self.connect((self.analog_nbfm_rx_0, 0), (self.low_pass_filter_0_0, 0))
+ self.connect((self.analog_quadrature_demod_cf_0, 0), (self.hilbert_fc_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.freq_xlating_fir_filter_xxx_0, 0), (self.blks2_rational_resampler_xxx_1, 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), (self.analog_quadrature_demod_cf_0, 0))
- self.connect((self.low_pass_filter_0, 0), (self.freq_xlating_fir_filter_xxx_0_0, 0))
self.connect((self.low_pass_filter_0_0, 0), (self.rational_resampler_xxx_0, 0))
self.connect((self.osmosdr_source_0, 0), (self.satnogs_coarse_doppler_correction_cc_0, 0))
self.connect((self.rational_resampler_xxx_0, 0), (self.satnogs_sstv_pd120_sink_0, 0))
diff --git a/apps/flowgraphs/sstv_pd120_demod.grc b/apps/flowgraphs/sstv_pd120_demod.grc
index 27e5998..8228e84 100644
--- a/apps/flowgraphs/sstv_pd120_demod.grc
+++ b/apps/flowgraphs/sstv_pd120_demod.grc
@@ -323,7 +323,7 @@ TX sampling rate
_coordinate
- (964, 562)
+ (877, 562)
_rotation
@@ -374,11 +374,11 @@ TX sampling rate
_coordinate
- (1204, 474)
+ (1252, 291)
_rotation
- 180
+ 0
gain
@@ -872,7 +872,7 @@ TX sampling rate
_coordinate
- (1164, 562)
+ (1076, 562)
_rotation
@@ -903,6 +903,57 @@ TX sampling rate
ccc
+
+ hilbert_fc
+
+ beta
+ 6.76
+
+
+ alias
+
+
+
+ comment
+
+
+
+ affinity
+
+
+
+ _enabled
+ True
+
+
+ _coordinate
+ (1323, 602)
+
+
+ _rotation
+ 180
+
+
+ id
+ hilbert_fc_0
+
+
+ maxoutbuf
+ 0
+
+
+ minoutbuf
+ 0
+
+
+ num_taps
+ 65
+
+
+ win
+ firdes.WIN_HAMMING
+
+
parameter
@@ -1159,7 +1210,7 @@ max_modulation_freq = 3000
_coordinate
- (781, 538)
+ (693, 538)
_rotation
@@ -2680,7 +2731,7 @@ max_modulation_freq = 3000
_coordinate
- (590, 562)
+ (494, 562)
_rotation
@@ -3017,11 +3068,11 @@ max_modulation_freq = 3000
_coordinate
- (1004, 458)
+ (1531, 275)
_rotation
- 180
+ 0
id
@@ -3056,7 +3107,7 @@ max_modulation_freq = 3000
_coordinate
- (342, 586)
+ (263, 586)
_rotation
@@ -3238,6 +3289,12 @@ max_modulation_freq = 3000
0
0
+
+ analog_quadrature_demod_cf_0
+ hilbert_fc_0
+ 0
+ 0
+
analog_quadrature_demod_cf_0
satnogs_ogg_encoder_0
@@ -3275,14 +3332,14 @@ max_modulation_freq = 3000
0
- low_pass_filter_0
- analog_quadrature_demod_cf_0
+ hilbert_fc_0
+ freq_xlating_fir_filter_xxx_0_0
0
0
low_pass_filter_0
- freq_xlating_fir_filter_xxx_0_0
+ analog_quadrature_demod_cf_0
0
0
diff --git a/grc/satnogs_cw_to_symbol.xml b/grc/satnogs_cw_to_symbol.xml
index 984c241..89ea992 100644
--- a/grc/satnogs_cw_to_symbol.xml
+++ b/grc/satnogs_cw_to_symbol.xml
@@ -1,51 +1,58 @@
- CW to Symbols
- satnogs_cw_to_symbol
- import satnogs
- satnogs.cw_to_symbol($sampling_rate, $threshold, $conf_level, $wpm)
- set_act_threshold($threshold)
-
-
- Sampling Rate
- sampling_rate
- samp_rate
- real
-
+ CW to Symbols
+ satnogs_cw_to_symbol
+ import satnogs
+ satnogs.cw_to_symbol($sampling_rate, $threshold, $conf_level, $wpm, $hysteresis)
+ set_act_threshold($threshold)
-
- Activation Threshold
- threshold
- real
-
-
-
- Confidence Level
- conf_level
- 0.9
- real
-
+
+ Sampling Rate
+ sampling_rate
+ samp_rate
+ real
+
-
- Words per Minute
- wpm
- 20
- int
-
+
+ Activation Threshold
+ threshold
+ real
+
-
- act_threshold
- message
- 1
-
-
-
- in
- float
-
+
+ Confidence Level
+ conf_level
+ 0.9
+ real
+
-
+
+ Words per Minute
+ wpm
+ 20
+ int
+
+
+
+ Hysteresis
+ hysteresis
+ 0
+ int
+
+
+
+ act_threshold
+ message
+ 1
+
+
+
+ in
+ float
+
+
+
diff --git a/include/satnogs/cw_to_symbol.h b/include/satnogs/cw_to_symbol.h
index acf5aef..6a05bbf 100644
--- a/include/satnogs/cw_to_symbol.h
+++ b/include/satnogs/cw_to_symbol.h
@@ -24,6 +24,9 @@
#include
#include
+#define MIN_WPM 5
+#define MAX_WPM 50
+
namespace gr
{
namespace satnogs
@@ -65,10 +68,19 @@ namespace gr
* symbols
*
* @param wpm Morse code Words per Minute
+ *
+ * @param hysteresis this value represents the hysteresis of a possible
+ * filter used before the CW to Symbol block. For example if there is
+ * a moving average filter with x taps, the full power of the signal
+ * will be available after x samples. The total length of samples with
+ * maximum power will be 2*x less. Because the block searches for plateaus
+ * with proper durations, this filtering hysteresis should be known.
+ * If no such a filter is used, the hysteresis value should be set to zero.
*/
static cw_to_symbol::sptr
make (double sampling_rate, float threshold, float conf_level = 0.9,
- size_t wpm = 20);
+ size_t wpm = 20,
+ size_t hysteresis = 0);
virtual void
set_act_threshold (float thrld) = 0;
diff --git a/include/satnogs/morse.h b/include/satnogs/morse.h
index af643b5..b7e96cf 100644
--- a/include/satnogs/morse.h
+++ b/include/satnogs/morse.h
@@ -2,7 +2,7 @@
/*
* gr-satnogs: SatNOGS GNU Radio Out-Of-Tree Module
*
- * Copyright (C) 2016,2017
+ * Copyright (C) 2016-2018
* Libre Space Foundation
*
* This program is free software: you can redistribute it and/or modify
@@ -22,8 +22,6 @@
#ifndef INCLUDE_SATNOGS_MORSE_H_
#define INCLUDE_SATNOGS_MORSE_H_
-#define MIN_WPM 5
-#define MAX_WPM 30
/**
* The different Morse symbols
*/
@@ -32,7 +30,8 @@ typedef enum {
MORSE_DASH, //!< Morse dash (-) symbol
MORSE_INTRA_SPACE, //!< Space between dot and dash symbols
MORSE_S_SPACE, //!< Morse short space between characters
- MORSE_L_SPACE //!
#include
#if BOOST_VERSION >= 106500
- #include
+#include
#else
- #include
+#include
#endif
#include
namespace gr
{
- namespace satnogs
- {
+namespace satnogs
+{
- cw_to_symbol::sptr
- cw_to_symbol::make (double sampling_rate, float threshold, float conf_level,
- size_t wpm)
- {
- return gnuradio::get_initial_sptr (
- new cw_to_symbol_impl (sampling_rate, threshold, conf_level, wpm));
- }
+cw_to_symbol::sptr
+cw_to_symbol::make (double sampling_rate, float threshold, float conf_level,
+ size_t wpm, size_t hysteresis)
+{
+ return gnuradio::get_initial_sptr (
+ new cw_to_symbol_impl (sampling_rate, threshold, conf_level, wpm,
+ hysteresis));
+}
- /*
- * The private constructor
- */
- cw_to_symbol_impl::cw_to_symbol_impl (double sampling_rate, float threshold,
- float conf_level, size_t wpm) :
- gr::sync_block ("cw_to_symbol",
- gr::io_signature::make (1, 1, sizeof(float)),
- gr::io_signature::make (0, 0, 0)),
- d_sampling_rate (sampling_rate),
- d_act_thrshld (threshold),
- d_confidence_level (conf_level),
- d_dot_samples ((1.2 / wpm) * sampling_rate),
- d_window_size(0),
- d_window_cnt(0),
- d_dot_windows_num(0),
- d_dec_state (NO_SYNC),
- d_prev_space_symbol (true)
- {
- if (wpm < MIN_WPM) {
- throw std::invalid_argument (
- "Decoder can not handle such low WPM setting");
- }
+/*
+ * The private constructor
+ */
+cw_to_symbol_impl::cw_to_symbol_impl (double sampling_rate, float threshold,
+ float conf_level, size_t wpm,
+ size_t hysteresis) :
+ gr::sync_block ("cw_to_symbol",
+ gr::io_signature::make (1, 1, sizeof(float)),
+ gr::io_signature::make (0, 0, 0)),
+ d_sampling_rate (sampling_rate),
+ d_act_thrshld (threshold),
+ d_confidence_level (conf_level),
+ d_dot_samples ((1.2 / wpm) * sampling_rate),
+ d_window_size (0),
+ d_window_cnt (0),
+ d_idle_cnt (0),
+ d_dot_windows_num (0),
+ d_dec_state (NO_SYNC),
+ d_prev_space_symbol (true)
+{
+ if (wpm < MIN_WPM) {
+ throw std::invalid_argument ("Decoder can not handle such low WPM setting");
+ }
- if (wpm > MAX_WPM) {
- throw std::invalid_argument (
- "Decoder can not handle such high WPM setting");
- }
+ if (wpm > MAX_WPM) {
+ throw std::invalid_argument (
+ "Decoder can not handle such high WPM setting");
+ }
- if (conf_level > 1.0 || conf_level < 0.5) {
- throw std::invalid_argument (
- "Confidence level should be in the range [0.5, 1.0]");
- }
+ if (conf_level > 1.0 || conf_level < 0.5) {
+ throw std::invalid_argument (
+ "Confidence level should be in the range [0.5, 1.0]");
+ }
- message_port_register_in (pmt::mp ("act_threshold"));
- message_port_register_out (pmt::mp ("out"));
+ if(hysteresis > d_dot_samples / 4) {
+ throw std::invalid_argument ("Too large hysteresis value");
+ }
- /* Register the message handlers */
- set_msg_handler (
- pmt::mp ("act_threshold"),
- boost::bind (&cw_to_symbol_impl::set_act_threshold_msg_handler, this,
- _1));
+ message_port_register_in (pmt::mp ("act_threshold"));
+ message_port_register_out (pmt::mp ("out"));
- /*
- * Try to split the CW pulses in smaller windows for detecting faster
- * a false alarm. As we use the window size for setting the history
- * it should have a reasonably size.
- */
- size_t i = 1;
- d_window_size = d_dot_samples / i;
- while(d_window_size > 64) {
- i++;
- d_window_size = d_dot_samples / i;
- }
+ /* Register the message handlers */
+ set_msg_handler (
+ pmt::mp ("act_threshold"),
+ boost::bind (&cw_to_symbol_impl::set_act_threshold_msg_handler, this,
+ _1));
- /* NOTE: The dot duration should be a perfect multiple of the window */
- while(d_dot_samples % d_window_size != 0) {
- d_window_size++;
- }
+ /*
+ * Reconsider the dot oulse duration based on the confidence level
+ * and hysteresis
+ */
+ d_dot_samples = d_dot_samples - 2 * (hysteresis * conf_level);
- LOG_WARN("Dot symbol samples: %lu", d_dot_samples);
- LOG_WARN("Window size: %lu", d_window_size);
- /* Set the duration of each symbol in multiples of the window size */
- d_dot_windows_num = d_dot_samples / d_window_size;
- d_dash_windows_num = 3 * d_dot_windows_num;
- d_short_pause_windows_num = d_dash_windows_num;
- d_long_pause_windows_num = 7 * d_dot_windows_num;
+ /*
+ * Try to split the CW pulses in smaller windows for detecting faster
+ * a false alarm. As we use the window size for setting the history
+ * it should have a reasonably size.
+ */
+ size_t i = 1;
+ d_window_size = d_dot_samples / i;
+ while (d_window_size > 64) {
+ i++;
+ d_window_size = d_dot_samples / i;
+ }
- const int alignment_multiple = volk_get_alignment ()
- / (d_window_size * sizeof(float));
- set_alignment (std::max (1, alignment_multiple));
+ /* NOTE: The dot duration should be a perfect multiple of the window */
+ while (d_dot_samples % d_window_size != 0) {
+ d_window_size++;
+ }
- d_const_val = (float *) volk_malloc(d_window_size * sizeof(float),
- volk_get_alignment ());
- d_tmp = (float *) volk_malloc(d_window_size * sizeof(float),
- volk_get_alignment ());
- d_out = (int32_t *) volk_malloc (d_window_size * sizeof(int32_t),
+ LOG_DEBUG("Dot symbol samples: %lu", d_dot_samples);
+ LOG_DEBUG("Window size: %lu", d_window_size);
+
+ /* Set the duration of each symbol in multiples of the window size */
+ d_dot_windows_num = d_dot_samples / d_window_size;
+ d_dash_windows_num = 3 * d_dot_windows_num;
+ d_short_pause_windows_num = d_dash_windows_num;
+ d_long_pause_windows_num = 7 * d_dot_windows_num;
+
+ const int alignment_multiple = volk_get_alignment ()
+ / (d_window_size * sizeof(float));
+ set_alignment (std::max (1, alignment_multiple));
+
+ d_const_val = (float *) volk_malloc (d_window_size * sizeof(float),
volk_get_alignment ());
+ d_tmp = (float *) volk_malloc (d_window_size * sizeof(float),
+ volk_get_alignment ());
+ d_out = (int32_t *) volk_malloc (d_window_size * sizeof(int32_t),
+ volk_get_alignment ());
- if(!d_const_val || !d_tmp || !d_out) {
- throw std::runtime_error("cw_to_symbol: Could not allocate memory");
- }
+ if (!d_const_val || !d_tmp || !d_out) {
+ throw std::runtime_error ("cw_to_symbol: Could not allocate memory");
+ }
- for(i = 0; i < d_window_size; i++) {
- d_const_val[i] = threshold;
- }
- set_history(d_window_size);
- }
+ for (i = 0; i < d_window_size; i++) {
+ d_const_val[i] = threshold;
+ }
+ set_history (d_window_size);
+}
- inline void
- cw_to_symbol_impl::send_symbol_msg (morse_symbol_t s)
- {
- if(s == MORSE_S_SPACE || s == MORSE_L_SPACE) {
- d_prev_space_symbol = true;
- }
- else{
- d_prev_space_symbol = false;
- }
- message_port_pub (pmt::mp ("out"), pmt::from_long (s));
- }
+inline void
+cw_to_symbol_impl::send_symbol_msg (morse_symbol_t s)
+{
+ if (s == MORSE_S_SPACE || s == MORSE_L_SPACE) {
+ d_prev_space_symbol = true;
+ }
+ else {
+ d_prev_space_symbol = false;
+ }
+ message_port_pub (pmt::mp ("out"), pmt::from_long (s));
+}
- inline bool
- cw_to_symbol_impl::check_conf_level(size_t cnt, size_t target)
- {
- return ((float)cnt > target * d_confidence_level);
- }
+inline bool
+cw_to_symbol_impl::check_conf_level (size_t cnt, size_t target)
+{
+ return ((float) cnt > target * d_confidence_level);
+}
- /*
- * Our virtual destructor.
- */
- cw_to_symbol_impl::~cw_to_symbol_impl ()
- {
- volk_free (d_const_val);
- volk_free (d_tmp);
- volk_free (d_out);
- }
+/*
+ * Our virtual destructor.
+ */
+cw_to_symbol_impl::~cw_to_symbol_impl ()
+{
+ volk_free (d_const_val);
+ volk_free (d_tmp);
+ volk_free (d_out);
+}
- inline void
- cw_to_symbol_impl::set_idle ()
- {
- d_dec_state = NO_SYNC;
- d_window_cnt = 0;
- }
+inline void
+cw_to_symbol_impl::set_idle ()
+{
+ d_dec_state = NO_SYNC;
+ d_window_cnt = 0;
+ d_idle_cnt = 0;
+}
- inline void
- cw_to_symbol_impl::set_short_on ()
- {
- d_dec_state = SEARCH_DOT;
- d_window_cnt = 1;
- }
+inline void
+cw_to_symbol_impl::set_short_on ()
+{
+ d_dec_state = SEARCH_DOT;
+ d_window_cnt = 1;
+}
- inline void
- cw_to_symbol_impl::set_long_on ()
- {
- d_dec_state = SEARCH_DASH;
- }
+inline void
+cw_to_symbol_impl::set_long_on ()
+{
+ d_dec_state = SEARCH_DASH;
+}
- inline void
- cw_to_symbol_impl::set_search_space ()
- {
- d_dec_state = SEARCH_SPACE;
- d_window_cnt = 1;
- }
+inline void
+cw_to_symbol_impl::set_search_space ()
+{
+ d_dec_state = SEARCH_SPACE;
+ d_window_cnt = 1;
+}
- void
- cw_to_symbol_impl::set_act_threshold_msg_handler (pmt::pmt_t msg)
- {
- if (pmt::is_pair (msg)) {
- set_act_threshold (pmt::to_double (pmt::cdr (msg)));
+void
+cw_to_symbol_impl::set_act_threshold_msg_handler (pmt::pmt_t msg)
+{
+ if (pmt::is_pair (msg)) {
+ set_act_threshold (pmt::to_double (pmt::cdr (msg)));
+ }
+}
+
+int
+cw_to_symbol_impl::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ bool triggered;
+ size_t i;
+ const float *in_old = (const float *) input_items[0];
+ const float *in = in_old + history () - 1;
+
+ if (noutput_items < 0) {
+ return noutput_items;
+ }
+
+ /* During idle state search for a possible trigger */
+ if (d_dec_state == NO_SYNC) {
+ for (i = 0; i < (size_t) noutput_items; i++) {
+ /*
+ * Clamp the input so the window mean is not affected by strong spikes
+ * Good luck understanding this black magic shit!
+ */
+ triggered = is_triggered (in_old + i, d_window_size);
+ if (triggered) {
+ LOG_DEBUG("Triggered!");
+ set_short_on ();
+ return i + 1;
}
}
+ d_idle_cnt += noutput_items / d_window_size;
+ if(d_idle_cnt > 10 * d_long_pause_windows_num) {
+ send_symbol_msg (MORSE_END_MSG_SPACE);
+ d_idle_cnt = 0;
+ }
+ return noutput_items;
+ }
- int
- cw_to_symbol_impl::work (int noutput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items)
- {
- bool triggered;
- size_t i;
- const float *in_old = (const float *) input_items[0];
- const float *in = in_old + history() - 1;
-
- if(noutput_items < 0) {
- return noutput_items;
- }
-
- /* During idle state search for a possible trigger */
- if(d_dec_state == NO_SYNC) {
- for(i = 0; i < (size_t)noutput_items; i++) {
- /*
- * Clamp the input so the window mean is not affected by strong spikes
- * Good luck understanding this black magic shit!
- */
- triggered = is_triggered(in_old + i, d_window_size);
- if(triggered) {
- LOG_DEBUG("Triggered!");
- set_short_on();
- return i+1;
+ /* From now one, we handle the input in multiples of a window */
+ for (i = 0; i < (size_t) noutput_items / d_window_size; i++) {
+ triggered = is_triggered (in + i * d_window_size, d_window_size);
+ switch (d_dec_state)
+ {
+ case SEARCH_DOT:
+ if (triggered) {
+ d_window_cnt++;
+ if (d_window_cnt > d_dot_windows_num) {
+ set_long_on ();
+ LOG_DEBUG("Going to search for long sequence");
}
}
- return noutput_items;
- }
-
- /* From now one, we handle the input in multiples of a window */
- for (i = 0; i < (size_t)noutput_items / d_window_size; i++) {
- triggered = is_triggered(in + i * d_window_size, d_window_size);
- switch(d_dec_state) {
- case SEARCH_DOT:
- if(triggered) {
- d_window_cnt++;
- if(d_window_cnt > d_dot_windows_num) {
- set_long_on();
- LOG_DEBUG("Going to search for long sequence");
- }
- }
- else {
- if(check_conf_level(d_window_cnt, d_dot_windows_num)) {
- LOG_DEBUG("DOT");
- send_symbol_msg(MORSE_DOT);
- }
- LOG_DEBUG("Going to search for space: win cnt %lu", d_window_cnt);
- set_search_space ();
- }
- break;
- case SEARCH_DASH:
- if(triggered) {
- d_window_cnt++;
- }
- else{
- if(check_conf_level(d_window_cnt, d_dash_windows_num)) {
- LOG_DEBUG("DASH");
- send_symbol_msg(MORSE_DASH);
- }
- else{
- LOG_DEBUG("DOT");
- send_symbol_msg(MORSE_DOT);
- }
- set_search_space ();
- LOG_DEBUG("Going to search for space");
- }
- break;
- case SEARCH_SPACE:
- if (triggered) {
- if(check_conf_level(d_window_cnt, d_long_pause_windows_num)) {
- LOG_DEBUG("LONG SPACE");
- send_symbol_msg(MORSE_L_SPACE);
- }
- else if(check_conf_level(d_window_cnt, d_short_pause_windows_num)){
- LOG_DEBUG("SHORT SPACE");
- send_symbol_msg(MORSE_S_SPACE);
- }
- set_short_on();
- LOG_DEBUG("Going to search for dot");
- }
- else{
- d_window_cnt++;
- if(d_window_cnt > d_long_pause_windows_num) {
- LOG_DEBUG("LONG SPACE");
- send_symbol_msg(MORSE_L_SPACE);
- set_idle();
- LOG_DEBUG("Going to idle");
- return (i + 1) * d_window_size;
- }
- }
- break;
- default:
- LOG_ERROR("Invalid decoder state");
+ else {
+ if (check_conf_level (d_window_cnt, d_dot_windows_num)) {
+ LOG_DEBUG("DOT");
+ send_symbol_msg (MORSE_DOT);
+ }
+ LOG_DEBUG("Going to search for space: win cnt %lu", d_window_cnt);
+ set_search_space ();
}
+ break;
+ case SEARCH_DASH:
+ if (triggered) {
+ d_window_cnt++;
+ }
+ else {
+ if (check_conf_level (d_window_cnt, d_dash_windows_num)) {
+ LOG_DEBUG("DASH");
+ send_symbol_msg (MORSE_DASH);
+ }
+ else {
+ LOG_DEBUG("DOT");
+ send_symbol_msg (MORSE_DOT);
+ }
+ set_search_space ();
+ LOG_DEBUG("Going to search for space");
+ }
+ break;
+ case SEARCH_SPACE:
+ if (triggered) {
+ if (check_conf_level (d_window_cnt, d_long_pause_windows_num)) {
+ LOG_DEBUG("LONG SPACE");
+ send_symbol_msg (MORSE_L_SPACE);
+ }
+ else if (check_conf_level (d_window_cnt, d_short_pause_windows_num)) {
+ LOG_DEBUG("SHORT SPACE");
+ send_symbol_msg (MORSE_S_SPACE);
+ }
+ set_short_on ();
+ LOG_DEBUG("Going to search for dot");
+ }
+ else {
+ d_window_cnt++;
+ if (d_window_cnt > d_long_pause_windows_num) {
+ LOG_DEBUG("LONG SPACE");
+ send_symbol_msg (MORSE_L_SPACE);
+ set_idle ();
+ LOG_DEBUG("Going to idle");
+ return (i + 1) * d_window_size;
+ }
+ }
+ break;
+ default:
+ LOG_ERROR("Invalid decoder state");
}
- return i * d_window_size;
- }
+ }
+ return i * d_window_size;
+}
- /**
- * Sets a new activation threshold.
- * @param thrhld the new threshold.
- */
- void
- cw_to_symbol_impl::set_act_threshold (float thrhld)
- {
- d_act_thrshld = thrhld;
- }
+/**
+ * Sets a new activation threshold.
+ * @param thrhld the new threshold.
+ */
+void
+cw_to_symbol_impl::set_act_threshold (float thrhld)
+{
+ d_act_thrshld = thrhld;
+}
- /**
- * Clamps the input and performs at the same time binary slicing.
- * With this way, a decision based on moving average is not affected
- * by strong peaks.
- * @param out the output buffer with the binary sliced output
- * @param in the input signal
- * @param len number of samples to process
- */
- inline void
- cw_to_symbol_impl::clamp_input (int32_t* out, const float* in, size_t len)
- {
- volk_32f_x2_subtract_32f(d_tmp, in, d_const_val, len);
- volk_32f_binary_slicer_32i(d_out, d_tmp, len);
- }
+/**
+ * Clamps the input and performs at the same time binary slicing.
+ * With this way, a decision based on moving average is not affected
+ * by strong peaks.
+ * @param out the output buffer with the binary sliced output
+ * @param in the input signal
+ * @param len number of samples to process
+ */
+inline void
+cw_to_symbol_impl::clamp_input (int32_t* out, const float* in, size_t len)
+{
+ volk_32f_x2_subtract_32f (d_tmp, in, d_const_val, len);
+ volk_32f_binary_slicer_32i (d_out, d_tmp, len);
+}
- static inline int32_t
- hadd (const int32_t* in, size_t len)
- {
- size_t i;
- int32_t cnt = 0;
- for(i = 0; i < len; i++) {
- cnt += in[i];
- }
- return cnt;
- }
+static inline int32_t
+hadd (const int32_t* in, size_t len)
+{
+ size_t i;
+ int32_t cnt = 0;
+ for (i = 0; i < len; i++) {
+ cnt += in[i];
+ }
+ return cnt;
+}
- inline bool
- cw_to_symbol_impl::is_triggered (const float* in, size_t len)
- {
- int32_t cnt;
- clamp_input(d_out, in, len);
- cnt = hadd(d_out, len);
- return (cnt >= (int32_t)(d_window_size * d_confidence_level)) ? true : false;
- }
+inline bool
+cw_to_symbol_impl::is_triggered (const float* in, size_t len)
+{
+ int32_t cnt;
+ clamp_input (d_out, in, len);
+ cnt = hadd (d_out, len);
+ return (cnt >= (int32_t) (d_window_size * d_confidence_level)) ? true : false;
+}
- } /* namespace satnogs */
+} /* namespace satnogs */
} /* namespace gr */
diff --git a/lib/cw_to_symbol_impl.h b/lib/cw_to_symbol_impl.h
index 59fa4ed..e2fd13b 100644
--- a/lib/cw_to_symbol_impl.h
+++ b/lib/cw_to_symbol_impl.h
@@ -45,6 +45,7 @@ namespace gr
size_t d_dot_samples;
size_t d_window_size;
size_t d_window_cnt;
+ size_t d_idle_cnt;
size_t d_dot_windows_num;
size_t d_dash_windows_num;
size_t d_short_pause_windows_num;
@@ -84,7 +85,7 @@ namespace gr
public:
cw_to_symbol_impl (double sampling_rate, float threshold,
- float conf_level, size_t wpm);
+ float conf_level, size_t wpm, size_t hysteresis);
~cw_to_symbol_impl ();
// Where all the action really happens
diff --git a/lib/morse_decoder_impl.cc b/lib/morse_decoder_impl.cc
index c86fb36..e54ddf8 100644
--- a/lib/morse_decoder_impl.cc
+++ b/lib/morse_decoder_impl.cc
@@ -28,94 +28,99 @@
#include
namespace gr
{
- namespace satnogs
- {
+namespace satnogs
+{
- morse_decoder::sptr
- morse_decoder::make (char unrecognized_char, size_t min_frame_len)
+morse_decoder::sptr
+morse_decoder::make (char unrecognized_char, size_t min_frame_len)
+{
+ return gnuradio::get_initial_sptr (
+ new morse_decoder_impl (unrecognized_char, min_frame_len));
+}
+
+void
+morse_decoder_impl::symbol_msg_handler (pmt::pmt_t msg)
+{
+ bool res = false;
+ morse_symbol_t s;
+ s = (morse_symbol_t) pmt::to_long (msg);
+
+ switch (s)
{
- return gnuradio::get_initial_sptr (
- new morse_decoder_impl (unrecognized_char, min_frame_len));
- }
-
- void
- morse_decoder_impl::symbol_msg_handler (pmt::pmt_t msg)
- {
- bool res = false;
- std::string str;
- morse_symbol_t s;
- s = (morse_symbol_t) pmt::to_long (msg);
-
- switch (s)
- {
- case MORSE_DOT:
- case MORSE_DASH:
- case MORSE_S_SPACE:
- res = d_morse_tree.received_symbol (s);
- break;
- /*
- * If a word separator occurs it is a good time to retrieve the decoded
- * word
- */
- case MORSE_L_SPACE:
- /*
- * Inject a character separator, for the morse decoder to commit
- * the outstanding character
- */
- res = d_morse_tree.received_symbol (MORSE_S_SPACE);
- /* Just ignore the word separator if no word is yet decoded */
- if (d_morse_tree.get_word_len () == 0) {
- res = true;
- break;
- }
- str = d_morse_tree.get_word ();
- if (str.length () > d_min_frame_len) {
- d_morse_tree.reset ();
- message_port_pub (pmt::mp ("out"),
- pmt::make_blob (str.c_str (), str.length ()));
- }
- break;
- case MORSE_INTRA_SPACE:
- /*Ignore it */
- break;
- default:
- LOG_ERROR("Unknown Morse symbol");
- return;
- }
-
+ case MORSE_DOT:
+ case MORSE_DASH:
+ case MORSE_S_SPACE:
+ res = d_morse_tree.received_symbol (s);
+ break;
/*
- * If the decoding return false, it means that either an non decode-able
- * character situation occurred or the maximum word limit reached
+ * If a word separator occurs it is a good time to retrieve the decoded
+ * word
*/
- if (!res) {
- if (d_morse_tree.get_max_word_len () == d_morse_tree.get_word_len ()) {
- str = d_morse_tree.get_word ();
- d_morse_tree.reset ();
- message_port_pub (pmt::mp ("out"),
- pmt::make_blob (str.c_str (), str.length ()));
- }
+ case MORSE_L_SPACE:
+ /*
+ * Inject a character separator, for the morse decoder to commit
+ * the outstanding character
+ */
+ res = d_morse_tree.received_symbol (MORSE_S_SPACE);
+ /* Just ignore the word separator if no word is yet decoded */
+ if (d_morse_tree.get_word_len () == 0) {
+ res = true;
+ break;
}
+ d_str = d_str.append(d_morse_tree.get_word ());
+ d_str = d_str.append(" ");
+ d_morse_tree.reset ();
+ break;
+ case MORSE_INTRA_SPACE:
+ /*Ignore it */
+ break;
+ case MORSE_END_MSG_SPACE:
+ if (d_str.length () > d_min_frame_len) {
+ d_morse_tree.reset ();
+ message_port_pub (pmt::mp ("out"),
+ pmt::make_blob (d_str.c_str (), d_str.length ()));
+ d_str = "";
+ }
+ break;
+ default:
+ LOG_ERROR("Unknown Morse symbol");
+ return;
}
- /*
- * The private constructor
- */
- morse_decoder_impl::morse_decoder_impl (char unrecognized_char,
- size_t min_frame_len) :
- gr::block ("morse_decoder", gr::io_signature::make (0, 0, 0),
- gr::io_signature::make (0, 0, 0)),
- d_morse_tree (unrecognized_char),
- d_min_frame_len (min_frame_len)
-
- {
- /* Register the input and output msg handler */
- message_port_register_in (pmt::mp ("in"));
- message_port_register_out (pmt::mp ("out"));
- set_msg_handler (
- pmt::mp ("in"),
- boost::bind (&morse_decoder_impl::symbol_msg_handler, this, _1));
+ /*
+ * If the decoding return false, it means that either an non decode-able
+ * character situation occurred or the maximum word limit reached
+ */
+ if (!res) {
+ if (d_morse_tree.get_max_word_len () == d_morse_tree.get_word_len ()) {
+ d_str = d_morse_tree.get_word ();
+ d_morse_tree.reset ();
+ message_port_pub (pmt::mp ("out"),
+ pmt::make_blob (d_str.c_str (), d_str.length ()));
}
+ }
+}
- } /* namespace satnogs */
+/*
+ * The private constructor
+ */
+morse_decoder_impl::morse_decoder_impl (char unrecognized_char,
+ size_t min_frame_len) :
+ gr::block ("morse_decoder", gr::io_signature::make (0, 0, 0),
+ gr::io_signature::make (0, 0, 0)),
+ d_morse_tree (unrecognized_char),
+ d_min_frame_len (min_frame_len),
+ d_str("")
+
+{
+ /* Register the input and output msg handler */
+ message_port_register_in (pmt::mp ("in"));
+ message_port_register_out (pmt::mp ("out"));
+ set_msg_handler (
+ pmt::mp ("in"),
+ boost::bind (&morse_decoder_impl::symbol_msg_handler, this, _1));
+}
+
+} /* namespace satnogs */
} /* namespace gr */
diff --git a/lib/morse_decoder_impl.h b/lib/morse_decoder_impl.h
index 0094e46..0eceedc 100644
--- a/lib/morse_decoder_impl.h
+++ b/lib/morse_decoder_impl.h
@@ -24,24 +24,27 @@
#include
#include
-namespace gr {
- namespace satnogs {
+namespace gr
+{
+namespace satnogs
+{
- class morse_decoder_impl : public morse_decoder
- {
- private:
- morse_tree d_morse_tree;
- size_t d_min_frame_len;
+class morse_decoder_impl : public morse_decoder
+{
- void
- symbol_msg_handler(pmt::pmt_t msg);
+public:
+ morse_decoder_impl (char unrecognized_char, size_t min_frame_len);
- public:
- morse_decoder_impl(char unrecognized_char, size_t min_frame_len);
+private:
+ morse_tree d_morse_tree;
+ size_t d_min_frame_len;
+ std::string d_str;
- };
+ void
+ symbol_msg_handler (pmt::pmt_t msg);
+};
- } // namespace satnogs
+} // namespace satnogs
} // namespace gr
#endif /* INCLUDED_SATNOGS_MORSE_DECODER_IMPL_H */