diff --git a/tnc/modem.py b/tnc/modem.py index 6fa4b40a..f8c539b6 100644 --- a/tnc/modem.py +++ b/tnc/modem.py @@ -47,7 +47,6 @@ DAT0_DATAC1_STATE = [] DAT0_DATAC3_STATE = [] - class RF: """Class to encapsulate interactions between the audio device and codec2""" @@ -69,7 +68,6 @@ class RF: self.AUDIO_CHANNELS = 1 self.MODE = 0 - # Locking state for mod out so buffer will be filled before we can use it # https://github.com/DJ2LS/FreeDATA/issues/127 # https://github.com/DJ2LS/FreeDATA/issues/99 @@ -112,7 +110,6 @@ class RF: self.sig1_datac0_nin = \ self.init_codec2_mode(codec2.api.FREEDV_MODE_DATAC0, None) - # DATAC1 self.dat0_datac1_freedv, \ self.dat0_datac1_bytes_per_frame, \ @@ -285,8 +282,6 @@ class RF: ) hamlib_set_thread.start() - - # self.log.debug("[MDM] Starting worker_receive") worker_received = threading.Thread( target=self.worker_received, name="WORKER_THREAD", daemon=True @@ -328,8 +323,8 @@ class RF: # (self.fsk_ldpc_buffer_1, static.ENABLE_FSK), ]: if ( - not (data_buffer.nbuffer + length_x) > data_buffer.size - and receive + not (data_buffer.nbuffer + length_x) > data_buffer.size + and receive ): data_buffer.push(x) @@ -367,7 +362,7 @@ class RF: # audio recording for debugging purposes if static.AUDIO_RECORD: - #static.AUDIO_RECORD_FILE.write(x) + # static.AUDIO_RECORD_FILE.write(x) static.AUDIO_RECORD_FILE.writeframes(x) # Avoid decoding when transmitting to reduce CPU @@ -415,7 +410,7 @@ class RF: # -------------------------------------------------------------------- def transmit( - self, mode, repeats: int, repeat_delay: int, frames: bytearray + self, mode, repeats: int, repeat_delay: int, frames: bytearray ) -> None: """ @@ -484,10 +479,10 @@ class RF: ) # Add empty data to handle ptt toggle time - #data_delay_mseconds = 0 # milliseconds - #data_delay = int(self.MODEM_SAMPLE_RATE * (data_delay_mseconds / 1000)) # type: ignore - #mod_out_silence = ctypes.create_string_buffer(data_delay * 2) - #txbuffer = bytes(mod_out_silence) + # data_delay_mseconds = 0 # milliseconds + # data_delay = int(self.MODEM_SAMPLE_RATE * (data_delay_mseconds / 1000)) # type: ignore + # mod_out_silence = ctypes.create_string_buffer(data_delay * 2) + # txbuffer = bytes(mod_out_silence) # TODO: Disabled this one for testing txbuffer = bytes() self.log.debug( @@ -561,7 +556,7 @@ class RF: # ------------------------------- chunk_length = self.AUDIO_FRAMES_PER_BUFFER_TX # 4800 chunk = [ - txbuffer_48k[i : i + chunk_length] + txbuffer_48k[i: i + chunk_length] for i in range(0, len(txbuffer_48k), chunk_length) ] for c in chunk: @@ -601,14 +596,14 @@ class RF: self.log.debug("[MDM] ON AIR TIME", time=transmission_time) def demodulate_audio( - self, - audiobuffer: codec2.audio_buffer, - nin: int, - freedv: ctypes.c_void_p, - bytes_out, - bytes_per_frame, - state_buffer, - mode_name, + self, + audiobuffer: codec2.audio_buffer, + nin: int, + freedv: ctypes.c_void_p, + bytes_out, + bytes_per_frame, + state_buffer, + mode_name, ) -> int: """ De-modulate supplied audio stream with supplied codec2 instance. @@ -654,7 +649,8 @@ class RF: static.IS_CODEC2_TRAFFIC = True self.log.debug( - "[MDM] [demod_audio] modem state", mode=mode_name, rx_status=rx_status, sync_flag=codec2.api.rx_sync_flags_to_text[rx_status] + "[MDM] [demod_audio] modem state", mode=mode_name, rx_status=rx_status, + sync_flag=codec2.api.rx_sync_flags_to_text[rx_status] ) else: static.IS_CODEC2_TRAFFIC = False @@ -662,8 +658,6 @@ class RF: if rx_status == 10: state_buffer.append(rx_status) - - audiobuffer.pop(nin) nin = codec2.api.freedv_nin(freedv) if nbytes == bytes_per_frame: @@ -885,7 +879,7 @@ class RF: scatterdata = [] # original function before itertool - #for i in range(codec2.MODEM_STATS_NC_MAX): + # for i in range(codec2.MODEM_STATS_NC_MAX): # for j in range(1, codec2.MODEM_STATS_NR_MAX, 2): # # print(f"{modemStats.rx_symbols[i][j]} - {modemStats.rx_symbols[i][j]}") # xsymbols = round(modemStats.rx_symbols[i][j - 1] // 1000) @@ -931,9 +925,9 @@ class RF: snr = round(modem_stats_snr, 1) self.log.info("[MDM] calculate_snr: ", snr=snr) static.SNR = snr - #static.SNR = np.clip( + # static.SNR = np.clip( # snr, -127, 127 - #) # limit to max value of -128/128 as a possible fix of #188 + # ) # limit to max value of -128/128 as a possible fix of #188 return static.SNR except Exception as err: self.log.error(f"[MDM] calculate_snr: Exception: {err}") @@ -963,15 +957,24 @@ class RF: - static.HAMLIB_BANDWIDTH """ while True: + # this looks weird, but is necessary for avoiding rigctld packet colission sock threading.Event().wait(0.25) static.HAMLIB_FREQUENCY = self.hamlib.get_frequency() + threading.Event().wait(0.1) static.HAMLIB_MODE = self.hamlib.get_mode() + threading.Event().wait(0.1) static.HAMLIB_BANDWIDTH = self.hamlib.get_bandwidth() + threading.Event().wait(0.1) static.HAMLIB_STATUS = self.hamlib.get_status() + threading.Event().wait(0.1) static.HAMLIB_ALC = self.hamlib.get_alc() + threading.Event().wait(0.1) static.HAMLIB_RF = self.hamlib.get_level() + threading.Event().wait(0.1) static.HAMLIB_STRENGTH = self.hamlib.get_strength() + print(f"ALC: {static.HAMLIB_ALC}, RF: {static.HAMLIB_RF}, STRENGTH: {static.HAMLIB_STRENGTH}") + def calculate_fft(self) -> None: """ Calculate an average signal strength of the channel to assess @@ -1178,4 +1181,4 @@ def get_modem_error_state(): DAT0_DATAC3_STATE.clear() return True - return False + return False \ No newline at end of file diff --git a/tnc/rigctld.py b/tnc/rigctld.py index 0daf3700..27cea704 100644 --- a/tnc/rigctld.py +++ b/tnc/rigctld.py @@ -39,17 +39,17 @@ class radio: self.rf = '' def open_rig( - self, - devicename, - deviceport, - hamlib_ptt_type, - serialspeed, - pttport, - data_bits, - stop_bits, - handshake, - rigctld_ip, - rigctld_port, + self, + devicename, + deviceport, + hamlib_ptt_type, + serialspeed, + pttport, + data_bits, + stop_bits, + handshake, + rigctld_ip, + rigctld_port, ): """ @@ -71,8 +71,8 @@ class radio: self.hostname = rigctld_ip self.port = int(rigctld_port) - #_ptt_connect = self.ptt_connect() - #_data_connect = self.data_connect() + # _ptt_connect = self.ptt_connect() + # _data_connect = self.data_connect() ptt_thread = threading.Thread(target=self.ptt_connect, args=[], daemon=True) ptt_thread.start() @@ -173,8 +173,12 @@ class radio: """ if self.data_connected: + self.data_connection.setblocking(False) + self.data_connection.settimeout(0.05) try: self.data_connection.sendall(command + b"\n") + + except Exception: self.log.warning( "[RIGCTLD] Command not executed!", @@ -187,7 +191,20 @@ class radio: try: # recv seems to be blocking so in case of ptt we don't need the response # maybe this speeds things up and avoids blocking states - return self.data_connection.recv(64) if expect_answer else True + recv = True + data = b'' + + while recv: + try: + + data = self.data_connection.recv(64) + + except socket.timeout: + recv = False + + return data + + # return self.data_connection.recv(64) if expect_answer else True except Exception: self.log.warning( "[RIGCTLD] No command response!", @@ -209,7 +226,7 @@ class radio: rf = data[0].decode("utf-8") if 'RPRT' not in rf: try: - self.rf = int(rf) + self.rf = str(rf) except ValueError: self.rf = str(rf) @@ -239,7 +256,7 @@ class radio: alc = data[0].decode("utf-8") if 'RPRT' not in alc: try: - self.alc = int(alc) + self.alc = float(alc) except ValueError: self.alc = str(alc)