mirror of
https://github.com/DJ2LS/FreeDATA
synced 2024-05-14 08:04:33 +00:00
scatter plott support
This commit is contained in:
parent
e3cb2eb46a
commit
c0ec0c1853
4 changed files with 101 additions and 15 deletions
|
@ -682,7 +682,7 @@ def received_ping_ack(data_in):
|
||||||
static.DXGRID = bytes(data_in[3:9]).rstrip(b'\x00')
|
static.DXGRID = bytes(data_in[3:9]).rstrip(b'\x00')
|
||||||
|
|
||||||
|
|
||||||
helpers.add_to_heard_stations(static.DXCALLSIGN,static.DXGRID, 'PING-ACK')
|
helpers.add_to_heard_stations(static.DXCALLSIGN,static.DXGRID, 'PING-ACK', static.SNR)
|
||||||
|
|
||||||
logging.info("PING [" + str(static.MYCALLSIGN, 'utf-8') + "] >|< [" + str(static.DXCALLSIGN, 'utf-8') + "]["+ str(static.DXGRID, 'utf-8') +"] [SNR:" + str(static.SNR) + "]")
|
logging.info("PING [" + str(static.MYCALLSIGN, 'utf-8') + "] >|< [" + str(static.DXCALLSIGN, 'utf-8') + "]["+ str(static.DXGRID, 'utf-8') +"] [SNR:" + str(static.SNR) + "]")
|
||||||
static.TNC_STATE = 'IDLE'
|
static.TNC_STATE = 'IDLE'
|
||||||
|
@ -723,7 +723,7 @@ def received_cq(data_in):
|
||||||
dxgrid = bytes(data_in[8:14]).rstrip(b'\x00')
|
dxgrid = bytes(data_in[8:14]).rstrip(b'\x00')
|
||||||
|
|
||||||
logging.info("CQ RCVD [" + str(dxcallsign, 'utf-8') + "]["+ str(dxgrid, 'utf-8') +"] [SNR" + str(static.SNR) + "]")
|
logging.info("CQ RCVD [" + str(dxcallsign, 'utf-8') + "]["+ str(dxgrid, 'utf-8') +"] [SNR" + str(static.SNR) + "]")
|
||||||
helpers.add_to_heard_stations(dxcallsign,dxgrid, 'CQ CQ CQ')
|
helpers.add_to_heard_stations(dxcallsign,dxgrid, 'CQ CQ CQ', static.SNR)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -748,4 +748,4 @@ def received_beacon():
|
||||||
dxgrid = bytes(data_in[8:14]).rstrip(b'\x00')
|
dxgrid = bytes(data_in[8:14]).rstrip(b'\x00')
|
||||||
|
|
||||||
logging.info("BEACON RCVD [" + str(dxcallsign, 'utf-8') + "]["+ str(dxgrid, 'utf-8') +"] [SNR" + str(static.SNR) + "]")
|
logging.info("BEACON RCVD [" + str(dxcallsign, 'utf-8') + "]["+ str(dxgrid, 'utf-8') +"] [SNR" + str(static.SNR) + "]")
|
||||||
helpers.add_to_heard_stations(dxcallsign,dxgrid, 'BEACON')
|
helpers.add_to_heard_stations(dxcallsign,dxgrid, 'BEACON', static.SNR)
|
||||||
|
|
82
tnc/modem.py
82
tnc/modem.py
|
@ -31,6 +31,32 @@ import numpy as np
|
||||||
from scipy.fft import fft, ifft
|
from scipy.fft import fft, ifft
|
||||||
from scipy import signal
|
from scipy import signal
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
MODEM_STATS_NR_MAX = 320
|
||||||
|
MODEM_STATS_NC_MAX = 51
|
||||||
|
|
||||||
|
class MODEMSTATS(ctypes.Structure):
|
||||||
|
_fields_ = [
|
||||||
|
("Nc", ctypes.c_int),
|
||||||
|
("snr_est", ctypes.c_float),
|
||||||
|
("rx_symbols", (ctypes.c_float * MODEM_STATS_NR_MAX)*MODEM_STATS_NC_MAX),
|
||||||
|
("nr", ctypes.c_int),
|
||||||
|
("sync", ctypes.c_int),
|
||||||
|
("foff", ctypes.c_float),
|
||||||
|
("rx_timing", ctypes.c_float),
|
||||||
|
("clock_offset", ctypes.c_float),
|
||||||
|
("sync_metric", ctypes.c_float),
|
||||||
|
("pre", ctypes.c_int),
|
||||||
|
("post", ctypes.c_int),
|
||||||
|
("uw_fails", ctypes.c_int),
|
||||||
|
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class RF():
|
class RF():
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
@ -437,13 +463,18 @@ class RF():
|
||||||
#print("listening-" + str(mode) + " - " + "nin: " + str(nin) + " - " + str(self.c_lib.freedv_get_rx_status(freedv)))
|
#print("listening-" + str(mode) + " - " + "nin: " + str(nin) + " - " + str(self.c_lib.freedv_get_rx_status(freedv)))
|
||||||
|
|
||||||
self.calculate_snr(freedv)
|
self.calculate_snr(freedv)
|
||||||
|
self.get_scatter(freedv)
|
||||||
# forward data only if broadcast or we are the receiver
|
# forward data only if broadcast or we are the receiver
|
||||||
# bytes_out[1:2] == callsign check for signalling frames, bytes_out[6:7] == callsign check for data frames, bytes_out[1:2] == b'\x01' --> broadcasts like CQ
|
# bytes_out[1:2] == callsign check for signalling frames, bytes_out[6:7] == callsign check for data frames, bytes_out[1:2] == b'\x01' --> broadcasts like CQ
|
||||||
# we could also create an own function, which returns True. In this case we could add callsign blacklists and so on
|
# we could also create an own function, which returns True. In this case we could add callsign blacklists and so on
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if nbytes == bytes_per_frame and bytes(bytes_out[1:2]) == static.MYCALLSIGN_CRC8 or bytes(bytes_out[6:7]) == static.MYCALLSIGN_CRC8 or bytes(bytes_out[1:2]) == b'\x01':
|
if nbytes == bytes_per_frame and bytes(bytes_out[1:2]) == static.MYCALLSIGN_CRC8 or bytes(bytes_out[6:7]) == static.MYCALLSIGN_CRC8 or bytes(bytes_out[1:2]) == b'\x01':
|
||||||
|
|
||||||
self.calculate_snr(freedv)
|
self.calculate_snr(freedv)
|
||||||
|
static.SCATTER = []
|
||||||
|
|
||||||
# CHECK IF FRAMETYPE IS BETWEEN 10 and 50 ------------------------
|
# CHECK IF FRAMETYPE IS BETWEEN 10 and 50 ------------------------
|
||||||
frametype = int.from_bytes(bytes(bytes_out[:1]), "big")
|
frametype = int.from_bytes(bytes(bytes_out[:1]), "big")
|
||||||
|
@ -553,7 +584,40 @@ class RF():
|
||||||
# for debugging purposes to receive all data
|
# for debugging purposes to receive all data
|
||||||
pass
|
pass
|
||||||
# print(bytes_out[:-2])
|
# print(bytes_out[:-2])
|
||||||
|
def get_scatter(self, freedv):
|
||||||
|
modemStats = MODEMSTATS()
|
||||||
|
self.c_lib.freedv_get_modem_extended_stats.restype = None
|
||||||
|
#c_lib.freedv_get_modem_extended_stats.argtypes = c_void_p, [MODEMSTATS]
|
||||||
|
#c_lib.freedv_get_modem_extended_stats(freedv, modemStats)
|
||||||
|
self.c_lib.freedv_get_modem_extended_stats(freedv, ctypes.byref(modemStats))
|
||||||
|
print("Nc: " + str(modemStats.Nc))
|
||||||
|
#print("snr_est: " + str(modemStats.snr_est))
|
||||||
|
print("nr: " + str(modemStats.nr))
|
||||||
|
#data = []
|
||||||
|
#MODEM_STATS_NR_MAX = 320
|
||||||
|
#MODEM_STATS_NC_MAX = 51
|
||||||
|
|
||||||
|
scatterdata = []
|
||||||
|
for i in range(MODEM_STATS_NC_MAX):
|
||||||
|
for j in range(MODEM_STATS_NR_MAX):
|
||||||
|
|
||||||
|
#xsymbols = modemStats.rx_symbols[i][j]
|
||||||
|
#xsymbols = modemStats.rx_symbols[i][::2]
|
||||||
|
#ysymbols = modemStats.rx_symbols[i][j+1]
|
||||||
|
|
||||||
|
#check if odd or not to get every 2nd item for x
|
||||||
|
if (j % 2) == 0:
|
||||||
|
xsymbols = modemStats.rx_symbols[i][j]
|
||||||
|
ysymbols = modemStats.rx_symbols[i][j+1]
|
||||||
|
|
||||||
|
if xsymbols != 0.0 and ysymbols != 0.0:
|
||||||
|
scatterdata.append({"x" : xsymbols, "y" : ysymbols })
|
||||||
|
|
||||||
|
# only append scatter data if new data arrived
|
||||||
|
if scatterdata != static.SCATTER:
|
||||||
|
static.SCATTER = scatterdata
|
||||||
|
|
||||||
|
|
||||||
def calculate_ber(self, freedv):
|
def calculate_ber(self, freedv):
|
||||||
Tbits = self.c_lib.freedv_get_total_bits(freedv)
|
Tbits = self.c_lib.freedv_get_total_bits(freedv)
|
||||||
Terrs = self.c_lib.freedv_get_total_bit_errors(freedv)
|
Terrs = self.c_lib.freedv_get_total_bit_errors(freedv)
|
||||||
|
@ -593,11 +657,11 @@ class RF():
|
||||||
#static.FFT = fft_raw.tolist()
|
#static.FFT = fft_raw.tolist()
|
||||||
#fft_raw = fft_raw.tobytes()
|
#fft_raw = fft_raw.tobytes()
|
||||||
|
|
||||||
rate = 48000
|
#rate = 48000
|
||||||
M = 1024
|
#M = 1024
|
||||||
freqs, times, Sx = signal.spectrogram(data_in_array, fs=rate, window='hanning', nperseg=1024, noverlap=M - 100, detrend=False, scaling='spectrum', return_onesided=True)
|
#freqs, times, Sx = signal.spectrogram(data_in_array, fs=rate, window='hanning', nperseg=1024, noverlap=M - 100, detrend=False, scaling='spectrum', return_onesided=True)
|
||||||
|
|
||||||
freqs, times, Sx = signal.spectrogram(data_in_array, fs=rate, return_onesided=True, axis=-1)
|
#freqs, times, Sx = signal.spectrogram(data_in_array, fs=rate, return_onesided=True, axis=-1)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -608,8 +672,8 @@ class RF():
|
||||||
#print(fft_raw)
|
#print(fft_raw)
|
||||||
#static.FFT = fft_raw.hex()
|
#static.FFT = fft_raw.hex()
|
||||||
#static.FFT = fft_raw
|
#static.FFT = fft_raw
|
||||||
data_in = np.frombuffer(data_in, dtype=np.int16)
|
#data_in = np.frombuffer(data_in, dtype=np.int16)
|
||||||
data = fft(data_in)
|
#data = fft(data_in)
|
||||||
#print(data)
|
#print(data)
|
||||||
#data = getFFT(data_in, 48000, 2048)
|
#data = getFFT(data_in, 48000, 2048)
|
||||||
#print(data)
|
#print(data)
|
||||||
|
@ -620,13 +684,13 @@ class RF():
|
||||||
|
|
||||||
|
|
||||||
#data = np.frombuffer(data_in, dtype=np.int16)
|
#data = np.frombuffer(data_in, dtype=np.int16)
|
||||||
data.resize((1,2048))
|
#data.resize((1,2048))
|
||||||
#data = np.delete(data,0)
|
#data = np.delete(data,0)
|
||||||
|
|
||||||
|
|
||||||
#data = data.tobytes()
|
#data = data.tobytes()
|
||||||
#print(data)
|
#print(data)
|
||||||
static.FFT = data.tolist()
|
#static.FFT = data.tolist()
|
||||||
#static.FFT = data.hex()
|
#static.FFT = data.hex()
|
||||||
|
|
||||||
def getFFT(data, rate, chunk_size, log_scale=False):
|
def getFFT(data, rate, chunk_size, log_scale=False):
|
||||||
|
|
26
tnc/sock.py
26
tnc/sock.py
|
@ -199,13 +199,15 @@ class CMDTCPRequestHandler(socketserver.BaseRequestHandler):
|
||||||
"COMMAND": "STATION_INFO",
|
"COMMAND": "STATION_INFO",
|
||||||
"MY_CALLSIGN": str(static.MYCALLSIGN, encoding),
|
"MY_CALLSIGN": str(static.MYCALLSIGN, encoding),
|
||||||
"DX_CALLSIGN": str(static.DXCALLSIGN, encoding),
|
"DX_CALLSIGN": str(static.DXCALLSIGN, encoding),
|
||||||
"DX_GRID": str(static.DXGRID, encoding)
|
"DX_GRID": str(static.DXGRID, encoding),
|
||||||
|
"EOF" : "EOF",
|
||||||
}
|
}
|
||||||
|
|
||||||
jsondata = json.dumps(output)
|
jsondata = json.dumps(output)
|
||||||
self.request.sendall(bytes(jsondata, encoding))
|
self.request.sendall(bytes(jsondata, encoding))
|
||||||
|
|
||||||
if received_json["type"] == 'GET' and received_json["command"] == 'TNC_STATE':
|
if received_json["type"] == 'GET' and received_json["command"] == 'TNC_STATE':
|
||||||
|
print(static.SCATTER)
|
||||||
output = {
|
output = {
|
||||||
"COMMAND": "TNC_STATE",
|
"COMMAND": "TNC_STATE",
|
||||||
"PTT_STATE": str(static.PTT_STATE),
|
"PTT_STATE": str(static.PTT_STATE),
|
||||||
|
@ -219,6 +221,7 @@ class CMDTCPRequestHandler(socketserver.BaseRequestHandler):
|
||||||
"MODE" : str(static.HAMLIB_MODE),
|
"MODE" : str(static.HAMLIB_MODE),
|
||||||
"BANDWITH" : str(static.HAMLIB_BANDWITH),
|
"BANDWITH" : str(static.HAMLIB_BANDWITH),
|
||||||
"FFT" : str(static.FFT),
|
"FFT" : str(static.FFT),
|
||||||
|
"SCATTER" : static.SCATTER,
|
||||||
#"RX_BUFFER_LENGTH": str(len(static.RX_BUFFER)),
|
#"RX_BUFFER_LENGTH": str(len(static.RX_BUFFER)),
|
||||||
#"TX_N_MAX_RETRIES": str(static.TX_N_MAX_RETRIES),
|
#"TX_N_MAX_RETRIES": str(static.TX_N_MAX_RETRIES),
|
||||||
#"ARQ_TX_N_FRAMES_PER_BURST": str(static.ARQ_TX_N_FRAMES_PER_BURST),
|
#"ARQ_TX_N_FRAMES_PER_BURST": str(static.ARQ_TX_N_FRAMES_PER_BURST),
|
||||||
|
@ -228,7 +231,9 @@ class CMDTCPRequestHandler(socketserver.BaseRequestHandler):
|
||||||
#"ARQ_RX_FRAME_N_BURSTS": str(static.ARQ_RX_FRAME_N_BURSTS),
|
#"ARQ_RX_FRAME_N_BURSTS": str(static.ARQ_RX_FRAME_N_BURSTS),
|
||||||
#"ARQ_RX_N_CURRENT_ARQ_FRAME": str(static.ARQ_RX_N_CURRENT_ARQ_FRAME),
|
#"ARQ_RX_N_CURRENT_ARQ_FRAME": str(static.ARQ_RX_N_CURRENT_ARQ_FRAME),
|
||||||
#"ARQ_N_ARQ_FRAMES_PER_DATA_FRAME": str(static.ARQ_N_ARQ_FRAMES_PER_DATA_FRAME)
|
#"ARQ_N_ARQ_FRAMES_PER_DATA_FRAME": str(static.ARQ_N_ARQ_FRAMES_PER_DATA_FRAME)
|
||||||
}
|
"EOF" : "EOF",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
jsondata = json.dumps(output)
|
jsondata = json.dumps(output)
|
||||||
#print(len(jsondata))
|
#print(len(jsondata))
|
||||||
|
@ -242,6 +247,17 @@ class CMDTCPRequestHandler(socketserver.BaseRequestHandler):
|
||||||
jsondata = json.dumps(output)
|
jsondata = json.dumps(output)
|
||||||
self.request.sendall(bytes(jsondata, encoding))
|
self.request.sendall(bytes(jsondata, encoding))
|
||||||
|
|
||||||
|
#if received_json["type"] == 'GET' and received_json["command"] == 'SCATTER':
|
||||||
|
#
|
||||||
|
# print(static.SCATTER)
|
||||||
|
# output = {
|
||||||
|
# "COMMAND" : "SCATTER",
|
||||||
|
# "DATA" : static.SCATTER
|
||||||
|
# }
|
||||||
|
# print(output)
|
||||||
|
# jsondata = json.dumps(output)
|
||||||
|
# self.request.sendall(bytes(jsondata, encoding))
|
||||||
|
|
||||||
if received_json["type"] == 'GET' and received_json["command"] == 'DATA_STATE':
|
if received_json["type"] == 'GET' and received_json["command"] == 'DATA_STATE':
|
||||||
output = {
|
output = {
|
||||||
"COMMAND": "DATA_STATE",
|
"COMMAND": "DATA_STATE",
|
||||||
|
@ -253,7 +269,8 @@ class CMDTCPRequestHandler(socketserver.BaseRequestHandler):
|
||||||
"ARQ_TX_N_TOTAL_ARQ_FRAMES": str(int.from_bytes(bytes(static.ARQ_TX_N_TOTAL_ARQ_FRAMES), "big")),
|
"ARQ_TX_N_TOTAL_ARQ_FRAMES": str(int.from_bytes(bytes(static.ARQ_TX_N_TOTAL_ARQ_FRAMES), "big")),
|
||||||
"ARQ_RX_FRAME_N_BURSTS": str(static.ARQ_RX_FRAME_N_BURSTS),
|
"ARQ_RX_FRAME_N_BURSTS": str(static.ARQ_RX_FRAME_N_BURSTS),
|
||||||
"ARQ_RX_N_CURRENT_ARQ_FRAME": str(static.ARQ_RX_N_CURRENT_ARQ_FRAME),
|
"ARQ_RX_N_CURRENT_ARQ_FRAME": str(static.ARQ_RX_N_CURRENT_ARQ_FRAME),
|
||||||
"ARQ_N_ARQ_FRAMES_PER_DATA_FRAME": str(static.ARQ_N_ARQ_FRAMES_PER_DATA_FRAME)
|
"ARQ_N_ARQ_FRAMES_PER_DATA_FRAME": str(static.ARQ_N_ARQ_FRAMES_PER_DATA_FRAME),
|
||||||
|
"EOF" : "EOF",
|
||||||
}
|
}
|
||||||
|
|
||||||
jsondata = json.dumps(output)
|
jsondata = json.dumps(output)
|
||||||
|
@ -267,6 +284,9 @@ class CMDTCPRequestHandler(socketserver.BaseRequestHandler):
|
||||||
for i in range(0, len(static.HEARD_STATIONS)):
|
for i in range(0, len(static.HEARD_STATIONS)):
|
||||||
data["STATIONS"].append({"DXCALLSIGN": str(static.HEARD_STATIONS[i][0], 'utf-8'),"DXGRID": str(static.HEARD_STATIONS[i][1], 'utf-8'), "TIMESTAMP": static.HEARD_STATIONS[i][2], "DATATYPE": static.HEARD_STATIONS[i][3], "SNR": static.HEARD_STATIONS[i][4]})
|
data["STATIONS"].append({"DXCALLSIGN": str(static.HEARD_STATIONS[i][0], 'utf-8'),"DXGRID": str(static.HEARD_STATIONS[i][1], 'utf-8'), "TIMESTAMP": static.HEARD_STATIONS[i][2], "DATATYPE": static.HEARD_STATIONS[i][3], "SNR": static.HEARD_STATIONS[i][4]})
|
||||||
# print(static.HEARD_STATIONS[i][1])
|
# print(static.HEARD_STATIONS[i][1])
|
||||||
|
|
||||||
|
|
||||||
|
#data.append({"EOF" : "EOF"})
|
||||||
jsondata = json.dumps(data)
|
jsondata = json.dumps(data)
|
||||||
self.request.sendall(bytes(jsondata, encoding))
|
self.request.sendall(bytes(jsondata, encoding))
|
||||||
|
|
||||||
|
|
|
@ -80,6 +80,7 @@ FREEDV_SIGNALLING_PAYLOAD_PER_FRAME = 0
|
||||||
|
|
||||||
BER = 0
|
BER = 0
|
||||||
SNR = 0
|
SNR = 0
|
||||||
|
SCATTER = []
|
||||||
# ---------------------------------
|
# ---------------------------------
|
||||||
|
|
||||||
# Audio Defaults
|
# Audio Defaults
|
||||||
|
@ -95,6 +96,7 @@ AUDIO_FRAMES_PER_BUFFER = 8192 # 256 # 512 # 1024 #2048 --> nicht 880
|
||||||
AUDIO_CHANNELS = 1
|
AUDIO_CHANNELS = 1
|
||||||
AUDIO_RMS = 0
|
AUDIO_RMS = 0
|
||||||
FFT = []
|
FFT = []
|
||||||
|
|
||||||
# ---------------------------------
|
# ---------------------------------
|
||||||
|
|
||||||
# ARQ DEFAULTS
|
# ARQ DEFAULTS
|
||||||
|
|
Loading…
Reference in a new issue