WIP qam16c2, ofdm_mod runs but doesn't decode in Octave

dr-qam16-cport
drowe67 2024-04-04 09:16:21 +10:30 committed by David Rowe
parent 6a5687c5f5
commit 4726a97450
5 changed files with 50 additions and 22 deletions

View File

@ -472,7 +472,7 @@ endif()
add_test(NAME test_OFDM_modem_octave_qam16_uncoded
COMMAND sh -c "cd ${CMAKE_CURRENT_SOURCE_DIR}/octave;
echo \"ofdm_tx('test_qam16.raw','qam16c1',3,12,'awgn','bursts',3); ofdm_rx('test_qam16.raw','qam16c1', 'passber', 0.05, 'packetsperburst', 1); quit\" |
echo \"ofdm_tx('test_qam16.raw','qam16c2',1,12,'awgn','bursts',3); ofdm_rx('test_qam16.raw','qam16c2', 'passber', 0.05, 'packetsperburst', 1); quit\" |
DISPLAY=\"\" octave-cli")
set_tests_properties(test_OFDM_modem_octave_qam16_uncoded PROPERTIES PASS_REGULAR_EXPRESSION "Pass")

View File

@ -76,7 +76,7 @@ function states = ofdm_init(config)
1 + j, 1 + j*3, 3 + j, 3 + j*3;
1 - j, 1 - j*3, 3 - j, 3 - j*3;
-1 + j, -1 + j*3, -3 + j, -3 + j*3;
-1 - j, -1 - j*3, -3 - j, -3 - j*3]/3;
-1 - j, -1 - j*3, -3 - j, -3 - j*3];
rms = sqrt(states.qam16(:)'*states.qam16(:)/16);% set average Es to 1
states.qam16 /= rms;
states.qam16 *= exp(-j*pi/4); % same rotation as QPSK constellation

View File

@ -75,13 +75,22 @@ static void ofdm_demod_core(struct OFDM *, int *);
*/
static const complex float qpsk[] = {1.0f + 0.0f * I, 0.0f + 1.0f * I,
0.0f - 1.0f * I, -1.0f + 0.0f * I};
/*
static const complex float qam16[] = {
1.0f + 1.0f * I, 1.0f + 3.0f * I, 3.0f + 1.0f * I, 3.0f + 3.0f * I,
1.0f - 1.0f * I, 1.0f - 3.0f * I, 3.0f - 1.0f * I, 3.0f - 3.0f * I,
-1.0f + 1.0f * I, -1.0f + 3.0f * I, -3.0f + 1.0f * I, -3.0f + 3.0f * I,
-1.0f - 1.0f * I, -1.0f - 3.0f * I, -3.0f - 1.0f * I, -3.0f - 3.0f * I};
*/
static const complex float qam16[] = {
4.4721e-01 + 2.7756e-17 * I, 8.9443e-01 + 4.4721e-01 * I,
8.9443e-01 - 4.4721e-01 * I, 1.3416e+00 + 1.1102e-16 * I,
2.7756e-17 - 4.4721e-01 * I, -4.4721e-01 - 8.9443e-01 * I,
4.4721e-01 - 8.9443e-01 * I, 1.1102e-16 - 1.3416e+00 * I,
-2.7756e-17 + 4.4721e-01 * I, 4.4721e-01 + 8.9443e-01 * I,
-4.4721e-01 + 8.9443e-01 * I, -1.1102e-16 + 1.3416e+00 * I,
-4.4721e-01 - 2.7756e-17 * I, -8.9443e-01 - 4.4721e-01 * I,
-8.9443e-01 + 4.4721e-01 * I, -1.3416e+00 - 1.1102e-16 * I};
/*
* These pilots are compatible with Octave version
*/
@ -468,12 +477,12 @@ struct OFDM *ofdm_create(const struct OFDM_CONFIG *config) {
MALLOC(sizeof(complex float) * (ofdm->nuwbits / ofdm->bps));
assert(ofdm->tx_uw_syms != NULL);
assert(ofdm->bps == 2); // TODO generalise
for (int s = 0; s < (ofdm->nuwbits / ofdm->bps); s++) {
int dibit[2];
dibit[1] = ofdm->tx_uw[2 * s];
dibit[0] = ofdm->tx_uw[2 * s + 1];
ofdm->tx_uw_syms[s] = qpsk_mod(dibit);
for (int b = 0, s = 0; b < ofdm->nuwbits; b += ofdm->bps, s++) {
int bits[ofdm->bps];
for (int i = 0; i < ofdm->bps; i++)
bits[ofdm->bps - 1 - i] = ofdm->tx_uw[b + i];
if (ofdm->bps == 2) ofdm->tx_uw_syms[s] = qpsk_mod(bits);
if (ofdm->bps == 4) ofdm->tx_uw_syms[s] = qam16_mod(bits);
}
/* sync state machine */
@ -1208,7 +1217,14 @@ void ofdm_mod(struct OFDM *ofdm, COMP *result, const int *tx_bits) {
tx_sym_lin[i] = qpsk_mod(dibit);
}
} /* else if (ofdm->bps == 3) { } TODO */
} else if (ofdm->bps == 4) {
for (int b = 0, s = 0; b < ofdm->bitsperpacket; b += ofdm->bps, s++) {
int bits[ofdm->bps];
for (int i = 0; i < ofdm->bps; i++)
bits[ofdm->bps - 1 - i] = tx_bits[b + i] & 0x1;
tx_sym_lin[s] = qam16_mod(bits);
}
}
ofdm_txframe(ofdm, tx, tx_sym_lin);
}
@ -2436,10 +2452,6 @@ void ofdm_assemble_qpsk_modem_packet_symbols(struct OFDM *ofdm,
int p = 0;
int u = 0;
assert(
ofdm->bps ==
2); /* this only works for QPSK at this stage (e.g. modem packet mod) */
for (s = 0; s < (Nsymsperpacket - Ntxtsyms); s++) {
if ((u < Nuwsyms) && (s == ofdm->uw_ind_sym[u])) {
modem_packet[s] = ofdm->tx_uw_syms[u++];
@ -2451,6 +2463,8 @@ void ofdm_assemble_qpsk_modem_packet_symbols(struct OFDM *ofdm,
assert(u == Nuwsyms);
assert(p == (Nsymsperpacket - Nuwsyms - Ntxtsyms));
/* txt bit insertion only works for QPSK at this stage */
assert((Ntxtsyms == 0) || (ofdm->bps == 2));
for (t = 0; s < Nsymsperpacket; s++, t += 2) {
dibit[1] = txt_bits[t] & 0x1;
dibit[0] = txt_bits[t + 1] & 0x1;

View File

@ -46,7 +46,7 @@ extern "C" {
#define TAU (2.0f * M_PI)
#define ROT45 (M_PI / 4.0f)
#define MAX_UW_BITS 64
#define MAX_UW_BITS 192
#define cmplx(value) (cosf(value) + sinf(value) * I)
#define cmplxconj(value) (cosf(value) + sinf(value) * -I)

View File

@ -42,6 +42,7 @@ void ofdm_init_mode(char mode[], struct OFDM_CONFIG *config) {
config->state_machine = "voice1";
config->data_mode = "";
config->codename = "HRA_112_112";
config->EsNodB = 3.0;
config->clip_gain1 = 2.5;
config->clip_gain2 = 0.8;
config->clip_en = true;
@ -92,23 +93,36 @@ void ofdm_init_mode(char mode[], struct OFDM_CONFIG *config) {
config->state_machine = "voice2";
config->ftwindowwidth = 64;
config->foff_limiter = true;
} else if (strcmp(mode, "qam16") == 0) {
/* not in use yet */
} else if (strcmp(mode, "qam16c2") == 0) {
config->ns = 5;
config->np = 5;
config->np = 31;
config->tcp = 0.004;
config->ts = 0.016;
config->nc = 33;
config->bps = 4;
config->txtbits = 0;
config->nuwbits = 15 * 4;
config->bad_uw_errors = 5;
config->ftwindowwidth = 32;
config->nuwbits = 42 * 4;
assert(config->nuwbits <= MAX_UW_BITS);
config->bad_uw_errors = 15;
config->ftwindowwidth = 80;
config->state_machine = "data";
config->amp_est_mode = 1;
config->tx_bpf_en = false;
config->clip_en = false;
config->data_mode = "streaming";
config->amp_scale = 135E3;
config->clip_en = false;
config->tx_bpf_en = false;
config->rx_bpf_en = false;
uint8_t uw[] = {1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1,
0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0};
memset(config->tx_uw, 0, config->nuwbits);
memcpy(config->tx_uw, uw, sizeof(uw));
memcpy(&config->tx_uw[config->nuwbits - sizeof(uw)], uw, sizeof(uw));
config->EsNodB = 10;
config->codename = "H_16200_9720";
} else if (strcmp(mode, "datac0") == 0) {
config->ns = 5;
config->np = 4;