Commit 60913f2a authored by Jenda's avatar Jenda

kukuruku-gui: added dB measurements and fix some bugs

parent fb35c142
[Main]
host=rdl
port=4444
mousechangedelay=1
histooffs=1
......@@ -13,7 +12,7 @@ antialias=no
spectrumscale=50
spectrumoffset=6
sqltrim=0.2
sqldelta=1
sqldelta=10
afcdecim=5
afcmult=0.1
preferformat=F32
......
......@@ -58,7 +58,7 @@ rate=32000
bw=15000
transition=2000
filtertype=hamming
program=_MODEPATH_/raw.sh 32
program=_MODEPATH_/raw.py -s 32000
resample=yes
[RAW128]
......@@ -67,5 +67,5 @@ rate=128000
bw=60000
transition=8000
filtertype=hamming
program=_MODEPATH_/raw.sh 128
program=_MODEPATH_/raw.py -s 128000
resample=yes
......@@ -4,7 +4,6 @@
from __future__ import print_function
import gtk
import configparser
import os
import sys
import struct
......@@ -79,7 +78,7 @@ def float2color(f):
Get color index from power readings
"""
idx = conf.spectrumscale*(f + conf.spectrumoffset)
return max(0, min(libutil.safe_cast(idx, int, 0), 1023))
return max(0, min(libutil.safe_cast(idx, int, 0), len(colormap)-1))
def pixel2freq(pixpos):
"""
......@@ -147,6 +146,8 @@ lastfft = None
fftframes = {}
# dictionary y position -> timestamp
ffttimes = {}
# dictionary y position -> list of power data [dB]
fftpowers = {}
# timestamp of last message in the left border
fft_lastshowntime = 0
......@@ -174,6 +175,7 @@ def fft_cb(d, frameno, timestamp):
fftframes[wfofs] = frameno
ffttimes[wfofs] = timestamp
fftpowers[wfofs] = data
if fft_lastshowntime + 4.5 < timestamp and wfofs > conf.fontsize and timestamp % 5 == 0:
wow = datetime.fromtimestamp(timestamp).strftime("%H:%M:%S %y%m%d")
......@@ -210,10 +212,17 @@ def sql_cb(rotation, decimation):
ave = 0.0
items = 0.0
for i in range(centerbin-rangebins, centerbin+rangebins):
if i < 0 or i > conf.fftw-1:
continue
ave += lastfft[i]
items += 1
ave /= items
relevant = lastfft[centerbin-rangebins:centerbin+rangebins]
if not relevant:
print("squelch: extracted empty measurement")
return True
ave = max(lastfft[centerbin-rangebins:centerbin+rangebins])
print("cutoff %f, range %i +/- %i, ave %f"%(cutoff, centerbin, rangebins, ave))
......@@ -379,9 +388,15 @@ def da_press(widget, event):
""" Handle button press on display area """
global wf_click_x,wf_click_y
# ignore presses outside drawing area
if event.get_coords()[0] < conf.borderleft or event.get_coords()[0] > conf.borderleft+conf.fftw:
return
# right click
if event.type == gtk.gdk.BUTTON_RELEASE and event.button == 3:
menu.popup(None, None, None, event.button, event.time)
# release on move
if event.type == gtk.gdk.BUTTON_RELEASE and event.button == 1:
cl.acquire_xlaters()
wid = pixel2xlater(wf_click_x)
......@@ -420,11 +435,15 @@ def da_motion(widget, event):
y = event.get_coords()[1]
timestamp = 0
dbstr = "?"
if y in ffttimes.keys():
timestamp = ffttimes[y]
if y in fftpowers.keys():
pwr = fftpowers[y][min(conf.fftw-1, max(0, int(event.get_coords()[0]-conf.borderleft)))]
dbstr = "%.1f"%pwr
datestr = datetime.fromtimestamp(timestamp).strftime('%Y-%m-%d %H:%M:%S')
tb_cursor_label.set_text("%i kHz, %s"%(freq, datestr))
tb_cursor_label.set_text("%i kHz, %s, %s dB"%(freq, datestr, dbstr))
def on_freq_change(widget, event):
""" Handle edit in the Frequency textbox """
......
......@@ -137,8 +137,8 @@ class client():
def set_afc_params(self, decim, mult):
""" Set parameters of automatic frequency correction
decim -- trigger AFC every N frames
mult -- mulriply the obtained power difference with this value and add it to the rotator
expected are very small numbers between 0.1 and 10 μ.
mult -- multiply the obtained power difference with this value and add it to the rotator
expected are small numbers, about 0.01 - 0.2
"""
self.afcdecim = decim
self.afcmult = mult
......@@ -357,7 +357,8 @@ class client():
if msg.id in self.xlaters.keys():
# push None to the feeder thread, it will gracefully exit
self.xlaters[msg.id].data.put(None)
if self.xlaters[msg.id].data:
self.xlaters[msg.id].data.put(None)
del(self.xlaters[msg.id])
if self.xlater_callback:
......@@ -568,6 +569,7 @@ class client():
self.q_msg(hdr + msg.SerializeToString())
def set_ppm(self, ppm):
""" Set radio PPM """
hdr = struct.pack(proto.ENDIAN+"i", proto.SET_PPM)
msg = c2s.CLI_SET_PPM()
......
......@@ -3,7 +3,7 @@ CFLAGS = -d .
all: modes
MODES = tetrapol.py tetra.py nfm.py mfm.py wfm.py
MODES = tetrapol.py tetra.py nfm.py mfm.py wfm.py raw.py
%.py: %.grc
$(CC) $(CFLAGS) $<
......
<?xml version='1.0' encoding='utf-8'?>
<?grc format='1' created='3.7.11'?>
<flow_graph>
<timestamp>Mon May 9 11:02:35 2016</timestamp>
<block>
<key>options</key>
<param>
<key>author</key>
<value></value>
</param>
<param>
<key>window_size</key>
<value></value>
</param>
<param>
<key>category</key>
<value>Custom</value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>description</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(8, 8)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>generate_options</key>
<value>wx_gui</value>
</param>
<param>
<key>hier_block_src_path</key>
<value>.:</value>
</param>
<param>
<key>id</key>
<value>raw</value>
</param>
<param>
<key>max_nouts</key>
<value>0</value>
</param>
<param>
<key>qt_qss_theme</key>
<value></value>
</param>
<param>
<key>realtime_scheduling</key>
<value></value>
</param>
<param>
<key>run_command</key>
<value>{python} -u {filename}</value>
</param>
<param>
<key>run_options</key>
<value>prompt</value>
</param>
<param>
<key>run</key>
<value>True</value>
</param>
<param>
<key>thread_safe_setters</key>
<value></value>
</param>
<param>
<key>title</key>
<value>Raw WF/IQ recorder</value>
</param>
</block>
<block>
<key>variable</key>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(528, 61)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>filename</value>
</param>
<param>
<key>value</key>
<value>datetime.now().strftime("raw-%F-%T-"+str(samp_rate)+".cfile")</value>
</param>
</block>
<block>
<key>blocks_file_sink</key>
<param>
<key>append</key>
<value>False</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>file</key>
<value>filename</value>
</param>
<param>
<key>_coordinate</key>
<value>(376, 404)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>blocks_file_sink_0</value>
</param>
<param>
<key>type</key>
<value>complex</value>
</param>
<param>
<key>unbuffered</key>
<value>False</value>
</param>
<param>
<key>vlen</key>
<value>1</value>
</param>
</block>
<block>
<key>blocks_file_source</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>file</key>
<value>/dev/stdin</value>
</param>
<param>
<key>_coordinate</key>
<value>(0, 213)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>blocks_file_source_0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>type</key>
<value>complex</value>
</param>
<param>
<key>repeat</key>
<value>False</value>
</param>
<param>
<key>vlen</key>
<value>1</value>
</param>
</block>
<block>
<key>fractional_resampler_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>(152, 217)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>fractional_resampler_xx_0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>phase_shift</key>
<value>0</value>
</param>
<param>
<key>resamp_ratio</key>
<value>resample</value>
</param>
<param>
<key>type</key>
<value>complex</value>
</param>
</block>
<block>
<key>import</key>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(8, 124)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>import_0</value>
</param>
<param>
<key>import</key>
<value>from datetime import datetime</value>
</param>
</block>
<block>
<key>parameter</key>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(192, 53)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>resample</value>
</param>
<param>
<key>label</key>
<value>resample</value>
</param>
<param>
<key>short_id</key>
<value>r</value>
</param>
<param>
<key>type</key>
<value>eng_float</value>
</param>
<param>
<key>value</key>
<value>1.0</value>
</param>
</block>
<block>
<key>parameter</key>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(296, 56)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>samp_rate</value>
</param>
<param>
<key>label</key>
<value>samplerate</value>
</param>
<param>
<key>short_id</key>
<value>s</value>
</param>
<param>
<key>type</key>
<value>intx</value>
</param>
<param>
<key>value</key>
<value>32000</value>
</param>
</block>
<block>
<key>wxgui_waterfallsink2</key>
<param>
<key>avg_alpha</key>
<value>0</value>
</param>
<param>
<key>average</key>
<value>False</value>
</param>
<param>
<key>baseband_freq</key>
<value>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>dynamic_range</key>
<value>100</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>fft_rate</key>
<value>15</value>
</param>
<param>
<key>fft_size</key>
<value>512</value>
</param>
<param>
<key>freqvar</key>
<value>None</value>
</param>
<param>
<key>_coordinate</key>
<value>(400, 172)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>grid_pos</key>
<value></value>
</param>
<param>
<key>id</key>
<value>wxgui_waterfallsink2_0</value>
</param>
<param>
<key>notebook</key>
<value></value>
</param>
<param>
<key>ref_scale</key>
<value>2.0</value>
</param>
<param>
<key>ref_level</key>
<value>0</value>
</param>
<param>
<key>samp_rate</key>
<value>samp_rate</value>
</param>
<param>
<key>title</key>
<value>Baseband</value>
</param>
<param>
<key>type</key>
<value>complex</value>
</param>
<param>
<key>win_size</key>
<value></value>
</param>
<param>
<key>win</key>
<value>None</value>
</param>
</block>
<connection>
<source_block_id>blocks_file_source_0</source_block_id>
<sink_block_id>fractional_resampler_xx_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>fractional_resampler_xx_0</source_block_id>
<sink_block_id>blocks_file_sink_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>fractional_resampler_xx_0</source_block_id>
<sink_block_id>wxgui_waterfallsink2_0</sink_block_id>
<source_key>0</source_key>