diff --git a/modem/arq_session.py b/modem/arq_session.py index dabf0ae2..6d97561a 100644 --- a/modem/arq_session.py +++ b/modem/arq_session.py @@ -30,6 +30,18 @@ class ARQSession: 'duration_per_frame': 4.18, 'bandwidth': 1700, }, + 3: { + 'mode': codec2.FREEDV_MODE.data_ofdm_2438, + 'min_snr': 7, + 'duration_per_frame': 4.18, + 'bandwidth': 2375, + }, + 4: { + 'mode': codec2.FREEDV_MODE.qam16c2, + 'min_snr': 10, + 'duration_per_frame': 4.18, + 'bandwidth': 2100, + }, } def __init__(self, config: dict, modem, dxcall: str, state_manager): diff --git a/modem/codec2.py b/modem/codec2.py index c79fcb39..885c3ffc 100644 --- a/modem/codec2.py +++ b/modem/codec2.py @@ -35,7 +35,8 @@ class FREEDV_MODE(Enum): datac13 = 19 datac14 = 20 data_ofdm_500 = 21500 - data_ofdm_2438 = 212438 + data_ofdm_2438 = 2124381 + #data_qam_2438 = 2124382 qam16c2 = 22 class FREEDV_MODE_USED_SLOTS(Enum): @@ -52,6 +53,7 @@ class FREEDV_MODE_USED_SLOTS(Enum): datac14 = [False, False, True, False, False] data_ofdm_500 = [False, False, True, False, False] data_ofdm_2438 = [True, True, True, True, True] + data_qam_2438 = [True, True, True, True, True] qam16c2 = [True, True, True, True, True] # Function for returning the mode value @@ -111,7 +113,7 @@ for file in files: if api is None or "api" not in locals(): log.critical("[C2 ] Error: Libcodec2 not loaded - Exiting") sys.exit(1) -log.info("[C2 ] Libcodec2 loaded...", path=file) +#log.info("[C2 ] Libcodec2 loaded...", path=file) # ctypes function init # api.freedv_set_tuning_range.restype = ctypes.c_int @@ -372,8 +374,8 @@ class resampler: def open_instance(mode: int) -> ctypes.c_void_p: data_custom = 21 - if mode in [FREEDV_MODE.data_ofdm_500.value, FREEDV_MODE.data_ofdm_2438.value]: + #if mode in [FREEDV_MODE.data_ofdm_500.value, FREEDV_MODE.data_ofdm_2438.value, FREEDV_MODE.data_qam_2438]: custom_params = ofdm_configurations[mode] return ctypes.cast( api.freedv_open_advanced( @@ -511,6 +513,25 @@ def create_default_ofdm_config(): ) +def create_tx_uw(nuwbits, uw_sequence): + """ + Creates a tx_uw ctypes array filled with the uw_sequence up to nuwbits. + If uw_sequence is shorter than nuwbits, the rest of the array is filled with zeros. + + :param nuwbits: The number of bits for the tx_uw array, should not exceed MAX_UW_BITS. + :param uw_sequence: List of integers representing the unique word sequence. + :return: A ctypes array representing the tx_uw. + """ + # Ensure nuwbits does not exceed MAX_UW_BITS + if nuwbits > MAX_UW_BITS: + raise ValueError(f"nuwbits exceeds MAX_UW_BITS: {MAX_UW_BITS}") + + tx_uw_array = (ctypes.c_uint8 * MAX_UW_BITS)(*([0] * MAX_UW_BITS)) + for i in range(min(len(uw_sequence), MAX_UW_BITS)): + tx_uw_array[i] = uw_sequence[i] + + return tx_uw_array + """ # DATAC1 data_ofdm_500_config = create_default_ofdm_config() @@ -524,19 +545,10 @@ data_ofdm_500_config.config.contents.nuwbits = 16 data_ofdm_500_config.config.contents.timing_mx_thresh = 0.10 data_ofdm_500_config.config.contents.bad_uw_errors = 6 data_ofdm_500_config.config.contents.codename = b"H_4096_8192_3d" -data_ofdm_500_config.config.contents.clip_gain1 = 2.2 -data_ofdm_500_config.config.contents.clip_gain2 = 0.8 data_ofdm_500_config.config.contents.amp_scale = 145E3 - -uw_sequence = [1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0] -data_ofdm_500_config.config.contents.tx_uw = (ctypes.c_uint8 * MAX_UW_BITS)(*(uw_sequence + [0]*(MAX_UW_BITS-len(uw_sequence)))) -#tx_uw_array = (ctypes.c_uint8 * MAX_UW_BITS)(*([0] * MAX_UW_BITS)) -#for i in range(min(len(uw_sequence), MAX_UW_BITS)): -# tx_uw_array[i] = uw_sequence[i] -#data_ofdm_500_config.config.contents.tx_uw = tx_uw_array +data_ofdm_500_config.config.contents.tx_uw = create_tx_uw(16, [1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0]) +""" """ - - # DATAC3 data_ofdm_500_config = create_default_ofdm_config() data_ofdm_500_config.config.contents.ns = 5 @@ -551,24 +563,34 @@ data_ofdm_500_config.config.contents.bad_uw_errors = 10 data_ofdm_500_config.config.contents.codename = b"H_1024_2048_4f" data_ofdm_500_config.config.contents.clip_gain1 = 2.2 data_ofdm_500_config.config.contents.clip_gain2 = 0.8 -uw_sequence = [1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0] -data_ofdm_500_config.config.contents.tx_uw = (ctypes.c_uint8 * MAX_UW_BITS)(*(uw_sequence + [0]*(MAX_UW_BITS-len(uw_sequence)))) -#tx_uw_array = (ctypes.c_uint8 * MAX_UW_BITS)(*([0] * MAX_UW_BITS)) -#for i in range(min(len(uw_sequence), MAX_UW_BITS)): -# tx_uw_array[i] = uw_sequence[i] -#data_ofdm_500_config.config.contents.tx_uw = tx_uw_array - - +data_ofdm_500_config.config.contents.tx_uw = create_tx_uw(40, [1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0]) +""" +# ---------------- OFDM 500 Hz Bandwidth ---------------# +data_ofdm_500_config = create_default_ofdm_config() +data_ofdm_500_config.config.contents.ns = 5 +data_ofdm_500_config.config.contents.np = 38 +data_ofdm_500_config.config.contents.tcp = 0.006 +data_ofdm_500_config.config.contents.ts = 0.016 +data_ofdm_500_config.config.contents.rs = 1.0 / data_ofdm_500_config.config.contents.ts +data_ofdm_500_config.config.contents.nc = 27 +data_ofdm_500_config.config.contents.nuwbits = 16 +data_ofdm_500_config.config.contents.timing_mx_thresh = 0.10 +data_ofdm_500_config.config.contents.bad_uw_errors = 6 +data_ofdm_500_config.config.contents.codename = b"H_4096_8192_3d" +data_ofdm_500_config.config.contents.amp_scale = 145E3 +data_ofdm_500_config.config.contents.tx_uw = create_tx_uw(16, [1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0]) +""" +# ---------------- OFDM 2438 Hz Bandwidth 16200,9720 ---------------# data_ofdm_2438_config = create_default_ofdm_config() data_ofdm_2438_config.config.contents.ns = 5 data_ofdm_2438_config.config.contents.np = 51 data_ofdm_2438_config.config.contents.tcp = 0.005 data_ofdm_2438_config.config.contents.ts = 0.018 -data_ofdm_500_config.config.contents.rs = 1.0 / data_ofdm_2438_config.config.contents.ts +data_ofdm_2438_config.config.contents.rs = 1.0 / data_ofdm_2438_config.config.contents.ts data_ofdm_2438_config.config.contents.nc = 39 -data_ofdm_2438_config.config.contents.nuwbits =12 +data_ofdm_2438_config.config.contents.nuwbits = 24 data_ofdm_2438_config.config.contents.timing_mx_thresh = 0.10 data_ofdm_2438_config.config.contents.bad_uw_errors = 8 data_ofdm_2438_config.config.contents.amp_est_mode = 0 @@ -577,17 +599,50 @@ data_ofdm_2438_config.config.contents.codename = b"H_16200_9720" data_ofdm_2438_config.config.contents.clip_gain1 = 2.7 data_ofdm_2438_config.config.contents.clip_gain2 = 0.8 data_ofdm_2438_config.config.contents.timing_mx_thresh = 0.10 +data_ofdm_2438_config.config.contents.tx_uw = create_tx_uw(24, [1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1]) +""" +# ---------------- OFDM 2438 Hz Bandwidth 8192,4096 ---------------# +data_ofdm_2438_config = create_default_ofdm_config() +data_ofdm_2438_config.config.contents.ns = 5 +data_ofdm_2438_config.config.contents.np = 27 +data_ofdm_2438_config.config.contents.tcp = 0.005 +data_ofdm_2438_config.config.contents.ts = 0.018 +data_ofdm_2438_config.config.contents.rs = 1.0 / data_ofdm_2438_config.config.contents.ts +data_ofdm_2438_config.config.contents.nc = 38 +data_ofdm_2438_config.config.contents.nuwbits = 16 +data_ofdm_2438_config.config.contents.timing_mx_thresh = 0.10 +data_ofdm_2438_config.config.contents.bad_uw_errors = 8 +data_ofdm_2438_config.config.contents.amp_est_mode = 0 +data_ofdm_2438_config.config.contents.amp_scale = 145E3 +data_ofdm_2438_config.config.contents.codename = b"H_4096_8192_3d" +data_ofdm_2438_config.config.contents.clip_gain1 = 2.7 +data_ofdm_2438_config.config.contents.clip_gain2 = 0.8 +data_ofdm_2438_config.config.contents.timing_mx_thresh = 0.10 +data_ofdm_2438_config.config.contents.tx_uw = create_tx_uw(16, [1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1]) -# Fill the tx_uw field with the uw_sequence, and pad the rest with zeros if necessary -#uw_sequence = [1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1] -uw_sequence = [1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0] -data_ofdm_2438_config.config.contents.tx_uw = (ctypes.c_uint8 * MAX_UW_BITS)(*(uw_sequence + [0]*(MAX_UW_BITS-len(uw_sequence)))) - - - +# ---------------- QAM 2438 Hz Bandwidth ---------------# +data_qam_2438_config = create_default_ofdm_config() +data_qam_2438_config.config.contents.bps = 4 +data_qam_2438_config.config.contents.ns = 5 +data_qam_2438_config.config.contents.np = 26 +data_qam_2438_config.config.contents.tcp = 0.005 +data_qam_2438_config.config.contents.ts = 0.018 +data_qam_2438_config.config.contents.rs = 1.0 / data_qam_2438_config.config.contents.ts +data_qam_2438_config.config.contents.nc = 39 +data_qam_2438_config.config.contents.nuwbits = 162 +data_qam_2438_config.config.contents.timing_mx_thresh = 0.10 +data_qam_2438_config.config.contents.bad_uw_errors = 50 +data_qam_2438_config.config.contents.amp_est_mode = 0 +data_qam_2438_config.config.contents.amp_scale = 145E3 +data_qam_2438_config.config.contents.codename = b"H_16200_9720" +data_qam_2438_config.config.contents.clip_gain1 = 2.7 +data_qam_2438_config.config.contents.clip_gain2 = 0.8 +data_qam_2438_config.config.contents.timing_mx_thresh = 0.10 +data_qam_2438_config.config.contents.tx_uw = create_tx_uw(162, [1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0]) ofdm_configurations = { FREEDV_MODE.data_ofdm_500.value: data_ofdm_500_config, - FREEDV_MODE.data_ofdm_2438.value: data_ofdm_2438_config + FREEDV_MODE.data_ofdm_2438.value: data_ofdm_2438_config, + #FREEDV_MODE.data_qam_2438.value: data_qam_2438_config } diff --git a/modem/command_cq.py b/modem/command_cq.py index 8b54e4a7..bd71c7e3 100644 --- a/modem/command_cq.py +++ b/modem/command_cq.py @@ -6,7 +6,8 @@ class CQCommand(TxCommand): return self.frame_factory.build_cq() def get_tx_mode(self): - return FREEDV_MODE.data_ofdm_500 + #return FREEDV_MODE.data_ofdm_500 #return FREEDV_MODE.datac3 - #return FREEDV_MODE.data_ofdm_2438 + return FREEDV_MODE.data_ofdm_2438 + #return FREEDV_MODE.data_qam_2438 #return FREEDV_MODE.qam16c2 \ No newline at end of file diff --git a/modem/config.py b/modem/config.py index 0b7debca..97295a0b 100644 --- a/modem/config.py +++ b/modem/config.py @@ -94,7 +94,7 @@ class CONFIG: except Exception: self.config_name = "config.ini" - self.log.info("[CFG] config init", file=self.config_name) + #self.log.info("[CFG] config init", file=self.config_name) # check if config file exists self.config_exists() diff --git a/modem/demodulator.py b/modem/demodulator.py index a8e2b1c0..d22a083a 100644 --- a/modem/demodulator.py +++ b/modem/demodulator.py @@ -74,17 +74,12 @@ class Demodulator(): #c2instance = ctypes.cast( # codec2.api.freedv_open(mode), ctypes.c_void_p #) - print(mode) c2instance = codec2.open_instance(mode) - print(c2instance) - print("hat geklappt...") - # get bytes per frame bytes_per_frame = int( codec2.api.freedv_get_bits_per_modem_frame(c2instance) / 8 ) - print(f"bytes per frame: {bytes_per_frame}") # create byte out buffer bytes_out = ctypes.create_string_buffer(bytes_per_frame) diff --git a/tools/custom_mode_tests/create_custom_ofdm_mod.py b/tools/custom_mode_tests/create_custom_ofdm_mod.py index c304a1b6..26ca1af0 100644 --- a/tools/custom_mode_tests/create_custom_ofdm_mod.py +++ b/tools/custom_mode_tests/create_custom_ofdm_mod.py @@ -23,8 +23,10 @@ import config as config config = config.CONFIG('config.ini') modulator = modulator.Modulator(config.read()) #freedv = open_instance(FREEDV_MODE.data_ofdm_2438.value) -#freedv = open_instance(FREEDV_MODE.datac3.value) -freedv = open_instance(FREEDV_MODE.data_ofdm_500.value) +#freedv = open_instance(FREEDV_MODE.datac14.value) +#freedv = open_instance(FREEDV_MODE.datac1.value) +freedv = open_instance(FREEDV_MODE.datac3.value) +#freedv = open_instance(FREEDV_MODE.data_ofdm_500.value) #freedv = open_instance(FREEDV_MODE.qam16c2.value) @@ -38,5 +40,6 @@ for frame in range(0,frames): txbuffer = modulator.transmit_add_postamble(txbuffer, freedv) txbuffer = modulator.transmit_add_silence(txbuffer, 1000) +sys.stdout.buffer.flush() sys.stdout.buffer.write(txbuffer) sys.stdout.buffer.flush()