diff --git a/tnc/codec2.py b/tnc/codec2.py index f578cac5..ad27a6c3 100644 --- a/tnc/codec2.py +++ b/tnc/codec2.py @@ -18,16 +18,19 @@ import structlog log = structlog.get_logger("codec2") + # Enum for codec2 modes class FREEDV_MODE(Enum): """ Enumeration for codec2 modes and names """ - sig0 = 14 - sig1 = 14 + sig0 = 19 + sig1 = 19 datac0 = 14 datac1 = 10 datac3 = 12 + datac4 = 18 + datac13 = 19 fsk_ldpc = 9 fsk_ldpc_0 = 200 fsk_ldpc_1 = 201 @@ -150,10 +153,15 @@ api.freedv_get_n_max_modem_samples.argtype = [ctypes.c_void_p] # type: ignore api.freedv_get_n_max_modem_samples.restype = ctypes.c_int api.FREEDV_FS_8000 = 8000 # type: ignore -api.FREEDV_MODE_DATAC1 = 10 # type: ignore -api.FREEDV_MODE_DATAC3 = 12 # type: ignore -api.FREEDV_MODE_DATAC0 = 14 # type: ignore -api.FREEDV_MODE_FSK_LDPC = 9 # type: ignore + +# TODO: do we need this code? Can we change it to just use Enum from above? +api.FREEDV_MODE_DATAC1 = FREEDV_MODE.datac1.value # type: ignore +api.FREEDV_MODE_DATAC3 = FREEDV_MODE.datac3.value # type: ignore +api.FREEDV_MODE_DATAC4 = FREEDV_MODE.datac4.value # type: ignore +# api.FREEDV_MODE_DATAC0 = FREEDV_MODE.datac0.value # type: ignore +api.FREEDV_MODE_DATAC13 = FREEDV_MODE.datac13.value # type: ignore + +api.FREEDV_MODE_FSK_LDPC = FREEDV_MODE.fsk_ldpc.value # type: ignore # -------------------------------- FSK LDPC MODE SETTINGS diff --git a/tnc/config.ini b/tnc/config.ini index 0f15a8df..d9c94013 100644 --- a/tnc/config.ini +++ b/tnc/config.ini @@ -4,20 +4,20 @@ tncport = 3000 [STATION] #station settings -mycall = DJ2LS-9 -mygrid = JN12AA +mycall = DN2LS-0 +mygrid = JN48cs ssid_list = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] [AUDIO] #audio settings rx = 0 -tx = 1 -txaudiolevel = 78 +tx = 0 +txaudiolevel = 250 auto_tune = False [RADIO] #radio settings -radiocontrol = rigctld +radiocontrol = disabled rigctld_ip = 127.0.0.1 rigctld_port = 4532 @@ -26,12 +26,12 @@ rigctld_port = 4532 scatter = True fft = True narrowband = False -fmin = -250.0 -fmax = 250.0 +fmin = -150.0 +fmax = 150.0 qrv = True rxbuffersize = 16 explorer = False stats = False fsk = False -tx_delay = 0 +tx_delay = 800 diff --git a/tnc/data_handler.py b/tnc/data_handler.py index 70411978..64d1ed5e 100644 --- a/tnc/data_handler.py +++ b/tnc/data_handler.py @@ -431,7 +431,7 @@ class DATA: def enqueue_frame_for_tx( self, frame_to_tx,# : list[bytearray], # this causes a crash on python 3.7 - c2_mode=FREEDV_MODE.datac0.value, + c2_mode=FREEDV_MODE.sig0.value, copies=1, repeat_delay=0, ) -> None: @@ -504,7 +504,7 @@ class DATA: # Transmit frame if transmit: - self.enqueue_frame_for_tx([ident_frame], c2_mode=FREEDV_MODE.datac0.value) + self.enqueue_frame_for_tx([ident_frame], c2_mode=FREEDV_MODE.sig0.value) else: return ident_frame @@ -1685,7 +1685,7 @@ class DATA: dxcallsign=str(self.dxcallsign, 'UTF-8'), ) - self.enqueue_frame_for_tx([connection_frame], c2_mode=FREEDV_MODE.datac0.value, copies=1, repeat_delay=0) + self.enqueue_frame_for_tx([connection_frame], c2_mode=FREEDV_MODE.sig0.value, copies=1, repeat_delay=0) # Wait for a time, looking to see if `static.ARQ_SESSION` # indicates we've received a positive response from the far station. @@ -1877,7 +1877,7 @@ class DATA: dxcallsign=str(self.dxcallsign, 'UTF-8'), ) - self.enqueue_frame_for_tx([connection_frame], c2_mode=FREEDV_MODE.datac0.value, copies=1, repeat_delay=0) + self.enqueue_frame_for_tx([connection_frame], c2_mode=FREEDV_MODE.sig0.value, copies=1, repeat_delay=0) def received_session_heartbeat(self, data_in: bytes) -> None: """ @@ -2076,7 +2076,7 @@ class DATA: while static.CHANNEL_BUSY and time.time() < channel_busy_timeout: threading.Event().wait(0.01) - self.enqueue_frame_for_tx([connection_frame], c2_mode=FREEDV_MODE.datac0.value, copies=1, repeat_delay=0) + self.enqueue_frame_for_tx([connection_frame], c2_mode=FREEDV_MODE.sig0.value, copies=1, repeat_delay=0) timeout = time.time() + 3 + (static.TX_DELAY/1000 * 2) while time.time() < timeout: @@ -2284,7 +2284,7 @@ class DATA: connection_frame[8:9] = bytes([self.speed_level]) connection_frame[13:14] = bytes([static.ARQ_PROTOCOL_VERSION]) - self.enqueue_frame_for_tx([connection_frame], c2_mode=FREEDV_MODE.datac0.value, copies=1, repeat_delay=0) + self.enqueue_frame_for_tx([connection_frame], c2_mode=FREEDV_MODE.sig0.value, copies=1, repeat_delay=0) self.send_data_to_socket_queue( freedata="tnc-message", @@ -2429,7 +2429,7 @@ class DATA: self.log.info("[TNC] ENABLE FSK", state=static.ENABLE_FSK) self.enqueue_frame_for_tx([ping_frame], c2_mode=FREEDV_MODE.fsk_ldpc_0.value) else: - self.enqueue_frame_for_tx([ping_frame], c2_mode=FREEDV_MODE.datac0.value) + self.enqueue_frame_for_tx([ping_frame], c2_mode=FREEDV_MODE.sig0.value) def received_ping(self, data_in: bytes) -> None: """ @@ -2499,7 +2499,7 @@ class DATA: if static.ENABLE_FSK: self.enqueue_frame_for_tx([ping_frame], c2_mode=FREEDV_MODE.fsk_ldpc_0.value) else: - self.enqueue_frame_for_tx([ping_frame], c2_mode=FREEDV_MODE.datac0.value) + self.enqueue_frame_for_tx([ping_frame], c2_mode=FREEDV_MODE.sig0.value) def received_ping_ack(self, data_in: bytes) -> None: """ @@ -2650,7 +2650,7 @@ class DATA: c2_mode=FREEDV_MODE.fsk_ldpc_0.value, ) else: - self.enqueue_frame_for_tx([beacon_frame], c2_mode=FREEDV_MODE.datac0.value, copies=1, + self.enqueue_frame_for_tx([beacon_frame], c2_mode=FREEDV_MODE.sig0.value, copies=1, repeat_delay=0) interval_timer = time.time() + self.beacon_interval @@ -2728,7 +2728,7 @@ class DATA: self.log.info("[TNC] ENABLE FSK", state=static.ENABLE_FSK) self.enqueue_frame_for_tx([cq_frame], c2_mode=FREEDV_MODE.fsk_ldpc_0.value) else: - self.enqueue_frame_for_tx([cq_frame], c2_mode=FREEDV_MODE.datac0.value, copies=1, repeat_delay=0) + self.enqueue_frame_for_tx([cq_frame], c2_mode=FREEDV_MODE.sig0.value, copies=1, repeat_delay=0) def received_cq(self, data_in: bytes) -> None: """ @@ -2801,7 +2801,7 @@ class DATA: self.log.info("[TNC] ENABLE FSK", state=static.ENABLE_FSK) self.enqueue_frame_for_tx([qrv_frame], c2_mode=FREEDV_MODE.fsk_ldpc_0.value) else: - self.enqueue_frame_for_tx([qrv_frame], c2_mode=FREEDV_MODE.datac0.value, copies=1, repeat_delay=0) + self.enqueue_frame_for_tx([qrv_frame], c2_mode=FREEDV_MODE.sig0.value, copies=1, repeat_delay=0) def received_qrv(self, data_in: bytes) -> None: """ @@ -3300,7 +3300,7 @@ class DATA: # otherwise burst will be dropped if not static.CHANNEL_BUSY and not static.TRANSMITTING: self.enqueue_frame_for_tx( - frame_to_tx=[fec_frame], c2_mode=codec2.FREEDV_MODE["datac0"].value + frame_to_tx=[fec_frame], c2_mode=codec2.FREEDV_MODE["sig0"].value ) else: return False diff --git a/tnc/modem.py b/tnc/modem.py index 996bcd1b..4137dc5b 100644 --- a/tnc/modem.py +++ b/tnc/modem.py @@ -40,12 +40,20 @@ RECEIVE_SIG0 = True RECEIVE_SIG1 = False RECEIVE_DATAC1 = False RECEIVE_DATAC3 = False +RECEIVE_DATAC4 = False + # state buffer -SIG0_DATAC0_STATE = [] -SIG1_DATAC0_STATE = [] +# TODO: Remove datac0 +#SIG0_DATAC0_STATE = [] +#SIG1_DATAC0_STATE = [] + +SIG0_DATAC13_STATE = [] +SIG1_DATAC13_STATE = [] DAT0_DATAC1_STATE = [] DAT0_DATAC3_STATE = [] +DAT0_DATAC4_STATE = [] + FSK_LDPC0_STATE = [] FSK_LDPC1_STATE = [] @@ -100,6 +108,7 @@ class RF: # DATAC0 # SIGNALLING MODE 0 - Used for Connecting - Payload 14 Bytes + """ self.sig0_datac0_freedv, \ self.sig0_datac0_bytes_per_frame, \ self.sig0_datac0_bytes_out, \ @@ -115,6 +124,26 @@ class RF: self.sig1_datac0_buffer, \ self.sig1_datac0_nin = \ self.init_codec2_mode(codec2.api.FREEDV_MODE_DATAC0, None) + """ + + + # DATAC13 + # SIGNALLING MODE 0 - Used for Connecting - Payload 14 Bytes + self.sig0_datac13_freedv, \ + self.sig0_datac13_bytes_per_frame, \ + self.sig0_datac13_bytes_out, \ + self.sig0_datac13_buffer, \ + self.sig0_datac13_nin = \ + self.init_codec2_mode(codec2.api.FREEDV_MODE_DATAC13, None) + + # DATAC13 + # SIGNALLING MODE 1 - Used for ACK/NACK - Payload 5 Bytes + self.sig1_datac13_freedv, \ + self.sig1_datac13_bytes_per_frame, \ + self.sig1_datac13_bytes_out, \ + self.sig1_datac13_buffer, \ + self.sig1_datac13_nin = \ + self.init_codec2_mode(codec2.api.FREEDV_MODE_DATAC13, None) # DATAC1 self.dat0_datac1_freedv, \ @@ -132,6 +161,15 @@ class RF: self.dat0_datac3_nin = \ self.init_codec2_mode(codec2.api.FREEDV_MODE_DATAC3, None) + # DATAC4 + self.dat0_datac4_freedv, \ + self.dat0_datac4_bytes_per_frame, \ + self.dat0_datac4_bytes_out, \ + self.dat0_datac4_buffer, \ + self.dat0_datac4_nin = \ + self.init_codec2_mode(codec2.api.FREEDV_MODE_DATAC4, None) + + # FSK LDPC - 0 self.fsk_ldpc_freedv_0, \ self.fsk_ldpc_bytes_per_frame_0, \ @@ -155,9 +193,13 @@ class RF: ) # INIT TX MODES - self.freedv_datac0_tx = open_codec2_instance(14) - self.freedv_datac1_tx = open_codec2_instance(10) - self.freedv_datac3_tx = open_codec2_instance(12) + # TODO: Use enum from codec2 + self.freedv_datac0_tx = open_codec2_instance(codec2.FREEDV_MODE.datac0.value) + self.freedv_datac1_tx = open_codec2_instance(codec2.FREEDV_MODE.datac1.value) + self.freedv_datac3_tx = open_codec2_instance(codec2.FREEDV_MODE.datac3.value) + self.freedv_datac4_tx = open_codec2_instance(codec2.FREEDV_MODE.datac4.value) + self.freedv_datac13_tx = open_codec2_instance(codec2.FREEDV_MODE.datac13.value) + self.freedv_ldpc0_tx = open_codec2_instance(200) self.freedv_ldpc1_tx = open_codec2_instance(201) # --------------------------------------------CREATE PYAUDIO INSTANCE @@ -179,7 +221,7 @@ class RF: try: self.log.debug("[MDM] init: starting pyaudio callback") - # self.audio_stream.start_stream() + # self.audio_stream.start_stream( self.stream.start() except Exception as err: self.log.error("[MDM] init: starting pyaudio callback failed", e=err) @@ -288,12 +330,12 @@ class RF: else: audio_thread_sig0_datac0 = threading.Thread( - target=self.audio_sig0_datac0, name="AUDIO_THREAD DATAC0 - 0", daemon=True + target=self.audio_sig0_datac13, name="AUDIO_THREAD DATAC13 - 0", daemon=True ) audio_thread_sig0_datac0.start() audio_thread_sig1_datac0 = threading.Thread( - target=self.audio_sig1_datac0, name="AUDIO_THREAD DATAC0 - 1", daemon=True + target=self.audio_sig1_datac13, name="AUDIO_THREAD DATAC13 - 1", daemon=True ) audio_thread_sig1_datac0.start() @@ -368,6 +410,7 @@ class RF: (self.sig1_datac0_buffer, RECEIVE_SIG1), (self.dat0_datac1_buffer, RECEIVE_DATAC1), (self.dat0_datac3_buffer, RECEIVE_DATAC3), + (self.dat0_datac4_buffer, RECEIVE_DATAC4), (self.fsk_ldpc_buffer_0, static.ENABLE_FSK), (self.fsk_ldpc_buffer_1, static.ENABLE_FSK), ]: @@ -401,6 +444,7 @@ class RF: (self.sig1_datac0_buffer, RECEIVE_SIG1), (self.dat0_datac1_buffer, RECEIVE_DATAC1), (self.dat0_datac3_buffer, RECEIVE_DATAC3), + (self.dat0_datac4_buffer, RECEIVE_DATAC4), (self.fsk_ldpc_buffer_0, static.ENABLE_FSK), (self.fsk_ldpc_buffer_1, static.ENABLE_FSK), ]: @@ -454,12 +498,13 @@ class RF: # Avoid buffer overflow by filling only if buffer for # selected datachannel mode is not full for audiobuffer, receive, index in [ - (self.sig0_datac0_buffer, RECEIVE_SIG0, 0), - (self.sig1_datac0_buffer, RECEIVE_SIG1, 1), + (self.sig0_datac13_buffer, RECEIVE_SIG0, 0), + (self.sig1_datac13_buffer, RECEIVE_SIG1, 1), (self.dat0_datac1_buffer, RECEIVE_DATAC1, 2), (self.dat0_datac3_buffer, RECEIVE_DATAC3, 3), - (self.fsk_ldpc_buffer_0, static.ENABLE_FSK, 4), - (self.fsk_ldpc_buffer_1, static.ENABLE_FSK, 5), + (self.dat0_datac4_buffer, RECEIVE_DATAC4, 4), + (self.fsk_ldpc_buffer_0, static.ENABLE_FSK, 5), + (self.fsk_ldpc_buffer_1, static.ENABLE_FSK, 6), ]: if (audiobuffer.nbuffer + length_x) > audiobuffer.size: static.BUFFER_OVERFLOW_COUNTER[index] += 1 @@ -513,15 +558,19 @@ class RF: fsk_ldpc_0 = 200 fsk_ldpc_1 = 201 """ - if mode == 14: + if mode == codec2.FREEDV_MODE.datac0.value: freedv = self.freedv_datac0_tx - elif mode == 10: + elif mode == codec2.FREEDV_MODE.datac1.value: freedv = self.freedv_datac1_tx - elif mode == 12: + elif mode == codec2.FREEDV_MODE.datac3.value: freedv = self.freedv_datac3_tx - elif mode == 200: + elif mode == codec2.FREEDV_MODE.datac4.value: + freedv = self.freedv_datac4_tx + elif mode == codec2.FREEDV_MODE.datac13.value: + freedv = self.freedv_datac13_tx + elif mode == codec2.FREEDV_MODE.fsk_ldpc_0.value: freedv = self.freedv_ldpc0_tx - elif mode == 201: + elif mode == codec2.FREEDV_MODE.fsk_ldpc_1.value: freedv = self.freedv_ldpc1_tx else: return False @@ -884,28 +933,66 @@ class RF: # return values return c2instance, bytes_per_frame, bytes_out, audio_buffer, nin - def audio_sig0_datac0(self) -> None: - """Receive data encoded with datac0 - 0""" - self.sig0_datac0_nin = self.demodulate_audio( - self.sig0_datac0_buffer, - self.sig0_datac0_nin, - self.sig0_datac0_freedv, - self.sig0_datac0_bytes_out, - self.sig0_datac0_bytes_per_frame, - SIG0_DATAC0_STATE, - "sig0-datac0" + # TODO: Remove datac0 + # def audio_sig0_datac0(self) -> None: + # """Receive data encoded with datac0 - 0""" + # self.sig0_datac0_nin = self.demodulate_audio( + # self.sig0_datac0_buffer, + # self.sig0_datac0_nin, + # self.sig0_datac0_freedv, + # self.sig0_datac0_bytes_out, + # self.sig0_datac0_bytes_per_frame, + # SIG0_DATAC0_STATE, + # "sig0-datac0" + # ) + + # def audio_sig1_datac0(self) -> None: + # """Receive data encoded with datac0 - 1""" + # self.sig1_datac0_nin = self.demodulate_audio( + # self.sig1_datac0_buffer, + # self.sig1_datac0_nin, + # self.sig1_datac0_freedv, + # self.sig1_datac0_bytes_out, + # self.sig1_datac0_bytes_per_frame, + # SIG1_DATAC0_STATE, + # "sig1-datac0" + # ) + + + def audio_sig0_datac13(self) -> None: + """Receive data encoded with datac13 - 0""" + self.sig0_datac13_nin = self.demodulate_audio( + self.sig0_datac13_buffer, + self.sig0_datac13_nin, + self.sig0_datac13_freedv, + self.sig0_datac13_bytes_out, + self.sig0_datac13_bytes_per_frame, + SIG0_DATAC13_STATE, + "sig0-datac13" ) - def audio_sig1_datac0(self) -> None: - """Receive data encoded with datac0 - 1""" - self.sig1_datac0_nin = self.demodulate_audio( - self.sig1_datac0_buffer, - self.sig1_datac0_nin, - self.sig1_datac0_freedv, - self.sig1_datac0_bytes_out, - self.sig1_datac0_bytes_per_frame, - SIG1_DATAC0_STATE, - "sig1-datac0" + def audio_sig1_datac13(self) -> None: + """Receive data encoded with datac13 - 1""" + self.sig1_datac13_nin = self.demodulate_audio( + self.sig1_datac13_buffer, + self.sig1_datac13_nin, + self.sig1_datac13_freedv, + self.sig1_datac13_bytes_out, + self.sig1_datac13_bytes_per_frame, + SIG1_DATAC13_STATE, + "sig1-datac13" + ) + + def audio_dat0_datac4(self) -> None: + """Receive data encoded with datac4""" + self.dat0_datac4_nin = self.demodulate_audio( + self.dat0_datac4_buffer, + self.dat0_datac4_nin, + self.dat0_datac4_freedv, + self.dat0_datac4_bytes_out, + self.dat0_datac4_bytes_per_frame, + DAT0_DATAC4_STATE, + "dat0-datac4" ) def audio_dat0_datac1(self) -> None: @@ -1234,6 +1321,7 @@ class RF: codec2.api.freedv_set_frames_per_burst(self.dat0_datac1_freedv, frames_per_burst) codec2.api.freedv_set_frames_per_burst(self.dat0_datac3_freedv, frames_per_burst) + codec2.api.freedv_set_frames_per_burst(self.dat0_datac4_freedv, frames_per_burst) codec2.api.freedv_set_frames_per_burst(self.fsk_ldpc_freedv_0, frames_per_burst) @@ -1320,5 +1408,8 @@ def get_modem_error_state(): if RECEIVE_DATAC3 and 10 in DAT0_DATAC3_STATE: DAT0_DATAC3_STATE.clear() return True + if RECEIVE_DATAC4 and 10 in DAT0_DATAC4_STATE: + DAT0_DATAC4_STATE.clear() + return True - return False \ No newline at end of file + return False