Merge branch 'sstv-decoder'

This commit is contained in:
Sebastian 2019-07-30 20:44:55 +02:00
commit 96fd9bcad8
35 changed files with 7485 additions and 1325 deletions

View File

@ -8,11 +8,11 @@
# Contributors
* Corey Shields (cshields@gmail.com)
* LongHairedHacker(sebastian@sebastians-site.de)
* Sebastian Schumb (sebastian@sebastians-site.de)
* Nikos Karamolegkos (nkaramolegos@csd.uoc.g)
* Mark Jessop (vk5qi@rfhead.net)
* Fabian P. Schmidt (kerel-fs@gmx.de)
* Thanos Gkiolias (agiolias@csd.uoc.gr)
* Patrick Dohmen (dl4pd@darc.de)
* Kostis Triantayllakis (ctriant@csd.uoc.gr)
* Alexander Jenke
* Alexander Jenke

View File

@ -14,6 +14,7 @@ for decoding signals from various scientific and academic sattelites.
* libpng
* libpng++
* git
* swig
**Optional**
* gr-osmocom (for using the flowgraphs with real SDR hardware)
@ -23,14 +24,15 @@ for decoding signals from various scientific and academic sattelites.
```
apt install -y build-essential cmake gnuradio g++ \
python-mako python-six libogg-dev \
libvorbis-dev libpng-dev libpng++-dev
libvorbis-dev libpng-dev libpng++-dev \
swig
cd /tmp
git clone https://github.com/gnuradio/volk.git
cd volk
mkdir build
cd build
cmake ..
make -j 8
make -j $(nproc --all)
sudo make install
```
@ -41,7 +43,7 @@ sudo make install
3. `mkdir build`
4. `cd build`
5. `cmake ..`
6. `make`
6. `make -j $(nproc --all)`
7. `sudo make install`
If this is the first time you are building the gr-satnogs module run

View File

@ -37,5 +37,6 @@ GR_PYTHON_INSTALL(
flowgraphs/satnogs_fsk_ax25.py
flowgraphs/satnogs_msk_ax25.py
flowgraphs/satnogs_bpsk_ax25.py
flowgraphs/satnogs_sstv_pd120_demod.py
DESTINATION bin
)

View File

@ -217,7 +217,7 @@
</param>
<param>
<key>_coordinate</key>
<value>(1364, 578)</value>
<value>(1168, 580)</value>
</param>
<param>
<key>_rotation</key>
@ -225,7 +225,7 @@
</param>
<param>
<key>gain</key>
<value>((audio_samp_rate/10) / baud_rate)/(math.pi*1)</value>
<value>((audio_samp_rate/20) / baud_rate)/(math.pi*1)</value>
</param>
<param>
<key>id</key>
@ -260,7 +260,7 @@
</param>
<param>
<key>_coordinate</key>
<value>(574, 394)</value>
<value>(936, 396)</value>
</param>
<param>
<key>_rotation</key>
@ -283,6 +283,49 @@
<value>0</value>
</param>
</block>
<block>
<key>analog_quadrature_demod_cf</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>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(813, 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_quadrature_demod_cf_0_0_0_0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
</block>
<block>
<key>analog_sig_source_x</key>
<param>
@ -311,7 +354,7 @@
</param>
<param>
<key>_coordinate</key>
<value>(750, 646)</value>
<value>(664, 644)</value>
</param>
<param>
<key>_rotation</key>
@ -393,6 +436,85 @@
<value>satnogs.not_set_antenna</value>
</param>
</block>
<block>
<key>band_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>decim</key>
<value>1</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>type</key>
<value>fir_filter_fff</value>
</param>
<param>
<key>_coordinate</key>
<value>(360, 492)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>gain</key>
<value>1</value>
</param>
<param>
<key>high_cutoff_freq</key>
<value>2400</value>
</param>
<param>
<key>id</key>
<value>band_pass_filter_0</value>
</param>
<param>
<key>interp</key>
<value>1</value>
</param>
<param>
<key>low_cutoff_freq</key>
<value>1000</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>400</value>
</param>
<param>
<key>win</key>
<value>firdes.WIN_HAMMING</value>
</param>
</block>
<block>
<key>parameter</key>
<param>
@ -437,7 +559,7 @@
</param>
<param>
<key>value</key>
<value>9600.0</value>
<value>1200.0</value>
</param>
</block>
<block>
@ -487,6 +609,61 @@
<value>satnogs.not_set_rx_bb_gain</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>1024/2</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(821, 219)</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_float_to_complex</key>
<param>
@ -530,6 +707,65 @@
<value>1</value>
</param>
</block>
<block>
<key>blocks_moving_average_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>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(981, 267)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>blocks_moving_average_xx_0</value>
</param>
<param>
<key>vlen</key>
<value>1</value>
</param>
<param>
<key>length</key>
<value>1024</value>
</param>
<param>
<key>max_iter</key>
<value>4096</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>scale</key>
<value>1.0/1024.0</value>
</param>
<param>
<key>type</key>
<value>float</value>
</param>
</block>
<block>
<key>blocks_multiply_xx</key>
<param>
@ -550,7 +786,7 @@
</param>
<param>
<key>_coordinate</key>
<value>(957, 566)</value>
<value>(872, 568)</value>
</param>
<param>
<key>_rotation</key>
@ -581,6 +817,57 @@
<value>1</value>
</param>
</block>
<block>
<key>blocks_multiply_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>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(1308, 223)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>blocks_multiply_xx_0_0</value>
</param>
<param>
<key>type</key>
<value>complex</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>num_inputs</key>
<value>2</value>
</param>
<param>
<key>vlen</key>
<value>1</value>
</param>
</block>
<block>
<key>blocks_rotator_cc</key>
<param>
@ -624,6 +911,57 @@
<value>-2.0 * math.pi * (lo_offset / satnogs.handle_samp_rate_rx(rx_sdr_device, samp_rate_rx))</value>
</param>
</block>
<block>
<key>blocks_vco_c</key>
<param>
<key>amplitude</key>
<value>1.0</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>(1140, 267)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>blocks_vco_c_0</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>sensitivity</key>
<value>-audio_samp_rate</value>
</param>
</block>
<block>
<key>dc_blocker_xx</key>
<param>
@ -644,7 +982,7 @@
</param>
<param>
<key>_coordinate</key>
<value>(534, 538)</value>
<value>(544, 540)</value>
</param>
<param>
<key>_rotation</key>
@ -675,6 +1013,57 @@
<value>ff</value>
</param>
</block>
<block>
<key>dc_blocker_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>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(1344, 572)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>dc_blocker_xx_0_0</value>
</param>
<param>
<key>length</key>
<value>1024</value>
</param>
<param>
<key>long_form</key>
<value>True</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>type</key>
<value>ff</value>
</param>
</block>
<block>
<key>parameter</key>
<param>
@ -789,11 +1178,11 @@
</param>
<param>
<key>_coordinate</key>
<value>(2034, 606)</value>
<value>(1928, 752)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
<value>180</value>
</param>
<param>
<key>id</key>
@ -828,7 +1217,7 @@
</param>
<param>
<key>_coordinate</key>
<value>(1563, 550)</value>
<value>(1928, 548)</value>
</param>
<param>
<key>_rotation</key>
@ -836,11 +1225,11 @@
</param>
<param>
<key>gain_mu</key>
<value>0.175</value>
<value>0.5/8.0</value>
</param>
<param>
<key>gain_omega</key>
<value>0.25*0.175*0.175</value>
<value>2*math.pi/100.0</value>
</param>
<param>
<key>id</key>
@ -860,11 +1249,11 @@
</param>
<param>
<key>omega_relative_limit</key>
<value>0.005</value>
<value>0.01</value>
</param>
<param>
<key>omega</key>
<value>(48e3/10)/baud_rate</value>
<value>(48e3/20)/baud_rate</value>
</param>
<param>
<key>type</key>
@ -1193,7 +1582,7 @@ max_modulation_freq = 3000</value>
</param>
<param>
<key>_coordinate</key>
<value>(1144, 276)</value>
<value>(1208, 348)</value>
</param>
<param>
<key>_rotation</key>
@ -1225,7 +1614,7 @@ max_modulation_freq = 3000</value>
</param>
<param>
<key>width</key>
<value>3000</value>
<value>1000</value>
</param>
<param>
<key>win</key>
@ -1252,11 +1641,11 @@ max_modulation_freq = 3000</value>
</param>
<param>
<key>cutoff_freq</key>
<value>(mark_frequency - space_frequency)/2.0</value>
<value>(mark_frequency - space_frequency)/2.0 + 250</value>
</param>
<param>
<key>decim</key>
<value>10</value>
<value>20</value>
</param>
<param>
<key>_enabled</key>
@ -1268,7 +1657,7 @@ max_modulation_freq = 3000</value>
</param>
<param>
<key>_coordinate</key>
<value>(1152, 532)</value>
<value>(992, 532)</value>
</param>
<param>
<key>_rotation</key>
@ -1276,7 +1665,7 @@ max_modulation_freq = 3000</value>
</param>
<param>
<key>gain</key>
<value>10</value>
<value>1</value>
</param>
<param>
<key>id</key>
@ -1300,7 +1689,82 @@ max_modulation_freq = 3000</value>
</param>
<param>
<key>width</key>
<value>1000</value>
<value>500</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>baudrate /2+ 500 /2</value>
</param>
<param>
<key>decim</key>
<value>1</value>
</param>
<param>
<key>_enabled</key>
<value>1</value>
</param>
<param>
<key>type</key>
<value>fir_filter_fff</value>
</param>
<param>
<key>_coordinate</key>
<value>(1760, 532)</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_2_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>baudrate*2</value>
</param>
<param>
<key>width</key>
<value>500</value>
</param>
<param>
<key>win</key>
@ -2781,7 +3245,7 @@ max_modulation_freq = 3000</value>
</param>
<param>
<key>_coordinate</key>
<value>(640, 196)</value>
<value>(534, 195)</value>
</param>
<param>
<key>_rotation</key>
@ -3338,7 +3802,7 @@ max_modulation_freq = 3000</value>
</param>
<param>
<key>_coordinate</key>
<value>(1304, 28)</value>
<value>(773, 27)</value>
</param>
<param>
<key>_rotation</key>
@ -3381,11 +3845,11 @@ max_modulation_freq = 3000</value>
</param>
<param>
<key>_coordinate</key>
<value>(368, 452)</value>
<value>(303, 379)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
<value>180</value>
</param>
<param>
<key>id</key>
@ -3400,53 +3864,6 @@ max_modulation_freq = 3000</value>
<value>audio_samp_rate</value>
</param>
</block>
<block>
<key>satnogs_quad_demod_filter_ff</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>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(1795, 578)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>gain</key>
<value>((audio_samp_rate/10) / baud_rate)/(math.pi*1)</value>
</param>
<param>
<key>id</key>
<value>satnogs_quad_demod_filter_ff_0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>win</key>
<value>80</value>
</param>
</block>
<block>
<key>satnogs_tcp_rigctl_msg_source</key>
<param>
@ -3526,7 +3943,7 @@ max_modulation_freq = 3000</value>
</param>
<param>
<key>_coordinate</key>
<value>(1268, 666)</value>
<value>(1292, 785)</value>
</param>
<param>
<key>_rotation</key>
@ -3581,7 +3998,7 @@ max_modulation_freq = 3000</value>
</param>
<param>
<key>_coordinate</key>
<value>(872, 4)</value>
<value>(550, 3)</value>
</param>
<param>
<key>_rotation</key>
@ -3794,13 +4211,13 @@ max_modulation_freq = 3000</value>
</block>
<connection>
<source_block_id>analog_quadrature_demod_cf_0</source_block_id>
<sink_block_id>digital_clock_recovery_mm_xx_0</sink_block_id>
<sink_block_id>dc_blocker_xx_0_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>analog_quadrature_demod_cf_0_0</source_block_id>
<sink_block_id>dc_blocker_xx_0</sink_block_id>
<sink_block_id>band_pass_filter_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
@ -3810,36 +4227,78 @@ 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_0_0_0</source_block_id>
<sink_block_id>blocks_moving_average_xx_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>analog_sig_source_x_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>band_pass_filter_0</source_block_id>
<sink_block_id>dc_blocker_xx_0</sink_block_id>
<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_xx_0_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>blocks_float_to_complex_0</source_block_id>
<sink_block_id>blocks_multiply_xx_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>blocks_moving_average_xx_0</source_block_id>
<sink_block_id>blocks_vco_c_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>low_pass_filter_1</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>blocks_multiply_xx_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>
<connection>
<source_block_id>blocks_rotator_cc_0</source_block_id>
<sink_block_id>satnogs_coarse_doppler_correction_cc_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>blocks_vco_c_0</source_block_id>
<sink_block_id>blocks_multiply_xx_0_0</sink_block_id>
<source_key>0</source_key>
<sink_key>1</sink_key>
</connection>
<connection>
<source_block_id>dc_blocker_xx_0</source_block_id>
<sink_block_id>blocks_float_to_complex_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>dc_blocker_xx_0_0</source_block_id>
<sink_block_id>low_pass_filter_2_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>digital_binary_slicer_fb_0</source_block_id>
<sink_block_id>satnogs_ax25_decoder_bm_0</sink_block_id>
@ -3854,7 +4313,7 @@ max_modulation_freq = 3000</value>
</connection>
<connection>
<source_block_id>digital_clock_recovery_mm_xx_0</source_block_id>
<sink_block_id>satnogs_quad_demod_filter_ff_0</sink_block_id>
<sink_block_id>digital_binary_slicer_fb_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
@ -3870,6 +4329,12 @@ max_modulation_freq = 3000</value>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>low_pass_filter_2_0</source_block_id>
<sink_block_id>digital_clock_recovery_mm_xx_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>
@ -3878,7 +4343,13 @@ max_modulation_freq = 3000</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_quadrature_demod_cf_0_0_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>blocks_delay_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
@ -3924,12 +4395,6 @@ max_modulation_freq = 3000</value>
<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>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>satnogs_tcp_rigctl_msg_source_0</source_block_id>
<sink_block_id>satnogs_coarse_doppler_correction_cc_0</sink_block_id>

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>(1328, 420)</value>
</param>
<param>
<key>_rotation</key>
@ -179,7 +179,7 @@
</param>
<param>
<key>_coordinate</key>
<value>(992, 316)</value>
<value>(1316, 83)</value>
</param>
<param>
<key>_rotation</key>
@ -202,6 +202,49 @@
<value>0</value>
</param>
</block>
<block>
<key>analog_quadrature_demod_cf</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>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(965, 259)</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_quadrature_demod_cf_0_0_0_0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
</block>
<block>
<key>parameter</key>
<param>
@ -343,6 +386,171 @@
<value>satnogs.not_set_rx_bb_gain</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>1024/2</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(1260, 171)</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_moving_average_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>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(1125, 243)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>blocks_moving_average_xx_0</value>
</param>
<param>
<key>vlen</key>
<value>1</value>
</param>
<param>
<key>length</key>
<value>1024</value>
</param>
<param>
<key>max_iter</key>
<value>4096</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>scale</key>
<value>1.0/1024.0</value>
</param>
<param>
<key>type</key>
<value>float</value>
</param>
</block>
<block>
<key>blocks_multiply_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>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(1452, 175)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>blocks_multiply_xx_0</value>
</param>
<param>
<key>type</key>
<value>complex</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>num_inputs</key>
<value>2</value>
</param>
<param>
<key>vlen</key>
<value>1</value>
</param>
</block>
<block>
<key>blocks_rotator_cc</key>
<param>
@ -386,6 +594,57 @@
<value>-2.0 * math.pi * (lo_offset / satnogs.handle_samp_rate_rx(rx_sdr_device, samp_rate_rx))</value>
</param>
</block>
<block>
<key>blocks_vco_c</key>
<param>
<key>amplitude</key>
<value>1.0</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>(1276, 243)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>blocks_vco_c_0</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>sensitivity</key>
<value>-audio_samp_rate</value>
</param>
</block>
<block>
<key>dc_blocker_xx</key>
<param>
@ -406,7 +665,7 @@
</param>
<param>
<key>_coordinate</key>
<value>(1432, 188)</value>
<value>(1824, 412)</value>
</param>
<param>
<key>_rotation</key>
@ -457,7 +716,7 @@
</param>
<param>
<key>_coordinate</key>
<value>(1208, 308)</value>
<value>(1492, 75)</value>
</param>
<param>
<key>_rotation</key>
@ -641,19 +900,19 @@
</param>
<param>
<key>_coordinate</key>
<value>(1616, 164)</value>
<value>(1768, 556)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
<value>180</value>
</param>
<param>
<key>gain_mu</key>
<value>0.175</value>
<value>0.5/8.0</value>
</param>
<param>
<key>gain_omega</key>
<value>0.25*0.175*0.175</value>
<value>2 * math.pi / 100</value>
</param>
<param>
<key>id</key>
@ -673,7 +932,7 @@
</param>
<param>
<key>omega_relative_limit</key>
<value>0.005</value>
<value>0.01</value>
</param>
<param>
<key>omega</key>
@ -998,6 +1257,156 @@ 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>Avoid aliasing of the polyphase resampler</value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>cutoff_freq</key>
<value>0.75 * baudrate</value>
</param>
<param>
<key>decim</key>
<value>1</value>
</param>
<param>
<key>_enabled</key>
<value>1</value>
</param>
<param>
<key>type</key>
<value>fir_filter_ccf</value>
</param>
<param>
<key>_coordinate</key>
<value>(832, 372)</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>audio_samp_rate</value>
</param>
<param>
<key>width</key>
<value>1000</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>baudrate * 0.60</value>
</param>
<param>
<key>decim</key>
<value>1</value>
</param>
<param>
<key>_enabled</key>
<value>1</value>
</param>
<param>
<key>type</key>
<value>fir_filter_fff</value>
</param>
<param>
<key>_coordinate</key>
<value>(1584, 372)</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_1</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>2 * baudrate</value>
</param>
<param>
<key>width</key>
<value>baudrate / 8.0</value>
</param>
<param>
<key>win</key>
<value>firdes.WIN_HAMMING</value>
</param>
</block>
<block>
<key>osmosdr_source</key>
<param>
@ -2457,7 +2866,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 +2897,7 @@ we shift the LO a little further</value>
</param>
<param>
<key>_coordinate</key>
<value>(984, 172)</value>
<value>(1016, 396)</value>
</param>
<param>
<key>_rotation</key>
@ -2496,7 +2905,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>
@ -2520,7 +2929,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>
@ -3045,7 +3454,7 @@ we shift the LO a little further</value>
</param>
<param>
<key>_coordinate</key>
<value>(992, 68)</value>
<value>(965, 27)</value>
</param>
<param>
<key>_rotation</key>
@ -3088,7 +3497,7 @@ we shift the LO a little further</value>
</param>
<param>
<key>_coordinate</key>
<value>(1384, 300)</value>
<value>(1667, 67)</value>
</param>
<param>
<key>_rotation</key>
@ -3107,53 +3516,6 @@ we shift the LO a little further</value>
<value>audio_samp_rate</value>
</param>
</block>
<block>
<key>satnogs_quad_demod_filter_ff</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>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(1664, 580)</value>
</param>
<param>
<key>_rotation</key>
<value>180</value>
</param>
<param>
<key>gain</key>
<value>1.2</value>
</param>
<param>
<key>id</key>
<value>satnogs_quad_demod_filter_ff_0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>win</key>
<value>80</value>
</param>
</block>
<block>
<key>satnogs_tcp_rigctl_msg_source</key>
<param>
@ -3288,7 +3650,7 @@ we shift the LO a little further</value>
</param>
<param>
<key>_coordinate</key>
<value>(760, 44)</value>
<value>(726, 3)</value>
</param>
<param>
<key>_rotation</key>
@ -3454,7 +3816,7 @@ we shift the LO a little further</value>
</block>
<connection>
<source_block_id>analog_quadrature_demod_cf_0_0</source_block_id>
<sink_block_id>dc_blocker_xx_0</sink_block_id>
<sink_block_id>low_pass_filter_1</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
@ -3464,12 +3826,42 @@ we shift the LO a little further</value>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>analog_quadrature_demod_cf_0_0_0_0</source_block_id>
<sink_block_id>blocks_moving_average_xx_0</sink_block_id>
<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_xx_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>blocks_moving_average_xx_0</source_block_id>
<sink_block_id>blocks_vco_c_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>low_pass_filter_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>blocks_rotator_cc_0</source_block_id>
<sink_block_id>satnogs_coarse_doppler_correction_cc_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>blocks_vco_c_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>dc_blocker_xx_0</source_block_id>
<sink_block_id>digital_clock_recovery_mm_xx_0</sink_block_id>
@ -3496,7 +3888,19 @@ we shift the LO a little further</value>
</connection>
<connection>
<source_block_id>digital_clock_recovery_mm_xx_0</source_block_id>
<sink_block_id>satnogs_quad_demod_filter_ff_0</sink_block_id>
<sink_block_id>digital_binary_slicer_fb_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>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>low_pass_filter_1</source_block_id>
<sink_block_id>dc_blocker_xx_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
@ -3514,7 +3918,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>pfb_arb_resampler_xxx_0_0</sink_block_id>
<sink_block_id>analog_quadrature_demod_cf_0_0_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>blocks_delay_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
@ -3531,7 +3941,7 @@ 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>
<source_block_id>pfb_arb_resampler_xxx_0_0_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>
@ -3566,12 +3976,6 @@ we shift the LO a little further</value>
<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>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>satnogs_tcp_rigctl_msg_source_0</source_block_id>
<sink_block_id>satnogs_coarse_doppler_correction_cc_0</sink_block_id>

View File

@ -136,7 +136,7 @@
</param>
<param>
<key>_coordinate</key>
<value>(1248, 196)</value>
<value>(1544, 420)</value>
</param>
<param>
<key>_rotation</key>
@ -179,7 +179,7 @@
</param>
<param>
<key>_coordinate</key>
<value>(992, 316)</value>
<value>(1460, 83)</value>
</param>
<param>
<key>_rotation</key>
@ -202,6 +202,49 @@
<value>0</value>
</param>
</block>
<block>
<key>analog_quadrature_demod_cf</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>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(981, 291)</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_quadrature_demod_cf_0_0_0_0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
</block>
<block>
<key>parameter</key>
<param>
@ -343,6 +386,171 @@
<value>satnogs.not_set_rx_bb_gain</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>1024/2</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(1360, 228)</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_moving_average_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>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(1164, 275)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>blocks_moving_average_xx_0</value>
</param>
<param>
<key>vlen</key>
<value>1</value>
</param>
<param>
<key>length</key>
<value>1024</value>
</param>
<param>
<key>max_iter</key>
<value>4096</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>scale</key>
<value>1.0/1024.0</value>
</param>
<param>
<key>type</key>
<value>float</value>
</param>
</block>
<block>
<key>blocks_multiply_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>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(1531, 239)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>blocks_multiply_xx_0</value>
</param>
<param>
<key>type</key>
<value>complex</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>num_inputs</key>
<value>2</value>
</param>
<param>
<key>vlen</key>
<value>1</value>
</param>
</block>
<block>
<key>blocks_rotator_cc</key>
<param>
@ -386,6 +594,57 @@
<value>-2.0 * math.pi * (lo_offset / satnogs.handle_samp_rate_rx(rx_sdr_device, samp_rate_rx))</value>
</param>
</block>
<block>
<key>blocks_vco_c</key>
<param>
<key>amplitude</key>
<value>1.0</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>(1324, 275)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>blocks_vco_c_0</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>sensitivity</key>
<value>-audio_samp_rate</value>
</param>
</block>
<block>
<key>dc_blocker_xx</key>
<param>
@ -406,7 +665,7 @@
</param>
<param>
<key>_coordinate</key>
<value>(1432, 188)</value>
<value>(1912, 412)</value>
</param>
<param>
<key>_rotation</key>
@ -457,7 +716,7 @@
</param>
<param>
<key>_coordinate</key>
<value>(1208, 308)</value>
<value>(1659, 75)</value>
</param>
<param>
<key>_rotation</key>
@ -602,7 +861,7 @@
</param>
<param>
<key>_coordinate</key>
<value>(1512, 592)</value>
<value>(1520, 592)</value>
</param>
<param>
<key>_rotation</key>
@ -641,19 +900,19 @@
</param>
<param>
<key>_coordinate</key>
<value>(1616, 164)</value>
<value>(1704, 556)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
<value>180</value>
</param>
<param>
<key>gain_mu</key>
<value>0.175</value>
<value>0.5/8.0</value>
</param>
<param>
<key>gain_omega</key>
<value>0.25*0.175*0.175</value>
<value>2 * math.pi / 100</value>
</param>
<param>
<key>id</key>
@ -673,7 +932,7 @@
</param>
<param>
<key>omega_relative_limit</key>
<value>0.005</value>
<value>0.01</value>
</param>
<param>
<key>omega</key>
@ -998,6 +1257,156 @@ 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>Avoid aliasing of the polyphase resampler</value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>cutoff_freq</key>
<value>0.75 * baudrate</value>
</param>
<param>
<key>decim</key>
<value>1</value>
</param>
<param>
<key>_enabled</key>
<value>1</value>
</param>
<param>
<key>type</key>
<value>fir_filter_ccf</value>
</param>
<param>
<key>_coordinate</key>
<value>(768, 372)</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>audio_samp_rate</value>
</param>
<param>
<key>width</key>
<value>1000</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>baudrate * 0.60</value>
</param>
<param>
<key>decim</key>
<value>1</value>
</param>
<param>
<key>_enabled</key>
<value>1</value>
</param>
<param>
<key>type</key>
<value>fir_filter_fff</value>
</param>
<param>
<key>_coordinate</key>
<value>(1712, 372)</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_1</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>2 * baudrate</value>
</param>
<param>
<key>width</key>
<value>baudrate / 8.0</value>
</param>
<param>
<key>win</key>
<value>firdes.WIN_HAMMING</value>
</param>
</block>
<block>
<key>osmosdr_source</key>
<param>
@ -2488,7 +2897,7 @@ we shift the LO a little further</value>
</param>
<param>
<key>_coordinate</key>
<value>(984, 172)</value>
<value>(1288, 396)</value>
</param>
<param>
<key>_rotation</key>
@ -2496,7 +2905,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>
@ -2520,7 +2929,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>
@ -3045,7 +3454,7 @@ we shift the LO a little further</value>
</param>
<param>
<key>_coordinate</key>
<value>(976, 60)</value>
<value>(1008, 60)</value>
</param>
<param>
<key>_rotation</key>
@ -3088,7 +3497,7 @@ we shift the LO a little further</value>
</param>
<param>
<key>_coordinate</key>
<value>(1384, 300)</value>
<value>(1835, 67)</value>
</param>
<param>
<key>_rotation</key>
@ -3107,53 +3516,6 @@ we shift the LO a little further</value>
<value>audio_samp_rate</value>
</param>
</block>
<block>
<key>satnogs_quad_demod_filter_ff</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>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(1664, 580)</value>
</param>
<param>
<key>_rotation</key>
<value>180</value>
</param>
<param>
<key>gain</key>
<value>1.2</value>
</param>
<param>
<key>id</key>
<value>satnogs_quad_demod_filter_ff_0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>win</key>
<value>80</value>
</param>
</block>
<block>
<key>satnogs_tcp_rigctl_msg_source</key>
<param>
@ -3454,7 +3816,7 @@ we shift the LO a little further</value>
</block>
<connection>
<source_block_id>analog_quadrature_demod_cf_0_0</source_block_id>
<sink_block_id>dc_blocker_xx_0</sink_block_id>
<sink_block_id>low_pass_filter_1</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
@ -3464,12 +3826,42 @@ we shift the LO a little further</value>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>analog_quadrature_demod_cf_0_0_0_0</source_block_id>
<sink_block_id>blocks_moving_average_xx_0</sink_block_id>
<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_xx_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>blocks_moving_average_xx_0</source_block_id>
<sink_block_id>blocks_vco_c_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>low_pass_filter_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>blocks_rotator_cc_0</source_block_id>
<sink_block_id>satnogs_coarse_doppler_correction_cc_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>blocks_vco_c_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>dc_blocker_xx_0</source_block_id>
<sink_block_id>digital_clock_recovery_mm_xx_0</sink_block_id>
@ -3496,7 +3888,19 @@ we shift the LO a little further</value>
</connection>
<connection>
<source_block_id>digital_clock_recovery_mm_xx_0</source_block_id>
<sink_block_id>satnogs_quad_demod_filter_ff_0</sink_block_id>
<sink_block_id>digital_binary_slicer_fb_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>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>low_pass_filter_1</source_block_id>
<sink_block_id>dc_blocker_xx_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
@ -3514,7 +3918,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>pfb_arb_resampler_xxx_0_0</sink_block_id>
<sink_block_id>analog_quadrature_demod_cf_0_0_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>blocks_delay_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
@ -3531,7 +3941,7 @@ 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>
<source_block_id>pfb_arb_resampler_xxx_0_0_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>
@ -3566,12 +3976,6 @@ we shift the LO a little further</value>
<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>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>satnogs_tcp_rigctl_msg_source_0</source_block_id>
<sink_block_id>satnogs_coarse_doppler_correction_cc_0</sink_block_id>

View File

@ -175,7 +175,7 @@
</param>
<param>
<key>_coordinate</key>
<value>(1248, 196)</value>
<value>(904, 412)</value>
</param>
<param>
<key>_rotation</key>
@ -183,11 +183,11 @@
</param>
<param>
<key>gain</key>
<value>1.2</value>
<value>0.9</value>
</param>
<param>
<key>id</key>
<value>analog_quadrature_demod_cf_0_0</value>
<value>analog_quadrature_demod_cf_0_0_0</value>
</param>
<param>
<key>maxoutbuf</key>
@ -214,11 +214,11 @@
</param>
<param>
<key>_enabled</key>
<value>True</value>
<value>1</value>
</param>
<param>
<key>_coordinate</key>
<value>(992, 316)</value>
<value>(952, 316)</value>
</param>
<param>
<key>_rotation</key>
@ -226,11 +226,54 @@
</param>
<param>
<key>gain</key>
<value>0.9</value>
<value>1.0</value>
</param>
<param>
<key>id</key>
<value>analog_quadrature_demod_cf_0_0_0</value>
<value>analog_quadrature_demod_cf_0_0_0_0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
</block>
<block>
<key>analog_quadrature_demod_cf</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>(1824, 180)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>gain</key>
<value>1.2</value>
</param>
<param>
<key>id</key>
<value>analog_quadrature_demod_cf_0_0_0_1</value>
</param>
<param>
<key>maxoutbuf</key>
@ -382,6 +425,171 @@
<value>satnogs.not_set_rx_bb_gain</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>1024/2</value>
</param>
<param>
<key>_enabled</key>
<value>1</value>
</param>
<param>
<key>_coordinate</key>
<value>(992, 164)</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_moving_average_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>(1136, 300)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>blocks_moving_average_xx_0</value>
</param>
<param>
<key>vlen</key>
<value>1</value>
</param>
<param>
<key>length</key>
<value>1024</value>
</param>
<param>
<key>max_iter</key>
<value>4096</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>scale</key>
<value>1.0/1024.0</value>
</param>
<param>
<key>type</key>
<value>float</value>
</param>
</block>
<block>
<key>blocks_multiply_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>(1296, 168)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>blocks_multiply_xx_0_0</value>
</param>
<param>
<key>type</key>
<value>complex</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>num_inputs</key>
<value>2</value>
</param>
<param>
<key>vlen</key>
<value>1</value>
</param>
</block>
<block>
<key>blocks_rotator_cc</key>
<param>
@ -402,7 +610,7 @@
</param>
<param>
<key>_coordinate</key>
<value>(472, 372)</value>
<value>(368, 372)</value>
</param>
<param>
<key>_rotation</key>
@ -425,6 +633,57 @@
<value>-2.0 * math.pi * (lo_offset / satnogs.handle_samp_rate_rx(rx_sdr_device, samp_rate_rx))</value>
</param>
</block>
<block>
<key>blocks_vco_c</key>
<param>
<key>amplitude</key>
<value>1.0</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>1</value>
</param>
<param>
<key>_coordinate</key>
<value>(1296, 300)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>blocks_vco_c_0</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>sensitivity</key>
<value>-audio_samp_rate</value>
</param>
</block>
<block>
<key>dc_blocker_xx</key>
<param>
@ -445,7 +704,7 @@
</param>
<param>
<key>_coordinate</key>
<value>(1432, 188)</value>
<value>(1120, 404)</value>
</param>
<param>
<key>_rotation</key>
@ -453,7 +712,7 @@
</param>
<param>
<key>id</key>
<value>dc_blocker_xx_0</value>
<value>dc_blocker_xx_0_0</value>
</param>
<param>
<key>length</key>
@ -492,19 +751,19 @@
</param>
<param>
<key>_enabled</key>
<value>True</value>
<value>1</value>
</param>
<param>
<key>_coordinate</key>
<value>(1208, 308)</value>
<value>(1912, 556)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
<value>180</value>
</param>
<param>
<key>id</key>
<value>dc_blocker_xx_0_0</value>
<value>dc_blocker_xx_0_0_0</value>
</param>
<param>
<key>length</key>
@ -680,19 +939,19 @@
</param>
<param>
<key>_coordinate</key>
<value>(1616, 164)</value>
<value>(1672, 532)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
<value>180</value>
</param>
<param>
<key>gain_mu</key>
<value>0.175</value>
<value>0.5/8.0</value>
</param>
<param>
<key>gain_omega</key>
<value>0.25*0.175*0.175</value>
<value>2 * math.pi / 100</value>
</param>
<param>
<key>id</key>
@ -712,7 +971,7 @@
</param>
<param>
<key>omega_relative_limit</key>
<value>0.005</value>
<value>0.01</value>
</param>
<param>
<key>omega</key>
@ -1037,6 +1296,156 @@ 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>0.75 * baudrate</value>
</param>
<param>
<key>decim</key>
<value>1</value>
</param>
<param>
<key>_enabled</key>
<value>1</value>
</param>
<param>
<key>type</key>
<value>fir_filter_ccf</value>
</param>
<param>
<key>_coordinate</key>
<value>(1424, 132)</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>audio_samp_rate</value>
</param>
<param>
<key>width</key>
<value>1000</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>baudrate * 0.60</value>
</param>
<param>
<key>decim</key>
<value>1</value>
</param>
<param>
<key>_enabled</key>
<value>1</value>
</param>
<param>
<key>type</key>
<value>fir_filter_fff</value>
</param>
<param>
<key>_coordinate</key>
<value>(1984, 132)</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_1</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>2 * baudrate</value>
</param>
<param>
<key>width</key>
<value>baudrate / 8.0</value>
</param>
<param>
<key>win</key>
<value>firdes.WIN_HAMMING</value>
</param>
</block>
<block>
<key>osmosdr_source</key>
<param>
@ -2341,7 +2750,7 @@ we shift the LO a little further</value>
</param>
<param>
<key>_coordinate</key>
<value>(216, 284)</value>
<value>(112, 284)</value>
</param>
<param>
<key>_rotation</key>
@ -2464,7 +2873,7 @@ we shift the LO a little further</value>
</param>
<param>
<key>_coordinate</key>
<value>(728, 172)</value>
<value>(624, 172)</value>
</param>
<param>
<key>_rotation</key>
@ -2523,11 +2932,11 @@ we shift the LO a little further</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
<value>1</value>
</param>
<param>
<key>_coordinate</key>
<value>(984, 172)</value>
<value>(1592, 156)</value>
</param>
<param>
<key>_rotation</key>
@ -2535,7 +2944,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>
@ -2872,7 +3281,7 @@ we shift the LO a little further</value>
</param>
<param>
<key>_coordinate</key>
<value>(496, 184)</value>
<value>(392, 184)</value>
</param>
<param>
<key>_rotation</key>
@ -3045,7 +3454,7 @@ we shift the LO a little further</value>
</param>
<param>
<key>_coordinate</key>
<value>(992, 68)</value>
<value>(888, 44)</value>
</param>
<param>
<key>_rotation</key>
@ -3088,7 +3497,7 @@ we shift the LO a little further</value>
</param>
<param>
<key>_coordinate</key>
<value>(1384, 300)</value>
<value>(1296, 396)</value>
</param>
<param>
<key>_rotation</key>
@ -3127,7 +3536,7 @@ we shift the LO a little further</value>
</param>
<param>
<key>_coordinate</key>
<value>(216, 148)</value>
<value>(112, 148)</value>
</param>
<param>
<key>_rotation</key>
@ -3241,7 +3650,7 @@ we shift the LO a little further</value>
</param>
<param>
<key>_coordinate</key>
<value>(760, 44)</value>
<value>(656, 44)</value>
</param>
<param>
<key>_rotation</key>
@ -3406,14 +3815,38 @@ we shift the LO a little further</value>
</param>
</block>
<connection>
<source_block_id>analog_quadrature_demod_cf_0_0</source_block_id>
<sink_block_id>dc_blocker_xx_0</sink_block_id>
<source_block_id>analog_quadrature_demod_cf_0_0_0</source_block_id>
<sink_block_id>dc_blocker_xx_0_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>analog_quadrature_demod_cf_0_0_0</source_block_id>
<sink_block_id>dc_blocker_xx_0_0</sink_block_id>
<source_block_id>analog_quadrature_demod_cf_0_0_0_0</source_block_id>
<sink_block_id>blocks_moving_average_xx_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>analog_quadrature_demod_cf_0_0_0_1</source_block_id>
<sink_block_id>low_pass_filter_1</sink_block_id>
<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_xx_0_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>blocks_moving_average_xx_0</source_block_id>
<sink_block_id>blocks_vco_c_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>blocks_multiply_xx_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>
@ -3424,10 +3857,10 @@ we shift the LO a little further</value>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>dc_blocker_xx_0</source_block_id>
<sink_block_id>digital_clock_recovery_mm_xx_0</sink_block_id>
<source_block_id>blocks_vco_c_0</source_block_id>
<sink_block_id>blocks_multiply_xx_0_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
<sink_key>1</sink_key>
</connection>
<connection>
<source_block_id>dc_blocker_xx_0_0</source_block_id>
@ -3435,6 +3868,12 @@ we shift the LO a little further</value>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>dc_blocker_xx_0_0_0</source_block_id>
<sink_block_id>digital_clock_recovery_mm_xx_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>digital_binary_slicer_fb_0</source_block_id>
<sink_block_id>satnogs_frame_acquisition_0</sink_block_id>
@ -3447,6 +3886,18 @@ 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>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>low_pass_filter_1</source_block_id>
<sink_block_id>dc_blocker_xx_0_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>
@ -3461,7 +3912,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>pfb_arb_resampler_xxx_0_0</sink_block_id>
<sink_block_id>analog_quadrature_demod_cf_0_0_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>blocks_delay_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
@ -3478,8 +3935,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>analog_quadrature_demod_cf_0_0_0_1</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>

View File

@ -5,9 +5,10 @@
# Title: satnogs_reaktor_hello_world_fsk9600_decoder
# Author: Manolis Surligas (surligas@gmail.com)
# Description: FSK 9600 Decoder for the Reaktor-Hello-World satellite
# Generated: Mon Dec 3 11:51:46 2018
# GNU Radio version: 3.7.13.5
##################################################
from gnuradio import analog
from gnuradio import blocks
from gnuradio import digital
@ -70,11 +71,11 @@ class satnogs_reaktor_hello_world_fsk9600_decoder(gr.top_block):
self.satnogs_frame_file_sink_0_1_0 = satnogs.frame_file_sink(decoded_data_file_path, 0)
self.satnogs_frame_acquisition_0 = satnogs.frame_acquisition(1, [0xAA, 0xAA, 0xAA, 0xAA], 4, [0x35, 0x2E, 0x35, 0x2E], 3, 1, 256, 3, variable_whitening_0, 2048)
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_0 = pfb.arb_resampler_ccf(
self.pfb_arb_resampler_xxx_0_0_0 = pfb.arb_resampler_ccf(
(2.0*baudrate)/audio_samp_rate,
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),
@ -95,13 +96,22 @@ class satnogs_reaktor_hello_world_fsk9600_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.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_1 = filter.fir_filter_fff(1, firdes.low_pass(
1, 2 * baudrate, baudrate * 0.60, baudrate / 8.0, firdes.WIN_HAMMING, 6.76))
self.low_pass_filter_0 = filter.fir_filter_ccf(1, firdes.low_pass(
1, audio_samp_rate, 0.75 * baudrate, 1000, firdes.WIN_HAMMING, 6.76))
self.digital_clock_recovery_mm_xx_0 = digital.clock_recovery_mm_ff(2, 2 * math.pi / 100, 0.5, 0.5/8.0, 0.01)
self.digital_binary_slicer_fb_0 = digital.binary_slicer_fb()
self.dc_blocker_xx_0_0_0 = filter.dc_blocker_ff(1024, True)
self.dc_blocker_xx_0_0 = filter.dc_blocker_ff(1024, True)
self.dc_blocker_xx_0 = filter.dc_blocker_ff(1024, True)
self.blocks_vco_c_0 = blocks.vco_c(audio_samp_rate, -audio_samp_rate, 1.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_0 = blocks.multiply_vcc(1)
self.blocks_moving_average_xx_0 = blocks.moving_average_ff(1024, 1.0/1024.0, 4096)
self.blocks_delay_0 = blocks.delay(gr.sizeof_gr_complex*1, 1024/2)
self.analog_quadrature_demod_cf_0_0_0_1 = analog.quadrature_demod_cf(1.2)
self.analog_quadrature_demod_cf_0_0_0_0 = analog.quadrature_demod_cf(1.0)
self.analog_quadrature_demod_cf_0_0_0 = analog.quadrature_demod_cf(0.9)
self.analog_quadrature_demod_cf_0_0 = analog.quadrature_demod_cf(1.2)
@ -111,19 +121,27 @@ class satnogs_reaktor_hello_world_fsk9600_decoder(gr.top_block):
self.msg_connect((self.satnogs_frame_acquisition_0, 'out'), (self.satnogs_frame_file_sink_0_1_0, 'frame'))
self.msg_connect((self.satnogs_frame_acquisition_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_quadrature_demod_cf_0_0, 0), (self.dc_blocker_xx_0, 0))
self.connect((self.analog_quadrature_demod_cf_0_0_0, 0), (self.dc_blocker_xx_0_0, 0))
self.connect((self.analog_quadrature_demod_cf_0_0_0_0, 0), (self.blocks_moving_average_xx_0, 0))
self.connect((self.analog_quadrature_demod_cf_0_0_0_1, 0), (self.low_pass_filter_1, 0))
self.connect((self.blocks_delay_0, 0), (self.blocks_multiply_xx_0_0, 0))
self.connect((self.blocks_moving_average_xx_0, 0), (self.blocks_vco_c_0, 0))
self.connect((self.blocks_multiply_xx_0_0, 0), (self.low_pass_filter_0, 0))
self.connect((self.blocks_rotator_cc_0, 0), (self.satnogs_coarse_doppler_correction_cc_0, 0))
self.connect((self.dc_blocker_xx_0, 0), (self.digital_clock_recovery_mm_xx_0, 0))
self.connect((self.blocks_vco_c_0, 0), (self.blocks_multiply_xx_0_0, 1))
self.connect((self.dc_blocker_xx_0_0, 0), (self.satnogs_ogg_encoder_0, 0))
self.connect((self.dc_blocker_xx_0_0_0, 0), (self.digital_clock_recovery_mm_xx_0, 0))
self.connect((self.digital_binary_slicer_fb_0, 0), (self.satnogs_frame_acquisition_0, 0))
self.connect((self.digital_clock_recovery_mm_xx_0, 0), (self.digital_binary_slicer_fb_0, 0))
self.connect((self.low_pass_filter_0, 0), (self.pfb_arb_resampler_xxx_0_0_0, 0))
self.connect((self.low_pass_filter_1, 0), (self.dc_blocker_xx_0_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.analog_quadrature_demod_cf_0_0_0_0, 0))
self.connect((self.pfb_arb_resampler_xxx_0, 0), (self.blocks_delay_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.analog_quadrature_demod_cf_0_0_0_1, 0))
self.connect((self.satnogs_coarse_doppler_correction_cc_0, 0), (self.pfb_arb_resampler_xxx_0, 0))
def get_antenna(self):
@ -138,7 +156,9 @@ class satnogs_reaktor_hello_world_fsk9600_decoder(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((2.0*self.baudrate)/self.audio_samp_rate)
self.low_pass_filter_1.set_taps(firdes.low_pass(1, 2 * self.baudrate, self.baudrate * 0.60, self.baudrate / 8.0, firdes.WIN_HAMMING, 6.76))
self.low_pass_filter_0.set_taps(firdes.low_pass(1, self.audio_samp_rate, 0.75 * self.baudrate, 1000, firdes.WIN_HAMMING, 6.76))
def get_bb_gain(self):
return self.bb_gain
@ -279,8 +299,9 @@ class satnogs_reaktor_hello_world_fsk9600_decoder(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_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))
self.low_pass_filter_0.set_taps(firdes.low_pass(1, self.audio_samp_rate, 0.75 * self.baudrate, 1000, firdes.WIN_HAMMING, 6.76))
def argument_parser():

View File

@ -5,9 +5,10 @@
# Title: AFSK1200 AX.25 decoder
# Author: Manolis Surligas (surligas@gmail.com), Vardakis Giorgos (vardakis.grg@gmail.com)
# Description: AFSK1200 AX.25 decoder
# Generated: Sun Nov 25 23:43:12 2018
# GNU Radio version: 3.7.13.5
##################################################
from gnuradio import analog
from gnuradio import blocks
from gnuradio import digital
@ -26,7 +27,7 @@ import time
class satnogs_afsk1200_ax25(gr.top_block):
def __init__(self, antenna=satnogs.not_set_antenna, baudrate=9600.0, bb_gain=satnogs.not_set_rx_bb_gain, 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.wav', if_gain=satnogs.not_set_rx_if_gain, iq_file_path='/tmp/iq.dat', lo_offset=100e3, mark_frequency=2200.0, 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, space_frequency=1200.0, udp_IP='127.0.0.1', udp_port=16887, waterfall_file_path='/tmp/waterfall.dat'):
def __init__(self, antenna=satnogs.not_set_antenna, baudrate=1200.0, bb_gain=satnogs.not_set_rx_bb_gain, 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.wav', if_gain=satnogs.not_set_rx_if_gain, iq_file_path='/tmp/iq.dat', lo_offset=100e3, mark_frequency=2200.0, 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, space_frequency=1200.0, udp_IP='127.0.0.1', udp_port=16887, waterfall_file_path='/tmp/waterfall.dat'):
gr.top_block.__init__(self, "AFSK1200 AX.25 decoder ")
##################################################
@ -69,7 +70,6 @@ class satnogs_afsk1200_ax25(gr.top_block):
self.satnogs_waterfall_sink_0 = satnogs.waterfall_sink(audio_samp_rate, 0.0, 10, 1024, waterfall_file_path, 1)
self.satnogs_udp_msg_sink_0_0 = satnogs.udp_msg_sink(udp_IP, udp_port, 1500)
self.satnogs_tcp_rigctl_msg_source_0 = satnogs.tcp_rigctl_msg_source("127.0.0.1", rigctl_port, False, 1000, 1500)
self.satnogs_quad_demod_filter_ff_0 = satnogs.quad_demod_filter_ff(((audio_samp_rate/10) / baud_rate)/(math.pi*1))
self.satnogs_ogg_encoder_0 = satnogs.ogg_encoder(file_path, audio_samp_rate, 1.0)
self.satnogs_iq_sink_0 = satnogs.iq_sink(16768, iq_file_path, False, enable_iq_dump)
self.satnogs_frame_file_sink_0_1_0 = satnogs.frame_file_sink(decoded_data_file_path, 0)
@ -95,19 +95,29 @@ class satnogs_afsk1200_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.low_pass_filter_1 = filter.fir_filter_ccf(10, firdes.low_pass(
10, audio_samp_rate, (mark_frequency - space_frequency)/2.0, 1000, firdes.WIN_HAMMING, 6.76))
self.low_pass_filter_2_0 = filter.fir_filter_fff(1, firdes.low_pass(
1, baudrate*2, baudrate /2+ 500 /2, 500, firdes.WIN_HAMMING, 6.76))
self.low_pass_filter_1 = filter.fir_filter_ccf(20, firdes.low_pass(
1, audio_samp_rate, (mark_frequency - space_frequency)/2.0 + 250, 500, 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.digital_clock_recovery_mm_xx_0 = digital.clock_recovery_mm_ff((48e3/10)/baud_rate, 0.25*0.175*0.175, 0.5, 0.175, 0.005)
1, audio_samp_rate, deviation+max_modulation_freq, 1000, firdes.WIN_HAMMING, 6.76))
self.digital_clock_recovery_mm_xx_0 = digital.clock_recovery_mm_ff((48e3/20)/baud_rate, 2*math.pi/100.0, 0.5, 0.5/8.0, 0.01)
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)
self.blocks_vco_c_0 = blocks.vco_c(audio_samp_rate, -audio_samp_rate, 1.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_0 = blocks.multiply_vcc(1)
self.blocks_multiply_xx_0 = blocks.multiply_vcc(1)
self.blocks_moving_average_xx_0 = blocks.moving_average_ff(1024, 1.0/1024.0, 4096)
self.blocks_float_to_complex_0 = blocks.float_to_complex(1)
self.blocks_delay_0 = blocks.delay(gr.sizeof_gr_complex*1, 1024/2)
self.band_pass_filter_0 = filter.fir_filter_fff(1, firdes.band_pass(
1, audio_samp_rate, 1000, 2400, 400, firdes.WIN_HAMMING, 6.76))
self.analog_sig_source_x_0 = analog.sig_source_c(audio_samp_rate, analog.GR_COS_WAVE, -(1200 + 2200) / 2, 1, 0)
self.analog_quadrature_demod_cf_0_0_0_0 = analog.quadrature_demod_cf(1.0)
self.analog_quadrature_demod_cf_0_0 = analog.quadrature_demod_cf((2*math.pi*deviation)/audio_samp_rate)
self.analog_quadrature_demod_cf_0 = analog.quadrature_demod_cf(((audio_samp_rate/10) / baud_rate)/(math.pi*1))
self.analog_quadrature_demod_cf_0 = analog.quadrature_demod_cf(((audio_samp_rate/20) / baud_rate)/(math.pi*1))
@ -119,25 +129,33 @@ class satnogs_afsk1200_ax25(gr.top_block):
self.msg_connect((self.satnogs_ax25_decoder_bm_0_0, 'pdu'), (self.satnogs_frame_file_sink_0_1_0, 'frame'))
self.msg_connect((self.satnogs_ax25_decoder_bm_0_0, 'pdu'), (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_quadrature_demod_cf_0, 0), (self.digital_clock_recovery_mm_xx_0, 0))
self.connect((self.analog_quadrature_demod_cf_0_0, 0), (self.dc_blocker_xx_0, 0))
self.connect((self.analog_quadrature_demod_cf_0, 0), (self.dc_blocker_xx_0_0, 0))
self.connect((self.analog_quadrature_demod_cf_0_0, 0), (self.band_pass_filter_0, 0))
self.connect((self.analog_quadrature_demod_cf_0_0, 0), (self.satnogs_ogg_encoder_0, 0))
self.connect((self.analog_quadrature_demod_cf_0_0_0_0, 0), (self.blocks_moving_average_xx_0, 0))
self.connect((self.analog_sig_source_x_0, 0), (self.blocks_multiply_xx_0, 1))
self.connect((self.band_pass_filter_0, 0), (self.dc_blocker_xx_0, 0))
self.connect((self.blocks_delay_0, 0), (self.blocks_multiply_xx_0_0, 0))
self.connect((self.blocks_float_to_complex_0, 0), (self.blocks_multiply_xx_0, 0))
self.connect((self.blocks_moving_average_xx_0, 0), (self.blocks_vco_c_0, 0))
self.connect((self.blocks_multiply_xx_0, 0), (self.low_pass_filter_1, 0))
self.connect((self.blocks_multiply_xx_0_0, 0), (self.low_pass_filter_0, 0))
self.connect((self.blocks_rotator_cc_0, 0), (self.satnogs_coarse_doppler_correction_cc_0, 0))
self.connect((self.blocks_vco_c_0, 0), (self.blocks_multiply_xx_0_0, 1))
self.connect((self.dc_blocker_xx_0, 0), (self.blocks_float_to_complex_0, 0))
self.connect((self.dc_blocker_xx_0_0, 0), (self.low_pass_filter_2_0, 0))
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.digital_clock_recovery_mm_xx_0, 0), (self.digital_binary_slicer_fb_0, 0))
self.connect((self.low_pass_filter_0, 0), (self.analog_quadrature_demod_cf_0_0, 0))
self.connect((self.low_pass_filter_1, 0), (self.analog_quadrature_demod_cf_0, 0))
self.connect((self.low_pass_filter_2_0, 0), (self.digital_clock_recovery_mm_xx_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_quadrature_demod_cf_0_0_0_0, 0))
self.connect((self.pfb_arb_resampler_xxx_0, 0), (self.blocks_delay_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))
self.connect((self.satnogs_quad_demod_filter_ff_0, 0), (self.digital_binary_slicer_fb_0, 0))
def get_antenna(self):
return self.antenna
@ -151,6 +169,7 @@ class satnogs_afsk1200_ax25(gr.top_block):
def set_baudrate(self, baudrate):
self.baudrate = baudrate
self.low_pass_filter_2_0.set_taps(firdes.low_pass(1, self.baudrate*2, self.baudrate /2+ 500 /2, 500, firdes.WIN_HAMMING, 6.76))
def get_bb_gain(self):
return self.bb_gain
@ -215,7 +234,7 @@ class satnogs_afsk1200_ax25(gr.top_block):
def set_mark_frequency(self, mark_frequency):
self.mark_frequency = mark_frequency
self.low_pass_filter_1.set_taps(firdes.low_pass(10, self.audio_samp_rate, (self.mark_frequency - self.space_frequency)/2.0, 1000, firdes.WIN_HAMMING, 6.76))
self.low_pass_filter_1.set_taps(firdes.low_pass(1, self.audio_samp_rate, (self.mark_frequency - self.space_frequency)/2.0 + 250, 500, firdes.WIN_HAMMING, 6.76))
def get_ppm(self):
return self.ppm
@ -274,7 +293,7 @@ class satnogs_afsk1200_ax25(gr.top_block):
def set_space_frequency(self, space_frequency):
self.space_frequency = space_frequency
self.low_pass_filter_1.set_taps(firdes.low_pass(10, self.audio_samp_rate, (self.mark_frequency - self.space_frequency)/2.0, 1000, firdes.WIN_HAMMING, 6.76))
self.low_pass_filter_1.set_taps(firdes.low_pass(1, self.audio_samp_rate, (self.mark_frequency - self.space_frequency)/2.0 + 250, 500, firdes.WIN_HAMMING, 6.76))
def get_udp_IP(self):
return self.udp_IP
@ -299,14 +318,14 @@ class satnogs_afsk1200_ax25(gr.top_block):
def set_max_modulation_freq(self, max_modulation_freq):
self.max_modulation_freq = max_modulation_freq
self.low_pass_filter_0.set_taps(firdes.low_pass(1, self.audio_samp_rate, self.deviation+self.max_modulation_freq, 3000, firdes.WIN_HAMMING, 6.76))
self.low_pass_filter_0.set_taps(firdes.low_pass(1, self.audio_samp_rate, self.deviation+self.max_modulation_freq, 1000, firdes.WIN_HAMMING, 6.76))
def get_deviation(self):
return self.deviation
def set_deviation(self, deviation):
self.deviation = deviation
self.low_pass_filter_0.set_taps(firdes.low_pass(1, self.audio_samp_rate, self.deviation+self.max_modulation_freq, 3000, firdes.WIN_HAMMING, 6.76))
self.low_pass_filter_0.set_taps(firdes.low_pass(1, self.audio_samp_rate, self.deviation+self.max_modulation_freq, 1000, firdes.WIN_HAMMING, 6.76))
self.analog_quadrature_demod_cf_0_0.set_gain((2*math.pi*self.deviation)/self.audio_samp_rate)
def get_baud_rate(self):
@ -314,8 +333,8 @@ class satnogs_afsk1200_ax25(gr.top_block):
def set_baud_rate(self, baud_rate):
self.baud_rate = baud_rate
self.digital_clock_recovery_mm_xx_0.set_omega((48e3/10)/self.baud_rate)
self.analog_quadrature_demod_cf_0.set_gain(((self.audio_samp_rate/10) / self.baud_rate)/(math.pi*1))
self.digital_clock_recovery_mm_xx_0.set_omega((48e3/20)/self.baud_rate)
self.analog_quadrature_demod_cf_0.set_gain(((self.audio_samp_rate/20) / self.baud_rate)/(math.pi*1))
def get_audio_samp_rate(self):
return self.audio_samp_rate
@ -323,11 +342,12 @@ class satnogs_afsk1200_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.set_rate(self.audio_samp_rate/satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx))
self.low_pass_filter_1.set_taps(firdes.low_pass(10, self.audio_samp_rate, (self.mark_frequency - self.space_frequency)/2.0, 1000, firdes.WIN_HAMMING, 6.76))
self.low_pass_filter_0.set_taps(firdes.low_pass(1, self.audio_samp_rate, self.deviation+self.max_modulation_freq, 3000, firdes.WIN_HAMMING, 6.76))
self.low_pass_filter_1.set_taps(firdes.low_pass(1, self.audio_samp_rate, (self.mark_frequency - self.space_frequency)/2.0 + 250, 500, firdes.WIN_HAMMING, 6.76))
self.low_pass_filter_0.set_taps(firdes.low_pass(1, self.audio_samp_rate, self.deviation+self.max_modulation_freq, 1000, firdes.WIN_HAMMING, 6.76))
self.band_pass_filter_0.set_taps(firdes.band_pass(1, self.audio_samp_rate, 1000, 2400, 400, firdes.WIN_HAMMING, 6.76))
self.analog_sig_source_x_0.set_sampling_freq(self.audio_samp_rate)
self.analog_quadrature_demod_cf_0_0.set_gain((2*math.pi*self.deviation)/self.audio_samp_rate)
self.analog_quadrature_demod_cf_0.set_gain(((self.audio_samp_rate/10) / self.baud_rate)/(math.pi*1))
self.analog_quadrature_demod_cf_0.set_gain(((self.audio_samp_rate/20) / self.baud_rate)/(math.pi*1))
def argument_parser():
@ -337,7 +357,7 @@ def argument_parser():
"", "--antenna", dest="antenna", type="string", default=satnogs.not_set_antenna,
help="Set antenna [default=%default]")
parser.add_option(
"", "--baudrate", dest="baudrate", type="eng_float", default=eng_notation.num_to_str(9600.0),
"", "--baudrate", dest="baudrate", type="eng_float", default=eng_notation.num_to_str(1200.0),
help="Set baudrate [default=%default]")
parser.add_option(
"", "--bb-gain", dest="bb_gain", type="eng_float", default=eng_notation.num_to_str(satnogs.not_set_rx_bb_gain),

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,9 +5,10 @@
# Title: satnogs_fsk_ax25
# Author: Manolis Surligas (surligas@gmail.com)
# Description: Generic FSK AX.25 decoder
# Generated: Fri Aug 17 00:38:04 2018
# GNU Radio version: 3.7.13.5
##################################################
from gnuradio import analog
from gnuradio import blocks
from gnuradio import digital
@ -64,18 +65,17 @@ class satnogs_fsk_ax25(gr.top_block):
self.satnogs_waterfall_sink_0 = satnogs.waterfall_sink(audio_samp_rate, 0.0, 10, 1024, waterfall_file_path, 1)
self.satnogs_udp_msg_sink_0_0 = satnogs.udp_msg_sink(udp_IP, udp_port, 1500)
self.satnogs_tcp_rigctl_msg_source_0 = satnogs.tcp_rigctl_msg_source("127.0.0.1", rigctl_port, False, 1000, 1500)
self.satnogs_quad_demod_filter_ff_0 = satnogs.quad_demod_filter_ff(1.2)
self.satnogs_ogg_encoder_0 = satnogs.ogg_encoder(file_path, audio_samp_rate, 1.0)
self.satnogs_iq_sink_0 = satnogs.iq_sink(16768, iq_file_path, False, enable_iq_dump)
self.satnogs_frame_file_sink_0_1_0 = satnogs.frame_file_sink(decoded_data_file_path, 0)
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(
self.pfb_arb_resampler_xxx_0_0_0 = pfb.arb_resampler_ccf(
(2.0*baudrate)/audio_samp_rate,
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,11 +96,20 @@ 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_1 = filter.fir_filter_fff(1, firdes.low_pass(
1, 2 * baudrate, baudrate * 0.60, baudrate / 8.0, firdes.WIN_HAMMING, 6.76))
self.low_pass_filter_0 = filter.fir_filter_ccf(1, firdes.low_pass(
1, audio_samp_rate, 0.75 * baudrate, 1000, firdes.WIN_HAMMING, 6.76))
self.digital_clock_recovery_mm_xx_0 = digital.clock_recovery_mm_ff(2, 2 * math.pi / 100, 0.5, 0.5/8.0, 0.01)
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)
self.blocks_vco_c_0 = blocks.vco_c(audio_samp_rate, -audio_samp_rate, 1.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_moving_average_xx_0 = blocks.moving_average_ff(1024, 1.0/1024.0, 4096)
self.blocks_delay_0 = blocks.delay(gr.sizeof_gr_complex*1, 1024/2)
self.analog_quadrature_demod_cf_0_0_0_0 = analog.quadrature_demod_cf(1.0)
self.analog_quadrature_demod_cf_0_0_0 = analog.quadrature_demod_cf(0.9)
self.analog_quadrature_demod_cf_0_0 = analog.quadrature_demod_cf(1.2)
@ -114,22 +123,29 @@ class satnogs_fsk_ax25(gr.top_block):
self.msg_connect((self.satnogs_ax25_decoder_bm_0_0, 'pdu'), (self.satnogs_frame_file_sink_0_1_0, 'frame'))
self.msg_connect((self.satnogs_ax25_decoder_bm_0_0, 'pdu'), (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_quadrature_demod_cf_0_0, 0), (self.dc_blocker_xx_0, 0))
self.connect((self.analog_quadrature_demod_cf_0_0, 0), (self.low_pass_filter_1, 0))
self.connect((self.analog_quadrature_demod_cf_0_0_0, 0), (self.dc_blocker_xx_0_0, 0))
self.connect((self.analog_quadrature_demod_cf_0_0_0_0, 0), (self.blocks_moving_average_xx_0, 0))
self.connect((self.blocks_delay_0, 0), (self.blocks_multiply_xx_0, 0))
self.connect((self.blocks_moving_average_xx_0, 0), (self.blocks_vco_c_0, 0))
self.connect((self.blocks_multiply_xx_0, 0), (self.low_pass_filter_0, 0))
self.connect((self.blocks_rotator_cc_0, 0), (self.satnogs_coarse_doppler_correction_cc_0, 0))
self.connect((self.blocks_vco_c_0, 0), (self.blocks_multiply_xx_0, 1))
self.connect((self.dc_blocker_xx_0, 0), (self.digital_clock_recovery_mm_xx_0, 0))
self.connect((self.dc_blocker_xx_0_0, 0), (self.satnogs_ogg_encoder_0, 0))
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.digital_clock_recovery_mm_xx_0, 0), (self.digital_binary_slicer_fb_0, 0))
self.connect((self.low_pass_filter_0, 0), (self.pfb_arb_resampler_xxx_0_0_0, 0))
self.connect((self.low_pass_filter_1, 0), (self.dc_blocker_xx_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.analog_quadrature_demod_cf_0_0_0_0, 0))
self.connect((self.pfb_arb_resampler_xxx_0, 0), (self.blocks_delay_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.analog_quadrature_demod_cf_0_0, 0))
self.connect((self.satnogs_coarse_doppler_correction_cc_0, 0), (self.pfb_arb_resampler_xxx_0, 0))
self.connect((self.satnogs_quad_demod_filter_ff_0, 0), (self.digital_binary_slicer_fb_0, 0))
def get_antenna(self):
return self.antenna
@ -143,7 +159,9 @@ 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_0.set_rate((2.0*self.baudrate)/self.audio_samp_rate)
self.low_pass_filter_1.set_taps(firdes.low_pass(1, 2 * self.baudrate, self.baudrate * 0.60, self.baudrate / 8.0, firdes.WIN_HAMMING, 6.76))
self.low_pass_filter_0.set_taps(firdes.low_pass(1, self.audio_samp_rate, 0.75 * self.baudrate, 1000, firdes.WIN_HAMMING, 6.76))
def get_bb_gain(self):
return self.bb_gain
@ -278,8 +296,9 @@ 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_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))
self.low_pass_filter_0.set_taps(firdes.low_pass(1, self.audio_samp_rate, 0.75 * self.baudrate, 1000, firdes.WIN_HAMMING, 6.76))
def argument_parser():

View File

@ -5,9 +5,10 @@
# Title: satnogs_msk_ax25
# Author: Manolis Surligas (surligas@gmail.com)
# Description: Generic MSK AX.25 decoder
# Generated: Fri Aug 17 00:38:15 2018
# GNU Radio version: 3.7.13.5
##################################################
from gnuradio import analog
from gnuradio import blocks
from gnuradio import digital
@ -64,18 +65,17 @@ class satnogs_msk_ax25(gr.top_block):
self.satnogs_waterfall_sink_0 = satnogs.waterfall_sink(audio_samp_rate, 0.0, 10, 1024, waterfall_file_path, 1)
self.satnogs_udp_msg_sink_0_0 = satnogs.udp_msg_sink(udp_IP, udp_port, 1500)
self.satnogs_tcp_rigctl_msg_source_0 = satnogs.tcp_rigctl_msg_source("127.0.0.1", rigctl_port, False, 1000, 1500)
self.satnogs_quad_demod_filter_ff_0 = satnogs.quad_demod_filter_ff(1.2)
self.satnogs_ogg_encoder_0 = satnogs.ogg_encoder(file_path, audio_samp_rate, 1.0)
self.satnogs_iq_sink_0 = satnogs.iq_sink(16768, iq_file_path, False, enable_iq_dump)
self.satnogs_frame_file_sink_0_1_0 = satnogs.frame_file_sink(decoded_data_file_path, 0)
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(
self.pfb_arb_resampler_xxx_0_0_0 = pfb.arb_resampler_ccf(
(2.0*baudrate)/audio_samp_rate,
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,11 +96,20 @@ 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_1 = filter.fir_filter_fff(1, firdes.low_pass(
1, 2 * baudrate, baudrate * 0.60, baudrate / 8.0, firdes.WIN_HAMMING, 6.76))
self.low_pass_filter_0 = filter.fir_filter_ccf(1, firdes.low_pass(
1, audio_samp_rate, 0.75 * baudrate, 1000, firdes.WIN_HAMMING, 6.76))
self.digital_clock_recovery_mm_xx_0 = digital.clock_recovery_mm_ff(2, 2 * math.pi / 100, 0.5, 0.5/8.0, 0.01)
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)
self.blocks_vco_c_0 = blocks.vco_c(audio_samp_rate, -audio_samp_rate, 1.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_moving_average_xx_0 = blocks.moving_average_ff(1024, 1.0/1024.0, 4096)
self.blocks_delay_0 = blocks.delay(gr.sizeof_gr_complex*1, 1024/2)
self.analog_quadrature_demod_cf_0_0_0_0 = analog.quadrature_demod_cf(1.0)
self.analog_quadrature_demod_cf_0_0_0 = analog.quadrature_demod_cf(0.9)
self.analog_quadrature_demod_cf_0_0 = analog.quadrature_demod_cf(1.2)
@ -114,22 +123,29 @@ class satnogs_msk_ax25(gr.top_block):
self.msg_connect((self.satnogs_ax25_decoder_bm_0_0, 'pdu'), (self.satnogs_frame_file_sink_0_1_0, 'frame'))
self.msg_connect((self.satnogs_ax25_decoder_bm_0_0, 'pdu'), (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_quadrature_demod_cf_0_0, 0), (self.dc_blocker_xx_0, 0))
self.connect((self.analog_quadrature_demod_cf_0_0, 0), (self.low_pass_filter_1, 0))
self.connect((self.analog_quadrature_demod_cf_0_0_0, 0), (self.dc_blocker_xx_0_0, 0))
self.connect((self.analog_quadrature_demod_cf_0_0_0_0, 0), (self.blocks_moving_average_xx_0, 0))
self.connect((self.blocks_delay_0, 0), (self.blocks_multiply_xx_0, 0))
self.connect((self.blocks_moving_average_xx_0, 0), (self.blocks_vco_c_0, 0))
self.connect((self.blocks_multiply_xx_0, 0), (self.low_pass_filter_0, 0))
self.connect((self.blocks_rotator_cc_0, 0), (self.satnogs_coarse_doppler_correction_cc_0, 0))
self.connect((self.blocks_vco_c_0, 0), (self.blocks_multiply_xx_0, 1))
self.connect((self.dc_blocker_xx_0, 0), (self.digital_clock_recovery_mm_xx_0, 0))
self.connect((self.dc_blocker_xx_0_0, 0), (self.satnogs_ogg_encoder_0, 0))
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.digital_clock_recovery_mm_xx_0, 0), (self.digital_binary_slicer_fb_0, 0))
self.connect((self.low_pass_filter_0, 0), (self.pfb_arb_resampler_xxx_0_0_0, 0))
self.connect((self.low_pass_filter_1, 0), (self.dc_blocker_xx_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.analog_quadrature_demod_cf_0_0_0_0, 0))
self.connect((self.pfb_arb_resampler_xxx_0, 0), (self.blocks_delay_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.analog_quadrature_demod_cf_0_0, 0))
self.connect((self.satnogs_coarse_doppler_correction_cc_0, 0), (self.pfb_arb_resampler_xxx_0, 0))
self.connect((self.satnogs_quad_demod_filter_ff_0, 0), (self.digital_binary_slicer_fb_0, 0))
def get_antenna(self):
return self.antenna
@ -143,7 +159,9 @@ 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((2.0*self.baudrate)/self.audio_samp_rate)
self.low_pass_filter_1.set_taps(firdes.low_pass(1, 2 * self.baudrate, self.baudrate * 0.60, self.baudrate / 8.0, firdes.WIN_HAMMING, 6.76))
self.low_pass_filter_0.set_taps(firdes.low_pass(1, self.audio_samp_rate, 0.75 * self.baudrate, 1000, firdes.WIN_HAMMING, 6.76))
def get_bb_gain(self):
return self.bb_gain
@ -278,8 +296,9 @@ 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_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))
self.low_pass_filter_0.set_taps(firdes.low_pass(1, self.audio_samp_rate, 0.75 * self.baudrate, 1000, firdes.WIN_HAMMING, 6.76))
def argument_parser():

View File

@ -0,0 +1,359 @@
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
##################################################
# GNU Radio Python Flow Graph
# Title: SSTV PD120 Demodulation
# Author: Sebastian Schumb (sebastian@sebastains-site.de)
# Description: A PD120 SSTV demodulator
# GNU Radio version: 3.7.13.5
##################################################
from gnuradio import analog
from gnuradio import eng_notation
from gnuradio import filter
from gnuradio import gr
from gnuradio.eng_option import eng_option
from gnuradio.filter import firdes
from optparse import OptionParser
import math
import osmosdr
import satnogs
import time
class satnogs_sstv_pd120_demod(gr.top_block):
def __init__(self, antenna=satnogs.not_set_antenna, bb_gain=satnogs.not_set_rx_bb_gain, decoded_data_file_path='/tmp/.satnogs/data/data', dev_args=satnogs.not_set_dev_args, doppler_correction_per_sec=20, enable_iq_dump=0, file_path='test.ogg', 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', waterfall_file_path='/tmp/waterfall.dat'):
gr.top_block.__init__(self, "SSTV PD120 Demodulation")
##################################################
# Parameters
##################################################
self.antenna = antenna
self.bb_gain = bb_gain
self.decoded_data_file_path = decoded_data_file_path
self.dev_args = dev_args
self.doppler_correction_per_sec = doppler_correction_per_sec
self.enable_iq_dump = enable_iq_dump
self.file_path = file_path
self.if_gain = if_gain
self.iq_file_path = iq_file_path
self.lo_offset = lo_offset
self.ppm = ppm
self.rf_gain = rf_gain
self.rigctl_port = rigctl_port
self.rx_freq = rx_freq
self.rx_sdr_device = rx_sdr_device
self.waterfall_file_path = waterfall_file_path
##################################################
# Variables
##################################################
self.samp_rate_rx = samp_rate_rx = satnogs.hw_rx_settings[rx_sdr_device]['samp_rate']
self.xlate_filter_taps = xlate_filter_taps = firdes.low_pass(1, samp_rate_rx, 125000, 25000, firdes.WIN_HAMMING, 6.76)
self.taps = taps = firdes.low_pass(12.0, samp_rate_rx, 100e3, 60000, firdes.WIN_HAMMING, 6.76)
self.max_modulation_freq = max_modulation_freq = 3000
self.filter_rate = filter_rate = 250000
self.deviation = deviation = 5000
self.audio_samp_rate = audio_samp_rate = 48000
##################################################
# Blocks
##################################################
self.satnogs_waterfall_sink_0 = satnogs.waterfall_sink(audio_samp_rate, 0.0, 10, 1024, waterfall_file_path, 1)
self.satnogs_tcp_rigctl_msg_source_0 = satnogs.tcp_rigctl_msg_source("127.0.0.1", rigctl_port, False, 1000/doppler_correction_per_sec, 1500)
self.satnogs_sstv_pd120_sink_0 = satnogs.sstv_pd120_sink(decoded_data_file_path)
self.satnogs_ogg_encoder_0 = satnogs.ogg_encoder(file_path, audio_samp_rate, 1.0)
self.satnogs_iq_sink_0 = satnogs.iq_sink(32767, iq_file_path, False, enable_iq_dump)
self.satnogs_coarse_doppler_correction_cc_0 = satnogs.coarse_doppler_correction_cc(rx_freq, samp_rate_rx)
self.rational_resampler_xxx_0 = filter.rational_resampler_fff(
interpolation=5263,
decimation=12000,
taps=None,
fractional_bw=None,
)
self.osmosdr_source_0 = osmosdr.source( args="numchan=" + str(1) + " " + satnogs.handle_rx_dev_args(rx_sdr_device, dev_args) )
self.osmosdr_source_0.set_sample_rate(samp_rate_rx)
self.osmosdr_source_0.set_center_freq(rx_freq - lo_offset, 0)
self.osmosdr_source_0.set_freq_corr(ppm, 0)
self.osmosdr_source_0.set_dc_offset_mode(2, 0)
self.osmosdr_source_0.set_iq_balance_mode(0, 0)
self.osmosdr_source_0.set_gain_mode(False, 0)
self.osmosdr_source_0.set_gain(satnogs.handle_rx_rf_gain(rx_sdr_device, rf_gain), 0)
self.osmosdr_source_0.set_if_gain(satnogs.handle_rx_if_gain(rx_sdr_device, if_gain), 0)
self.osmosdr_source_0.set_bb_gain(satnogs.handle_rx_bb_gain(rx_sdr_device, bb_gain), 0)
self.osmosdr_source_0.set_antenna(satnogs.handle_rx_antenna(rx_sdr_device, antenna), 0)
self.osmosdr_source_0.set_bandwidth(samp_rate_rx, 0)
self.low_pass_filter_0_0 = filter.fir_filter_fff(1, firdes.low_pass(
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(
interpolation=24,
decimation=125,
taps=None,
fractional_bw=None,
)
self.analog_quadrature_demod_cf_0 = analog.quadrature_demod_cf((2*math.pi*deviation)/audio_samp_rate)
self.analog_nbfm_rx_0 = analog.nbfm_rx(
audio_rate=12000,
quad_rate=12000,
tau=75e-6,
max_dev=600,
)
##################################################
# Connections
##################################################
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, 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))
self.connect((self.satnogs_coarse_doppler_correction_cc_0, 0), (self.freq_xlating_fir_filter_xxx_0, 0))
def get_antenna(self):
return self.antenna
def set_antenna(self, antenna):
self.antenna = antenna
self.osmosdr_source_0.set_antenna(satnogs.handle_rx_antenna(self.rx_sdr_device, self.antenna), 0)
def get_bb_gain(self):
return self.bb_gain
def set_bb_gain(self, bb_gain):
self.bb_gain = bb_gain
self.osmosdr_source_0.set_bb_gain(satnogs.handle_rx_bb_gain(self.rx_sdr_device, self.bb_gain), 0)
def get_decoded_data_file_path(self):
return self.decoded_data_file_path
def set_decoded_data_file_path(self, decoded_data_file_path):
self.decoded_data_file_path = decoded_data_file_path
def get_dev_args(self):
return self.dev_args
def set_dev_args(self, dev_args):
self.dev_args = dev_args
def get_doppler_correction_per_sec(self):
return self.doppler_correction_per_sec
def set_doppler_correction_per_sec(self, doppler_correction_per_sec):
self.doppler_correction_per_sec = doppler_correction_per_sec
def get_enable_iq_dump(self):
return self.enable_iq_dump
def set_enable_iq_dump(self, enable_iq_dump):
self.enable_iq_dump = enable_iq_dump
def get_file_path(self):
return self.file_path
def set_file_path(self, file_path):
self.file_path = file_path
def get_if_gain(self):
return self.if_gain
def set_if_gain(self, if_gain):
self.if_gain = if_gain
self.osmosdr_source_0.set_if_gain(satnogs.handle_rx_if_gain(self.rx_sdr_device, self.if_gain), 0)
def get_iq_file_path(self):
return self.iq_file_path
def set_iq_file_path(self, iq_file_path):
self.iq_file_path = iq_file_path
def get_lo_offset(self):
return self.lo_offset
def set_lo_offset(self, lo_offset):
self.lo_offset = lo_offset
self.osmosdr_source_0.set_center_freq(self.rx_freq - self.lo_offset, 0)
self.freq_xlating_fir_filter_xxx_0.set_center_freq(self.lo_offset)
def get_ppm(self):
return self.ppm
def set_ppm(self, ppm):
self.ppm = ppm
self.osmosdr_source_0.set_freq_corr(self.ppm, 0)
def get_rf_gain(self):
return self.rf_gain
def set_rf_gain(self, rf_gain):
self.rf_gain = rf_gain
self.osmosdr_source_0.set_gain(satnogs.handle_rx_rf_gain(self.rx_sdr_device, self.rf_gain), 0)
def get_rigctl_port(self):
return self.rigctl_port
def set_rigctl_port(self, rigctl_port):
self.rigctl_port = rigctl_port
def get_rx_freq(self):
return self.rx_freq
def set_rx_freq(self, rx_freq):
self.rx_freq = rx_freq
self.satnogs_coarse_doppler_correction_cc_0.set_new_freq_locked(self.rx_freq)
self.osmosdr_source_0.set_center_freq(self.rx_freq - self.lo_offset, 0)
def get_rx_sdr_device(self):
return self.rx_sdr_device
def set_rx_sdr_device(self, rx_sdr_device):
self.rx_sdr_device = rx_sdr_device
self.set_samp_rate_rx(satnogs.hw_rx_settings[self.rx_sdr_device]['samp_rate'])
self.osmosdr_source_0.set_gain(satnogs.handle_rx_rf_gain(self.rx_sdr_device, self.rf_gain), 0)
self.osmosdr_source_0.set_if_gain(satnogs.handle_rx_if_gain(self.rx_sdr_device, self.if_gain), 0)
self.osmosdr_source_0.set_bb_gain(satnogs.handle_rx_bb_gain(self.rx_sdr_device, self.bb_gain), 0)
self.osmosdr_source_0.set_antenna(satnogs.handle_rx_antenna(self.rx_sdr_device, self.antenna), 0)
def get_waterfall_file_path(self):
return self.waterfall_file_path
def set_waterfall_file_path(self, waterfall_file_path):
self.waterfall_file_path = waterfall_file_path
def get_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.set_xlate_filter_taps(firdes.low_pass(1, self.samp_rate_rx, 125000, 25000, firdes.WIN_HAMMING, 6.76))
self.osmosdr_source_0.set_sample_rate(self.samp_rate_rx)
self.osmosdr_source_0.set_bandwidth(self.samp_rate_rx, 0)
def get_xlate_filter_taps(self):
return self.xlate_filter_taps
def set_xlate_filter_taps(self, xlate_filter_taps):
self.xlate_filter_taps = xlate_filter_taps
self.freq_xlating_fir_filter_xxx_0.set_taps((self.xlate_filter_taps))
def get_taps(self):
return self.taps
def set_taps(self, taps):
self.taps = taps
def get_max_modulation_freq(self):
return self.max_modulation_freq
def set_max_modulation_freq(self, max_modulation_freq):
self.max_modulation_freq = max_modulation_freq
self.low_pass_filter_0.set_taps(firdes.low_pass(1, self.audio_samp_rate, self.deviation+self.max_modulation_freq, 3000, firdes.WIN_HAMMING, 6.76))
def get_filter_rate(self):
return self.filter_rate
def set_filter_rate(self, filter_rate):
self.filter_rate = filter_rate
def get_deviation(self):
return self.deviation
def set_deviation(self, deviation):
self.deviation = deviation
self.low_pass_filter_0.set_taps(firdes.low_pass(1, self.audio_samp_rate, self.deviation+self.max_modulation_freq, 3000, firdes.WIN_HAMMING, 6.76))
self.analog_quadrature_demod_cf_0.set_gain((2*math.pi*self.deviation)/self.audio_samp_rate)
def get_audio_samp_rate(self):
return self.audio_samp_rate
def set_audio_samp_rate(self, audio_samp_rate):
self.audio_samp_rate = audio_samp_rate
self.low_pass_filter_0.set_taps(firdes.low_pass(1, self.audio_samp_rate, self.deviation+self.max_modulation_freq, 3000, firdes.WIN_HAMMING, 6.76))
self.analog_quadrature_demod_cf_0.set_gain((2*math.pi*self.deviation)/self.audio_samp_rate)
def argument_parser():
description = 'A PD120 SSTV demodulator'
parser = OptionParser(usage="%prog: [options]", option_class=eng_option, description=description)
parser.add_option(
"", "--antenna", dest="antenna", type="string", default=satnogs.not_set_antenna,
help="Set antenna [default=%default]")
parser.add_option(
"", "--bb-gain", dest="bb_gain", type="eng_float", default=eng_notation.num_to_str(satnogs.not_set_rx_bb_gain),
help="Set bb_gain [default=%default]")
parser.add_option(
"", "--decoded-data-file-path", dest="decoded_data_file_path", type="string", default='/tmp/.satnogs/data/data',
help="Set decoded_data_file_path [default=%default]")
parser.add_option(
"", "--dev-args", dest="dev_args", type="string", default=satnogs.not_set_dev_args,
help="Set dev_args [default=%default]")
parser.add_option(
"", "--doppler-correction-per-sec", dest="doppler_correction_per_sec", type="intx", default=20,
help="Set doppler_correction_per_sec [default=%default]")
parser.add_option(
"", "--enable-iq-dump", dest="enable_iq_dump", type="intx", default=0,
help="Set enable_iq_dump [default=%default]")
parser.add_option(
"", "--file-path", dest="file_path", type="string", default='test.ogg',
help="Set file_path [default=%default]")
parser.add_option(
"", "--if-gain", dest="if_gain", type="eng_float", default=eng_notation.num_to_str(satnogs.not_set_rx_if_gain),
help="Set if_gain [default=%default]")
parser.add_option(
"", "--iq-file-path", dest="iq_file_path", type="string", default='/tmp/iq.dat',
help="Set iq_file_path [default=%default]")
parser.add_option(
"", "--lo-offset", dest="lo_offset", type="eng_float", default=eng_notation.num_to_str(100e3),
help="Set lo_offset [default=%default]")
parser.add_option(
"", "--ppm", dest="ppm", type="intx", default=0,
help="Set ppm [default=%default]")
parser.add_option(
"", "--rf-gain", dest="rf_gain", type="eng_float", default=eng_notation.num_to_str(satnogs.not_set_rx_rf_gain),
help="Set rf_gain [default=%default]")
parser.add_option(
"", "--rigctl-port", dest="rigctl_port", type="intx", default=4532,
help="Set rigctl_port [default=%default]")
parser.add_option(
"", "--rx-freq", dest="rx_freq", type="eng_float", default=eng_notation.num_to_str(100e6),
help="Set rx_freq [default=%default]")
parser.add_option(
"", "--rx-sdr-device", dest="rx_sdr_device", type="string", default='usrpb200',
help="Set rx_sdr_device [default=%default]")
parser.add_option(
"", "--waterfall-file-path", dest="waterfall_file_path", type="string", default='/tmp/waterfall.dat',
help="Set waterfall_file_path [default=%default]")
return parser
def main(top_block_cls=satnogs_sstv_pd120_demod, options=None):
if options is None:
options, _ = argument_parser().parse_args()
tb = top_block_cls(antenna=options.antenna, bb_gain=options.bb_gain, 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, waterfall_file_path=options.waterfall_file_path)
tb.start()
tb.wait()
if __name__ == '__main__':
main()

File diff suppressed because it is too large Load Diff

View File

@ -24,7 +24,7 @@ list(APPEND debug_blocks
satnogs_debug_msg_source.xml
satnogs_debug_msg_source_raw.xml
satnogs_leo_channel.xml
satnogs_cw_encoder.xml
satnogs_cw_encoder.xml
)
list(APPEND enabled_blocks
@ -36,11 +36,11 @@ list(APPEND enabled_blocks
satnogs_fox_telem_mm.xml
satnogs_frame_file_sink.xml
satnogs_iq_sink.xml
satnogs_lrpt_decoder.xml
satnogs_lrpt_sync.xml
satnogs_lrpt_decoder.xml
satnogs_lrpt_sync.xml
satnogs_morse_decoder.xml
satnogs_multi_format_msg_sink.xml
satnogs_ogg_encoder.xml
satnogs_ogg_encoder.xml
satnogs_cw_to_symbol.xml
satnogs_udp_msg_source.xml
satnogs_tcp_rigctl_msg_source.xml
@ -53,6 +53,7 @@ list(APPEND enabled_blocks
satnogs_noaa_apt_sink.xml
satnogs_whitening.xml
satnogs_frame_acquisition.xml
satnogs_sstv_pd120_sink.xml
)
if(${INCLUDE_DEBUG_BLOCKS})

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

@ -0,0 +1,17 @@
<block>
<name>SSTV PD120 sink</name>
<key>satnogs_sstv_pd120_sink</key>
<category>[satnogs]</category>
<import>import satnogs</import>
<make>satnogs.sstv_pd120_sink($filename_png)</make>
<param>
<name>Output PNG Filename</name>
<key>filename_png</key>
<value></value>
<type>file_save</type>
</param>
<sink>
<name>in</name>
<type>float</type>
</sink>
</block>

View File

@ -24,7 +24,7 @@ list(APPEND DEBUG_HEADER_FILES
morse_debug_source.h
debug_msg_source_raw.h
debug_msg_source.h
cw_encoder.h
cw_encoder.h
)
list(APPEND HEADER_FILES
@ -37,7 +37,7 @@ list(APPEND HEADER_FILES
morse.h
morse_decoder.h
multi_format_msg_sink.h
ogg_encoder.h
ogg_encoder.h
cw_to_symbol.h
utils.h
udp_msg_source.h
@ -59,6 +59,7 @@ list(APPEND HEADER_FILES
noaa_apt_sink.h
frame_file_sink.h
iq_sink.h
sstv_pd120_sink.h
)
if(${INCLUDE_DEBUG_BLOCKS})
@ -76,4 +77,4 @@ install(FILES
frame_acquisition.h
shift_reg.h
golay24.h DESTINATION include/satnogs
)
)

View File

@ -197,7 +197,10 @@ namespace gr
out[i++] = fcs & 0xFF;
out[i++] = (fcs >> 8) & 0xFF;
memset (out + i, AX25_SYNC_FLAG, postamble_len);
for(size_t j = preamble_len; j < i; j++) {
printf("0x%02x ", out[j]);
}
printf("\n");
return i + postamble_len;
}

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

@ -0,0 +1,56 @@
/* -*- c++ -*- */
/*
* gr-satnogs: SatNOGS GNU Radio Out-Of-Tree Module
*
* Copyright (C) 2017, Libre Space Foundation <http://librespacefoundation.org/>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef INCLUDED_SATNOGS_SSTV_PD120_SINK_H
#define INCLUDED_SATNOGS_SSTV_PD120_SINK_H
#include <satnogs/api.h>
#include <gnuradio/sync_block.h>
namespace gr {
namespace satnogs {
/*!
* \brief <+description of block+>
* \ingroup satnogs
*
*/
class SATNOGS_API sstv_pd120_sink : virtual public gr::sync_block
{
public:
typedef boost::shared_ptr<sstv_pd120_sink> sptr;
/*!
* \brief Return a shared_ptr to a new instance of satnogs::sstv_pd120_sink.
*
* To avoid accidental use of raw pointers, satnogs::sstv_pd120_sink's
* constructor is in a private implementation
* class. satnogs::sstv_pd120_sink::make is the public interface for
* creating new instances.
*/
static sptr make(const char *filename_png);
};
} // namespace satnogs
} // namespace gr
#endif /* INCLUDED_SATNOGS_SSTV_PD120_SINK_H */

1
lib/.clang_complete Normal file
View File

@ -0,0 +1 @@
-I..

View File

@ -74,7 +74,8 @@ list(APPEND satnogs_sources
lrpt_decoder_impl.cc
frame_acquisition_impl.cc
shift_reg.cc
golay24.cc)
golay24.cc
sstv_pd120_sink_impl.cc)
if(${INCLUDE_DEBUG_BLOCKS})
list(APPEND satnogs_sources ${satnogs_debug_sources})

View File

@ -2,7 +2,7 @@
/*
* gr-satnogs: SatNOGS GNU Radio Out-Of-Tree Module
*
* Copyright (C) 2016, 2017, 2018
* Copyright (C) 2016-2019
* Libre Space Foundation <http://librespacefoundation.org/>
*
* This program is free software: you can redistribute it and/or modify
@ -30,446 +30,299 @@
namespace gr
{
namespace satnogs
{
namespace satnogs
{
ax25_decoder_bm::sptr
ax25_decoder_bm::make (const std::string& addr, uint8_t ssid, bool promisc,
bool descramble, size_t max_frame_len)
{
return gnuradio::get_initial_sptr (
new ax25_decoder_bm_impl (addr, ssid, promisc, descramble,
max_frame_len));
}
ax25_decoder_bm::sptr
ax25_decoder_bm::make (const std::string &addr, uint8_t ssid, bool promisc,
bool descramble, size_t max_frame_len)
{
return gnuradio::get_initial_sptr (
new ax25_decoder_bm_impl (addr, ssid, promisc, descramble, max_frame_len));
}
/*
* The private constructor
*/
ax25_decoder_bm_impl::ax25_decoder_bm_impl (const std::string& addr,
uint8_t ssid, bool promisc,
bool descramble,
size_t max_frame_len) :
gr::sync_block ("ax25_decoder_bm",
gr::io_signature::make (1, 1, sizeof(uint8_t)),
gr::io_signature::make (0, 0, 0)),
d_promisc (promisc),
d_descramble (descramble),
d_max_frame_len (max_frame_len),
d_state (NO_SYNC),
d_shift_reg (0x0),
d_dec_b (0x0),
d_prev_bit_nrzi (0),
d_received_bytes (0),
d_decoded_bits (0),
d_lfsr (0x21, 0x0, 16),
d_frame_buffer (
new uint8_t[max_frame_len + AX25_MAX_ADDR_LEN
+ AX25_MAX_CTRL_LEN + sizeof(uint16_t)])
{
/* Valid PDUs output message port */
message_port_register_out (pmt::mp ("pdu"));
/*
* Valid invalid (wrong CRC, different destination Callsign/SSID,
* wrong frame size)PDUs output message port
*/
message_port_register_out (pmt::mp ("failed_pdu"));
}
/*
* The private constructor
*/
ax25_decoder_bm_impl::ax25_decoder_bm_impl (const std::string &addr,
uint8_t ssid, bool promisc,
bool descramble,
size_t max_frame_len) :
gr::sync_block ("ax25_decoder_bm",
gr::io_signature::make (1, 1, sizeof(uint8_t)),
gr::io_signature::make (0, 0, 0)),
d_promisc (promisc),
d_descramble (descramble),
d_max_frame_len (max_frame_len),
d_state (NO_SYNC),
d_shift_reg (0x0),
d_dec_b (0x0),
d_prev_bit_nrzi (0),
d_received_bytes (0),
d_decoded_bits (0),
d_lfsr (0x21, 0x0, 16),
d_frame_buffer (
new uint8_t[max_frame_len + AX25_MAX_ADDR_LEN + AX25_MAX_CTRL_LEN
+ sizeof(uint16_t)]),
d_start_idx(0)
{
/* Valid PDUs output message port */
message_port_register_out (pmt::mp ("pdu"));
/*
* Valid invalid (wrong CRC, different destination Callsign/SSID,
* wrong frame size)PDUs output message port
*/
message_port_register_out (pmt::mp ("failed_pdu"));
}
size_t
ax25_decoder_bm_impl::descramble_and_decode (const uint8_t* in,
size_t nitems)
{
size_t i;
uint8_t descr_bit;
uint8_t dec_bit;
switch (d_state)
{
case NO_SYNC:
for (i = 0; i < nitems; i++) {
descramble_and_decode_1b (in[i]);
if (d_shift_reg == AX25_SYNC_FLAG) {
enter_sync_state ();
return i + 1;
}
void
ax25_decoder_bm_impl::decode ()
{
while (1) {
bool cont = false;
switch (d_state)
{
case NO_SYNC:
for (size_t i = 0; i < d_bitstream.size (); i++) {
decode_1b (d_bitstream[i]);
if (d_shift_reg == AX25_SYNC_FLAG) {
d_bitstream.erase (d_bitstream.begin (),
d_bitstream.begin () + i + 1);
enter_sync_state ();
d_start_idx = 0;
cont = true;
break;
}
return nitems;
case IN_SYNC:
/*
* Most of the transmitters repeat several times the AX.25 SYNC
* In case of G3RUH this is mandatory to allow the self synchronizing
* scrambler to settle
*/
for (i = 0; i < nitems; i++) {
descramble_and_decode_1b (in[i]);
d_decoded_bits++;
if(d_decoded_bits == 8) {
/* Perhaps we are in frame! */
if(d_shift_reg != AX25_SYNC_FLAG) {
enter_decoding_state();
return i+1;
}
d_decoded_bits = 0;
}
}
return nitems;
case DECODING:
for (i = 0; i < nitems; i++) {
descramble_and_decode_1b (in[i]);
if (d_shift_reg == AX25_SYNC_FLAG) {
LOG_DEBUG("Found frame end");
enter_frame_end();
return i+1;
}
else if ((d_shift_reg & 0xfc) == 0x7c) {
/*This was a stuffed bit */
d_dec_b <<= 1;
}
else if((d_shift_reg & 0xfe) == 0xfe) {
LOG_DEBUG("Invalid shift register value %u", d_received_bytes);
reset_state ();
return i+1;
}
else{
d_decoded_bits++;
if(d_decoded_bits == 8) {
/* Check if the received byte is valid */
if(!check_byte()) {
reset_state ();
return i + 1;
}
d_frame_buffer[d_received_bytes] = d_dec_b;
d_received_bytes++;
d_decoded_bits = 0;
/*Check if the frame limit was reached */
if (d_received_bytes >= d_max_frame_len) {
LOG_DEBUG("Wrong size");
message_port_pub (
pmt::mp ("failed_pdu"),
pmt::make_blob (d_frame_buffer, d_max_frame_len));
reset_state ();
return i+1;
}
}
}
}
return nitems;
case FRAME_END:
for (i = 0; i < nitems; i++) {
descramble_and_decode_1b (in[i]);
d_decoded_bits++;
if (d_decoded_bits == 8) {
/* Repetitions of the trailing SYNC flag finished */
if (d_shift_reg != AX25_SYNC_FLAG) {
reset_state();
return i + 1;
}
d_decoded_bits = 0;
}
}
return nitems;
default:
LOG_ERROR("Invalid decoding state");
reset_state();
return nitems;
}
}
size_t
ax25_decoder_bm_impl::decode (const uint8_t* in, size_t nitems)
{
size_t i;
uint8_t descr_bit;
uint8_t dec_bit;
switch (d_state)
{
case NO_SYNC:
for (i = 0; i < nitems; i++) {
decode_1b (in[i]);
if (d_shift_reg == AX25_SYNC_FLAG) {
enter_sync_state ();
return i + 1;
}
}
return nitems;
case IN_SYNC:
/*
* Most of the transmitters repeat several times the AX.25 SYNC
* In case of G3RUH this is mandatory to allow the self synchronizing
* scrambler to settle
*/
for (i = 0; i < nitems; i++) {
decode_1b (in[i]);
d_decoded_bits++;
if (d_decoded_bits == 8) {
/* Perhaps we are in frame! */
if (d_shift_reg != AX25_SYNC_FLAG) {
enter_decoding_state ();
return i + 1;
}
d_decoded_bits = 0;
}
}
return nitems;
case DECODING:
for (i = 0; i < nitems; i++) {
decode_1b (in[i]);
if (d_shift_reg == AX25_SYNC_FLAG) {
enter_frame_end ();
return i + 1;
}
else if ((d_shift_reg & 0xfc) == 0x7c) {
/*This was a stuffed bit */
d_dec_b <<= 1;
}
else if ((d_shift_reg & 0xfe) == 0xfe) {
LOG_DEBUG("Invalid shift register value");
reset_state ();
return i + 1;
}
else {
d_decoded_bits++;
if (d_decoded_bits == 8) {
/* Check if the received byte is valid */
if(!check_byte()) {
reset_state ();
return i + 1;
}
d_frame_buffer[d_received_bytes] = d_dec_b;
d_received_bytes++;
d_decoded_bits = 0;
/*Check if the frame limit was reached */
if (d_received_bytes >= d_max_frame_len) {
LOG_DEBUG("Wrong size");
message_port_pub (
pmt::mp ("failed_pdu"),
pmt::make_blob (d_frame_buffer, d_max_frame_len));
reset_state ();
return i + 1;
}
}
}
}
return nitems;
case FRAME_END:
for (i = 0; i < nitems; i++) {
decode_1b (in[i]);
d_decoded_bits++;
if (d_decoded_bits == 8) {
/* Repetitions of the trailing SYNC flag finished */
if (d_shift_reg != AX25_SYNC_FLAG) {
reset_state ();
return i + 1;
}
d_decoded_bits = 0;
}
}
return nitems;
default:
LOG_ERROR("Invalid decoding state");
reset_state ();
return nitems;
if(cont) {
continue;
}
}
/*
* Our virtual destructor.
*/
ax25_decoder_bm_impl::~ax25_decoder_bm_impl ()
{
delete [] d_frame_buffer;
}
void
ax25_decoder_bm_impl::reset_state ()
{
d_state = NO_SYNC;
d_dec_b = 0x0;
d_shift_reg = 0x0;
d_decoded_bits = 0;
d_received_bytes = 0;
d_prev_bit_nrzi = 0;
}
void
ax25_decoder_bm_impl::enter_sync_state ()
{
d_state = IN_SYNC;
d_dec_b = 0x0;
d_shift_reg = 0x0;
d_decoded_bits = 0;
d_received_bytes = 0;
}
void
ax25_decoder_bm_impl::enter_decoding_state ()
{
uint8_t tmp;
d_state = DECODING;
d_decoded_bits = 0;
d_shift_reg = 0x0;
/*
* Due to the possibility of bit stuffing on the first byte some special
* handling is necessary
*/
tmp = d_dec_b;
d_dec_b = 0x0;
for (size_t i = 0; i < 8; i++) {
d_shift_reg = (d_shift_reg >> 1) | (((tmp >> i) & 0x1) << 7);
d_dec_b = (d_dec_b >> 1) | (((tmp >> i) & 0x1) << 7);
if ((d_shift_reg & 0xfc) == 0x7c) {
/*This was a stuffed bit */
d_dec_b <<= 1;
}
else{
d_bitstream.clear ();
return;
case IN_SYNC:
/*
* Most of the transmitters repeat several times the AX.25 SYNC
* In case of G3RUH this is mandatory to allow the self synchronizing
* scrambler to settle
*/
for (size_t i = d_start_idx; i < d_bitstream.size (); i++) {
decode_1b (d_bitstream[i]);
d_decoded_bits++;
if (d_decoded_bits == 8) {
/* Perhaps we are in frame! */
if (d_shift_reg != AX25_SYNC_FLAG) {
d_start_idx = i + 1;
enter_decoding_state ();
cont = true;
break;
}
d_decoded_bits = 0;
}
}
}
if(cont) {
continue;
}
d_start_idx = d_bitstream.size ();
return;
case DECODING:
for (size_t i = d_start_idx; i < d_bitstream.size (); i++) {
decode_1b (d_bitstream[i]);
if (d_shift_reg == AX25_SYNC_FLAG) {
LOG_DEBUG("Found frame end");
if (enter_frame_end ()) {
d_bitstream.erase (d_bitstream.begin (),
d_bitstream.begin () + i + 1);
}
cont = true;
break;
}
else if ((d_shift_reg & 0xfc) == 0x7c) {
/*This was a stuffed bit */
d_dec_b <<= 1;
}
else if ((d_shift_reg & 0xfe) == 0xfe) {
LOG_DEBUG("Invalid shift register value %u", d_received_bytes);
reset_state ();
cont = true;
break;
}
else {
d_decoded_bits++;
if (d_decoded_bits == 8) {
d_frame_buffer[d_received_bytes++] = d_dec_b;
d_decoded_bits = 0;
if(d_decoded_bits == 8) {
d_frame_buffer[0] = d_dec_b;
d_decoded_bits = 0;
d_received_bytes = 1;
}
else {
d_received_bytes = 0;
}
}
void
ax25_decoder_bm_impl::enter_frame_end ()
{
uint16_t fcs;
uint16_t recv_fcs = 0x0;
/* First check if the size of the frame is valid */
if (d_received_bytes < AX25_MIN_ADDR_LEN + sizeof(uint16_t)) {
d_dec_b = 0x0;
d_shift_reg = 0x0;
d_decoded_bits = 0;
d_received_bytes = 0;
d_state = FRAME_END;
/*Check if the frame limit was reached */
if (d_received_bytes >= d_max_frame_len) {
LOG_DEBUG("Wrong size");
reset_state ();
cont = true;
break;
}
}
}
}
if(cont) {
continue;
}
d_start_idx = d_bitstream.size ();
return;
default:
LOG_ERROR("Invalid decoding state");
reset_state ();
return;
}
}
}
/* Check if the frame is correct using the FCS field */
fcs = ax25_fcs (d_frame_buffer, d_received_bytes - sizeof(uint16_t));
recv_fcs = (((uint16_t) d_frame_buffer[d_received_bytes - 1]) << 8)
| d_frame_buffer[d_received_bytes - 2];
/*
* Our virtual destructor.
*/
ax25_decoder_bm_impl::~ax25_decoder_bm_impl ()
{
delete[] d_frame_buffer;
LOG_DEBUG("Left over: %lu", d_bitstream.size());
}
if (fcs == recv_fcs) {
message_port_pub (
pmt::mp ("pdu"),
pmt::make_blob (d_frame_buffer,
d_received_bytes - sizeof(uint16_t)));
}
else {
message_port_pub (
pmt::mp ("failed_pdu"),
pmt::make_blob (d_frame_buffer,
d_received_bytes - sizeof(uint16_t)));
LOG_DEBUG("Wrong crc");
}
d_dec_b = 0x0;
d_shift_reg = 0x0;
d_decoded_bits = 0;
d_received_bytes = 0;
d_state = FRAME_END;
}
void
ax25_decoder_bm_impl::reset_state ()
{
d_state = NO_SYNC;
d_dec_b = 0x0;
d_shift_reg = 0x0;
d_decoded_bits = 0;
d_received_bytes = 0;
}
/**
* Performs descrambling and NRZI decoding of an input bit.
* The decoded bit is then shifted in front of the d_shift_reg and the d_dec_b
* variables. This shift in front is due to the LS bit first transmission
* of the Ax.25 protocol.
*
* @param in input bit
*/
inline void
ax25_decoder_bm_impl::descramble_and_decode_1b (uint8_t in)
{
uint8_t descr_bit;
uint8_t dec_bit;
void
ax25_decoder_bm_impl::enter_sync_state ()
{
d_state = IN_SYNC;
d_dec_b = 0x0;
d_shift_reg = 0x0;
d_decoded_bits = 0;
d_received_bytes = 0;
}
in &= 0x1;
void
ax25_decoder_bm_impl::enter_decoding_state ()
{
uint8_t tmp;
d_state = DECODING;
d_decoded_bits = 0;
d_received_bytes = 0;
/*
* Due to the possibility of bit stuffing on the first byte some special
* handling is necessary
*/
if ((d_shift_reg & 0xfc) == 0x7c) {
/*This was a stuffed bit */
d_dec_b <<= 1;
d_decoded_bits = 7;
}
else {
d_frame_buffer[0] = d_dec_b;
d_decoded_bits = 0;
d_received_bytes = 1;
}
}
bool
ax25_decoder_bm_impl::enter_frame_end ()
{
uint16_t fcs;
uint16_t recv_fcs = 0x0;
/* First check if the size of the frame is valid */
if (d_received_bytes < AX25_MIN_ADDR_LEN + sizeof(uint16_t)) {
reset_state ();
return false;
}
/*
* Check if the frame is correct using the FCS field
* Using this field also try to correct up to 2 error bits
*/
if (frame_check ()) {
message_port_pub (
pmt::mp ("pdu"),
pmt::make_blob (d_frame_buffer, d_received_bytes - sizeof(uint16_t)));
reset_state ();
return true;
}
else {
message_port_pub (
pmt::mp ("failed_pdu"),
pmt::make_blob (d_frame_buffer, d_received_bytes - sizeof(uint16_t)));
LOG_DEBUG("Wrong crc");
reset_state ();
return false;
}
}
inline void
ax25_decoder_bm_impl::decode_1b (uint8_t in)
{
/* In AX.25 the LS bit is sent first */
d_shift_reg = (d_shift_reg >> 1) | (in << 7);
d_dec_b = (d_dec_b >> 1) | (in << 7);
}
bool
ax25_decoder_bm_impl::frame_check ()
{
uint16_t fcs;
uint16_t recv_fcs = 0x0;
uint8_t orig_byte;
/* Check if the frame is correct using the FCS field */
fcs = ax25_fcs (d_frame_buffer, d_received_bytes - sizeof(uint16_t));
recv_fcs = (((uint16_t) d_frame_buffer[d_received_bytes - 1]) << 8)
| d_frame_buffer[d_received_bytes - 2];
if (fcs == recv_fcs) {
return true;
}
return false;
}
int
ax25_decoder_bm_impl::work (int noutput_items,
gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items)
{
int ret;
const uint8_t *in = (const uint8_t*) input_items[0];
if (noutput_items < 1) {
return noutput_items;
}
if (d_descramble) {
for (int i = 0; i < noutput_items; i++) {
/* Perform NRZI decoding */
dec_bit = (~((in - d_prev_bit_nrzi) % 2)) & 0x1;
d_prev_bit_nrzi = in;
/* Descramble the input bit */
descr_bit = d_lfsr.next_bit_descramble (dec_bit);
/* In AX.25 the LS bit is sent first */
d_shift_reg = (d_shift_reg >> 1) | (descr_bit << 7);
d_dec_b = (d_dec_b >> 1) | (descr_bit << 7);
uint8_t b = (~((in[i] - d_prev_bit_nrzi) % 2)) & 0x1;
d_prev_bit_nrzi = in[i];
b = d_lfsr.next_bit_descramble (b);
d_bitstream.push_back (b);
}
inline void
ax25_decoder_bm_impl::decode_1b (uint8_t in)
{
uint8_t dec_bit;
in &= 0x1;
}
else {
for (int i = 0; i < noutput_items; i++) {
/* Perform NRZI decoding */
dec_bit = (~((in - d_prev_bit_nrzi) % 2)) & 0x1;
d_prev_bit_nrzi = in;
/* In AX.25 the LS bit is sent first */
d_shift_reg = (d_shift_reg >> 1) | (dec_bit << 7);
d_dec_b = (d_dec_b >> 1) | (dec_bit << 7);
uint8_t b = (~((in[i] - d_prev_bit_nrzi) % 2)) & 0x1;
d_prev_bit_nrzi = in[i];
d_bitstream.push_back (b);
}
}
decode();
return noutput_items;
}
/**
* Checks if a AX.25 decoded byte is valid. This actually can be checked
* only in the address field, where all fields should have the LS bit
* set to zero.
* @returns true if the decoded byte is valid, false otherwise
*/
inline bool
ax25_decoder_bm_impl::check_byte ()
{
if(d_received_bytes < AX25_MIN_ADDR_LEN - 1) {
if(d_dec_b & 0x1) {
return false;
}
}
else if(d_received_bytes == AX25_MIN_ADDR_LEN - 1) {
if(d_dec_b & 0x1) {
return true;
}
return false;
}
return true;
}
int
ax25_decoder_bm_impl::work (int noutput_items,
gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items)
{
int ret;
const uint8_t *in = (const uint8_t *) input_items[0];
if(noutput_items < 1) {
return noutput_items;
}
if (d_descramble) {
ret = descramble_and_decode (in, noutput_items);
}
else {
ret = decode (in, noutput_items);
}
return ret;
}
} /* namespace satnogs */
} /* namespace satnogs */
} /* namespace gr */

View File

@ -24,6 +24,7 @@
#include <satnogs/ax25_decoder_bm.h>
#include <gnuradio/digital/lfsr.h>
#include <deque>
namespace gr
{
@ -35,7 +36,7 @@ namespace gr
private:
typedef enum
{
NO_SYNC, IN_SYNC, DECODING, FRAME_END
NO_SYNC, IN_SYNC, DECODING
} decoding_state_t;
/**
@ -53,6 +54,8 @@ namespace gr
size_t d_decoded_bits;
digital::lfsr d_lfsr;
uint8_t *d_frame_buffer;
std::deque<uint8_t> d_bitstream;
size_t d_start_idx;
void
reset_state ();
@ -60,20 +63,16 @@ namespace gr
enter_sync_state ();
void
enter_decoding_state ();
void
bool
enter_frame_end ();
size_t
descramble_and_decode (const uint8_t *in, size_t nitems);
size_t
decode (const uint8_t *in, size_t nitems);
void
decode ();
inline void
descramble_and_decode_1b (uint8_t in);
inline void
decode_1b (uint8_t in);
inline bool
check_byte ();
bool
frame_check();
public:

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 */

210
lib/sstv_pd120_sink_impl.cc Normal file
View File

@ -0,0 +1,210 @@
/* -*- c++ -*- */
/*
* gr-satnogs: SatNOGS GNU Radio Out-Of-Tree Module
*
* Copyright (C) 2018, Libre Space Foundation <http://librespacefoundation.org/>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <gnuradio/io_signature.h>
#include "sstv_pd120_sink_impl.h"
namespace gr {
namespace satnogs {
const size_t image_width = 640;
const size_t image_height = 496;
const size_t sync_length = 105;
const size_t sync_thresh = 100;
const size_t porch_length = 10;
const size_t line_length = sync_length + porch_length + 4 * image_width;
const float max_dev = 600;
const float center = 1750;
const float min_freq = 1200;
const float max_freq = 2300;
const float color_low = 1500;
const float color_high = max_freq;
sstv_pd120_sink::sptr
sstv_pd120_sink::make(const char *filename_png)
{
return gnuradio::get_initial_sptr
(new sstv_pd120_sink_impl(filename_png));
}
/*
* The private constructor
*/
sstv_pd120_sink_impl::sstv_pd120_sink_impl(const char *filename_png)
: gr::sync_block("sstv_pd120_sink",
gr::io_signature::make (1, 1, sizeof(float)),
gr::io_signature::make (0, 0, 0)),
d_filename_png (filename_png),
d_has_sync(false),
d_initial_sync(true),
d_line_pos(0),
d_image_y (0),
d_num_image(0)
{
set_history(sync_length);
d_line = new float[line_length];
d_image = png::image<png::rgb_pixel>(image_width, image_height);
}
/*
* Our virtual destructor.
*/
sstv_pd120_sink_impl::~sstv_pd120_sink_impl()
{
delete[] d_line;
}
float
sstv_pd120_sink_impl::to_frequency(float sample) {
float freq = center + sample * max_dev;
freq = std::max(min_freq, freq);
freq = std::min(max_freq, freq);
return freq;
}
int
sstv_pd120_sink_impl::to_color(float sample) {
sample = (sample - color_low) / (color_high - color_low);
sample = sample * 255.0f;
sample = std::max(sample, 0.0f);
sample = std::min(sample, 255.0f);
return int(sample);
}
void
sstv_pd120_sink_impl::ycbcr_to_rgb(int ycbcr[3], int rgb[3]) {
int y = ycbcr[0];
int cb = ycbcr[1];
int cr = ycbcr[2];
//https://stackoverflow.com/questions/4041840/function-to-convert-ycbcr-to-rgb/15333019#15333019
cr = cr - 128;
cb = cb - 128;
int r = y + 45 * cr / 32;
int g = y - (11 * cb + 23 * cr) / 32;
int b = y + 113 * cb / 64;
rgb[0] = std::min(255, std::max(r, 0));
rgb[1] = std::min(255, std::max(g, 0));
rgb[2] = std::min(255, std::max(b, 0));
}
bool
sstv_pd120_sink_impl::is_sync(size_t pos, const float *samples) {
size_t count = 0;
for(size_t i = 0; i < sync_length; i++) {
float sample = to_frequency(samples[pos - (sync_length - 1) + i]);
//std::cout << sample << std::endl;
if(sample < color_low) {
count += 1;
}
}
bool res = count > sync_thresh && !d_has_sync;
d_has_sync = count > sync_thresh;
if(res) {
d_initial_sync = false;
}
return res;
}
void
sstv_pd120_sink_impl::render_line() {
int start_pos = d_line_pos - sync_length - 4 * image_width;
if(start_pos < 0) {
return;
}
for(size_t x = 0; x < image_width; x++) {
int y0 = to_color(d_line[start_pos + x]);
int cr = to_color(d_line[start_pos + image_width + x]);
int cb = to_color(d_line[start_pos + 2 * image_width + x]);
int y1 = to_color(d_line[start_pos + 3 * image_width + x]);
int rgb0[3] = {0, 0, 0};
int ycrcb0[] = {y0, cb, cr};
ycbcr_to_rgb(ycrcb0, rgb0);
d_image.set_pixel(x, d_image_y, png::rgb_pixel(rgb0[0], rgb0[1], rgb0[2]));
int rgb1[] = {0, 0, 0};
int ycrcb1[] = {y1, cb, cr};
ycbcr_to_rgb(ycrcb1, rgb1);
d_image.set_pixel(x, d_image_y + 1, png::rgb_pixel(rgb1[0], rgb1[1], rgb1[2]));
}
std::string file_name = std::string(d_filename_png) + "_" + std::to_string(d_num_image) + ".png";
std::cout << "Writing " << file_name << std::endl;
d_image.write(file_name.c_str());
std::cout << "Line number: " << d_image_y << std::endl;
d_image_y += 2;
if(d_image_y >= image_height){
std::cout << "Finished image, resetting." << std::endl;
d_image_y = 0;
d_initial_sync = true;
d_num_image++;
}
}
int
sstv_pd120_sink_impl::work(int noutput_items,
gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items)
{
const float *in = (const float *) input_items[0];
for (size_t i = sync_length - 1;
i < noutput_items + sync_length - 1; i++) {
float sample = to_frequency(in[i]);
d_line[d_line_pos] = sample;
d_line_pos++;
if(is_sync(i, in) || d_line_pos >= line_length) {
if(d_initial_sync) {
d_image_y = 0;
}
else if(!d_initial_sync && d_line_pos > line_length - porch_length) {
std::cout << "Rendering after: " << d_line_pos << std::endl;
render_line();
}
d_line_pos = 0;
}
}
// Tell runtime system how many output items we produced.
return noutput_items;
}
} /* namespace satnogs */
} /* namespace gr */

View File

@ -0,0 +1,67 @@
/* -*- c++ -*- */
/*
* gr-satnogs: SatNOGS GNU Radio Out-Of-Tree Module
*
* Copyright (C) 2018, Libre Space Foundation <http://librespacefoundation.org/>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef INCLUDED_SATNOGS_SSTV_PD120_SINK_IMPL_H
#define INCLUDED_SATNOGS_SSTV_PD120_SINK_IMPL_H
#include <satnogs/sstv_pd120_sink.h>
#define PNG_DEBUG 3
#include <png++/png.hpp>
namespace gr {
namespace satnogs {
class sstv_pd120_sink_impl : public sstv_pd120_sink
{
private:
std::string d_filename_png;
bool d_has_sync;
bool d_initial_sync;
float *d_line;
size_t d_line_pos;
size_t d_image_y;
size_t d_num_image;
png::image<png::rgb_pixel> d_image;
float to_frequency(float sample);
int to_color(float sample);
void ycbcr_to_rgb(int ycbcr[3], int rgb[3]);
bool is_sync(size_t pos, const float *samples);
void render_line();
public:
sstv_pd120_sink_impl(const char *filename_png);
~sstv_pd120_sink_impl();
// Where all the action really happens
int work(int noutput_items,
gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items);
};
} // namespace satnogs
} // namespace gr
#endif /* INCLUDED_SATNOGS_SSTV_PD120_SINK_IMPL_H */

View File

@ -37,13 +37,16 @@ hw_tx_settings = {'usrpb200' : {'rf_gain' : 60.0, 'if_gain' : 0.0,
hw_rx_settings = {'usrpb200' : {'rf_gain' : 50.0, 'if_gain' : 0.0,
'bb_gain' : 0.0, 'samp_rate' : 5e5,
'antenna' : 'TX/RX', 'dev_arg': 'uhd'},
'usrp1' : {'rf_gain' : 500.0, 'if_gain' : 30.0,
'bb_gain' : 0.0, 'samp_rate' : 5e5,
'antenna' : 'RX', 'dev_arg': 'uhd'},
'usrp2' : {'rf_gain' : 50.0, 'if_gain' : 0.0,
'bb_gain' : 0.0, 'samp_rate' : 5e5,
'antenna' : 'TX/RX', 'dev_arg': 'uhd'},
'usrpx3x0' : {'rf_gain' : 26.0, 'if_gain' : 0.0,
'bb_gain' : 0.0, 'samp_rate' : 2e6,
'antenna' : 'TX/RX', 'dev_arg': 'uhd'},
'airspy' : {'rf_gain' : 30.0, 'if_gain' : 0.0,
'airspy' : {'rf_gain' : 19.0, 'if_gain' : 0.0,
'bb_gain' : 0.0, 'samp_rate' : 10e6,
'antenna' : '', 'dev_arg': 'airspy'},
'airspymini' : {'rf_gain' : 15.0, 'if_gain' : 0.0,

View File

@ -33,6 +33,7 @@
#include "satnogs/ogg_encoder.h"
#include "satnogs/ogg_source.h"
#include "satnogs/noaa_apt_sink.h"
#include "satnogs/sstv_pd120_sink.h"
#include "satnogs/frame_file_sink.h"
#include "satnogs/iq_sink.h"
#include "satnogs/quad_demod_filter_ff.h"
@ -103,6 +104,9 @@ GR_SWIG_BLOCK_MAGIC2(satnogs, ogg_source);
%include "satnogs/noaa_apt_sink.h"
GR_SWIG_BLOCK_MAGIC2(satnogs, noaa_apt_sink);
%include "satnogs/sstv_pd120_sink.h"
GR_SWIG_BLOCK_MAGIC2(satnogs, sstv_pd120_sink);
%include "satnogs/frame_file_sink.h"
GR_SWIG_BLOCK_MAGIC2(satnogs, frame_file_sink);