From 6ad66452c72175a08343f311a25a2b1bfcb77229 Mon Sep 17 00:00:00 2001 From: DJ2LS <75909252+DJ2LS@users.noreply.github.com> Date: Wed, 10 Feb 2021 15:05:41 +0100 Subject: [PATCH] Delete modem.py --- modem.py | 355 ------------------------------------------------------- 1 file changed, 355 deletions(-) delete mode 100644 modem.py diff --git a/modem.py b/modem.py deleted file mode 100644 index 71191378..00000000 --- a/modem.py +++ /dev/null @@ -1,355 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -""" -Created on Wed Dec 23 07:04:24 2020 - -@author: DJ2LS -""" - -import ctypes -from ctypes import * -import pathlib -import pyaudio -import sys -import logging -import time -import threading - -import helpers -import static -import arq - - - - - - -class RF(): - - def __init__(self): - #-------------------------------------------- LOAD FREEDV - libname = pathlib.Path().absolute() / "codec2/build_linux/src/libcodec2.so" - self.c_lib = ctypes.CDLL(libname) - #--------------------------------------------CREATE PYAUDIO INSTANCE - self.p = pyaudio.PyAudio() - #--------------------------------------------GET SUPPORTED SAMPLE RATES FROM SOUND DEVICE - #static.AUDIO_SAMPLE_RATE_RX = int(self.p.get_device_info_by_index(static.AUDIO_INPUT_DEVICE)['defaultSampleRate']) - #static.AUDIO_SAMPLE_RATE_TX = int(self.p.get_device_info_by_index(static.AUDIO_OUTPUT_DEVICE)['defaultSampleRate']) - static.AUDIO_SAMPLE_RATE_TX = 8000 - static.AUDIO_SAMPLE_RATE_RX = 8000 - #--------------------------------------------OPEN AUDIO CHANNEL RX - self.stream_rx = self.p.open(format=pyaudio.paInt16, - channels=static.AUDIO_CHANNELS, - rate=static.AUDIO_SAMPLE_RATE_RX, - frames_per_buffer=static.AUDIO_FRAMES_PER_BUFFER, - input=True, - input_device_index=static.AUDIO_INPUT_DEVICE, - ) - #--------------------------------------------OPEN AUDIO CHANNEL TX - self.stream_tx = self.p.open(format=pyaudio.paInt16, - channels=1, - rate=static.AUDIO_SAMPLE_RATE_TX, - frames_per_buffer=static.AUDIO_FRAMES_PER_BUFFER, #n_nom_modem_samples - output=True, - output_device_index=static.AUDIO_OUTPUT_DEVICE, #static.AUDIO_OUTPUT_DEVICE - ) - #--------------------------------------------START DECODER THREAD - FREEDV_DECODER_THREAD = threading.Thread(target=self.receive, args=[static.FREEDV_DATA_MODE,static.FREEDV_SIGNALLING_MODE], name="FREEDV_DECODER_THREAD") - FREEDV_DECODER_THREAD.start() - -#-------------------------------------------------------------------------------------------------------- - def transmit_arq_ack(self,ack_buffer): - #print(ack_buffer) - static.ARQ_STATE = 'SENDING_ACK' - - self.c_lib.freedv_open.restype = ctypes.POINTER(ctypes.c_ubyte) - freedv = self.c_lib.freedv_open(static.FREEDV_SIGNALLING_MODE) - bytes_per_frame = int(self.c_lib.freedv_get_bits_per_modem_frame(freedv)/8) - payload_per_frame = bytes_per_frame -2 - n_nom_modem_samples = self.c_lib.freedv_get_n_nom_modem_samples(freedv) - n_tx_modem_samples = self.c_lib.freedv_get_n_tx_modem_samples(freedv)*2 #get n_tx_modem_samples which defines the size of the modulation object - - mod_out = ctypes.c_short * n_tx_modem_samples - mod_out = mod_out() - mod_out_preamble = ctypes.c_short * (1760*2) #1760 for mode 10,11,12 #4000 for mode 9 - mod_out_preamble = mod_out_preamble() - - buffer = bytearray(payload_per_frame) # use this if CRC16 checksum is required ( DATA1-3) - buffer[:len(ack_buffer)] = ack_buffer # set buffersize to length of data which will be send - - crc = ctypes.c_ushort(self.c_lib.freedv_gen_crc16(bytes(buffer), payload_per_frame)) # generate CRC16 - crc = crc.value.to_bytes(2, byteorder='big') # convert crc to 2 byte hex string - buffer += crc # append crc16 to buffer - data = (ctypes.c_ubyte * bytes_per_frame).from_buffer_copy(buffer) - - preamble_bytes = self.c_lib.freedv_rawdatapreambletx(freedv, mod_out_preamble) - self.c_lib.freedv_rawdatatx(freedv,mod_out,data) # modulate DATA and safe it into mod_out pointer - txbuffer = bytearray() - txbuffer += bytes(mod_out_preamble) - txbuffer = txbuffer.rstrip(b'\x00') #lets remove unallocated memory because of wrong buffer :-/ - txbuffer += bytes(mod_out) - txbuffer = txbuffer.rstrip(b'\x00') #lets remove unallocated memory because of wrong buffer :-/ - - # -------------- transmit audio twice - - print("SEND SIGNALLING FRAME...................................") - print(ack_buffer) - self.stream_tx.write(bytes(txbuffer)) - print("........................................................") - self.stream_tx.write(bytes(txbuffer)) - - print("...................................DONE!") - - static.ARQ_STATE = 'RECEIVING_DATA' -#-------------------------------------------------------------------------------------------------------- - # GET ARQ BURST FRAME VOM BUFFER AND MODULATE IT - def transmit_arq_burst(self): - static.ARQ_STATE = 'SENDING_DATA' - - self.c_lib.freedv_open.restype = ctypes.POINTER(ctypes.c_ubyte) - freedv = self.c_lib.freedv_open(static.FREEDV_DATA_MODE) - static.FREEDV_DATA_BYTES_PER_FRAME = int(self.c_lib.freedv_get_bits_per_modem_frame(freedv)/8) - static.FREEDV_DATA_PAYLOAD_PER_FRAME = static.FREEDV_DATA_BYTES_PER_FRAME -2 - - n_nom_modem_samples = self.c_lib.freedv_get_n_nom_modem_samples(freedv) - n_tx_modem_samples = self.c_lib.freedv_get_n_tx_modem_samples(freedv)*2 #get n_tx_modem_samples which defines the size of the modulation object - - mod_out = ctypes.c_short * n_tx_modem_samples - mod_out = mod_out() - mod_out_preamble = ctypes.c_short * (n_tx_modem_samples*2) #1760 for mode 10,11,12 #4000 for mode 9 - mod_out_preamble = mod_out_preamble() - - self.c_lib.freedv_rawdatapreambletx(freedv, mod_out_preamble); - txbuffer = bytearray() - txbuffer += bytes(mod_out_preamble) - txbuffer = txbuffer.rstrip(b'\x00') #lets remove unallocated memory because of wrong buffer :-/ - - if static.ARQ_RPT_RECEIVED == False: - for n in range(0,static.ARQ_TX_N_FRAMES_PER_BURST): - - #---------------------------BUILD ARQ BURST --------------------------------------------------------------------- - frame_type = 10 + n + 1 #static.ARQ_TX_N_FRAMES_PER_BURST - frame_type = bytes([frame_type]) - - payload_data = bytes(static.TX_BUFFER[static.ARQ_N_SENT_FRAMES + n]) - - n_current_arq_frame = static.ARQ_N_SENT_FRAMES + n + 1 - static.ARQ_TX_N_CURRENT_ARQ_FRAME = n_current_arq_frame.to_bytes(2, byteorder='big') - - n_total_arq_frame = len(static.TX_BUFFER) - static.ARQ_TX_N_TOTAL_ARQ_FRAMES = n_total_arq_frame.to_bytes(2, byteorder='big') - - arqframe = frame_type + \ - bytes([static.ARQ_TX_N_FRAMES_PER_BURST]) + \ - static.ARQ_TX_N_CURRENT_ARQ_FRAME + \ - static.ARQ_TX_N_TOTAL_ARQ_FRAMES + \ - static.DXCALLSIGN_CRC8 + \ - static.MYCALLSIGN_CRC8 + \ - payload_data - - #print(arqframe) - - buffer = bytearray(static.FREEDV_DATA_PAYLOAD_PER_FRAME) # create TX buffer - buffer[:len(arqframe)] = arqframe # set buffersize to length of data which will be send - - crc = ctypes.c_ushort(self.c_lib.freedv_gen_crc16(bytes(buffer), static.FREEDV_DATA_PAYLOAD_PER_FRAME)) # generate CRC16 - crc = crc.value.to_bytes(2, byteorder='big') # convert crc to 2 byte hex string - buffer += crc # append crc16 to buffer - - data = (ctypes.c_ubyte * static.FREEDV_DATA_BYTES_PER_FRAME).from_buffer_copy(buffer) - self.c_lib.freedv_rawdatatx(freedv,mod_out,data) # modulate DATA and safe it into mod_out pointer - txbuffer += bytes(mod_out) - txbuffer = txbuffer.rstrip(b'\x00') #lets remove unallocated memory because of wrong buffer :-/ - - elif static.ARQ_RPT_RECEIVED == True: - - for n in range(0,len(static.ARQ_RPT_FRAMES)): - - missing_frame = int.from_bytes(static.ARQ_RPT_FRAMES[n], "big") - - #---------------------------BUILD ARQ BURST --------------------------------------------------------------------- - frame_type = 10 + missing_frame #static.ARQ_TX_N_FRAMES_PER_BURST - frame_type = bytes([frame_type]) - - payload_data = bytes(static.TX_BUFFER[static.ARQ_N_SENT_FRAMES + missing_frame - 1]) - - n_current_arq_frame = static.ARQ_N_SENT_FRAMES + missing_frame - static.ARQ_TX_N_CURRENT_ARQ_FRAME = n_current_arq_frame.to_bytes(2, byteorder='big') - - n_total_arq_frame = len(static.TX_BUFFER) - static.ARQ_TX_N_TOTAL_ARQ_FRAMES = n_total_arq_frame.to_bytes(2, byteorder='big') - - arqframe = frame_type + \ - bytes([static.ARQ_TX_N_FRAMES_PER_BURST]) + \ - static.ARQ_TX_N_CURRENT_ARQ_FRAME + \ - static.ARQ_TX_N_TOTAL_ARQ_FRAMES + \ - static.DXCALLSIGN_CRC8 + \ - static.MYCALLSIGN_CRC8 + \ - payload_data - - buffer = bytearray(static.FREEDV_DATA_PAYLOAD_PER_FRAME) # create TX buffer - buffer[:len(arqframe)] = arqframe # set buffersize to length of data which will be send - - crc = ctypes.c_ushort(self.c_lib.freedv_gen_crc16(bytes(buffer), static.FREEDV_DATA_PAYLOAD_PER_FRAME)) # generate CRC16 - crc = crc.value.to_bytes(2, byteorder='big') # convert crc to 2 byte hex string - buffer += crc # append crc16 to buffer - - data = (ctypes.c_ubyte * static.FREEDV_DATA_BYTES_PER_FRAME).from_buffer_copy(buffer) - self.c_lib.freedv_rawdatatx(freedv,mod_out,data) # modulate DATA and safe it into mod_out pointer - txbuffer += bytes(mod_out) - txbuffer = txbuffer.rstrip(b'\x00') #lets remove unallocated memory because of wrong buffer :-/ - - - # -------------- transmit audio - self.stream_tx.write(bytes(txbuffer)) - #time.sleep(0.5) - static.ARQ_STATE = 'IDLE' - #static.ARQ_STATE = 'RECEIVING_SIGNALLING' - -#-------------------------------------------------------------------------------------------------------- - def receive(self,data_mode,signalling_mode): - force = False - - self.c_lib.freedv_open.restype = ctypes.POINTER(ctypes.c_ubyte) - - freedv_data = self.c_lib.freedv_open(data_mode) - freedv_signalling = self.c_lib.freedv_open(signalling_mode) - - static.FREEDV_DATA_BYTES_PER_FRAME = int(self.c_lib.freedv_get_bits_per_modem_frame(freedv_data)/8) - static.FREEDV_DATA_PAYLOAD_PER_FRAME = static.FREEDV_DATA_BYTES_PER_FRAME -2 - static.FREEDV_SIGNALLING_BYTES_PER_FRAME = int(self.c_lib.freedv_get_bits_per_modem_frame(freedv_signalling)/8) - static.FREEDV_SIGNALLING_PAYLOAD_PER_FRAME = static.FREEDV_SIGNALLING_BYTES_PER_FRAME -2 - - data_bytes_out = (ctypes.c_ubyte * static.FREEDV_DATA_BYTES_PER_FRAME) - data_bytes_out = data_bytes_out() #get pointer from bytes_out - - signalling_bytes_out = (ctypes.c_ubyte * static.FREEDV_SIGNALLING_BYTES_PER_FRAME) - signalling_bytes_out = signalling_bytes_out() #get pointer from bytes_out - - # with this we can interrupt receiving - while static.FREEDV_RECEIVE == True: - time.sleep(0.01) - - # stuck in sync counter - stuck_in_sync_counter = 0 - stuck_in_sync_10_counter = 0 - # - - while static.ARQ_STATE == 'RECEIVING_DATA': - time.sleep(0.01) - - nin = self.c_lib.freedv_nin(freedv_data) - nin = int(nin*(static.AUDIO_SAMPLE_RATE_RX/static.MODEM_SAMPLE_RATE)) - - data_in = self.stream_rx.read(nin, exception_on_overflow = False) - data_in = data_in.rstrip(b'\x00') - - #print(data_in) - - self.c_lib.freedv_rawdatarx.argtype = [ctypes.POINTER(ctypes.c_ubyte), data_bytes_out, data_in] # check if really neccessary - nbytes = self.c_lib.freedv_rawdatarx(freedv_data, data_bytes_out, data_in) # demodulate audio - print(self.c_lib.freedv_get_rx_status(freedv_data)) - - - #-------------STUCK IN SYNC DETECTOR - stuck_in_sync_counter += 1 - if self.c_lib.freedv_get_rx_status(freedv_data) == 10: - stuck_in_sync_10_counter += 1 - - - #print(stuck_in_sync_counter) - #if stuck_in_sync_counter == 33 and self.c_lib.freedv_get_rx_status(freedv_data) == 10: - # print("stuck in sync #1 --> DOING UNSYNC") - # self.c_lib.freedv_set_sync(freedv_data, 0) #FORCE UNSYNC - # stuck_in_sync_counter = 0 - # stuck_in_sync_10_counter = 0 - # data_in = None - - - if stuck_in_sync_counter >= 66 and stuck_in_sync_10_counter >= 2: - logging.warning("modem stuck in sync") - self.c_lib.freedv_set_sync(freedv_data, 0) #FORCE UNSYNC - stuck_in_sync_counter = 0 - stuck_in_sync_10_counter = 0 - data_in = None - #----------------------------------- - - - if nbytes == static.FREEDV_DATA_BYTES_PER_FRAME: - - # counter reset for stuck in sync counter - stuck_in_sync_counter = 0 - stuck_in_sync_10_counter = 0 - # - - # CHECK IF FRAMETYPE IS BETWEEN 10 and 50 ------------------------ - frametype = int.from_bytes(bytes(data_bytes_out[:1]), "big") - frame = frametype - 10 - n_frames_per_burst = int.from_bytes(bytes(data_bytes_out[1:2]), "big") - - if 50 >= frametype >= 10: - if frame != 3 or force == True: - arq.data_received(bytes(data_bytes_out[:-2])) #send payload data to arq checker without CRC16 - - #print("static.ARQ_RX_BURST_BUFFER.count(None) " + str(static.ARQ_RX_BURST_BUFFER.count(None))) - if static.ARQ_RX_BURST_BUFFER.count(None) <= 1: - print("FULL BURST BUFFER ---> UNSYNC") - self.c_lib.freedv_set_sync(freedv_data, 0) - - else: - print("---------------------------SIMULATED MISSING FRAME") - force = True - else: - print("MODE: " + str(data_mode) + " DATA: " + str(bytes(data_bytes_out))) - - - # DO UNSYNC AFTER LAST BURST by checking the frame numbers agains the total frames per burst - if frame == n_frames_per_burst: - print("LAST FRAME ---> UNSYNC") - self.c_lib.freedv_set_sync(freedv_data, 0) #FORCE UNSYNC - - - - while static.ARQ_STATE == 'IDLE' or static.ARQ_STATE == 'RECEIVING_SIGNALLING': - time.sleep(0.01) - - nin = self.c_lib.freedv_nin(freedv_signalling) - nin = int(nin*(static.AUDIO_SAMPLE_RATE_RX/static.MODEM_SAMPLE_RATE)) - - data_in = self.stream_rx.read(nin, exception_on_overflow = False) - data_in = data_in.rstrip(b'\x00') - - self.c_lib.freedv_rawdatarx.argtype = [ctypes.POINTER(ctypes.c_ubyte), signalling_bytes_out, data_in] # check if really neccessary - nbytes = self.c_lib.freedv_rawdatarx(freedv_signalling, signalling_bytes_out, data_in) # demodulate audio - - # CHECK IF FRAME CONTAINS ACK------------------------ - - if nbytes == static.FREEDV_SIGNALLING_BYTES_PER_FRAME: - self.c_lib.freedv_set_sync(freedv_signalling, 0) - frametype = int.from_bytes(bytes(signalling_bytes_out[:1]), "big") - - # BURST ACK - if frametype == 60: - print("ACK RECEIVED....") - arq.burst_ack_received() - - # FRAME ACK - elif frametype == 61: - print("FRAME ACK RECEIVED....") - arq.frame_ack_received() - - # FRAME RPT - elif frametype == 62: - print("REPEAT REQUEST RECEIVED....") - arq.burst_rpt_received(signalling_bytes_out[:-2]) - - else: - print("OTHER FRAME: " + str(signalling_bytes_out[:-2])) - - - rxstatus = self.c_lib.freedv_get_rx_status(freedv_signalling) - print("ACK-" + str(rxstatus)) - #print(rxstatus) - if nbytes == static.FREEDV_SIGNALLING_BYTES_PER_FRAME or rxstatus == 10: - self.c_lib.freedv_set_sync(freedv_signalling, 0) #FORCE UNSYNC -