first test with FSK_LDPC

highly experimental, not working yet
This commit is contained in:
dj2ls 2022-03-20 14:51:30 +01:00
parent 4b296a48df
commit 3d24d47ee5
2 changed files with 75 additions and 16 deletions

View file

@ -93,6 +93,9 @@ if not 'api' in locals():
api.freedv_open.argype = [c_int]
api.freedv_open.restype = c_void_p
api.freedv_open_advanced.argtype = [c_int, c_void_p]
api.freedv_open_advanced.restype = c_void_p
api.freedv_get_bits_per_modem_frame.argtype = [c_void_p]
api.freedv_get_bits_per_modem_frame.restype = c_int
@ -141,6 +144,55 @@ api.FREEDV_MODE_DATAC3 = 12
api.FREEDV_MODE_DATAC0 = 14
api.FREEDV_MODE_FSK_LDPC = 9
# -------------------------------- FSK LDPC MODE SETTINGS
# advanced structure for fsk modes
class ADVANCED(ctypes.Structure):
""" """
_fields_ = [
("interleave_frames", ctypes.c_int),
("M", ctypes.c_int),
("Rs", ctypes.c_int),
("Fs", ctypes.c_int),
("first_tone", ctypes.c_int),
("tone_spacing", ctypes.c_int),
("codename", ctypes.c_char_p),
]
'''
adv.interleave_frames = 0 # max amplitude
adv.M = 2 # number of fsk tones 2/4
adv.Rs = 100 # symbol rate
adv.Fs = 8000 # sample rate
adv.first_tone = 1500 # first tone freq
adv.tone_spacing = 200 # shift between tones
adv.codename = 'H_128_256_5'.encode('utf-8') # code word
HRA_112_112 rate 0.50 (224,112) BPF: 14 not working
HRA_56_56 rate 0.50 (112,56) BPF: 7 not working
H_2064_516_sparse rate 0.80 (2580,2064) BPF: 258 not working
HRAb_396_504 rate 0.79 (504,396) BPF: 49 not working
H_256_768_22 rate 0.33 (768,256) BPF: 32 working
H_256_512_4 rate 0.50 (512,256) BPF: 32 working
HRAa_1536_512 rate 0.75 (2048,1536) BPF: 192 not working
H_128_256_5 rate 0.50 (256,128) BPF: 16 working
H_4096_8192_3d rate 0.50 (8192,4096) BPF: 512 not working
H_16200_9720 rate 0.60 (16200,9720) BPF: 1215 not working
H_1024_2048_4f rate 0.50 (2048,1024) BPF: 128 not working
'''
# --------------- 2 FSK HRA_56_56, 7 bytes
api.FREEDV_MODE_FSK_LDPC_0_ADV = ADVANCED()
api.FREEDV_MODE_FSK_LDPC_0_ADV.interleave_frames = 0
api.FREEDV_MODE_FSK_LDPC_0_ADV.M = 2
api.FREEDV_MODE_FSK_LDPC_0_ADV.Rs = 100
api.FREEDV_MODE_FSK_LDPC_0_ADV.Fs = 8000
api.FREEDV_MODE_FSK_LDPC_0_ADV.first_tone = 1500
api.FREEDV_MODE_FSK_LDPC_0_ADV.tone_spacing = 200
api.FREEDV_MODE_FSK_LDPC_0_ADV.codename = 'HRA_56_56'.encode('utf-8') # code word
# Return code flags for freedv_get_rx_status() function
api.FREEDV_RX_TRIAL_SYNC = 0x1 # demodulator has trial sync
api.FREEDV_RX_SYNC = 0x2 # demodulator has sync

View file

@ -25,12 +25,13 @@ import queue
import codec2
import audio
from collections import deque
MODEM_STATS_NR_MAX = 320
MODEM_STATS_NC_MAX = 51
# modem stats structure
class MODEMSTATS(ctypes.Structure):
""" """
_fields_ = [
@ -48,6 +49,8 @@ class MODEMSTATS(ctypes.Structure):
("uw_fails", ctypes.c_int),
]
# init FIFO queue to store received frames in
MODEM_RECEIVED_QUEUE = queue.Queue()
MODEM_TRANSMIT_QUEUE = queue.Queue()
@ -56,7 +59,7 @@ static.TRANSMITTING = False
# receive only specific modes to reduce cpu load
RECEIVE_DATAC1 = False
RECEIVE_DATAC3 = False
RECEIVE_FSK_LDPC = False
RECEIVE_FSK_LDPC_0 = False
class RF():
""" """
@ -99,10 +102,7 @@ class RF():
# open codec2 instance
self.datac0_freedv = cast(codec2.api.freedv_open(codec2.api.FREEDV_MODE_DATAC0), c_void_p)
#self.datac0_freedv = cast(codec2.api.freedv_open(9), c_void_p)
self.c_lib.freedv_set_tuning_range(self.datac0_freedv, c_float(static.TUNING_RANGE_FMIN), c_float(static.TUNING_RANGE_FMAX))
self.datac0_bytes_per_frame = int(codec2.api.freedv_get_bits_per_modem_frame(self.datac0_freedv)/8)
self.datac0_payload_per_frame = self.datac0_bytes_per_frame -2
self.datac0_n_nom_modem_samples = self.c_lib.freedv_get_n_nom_modem_samples(self.datac0_freedv)
@ -127,11 +127,13 @@ class RF():
codec2.api.freedv_set_frames_per_burst(self.datac3_freedv,1)
self.datac3_buffer = codec2.audio_buffer(2*self.AUDIO_FRAMES_PER_BUFFER_RX)
self.fsk_ldpc_freedv = cast(codec2.api.freedv_open(codec2.api.FREEDV_MODE_FSK_LDPC), c_void_p)
self.fsk_ldpc_freedv = cast(codec2.api.freedv_open_advanced(9, ctypes.byref(codec2.api.FREEDV_MODE_FSK_LDPC_0_ADV)), c_void_p)
#self.fsk_ldpc_freedv = cast(codec2.api.freedv_open(codec2.api.FREEDV_MODE_FSK_LDPC), c_void_p)
self.fsk_ldpc_bytes_per_frame = int(codec2.api.freedv_get_bits_per_modem_frame(self.fsk_ldpc_freedv)/8)
self.fsk_ldpc_bytes_out = create_string_buffer(self.fsk_ldpc_bytes_per_frame)
codec2.api.freedv_set_frames_per_burst(self.fsk_ldpc_freedv,1)
self.fsk_ldpc_buffer = codec2.audio_buffer(2*self.AUDIO_FRAMES_PER_BUFFER_RX)
#codec2.api.freedv_set_frames_per_burst(self.fsk_ldpc_freedv,1)
self.fsk_ldpc_buffer = codec2.audio_buffer(self.AUDIO_FRAMES_PER_BUFFER_RX)
@ -218,8 +220,8 @@ class RF():
audio_thread_datac3 = threading.Thread(target=self.audio_datac3, name="AUDIO_THREAD DATAC3",daemon=True)
audio_thread_datac3.start()
audio_thread_fsk_ldpc = threading.Thread(target=self.audio_fsk_ldpc, name="AUDIO_THREAD FSK LDPC",daemon=True)
audio_thread_fsk_ldpc.start()
audio_thread_fsk_ldpc0 = threading.Thread(target=self.audio_fsk_ldpc_0, name="AUDIO_THREAD FSK LDPC0",daemon=True)
audio_thread_fsk_ldpc0.start()
hamlib_thread = threading.Thread(target=self.update_rig_data, name="HAMLIB_THREAD",daemon=True)
hamlib_thread.start()
@ -273,7 +275,7 @@ class RF():
# avoid buffer overflow by filling only if buffer not full and selected datachannel mode
if not self.fsk_ldpc_buffer.nbuffer+length_x > self.fsk_ldpc_buffer.size:
if RECEIVE_FSK_LDPC:
#if RECEIVE_FSK_LDPC_0:
self.fsk_ldpc_buffer.push(x)
else:
static.BUFFER_OVERFLOW_COUNTER[2] += 1
@ -313,12 +315,17 @@ class RF():
# open codec2 instance
self.MODE = mode
freedv = cast(codec2.api.freedv_open(self.MODE), c_void_p)
if self.MODE == 'FSK_LDPC_0':
freedv = cast(codec2.api.freedv_open_advanced(codec2.api.FREEDV_MODE_FSK_LDPC, ctypes.byref(codec2.api.FREEDV_MODE_FSK_LDPC_0_ADV)), c_void_p)
else:
freedv = cast(codec2.api.freedv_open(self.MODE), c_void_p)
# get number of bytes per frame for mode
bytes_per_frame = int(codec2.api.freedv_get_bits_per_modem_frame(freedv)/8)
payload_bytes_per_frame = bytes_per_frame -2
print(bytes_per_frame)
# init buffer for data
n_tx_modem_samples = codec2.api.freedv_get_n_tx_modem_samples(freedv)
mod_out = create_string_buffer(n_tx_modem_samples * 2)
@ -452,7 +459,7 @@ class RF():
self.get_scatter(self.datac3_freedv)
self.calculate_snr(self.datac3_freedv)
def audio_fsk_ldpc(self):
def audio_fsk_ldpc_0(self):
""" """
nbytes_fsk_ldpc = 0
while self.audio_stream.is_active():
@ -554,9 +561,9 @@ class RF():
modem_stats_snr = c_float()
modem_stats_sync = c_int()
self.c_lib.freedv_get_modem_stats(freedv, byref(
modem_stats_sync), byref(modem_stats_snr))
self.c_lib.freedv_get_modem_stats(freedv, byref(modem_stats_sync), byref(modem_stats_snr))
modem_stats_snr = modem_stats_snr.value
modem_stats_sync = modem_stats_sync.value
try:
snr = round(modem_stats_snr, 1)