From a4eeea8a039d7a64e2357b6fe2dcc86ca2c49380 Mon Sep 17 00:00:00 2001 From: dj2ls Date: Sat, 15 Jan 2022 19:23:28 +0100 Subject: [PATCH] decode only if needed this should reduce cpu load when in idle state and reduce it also when sending in specific mode. This is not yet working for AUTO mode selection. #106 --- tnc/codec2.py | 12 +++++++++--- tnc/data_handler.py | 20 +++++++++++++++++++- tnc/modem.py | 22 +++++++++++----------- 3 files changed, 39 insertions(+), 15 deletions(-) diff --git a/tnc/codec2.py b/tnc/codec2.py index 38e2d1fc..237080e3 100644 --- a/tnc/codec2.py +++ b/tnc/codec2.py @@ -16,11 +16,17 @@ class FREEDV_MODE(Enum): datac0 = 14 datac1 = 10 datac3 = 12 - -def freedv_get_mode(mode): + allmodes = 255 + +# function for returning the mode value +def freedv_get_mode_value_by_name(mode): return FREEDV_MODE[mode].value - +# function for returning the mode name +def freedv_get_mode_name_by_value(mode): + return FREEDV_MODE(mode).name + + # check if we are running in a pyinstaller environment try: app_path = sys._MEIPASS diff --git a/tnc/data_handler.py b/tnc/data_handler.py index cbe1f68e..96df8f8f 100644 --- a/tnc/data_handler.py +++ b/tnc/data_handler.py @@ -714,7 +714,7 @@ class DATA(): connection_frame[1:2] = static.DXCALLSIGN_CRC8 connection_frame[2:3] = static.MYCALLSIGN_CRC8 connection_frame[3:9] = static.MYCALLSIGN - connection_frame[9:10] = bytes([0]) # ONE BYTE LEFT FOR OTHER THINGS + connection_frame[9:10] = bytes([mode]) connection_frame[10:12] = data_len.to_bytes(2, byteorder='big') connection_frame[12:13] = bytes([compression_factor]) connection_frame[13:14] = bytes([n_frames_per_burst]) @@ -761,6 +761,20 @@ class DATA(): static.TOTAL_BYTES = int.from_bytes(bytes(data_in[10:12]), "big") # kBytes static.ARQ_COMPRESSION_FACTOR = float(int.from_bytes(bytes(data_in[12:13]), "big") / 10) n_frames_per_burst = int.from_bytes(bytes(data_in[13:14]), "big") + mode = int.from_bytes(bytes(data_in[9:10]), "big") + + # set modes we want to listening to + mode_name = codec2.freedv_get_mode_name_by_value(mode) + if mode_name == 'datac1': + modem.RECEIVE_DATAC1 = True + elif mode_name == 'datac3': + modem.RECEIVE_DATAC3 = True + elif mode_name == 'allmodes': + modem.RECEIVE_DATAC1 = True + modem.RECEIVE_DATAC3 = True + + + #we need to find a way how to do this. this isn't working anymore since we mode to a class based module #modem.set_frames_per_burst(n_frames_per_burst) @@ -1027,6 +1041,10 @@ class DATA(): static.RX_FRAME_BUFFER = b'' self.burst_ack_snr= 255 + # reset modem receiving state to reduce cpu load + modem.RECEIVE_DATAC1 = False + modem.RECEIVE_DATAC3 = False + def arq_reset_ack(self,state:bool): self.burst_ack = state diff --git a/tnc/modem.py b/tnc/modem.py index 87710238..33e168c0 100644 --- a/tnc/modem.py +++ b/tnc/modem.py @@ -88,6 +88,10 @@ MODEM_RECEIVED_QUEUE = queue.Queue() MODEM_TRANSMIT_QUEUE = queue.Queue() static.TRANSMITTING = False +# receive only specific modes to reduce cpu load +RECEIVE_DATAC1 = False +RECEIVE_DATAC3 = False + class RF(): def __init__(self): @@ -217,14 +221,15 @@ class RF(): x = np.frombuffer(data_in48k, dtype=np.int16) x = self.resampler.resample48_to_8(x) - # avoid buffer overflow + + # avoid buffer overflow by filling only if buffer not full if not self.datac0_buffer.nbuffer+len(x) > self.datac0_buffer.size: self.datac0_buffer.push(x) - # avoid buffer overflow - if not self.datac1_buffer.nbuffer+len(x) > self.datac1_buffer.size: + # avoid buffer overflow by filling only if buffer not full and selected datachannel mode + if not self.datac1_buffer.nbuffer+len(x) > self.datac1_buffer.size and RECEIVE_DATAC1: self.datac1_buffer.push(x) - # avoid buffer overflow - if not self.datac3_buffer.nbuffer+len(x) > self.datac3_buffer.size: + # avoid buffer overflow by filling only if buffer not full and selected datachannel mode + if not self.datac3_buffer.nbuffer+len(x) > self.datac3_buffer.size and RECEIVE_DATAC3: self.datac3_buffer.push(x) @@ -245,7 +250,6 @@ class RF(): # toggle ptt early to save some time static.PTT_STATE = self.hamlib.set_ptt(True) # open codec2 instance - #self.MODE = codec2.freedv_get_mode_value_by_name(mode) self.MODE = mode freedv = cast(codec2.api.freedv_open(self.MODE), c_void_p) @@ -340,12 +344,10 @@ class RF(): threading.Event().set() def audio_datac0(self): - nbytes_datac0 = 0 - + nbytes_datac0 = 0 while self.audio_stream.is_active(): threading.Event().wait(0.01) while self.datac0_buffer.nbuffer >= self.datac0_nin: - # demodulate audio nbytes_datac0 = codec2.api.freedv_rawdatarx(self.datac0_freedv, self.datac0_bytes_out, self.datac0_buffer.buffer.ctypes) self.datac0_buffer.pop(self.datac0_nin) @@ -360,7 +362,6 @@ class RF(): while self.audio_stream.is_active(): threading.Event().wait(0.01) while self.datac1_buffer.nbuffer >= self.datac1_nin: - # demodulate audio nbytes_datac1 = codec2.api.freedv_rawdatarx(self.datac1_freedv, self.datac1_bytes_out, self.datac1_buffer.buffer.ctypes) self.datac1_buffer.pop(self.datac1_nin) @@ -375,7 +376,6 @@ class RF(): while self.audio_stream.is_active(): threading.Event().wait(0.01) while self.datac3_buffer.nbuffer >= self.datac3_nin: - # demodulate audio nbytes_datac3 = codec2.api.freedv_rawdatarx(self.datac3_freedv, self.datac3_bytes_out, self.datac3_buffer.buffer.ctypes) self.datac3_buffer.pop(self.datac3_nin)