Merge branch 'sstv-decoder'

This commit is contained in:
Sebastian 2019-06-05 19:06:57 +02:00
commit fbb409f690
15 changed files with 1246 additions and 617 deletions

View File

@ -116,6 +116,123 @@
<value>48000</value>
</param>
</block>
<block>
<key>variable</key>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>1</value>
</param>
<param>
<key>_coordinate</key>
<value>(455, 35)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>dec</value>
</param>
<param>
<key>value</key>
<value>8</value>
</param>
</block>
<block>
<key>variable</key>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>1</value>
</param>
<param>
<key>_coordinate</key>
<value>(359, 35)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>dot_samples</value>
</param>
<param>
<key>value</key>
<value>int((1.2 / wpm) / (1.0 / (audio_samp_rate / 10.0)))</value>
</param>
</block>
<block>
<key>analog_agc2_xx</key>
<param>
<key>attack_rate</key>
<value>1e-4</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>decay_rate</key>
<value>1e-4</value>
</param>
<param>
<key>_enabled</key>
<value>1</value>
</param>
<param>
<key>_coordinate</key>
<value>(567, 283)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>gain</key>
<value>1.0</value>
</param>
<param>
<key>id</key>
<value>analog_agc2_xx_0</value>
</param>
<param>
<key>max_gain</key>
<value>65536</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>reference</key>
<value>1.0</value>
</param>
<param>
<key>type</key>
<value>complex</value>
</param>
</block>
<block>
<key>analog_agc2_xx</key>
<param>
@ -179,65 +296,6 @@
<value>complex</value>
</param>
</block>
<block>
<key>analog_agc_xx</key>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>1</value>
</param>
<param>
<key>_coordinate</key>
<value>(1372, 339)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>gain</key>
<value>1.0</value>
</param>
<param>
<key>id</key>
<value>analog_agc_xx_0</value>
</param>
<param>
<key>max_gain</key>
<value>65536</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>rate</key>
<value>1e-3</value>
</param>
<param>
<key>reference</key>
<value>1.0</value>
</param>
<param>
<key>type</key>
<value>float</value>
</param>
</block>
<block>
<key>analog_pll_carriertracking_cc</key>
<param>
@ -258,7 +316,7 @@
</param>
<param>
<key>_coordinate</key>
<value>(960, 348)</value>
<value>(919, 299)</value>
</param>
<param>
<key>_rotation</key>
@ -270,11 +328,11 @@
</param>
<param>
<key>w</key>
<value>2*math.pi/400.0</value>
<value>2*math.pi/100</value>
</param>
<param>
<key>max_freq</key>
<value>2*math.pi*2e3/audio_samp_rate</value>
<value>2*math.pi*2500</value>
</param>
<param>
<key>maxoutbuf</key>
@ -282,7 +340,7 @@
</param>
<param>
<key>min_freq</key>
<value>-2*math.pi*2e3/audio_samp_rate</value>
<value>-2*math.pi*2500</value>
</param>
<param>
<key>minoutbuf</key>
@ -496,7 +554,7 @@ tone. This tone is typically 1 kHz.</value>
</param>
</block>
<block>
<key>blocks_complex_to_mag_squared</key>
<key>blocks_complex_to_mag</key>
<param>
<key>alias</key>
<value></value>
@ -515,15 +573,15 @@ tone. This tone is typically 1 kHz.</value>
</param>
<param>
<key>_coordinate</key>
<value>(1168, 368)</value>
<value>(1630, 479)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
<value>180</value>
</param>
<param>
<key>id</key>
<value>blocks_complex_to_mag_squared_0</value>
<value>blocks_complex_to_mag_0</value>
</param>
<param>
<key>maxoutbuf</key>
@ -581,6 +639,104 @@ tone. This tone is typically 1 kHz.</value>
<value>1</value>
</param>
</block>
<block>
<key>blocks_delay</key>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>delay</key>
<value>int(dot_samples)/dec</value>
</param>
<param>
<key>_enabled</key>
<value>1</value>
</param>
<param>
<key>_coordinate</key>
<value>(1302, 403)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>blocks_delay_0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>num_ports</key>
<value>1</value>
</param>
<param>
<key>type</key>
<value>complex</value>
</param>
<param>
<key>vlen</key>
<value>1</value>
</param>
</block>
<block>
<key>blocks_multiply_conjugate_cc</key>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>1</value>
</param>
<param>
<key>_coordinate</key>
<value>(1358, 311)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>blocks_multiply_conjugate_cc_0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>vlen</key>
<value>1</value>
</param>
</block>
<block>
<key>blocks_multiply_xx</key>
<param>
@ -910,6 +1066,61 @@ tone. This tone is typically 1 kHz.</value>
<value>test.txt</value>
</param>
</block>
<block>
<key>fir_filter_xxx</key>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>decim</key>
<value>1</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(1574, 315)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>fir_filter_xxx_0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>samp_delay</key>
<value>0</value>
</param>
<param>
<key>taps</key>
<value>[1.0] * (int(dot_samples)/dec)</value>
</param>
<param>
<key>type</key>
<value>ccc</value>
</param>
</block>
<block>
<key>parameter</key>
<param>
@ -1134,7 +1345,7 @@ we shift the LO a little further</value>
</param>
<param>
<key>cutoff_freq</key>
<value>2e3</value>
<value>200</value>
</param>
<param>
<key>decim</key>
@ -1150,7 +1361,7 @@ we shift the LO a little further</value>
</param>
<param>
<key>_coordinate</key>
<value>(1268, 179)</value>
<value>(1102, 267)</value>
</param>
<param>
<key>_rotation</key>
@ -1178,11 +1389,11 @@ we shift the LO a little further</value>
</param>
<param>
<key>samp_rate</key>
<value>audio_samp_rate</value>
<value>audio_samp_rate/10</value>
</param>
<param>
<key>width</key>
<value>1e3</value>
<value>0.1e3</value>
</param>
<param>
<key>win</key>
@ -1201,7 +1412,7 @@ we shift the LO a little further</value>
</param>
<param>
<key>comment</key>
<value>Output samplerate: 20k / 4 = 5k</value>
<value></value>
</param>
<param>
<key>affinity</key>
@ -1209,11 +1420,11 @@ we shift the LO a little further</value>
</param>
<param>
<key>cutoff_freq</key>
<value>100</value>
<value>2500</value>
</param>
<param>
<key>decim</key>
<value>4</value>
<value>10</value>
</param>
<param>
<key>_enabled</key>
@ -1221,19 +1432,19 @@ we shift the LO a little further</value>
</param>
<param>
<key>type</key>
<value>fir_filter_fff</value>
<value>fir_filter_ccf</value>
</param>
<param>
<key>_coordinate</key>
<value>(1584, 420)</value>
<value>(743, 267)</value>
</param>
<param>
<key>_rotation</key>
<value>180</value>
<value>0</value>
</param>
<param>
<key>gain</key>
<value>4</value>
<value>1</value>
</param>
<param>
<key>id</key>
@ -1257,7 +1468,82 @@ we shift the LO a little further</value>
</param>
<param>
<key>width</key>
<value>100</value>
<value>0.4e3</value>
</param>
<param>
<key>win</key>
<value>firdes.WIN_HAMMING</value>
</param>
</block>
<block>
<key>low_pass_filter</key>
<param>
<key>beta</key>
<value>6.76</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>cutoff_freq</key>
<value>2500</value>
</param>
<param>
<key>decim</key>
<value>1</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>type</key>
<value>fir_filter_ccf</value>
</param>
<param>
<key>_coordinate</key>
<value>(1310, 155)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>gain</key>
<value>1</value>
</param>
<param>
<key>id</key>
<value>low_pass_filter_0_0_0</value>
</param>
<param>
<key>interp</key>
<value>1</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>samp_rate</key>
<value>audio_samp_rate</value>
</param>
<param>
<key>width</key>
<value>0.8e3</value>
</param>
<param>
<key>win</key>
@ -3067,7 +3353,7 @@ we shift the LO a little further</value>
<key>satnogs_cw_to_symbol</key>
<param>
<key>threshold</key>
<value>0.4</value>
<value>2.0</value>
</param>
<param>
<key>alias</key>
@ -3079,7 +3365,7 @@ we shift the LO a little further</value>
</param>
<param>
<key>conf_level</key>
<value>0.75</value>
<value>0.90</value>
</param>
<param>
<key>affinity</key>
@ -3091,12 +3377,16 @@ we shift the LO a little further</value>
</param>
<param>
<key>_coordinate</key>
<value>(1336, 460)</value>
<value>(1206, 459)</value>
</param>
<param>
<key>_rotation</key>
<value>180</value>
</param>
<param>
<key>hysteresis</key>
<value>dot_samples/dec</value>
</param>
<param>
<key>id</key>
<value>satnogs_cw_to_symbol_0</value>
@ -3111,7 +3401,7 @@ we shift the LO a little further</value>
</param>
<param>
<key>sampling_rate</key>
<value>audio_samp_rate/4</value>
<value>audio_samp_rate/10.0</value>
</param>
<param>
<key>wpm</key>
@ -3224,7 +3514,7 @@ we shift the LO a little further</value>
</param>
<param>
<key>_coordinate</key>
<value>(952, 444)</value>
<value>(951, 483)</value>
</param>
<param>
<key>_rotation</key>
@ -3639,21 +3929,21 @@ we shift the LO a little further</value>
<value>20</value>
</param>
</block>
<connection>
<source_block_id>analog_agc2_xx_0</source_block_id>
<sink_block_id>low_pass_filter_0_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>analog_agc2_xx_0_0</source_block_id>
<sink_block_id>blocks_multiply_xx_0</sink_block_id>
<source_key>0</source_key>
<sink_key>1</sink_key>
</connection>
<connection>
<source_block_id>analog_agc_xx_0</source_block_id>
<sink_block_id>low_pass_filter_0_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>analog_pll_carriertracking_cc_0</source_block_id>
<sink_block_id>blocks_complex_to_mag_squared_0</sink_block_id>
<sink_block_id>low_pass_filter_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
@ -3664,8 +3954,8 @@ we shift the LO a little further</value>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>blocks_complex_to_mag_squared_0</source_block_id>
<sink_block_id>analog_agc_xx_0</sink_block_id>
<source_block_id>blocks_complex_to_mag_0</source_block_id>
<sink_block_id>satnogs_cw_to_symbol_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
@ -3675,6 +3965,18 @@ we shift the LO a little further</value>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>blocks_delay_0</source_block_id>
<sink_block_id>blocks_multiply_conjugate_cc_0</sink_block_id>
<source_key>0</source_key>
<sink_key>1</sink_key>
</connection>
<connection>
<source_block_id>blocks_multiply_conjugate_cc_0</source_block_id>
<sink_block_id>fir_filter_xxx_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>blocks_multiply_xx_0</source_block_id>
<sink_block_id>blocks_complex_to_real_0</sink_block_id>
@ -3688,20 +3990,32 @@ we shift the LO a little further</value>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>low_pass_filter_0</source_block_id>
<sink_block_id>analog_agc2_xx_0_0</sink_block_id>
<source_block_id>fir_filter_xxx_0</source_block_id>
<sink_block_id>blocks_complex_to_mag_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>low_pass_filter_0</source_block_id>
<sink_block_id>analog_pll_carriertracking_cc_0</sink_block_id>
<sink_block_id>blocks_delay_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>low_pass_filter_0</source_block_id>
<sink_block_id>blocks_multiply_conjugate_cc_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>low_pass_filter_0_0</source_block_id>
<sink_block_id>satnogs_cw_to_symbol_0</sink_block_id>
<sink_block_id>analog_pll_carriertracking_cc_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>low_pass_filter_0_0_0</source_block_id>
<sink_block_id>analog_agc2_xx_0_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
@ -3713,7 +4027,13 @@ we shift the LO a little further</value>
</connection>
<connection>
<source_block_id>pfb_arb_resampler_xxx_0</source_block_id>
<sink_block_id>low_pass_filter_0</sink_block_id>
<sink_block_id>analog_agc2_xx_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>pfb_arb_resampler_xxx_0</source_block_id>
<sink_block_id>low_pass_filter_0_0_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>

View File

@ -136,7 +136,7 @@
</param>
<param>
<key>_coordinate</key>
<value>(1248, 196)</value>
<value>(1190, 411)</value>
</param>
<param>
<key>_rotation</key>
@ -179,7 +179,7 @@
</param>
<param>
<key>_coordinate</key>
<value>(992, 316)</value>
<value>(1030, 195)</value>
</param>
<param>
<key>_rotation</key>
@ -406,7 +406,7 @@
</param>
<param>
<key>_coordinate</key>
<value>(1432, 188)</value>
<value>(1390, 403)</value>
</param>
<param>
<key>_rotation</key>
@ -457,7 +457,7 @@
</param>
<param>
<key>_coordinate</key>
<value>(1208, 308)</value>
<value>(1206, 187)</value>
</param>
<param>
<key>_rotation</key>
@ -641,7 +641,7 @@
</param>
<param>
<key>_coordinate</key>
<value>(1616, 164)</value>
<value>(1590, 379)</value>
</param>
<param>
<key>_rotation</key>
@ -677,7 +677,7 @@
</param>
<param>
<key>omega</key>
<value>2</value>
<value>4</value>
</param>
<param>
<key>type</key>
@ -998,6 +998,81 @@ we shift the LO a little further</value>
<value>100e3</value>
</param>
</block>
<block>
<key>low_pass_filter</key>
<param>
<key>beta</key>
<value>6.76</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>cutoff_freq</key>
<value>baudrate / 2 + 1500</value>
</param>
<param>
<key>decim</key>
<value>1</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>type</key>
<value>fir_filter_ccf</value>
</param>
<param>
<key>_coordinate</key>
<value>(1007, 363)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>gain</key>
<value>1</value>
</param>
<param>
<key>id</key>
<value>low_pass_filter_0</value>
</param>
<param>
<key>interp</key>
<value>1</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>samp_rate</key>
<value>4.0 * baudrate</value>
</param>
<param>
<key>width</key>
<value>1000</value>
</param>
<param>
<key>win</key>
<value>firdes.WIN_HAMMING</value>
</param>
</block>
<block>
<key>osmosdr_source</key>
<param>
@ -2457,7 +2532,7 @@ we shift the LO a little further</value>
</param>
<param>
<key>atten</key>
<value>100</value>
<value>60</value>
</param>
<param>
<key>taps</key>
@ -2488,7 +2563,7 @@ we shift the LO a little further</value>
</param>
<param>
<key>_coordinate</key>
<value>(984, 172)</value>
<value>(727, 275)</value>
</param>
<param>
<key>_rotation</key>
@ -2512,7 +2587,7 @@ we shift the LO a little further</value>
</param>
<param>
<key>rrate</key>
<value>(2.0*baudrate)/audio_samp_rate</value>
<value>(4.0*baudrate)/satnogs.handle_samp_rate_rx(rx_sdr_device, samp_rate_rx)</value>
</param>
<param>
<key>samp_delay</key>
@ -2520,7 +2595,7 @@ we shift the LO a little further</value>
</param>
<param>
<key>atten</key>
<value>100</value>
<value>60</value>
</param>
<param>
<key>taps</key>
@ -3088,7 +3163,7 @@ we shift the LO a little further</value>
</param>
<param>
<key>_coordinate</key>
<value>(1384, 300)</value>
<value>(1382, 179)</value>
</param>
<param>
<key>_rotation</key>
@ -3500,6 +3575,12 @@ we shift the LO a little further</value>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>low_pass_filter_0</source_block_id>
<sink_block_id>analog_quadrature_demod_cf_0_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>osmosdr_source_0</source_block_id>
<sink_block_id>blocks_rotator_cc_0</sink_block_id>
@ -3512,12 +3593,6 @@ we shift the LO a little further</value>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>pfb_arb_resampler_xxx_0</source_block_id>
<sink_block_id>pfb_arb_resampler_xxx_0_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>pfb_arb_resampler_xxx_0</source_block_id>
<sink_block_id>satnogs_iq_sink_0</sink_block_id>
@ -3532,7 +3607,7 @@ we shift the LO a little further</value>
</connection>
<connection>
<source_block_id>pfb_arb_resampler_xxx_0_0</source_block_id>
<sink_block_id>analog_quadrature_demod_cf_0_0</sink_block_id>
<sink_block_id>low_pass_filter_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
@ -3566,6 +3641,12 @@ we shift the LO a little further</value>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>satnogs_coarse_doppler_correction_cc_0</source_block_id>
<sink_block_id>pfb_arb_resampler_xxx_0_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>satnogs_quad_demod_filter_ff_0</source_block_id>
<sink_block_id>digital_binary_slicer_fb_0</sink_block_id>

View File

@ -136,7 +136,7 @@
</param>
<param>
<key>_coordinate</key>
<value>(1248, 196)</value>
<value>(1214, 419)</value>
</param>
<param>
<key>_rotation</key>
@ -406,7 +406,7 @@
</param>
<param>
<key>_coordinate</key>
<value>(1432, 188)</value>
<value>(1430, 411)</value>
</param>
<param>
<key>_rotation</key>
@ -641,7 +641,7 @@
</param>
<param>
<key>_coordinate</key>
<value>(1616, 164)</value>
<value>(1614, 387)</value>
</param>
<param>
<key>_rotation</key>
@ -677,7 +677,7 @@
</param>
<param>
<key>omega</key>
<value>2</value>
<value>4</value>
</param>
<param>
<key>type</key>
@ -998,6 +998,81 @@ we shift the LO a little further</value>
<value>100e3</value>
</param>
</block>
<block>
<key>low_pass_filter</key>
<param>
<key>beta</key>
<value>6.76</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>cutoff_freq</key>
<value>baudrate / 2 + 1500</value>
</param>
<param>
<key>decim</key>
<value>1</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>type</key>
<value>fir_filter_ccf</value>
</param>
<param>
<key>_coordinate</key>
<value>(1022, 371)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>gain</key>
<value>1</value>
</param>
<param>
<key>id</key>
<value>low_pass_filter_0</value>
</param>
<param>
<key>interp</key>
<value>1</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>samp_rate</key>
<value>4.0 * baudrate</value>
</param>
<param>
<key>width</key>
<value>1000</value>
</param>
<param>
<key>win</key>
<value>firdes.WIN_HAMMING</value>
</param>
</block>
<block>
<key>osmosdr_source</key>
<param>
@ -2488,7 +2563,7 @@ we shift the LO a little further</value>
</param>
<param>
<key>_coordinate</key>
<value>(984, 172)</value>
<value>(735, 395)</value>
</param>
<param>
<key>_rotation</key>
@ -2496,7 +2571,7 @@ we shift the LO a little further</value>
</param>
<param>
<key>id</key>
<value>pfb_arb_resampler_xxx_0_0</value>
<value>pfb_arb_resampler_xxx_0_0_0</value>
</param>
<param>
<key>maxoutbuf</key>
@ -2512,7 +2587,7 @@ we shift the LO a little further</value>
</param>
<param>
<key>rrate</key>
<value>(2.0*baudrate)/audio_samp_rate</value>
<value>(4.0*baudrate)/satnogs.handle_samp_rate_rx(rx_sdr_device, samp_rate_rx)</value>
</param>
<param>
<key>samp_delay</key>
@ -2520,7 +2595,7 @@ we shift the LO a little further</value>
</param>
<param>
<key>atten</key>
<value>100</value>
<value>60</value>
</param>
<param>
<key>taps</key>
@ -3500,6 +3575,12 @@ we shift the LO a little further</value>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>low_pass_filter_0</source_block_id>
<sink_block_id>analog_quadrature_demod_cf_0_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>osmosdr_source_0</source_block_id>
<sink_block_id>blocks_rotator_cc_0</sink_block_id>
@ -3512,12 +3593,6 @@ we shift the LO a little further</value>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>pfb_arb_resampler_xxx_0</source_block_id>
<sink_block_id>pfb_arb_resampler_xxx_0_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>pfb_arb_resampler_xxx_0</source_block_id>
<sink_block_id>satnogs_iq_sink_0</sink_block_id>
@ -3531,8 +3606,8 @@ we shift the LO a little further</value>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>pfb_arb_resampler_xxx_0_0</source_block_id>
<sink_block_id>analog_quadrature_demod_cf_0_0</sink_block_id>
<source_block_id>pfb_arb_resampler_xxx_0_0_0</source_block_id>
<sink_block_id>low_pass_filter_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
@ -3566,6 +3641,12 @@ we shift the LO a little further</value>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>satnogs_coarse_doppler_correction_cc_0</source_block_id>
<sink_block_id>pfb_arb_resampler_xxx_0_0_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>satnogs_quad_demod_filter_ff_0</source_block_id>
<sink_block_id>digital_binary_slicer_fb_0</sink_block_id>

View File

@ -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()

View File

@ -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))

View File

@ -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))

View File

@ -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))

View File

@ -323,7 +323,7 @@ TX sampling rate</value>
</param>
<param>
<key>_coordinate</key>
<value>(964, 562)</value>
<value>(877, 562)</value>
</param>
<param>
<key>_rotation</key>
@ -374,11 +374,11 @@ TX sampling rate</value>
</param>
<param>
<key>_coordinate</key>
<value>(1204, 474)</value>
<value>(1252, 291)</value>
</param>
<param>
<key>_rotation</key>
<value>180</value>
<value>0</value>
</param>
<param>
<key>gain</key>
@ -872,7 +872,7 @@ TX sampling rate</value>
</param>
<param>
<key>_coordinate</key>
<value>(1164, 562)</value>
<value>(1076, 562)</value>
</param>
<param>
<key>_rotation</key>
@ -903,6 +903,57 @@ TX sampling rate</value>
<value>ccc</value>
</param>
</block>
<block>
<key>hilbert_fc</key>
<param>
<key>beta</key>
<value>6.76</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(1323, 602)</value>
</param>
<param>
<key>_rotation</key>
<value>180</value>
</param>
<param>
<key>id</key>
<value>hilbert_fc_0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>num_taps</key>
<value>65</value>
</param>
<param>
<key>win</key>
<value>firdes.WIN_HAMMING</value>
</param>
</block>
<block>
<key>parameter</key>
<param>
@ -1159,7 +1210,7 @@ max_modulation_freq = 3000</value>
</param>
<param>
<key>_coordinate</key>
<value>(781, 538)</value>
<value>(693, 538)</value>
</param>
<param>
<key>_rotation</key>
@ -2680,7 +2731,7 @@ max_modulation_freq = 3000</value>
</param>
<param>
<key>_coordinate</key>
<value>(590, 562)</value>
<value>(494, 562)</value>
</param>
<param>
<key>_rotation</key>
@ -3017,11 +3068,11 @@ max_modulation_freq = 3000</value>
</param>
<param>
<key>_coordinate</key>
<value>(1004, 458)</value>
<value>(1531, 275)</value>
</param>
<param>
<key>_rotation</key>
<value>180</value>
<value>0</value>
</param>
<param>
<key>id</key>
@ -3056,7 +3107,7 @@ max_modulation_freq = 3000</value>
</param>
<param>
<key>_coordinate</key>
<value>(342, 586)</value>
<value>(263, 586)</value>
</param>
<param>
<key>_rotation</key>
@ -3238,6 +3289,12 @@ max_modulation_freq = 3000</value>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>analog_quadrature_demod_cf_0</source_block_id>
<sink_block_id>hilbert_fc_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>analog_quadrature_demod_cf_0</source_block_id>
<sink_block_id>satnogs_ogg_encoder_0</sink_block_id>
@ -3275,14 +3332,14 @@ max_modulation_freq = 3000</value>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>low_pass_filter_0</source_block_id>
<sink_block_id>analog_quadrature_demod_cf_0</sink_block_id>
<source_block_id>hilbert_fc_0</source_block_id>
<sink_block_id>freq_xlating_fir_filter_xxx_0_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>low_pass_filter_0</source_block_id>
<sink_block_id>freq_xlating_fir_filter_xxx_0_0</sink_block_id>
<sink_block_id>analog_quadrature_demod_cf_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>

View File

@ -1,51 +1,58 @@
<?xml version="1.0"?>
<block>
<name>CW to Symbols</name>
<key>satnogs_cw_to_symbol</key>
<import>import satnogs</import>
<make>satnogs.cw_to_symbol($sampling_rate, $threshold, $conf_level, $wpm)</make>
<callback>set_act_threshold($threshold)</callback>
<param>
<name>Sampling Rate</name>
<key>sampling_rate</key>
<value>samp_rate</value>
<type>real</type>
</param>
<name>CW to Symbols</name>
<key>satnogs_cw_to_symbol</key>
<import>import satnogs</import>
<make>satnogs.cw_to_symbol($sampling_rate, $threshold, $conf_level, $wpm, $hysteresis)</make>
<callback>set_act_threshold($threshold)</callback>
<param>
<name>Activation Threshold</name>
<key>threshold</key>
<type>real</type>
</param>
<param>
<name>Confidence Level</name>
<key>conf_level</key>
<value>0.9</value>
<type>real</type>
</param>
<param>
<name>Sampling Rate</name>
<key>sampling_rate</key>
<value>samp_rate</value>
<type>real</type>
</param>
<param>
<name>Words per Minute</name>
<key>wpm</key>
<value>20</value>
<type>int</type>
</param>
<param>
<name>Activation Threshold</name>
<key>threshold</key>
<type>real</type>
</param>
<sink>
<name>act_threshold</name>
<type>message</type>
<optional>1</optional>
</sink>
<sink>
<name>in</name>
<type>float</type>
</sink>
<param>
<name>Confidence Level</name>
<key>conf_level</key>
<value>0.9</value>
<type>real</type>
</param>
<source>
<name>out</name>
<type>message</type>
</source>
<param>
<name>Words per Minute</name>
<key>wpm</key>
<value>20</value>
<type>int</type>
</param>
<param>
<name>Hysteresis</name>
<key>hysteresis</key>
<value>0</value>
<type>int</type>
</param>
<sink>
<name>act_threshold</name>
<type>message</type>
<optional>1</optional>
</sink>
<sink>
<name>in</name>
<type>float</type>
</sink>
<source>
<name>out</name>
<type>message</type>
</source>
</block>

View File

@ -24,6 +24,9 @@
#include <satnogs/api.h>
#include <gnuradio/sync_block.h>
#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;

View File

@ -2,7 +2,7 @@
/*
* gr-satnogs: SatNOGS GNU Radio Out-Of-Tree Module
*
* Copyright (C) 2016,2017
* Copyright (C) 2016-2018
* Libre Space Foundation <http://librespacefoundation.org/>
*
* 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 //!<Morse long space between words
MORSE_L_SPACE, //!<Morse long space between words
MORSE_END_MSG_SPACE //!< End of message
} morse_symbol_t;

View File

@ -31,322 +31,342 @@
#include <satnogs/utils.h>
#include <boost/version.hpp>
#if BOOST_VERSION >= 106500
#include <boost/integer/common_factor.hpp>
#include <boost/integer/common_factor.hpp>
#else
#include <boost/math/common_factor.hpp>
#include <boost/math/common_factor.hpp>
#endif
#include <volk/volk.h>
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 */

View File

@ -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

View File

@ -28,94 +28,99 @@
#include <satnogs/log.h>
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 */

View File

@ -24,24 +24,27 @@
#include <satnogs/morse_decoder.h>
#include <satnogs/morse_tree.h>
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 */