int main(int argc, char **argv) { int frame_cnt; float *llr; unsigned char *llr_c; char *data_tx, *data_rx, *symbols; int i, j; float var[SNR_POINTS]; int snr_points; float ber[MAX_ITERATIONS][SNR_POINTS]; unsigned int errors[100]; int coded_length; struct timeval tdata[3]; float mean_usec; tdec_t tdec; tcod_t tcod; parse_args(argc, argv); if (!seed) { seed = time(NULL); } srand(seed); if (test_known_data) { frame_length = KNOWN_DATA_LEN; } else { frame_length = lte_cb_size(lte_find_cb_index(frame_length)); } coded_length = 3 * (frame_length) + TOTALTAIL; printf(" Frame length: %d\n", frame_length); if (ebno_db < 100.0) { printf(" EbNo: %.2f\n", ebno_db); } data_tx = malloc(frame_length * sizeof(char)); if (!data_tx) { perror("malloc"); exit(-1); } data_rx = malloc(frame_length * sizeof(char)); if (!data_rx) { perror("malloc"); exit(-1); } symbols = malloc(coded_length * sizeof(char)); if (!symbols) { perror("malloc"); exit(-1); } llr = malloc(coded_length * sizeof(float)); if (!llr) { perror("malloc"); exit(-1); } llr_c = malloc(coded_length * sizeof(char)); if (!llr_c) { perror("malloc"); exit(-1); } if (tcod_init(&tcod, frame_length)) { fprintf(stderr, "Error initiating Turbo coder\n"); exit(-1); } if (tdec_init(&tdec, frame_length)) { fprintf(stderr, "Error initiating Turbo decoder\n"); exit(-1); } float ebno_inc, esno_db; ebno_inc = (SNR_MAX - SNR_MIN) / SNR_POINTS; if (ebno_db == 100.0) { snr_points = SNR_POINTS; for (i = 0; i < snr_points; i++) { ebno_db = SNR_MIN + i * ebno_inc; esno_db = ebno_db + 10 * log10((double) 1 / 3); var[i] = sqrt(1 / (pow(10, esno_db / 10))); } } else { esno_db = ebno_db + 10 * log10((double) 1 / 3); var[0] = sqrt(1 / (pow(10, esno_db / 10))); snr_points = 1; } for (i = 0; i < snr_points; i++) { mean_usec = 0; frame_cnt = 0; bzero(errors, sizeof(int) * MAX_ITERATIONS); while (frame_cnt < nof_frames) { /* generate data_tx */ for (j = 0; j < frame_length; j++) { if (test_known_data) { data_tx[j] = known_data[j]; } else { data_tx[j] = rand() % 2; } } /* coded BER */ if (test_known_data) { for (j = 0; j < coded_length; j++) { symbols[j] = known_data_encoded[j]; } } else { tcod_encode(&tcod, data_tx, symbols, frame_length); } for (j = 0; j < coded_length; j++) { llr[j] = symbols[j] ? sqrt(2) : -sqrt(2); } ch_awgn_f(llr, llr, var[i], coded_length); /* decoder */ tdec_reset(&tdec, frame_length); int t; if (nof_iterations == -1) { t = MAX_ITERATIONS; } else { t = nof_iterations; } for (j = 0; j < t; j++) { if (!j) gettimeofday(&tdata[1], NULL); // Only measure 1 iteration tdec_iteration(&tdec, llr, frame_length); tdec_decision(&tdec, data_rx, frame_length); if (!j) gettimeofday(&tdata[2], NULL); if (!j) get_time_interval(tdata); if (!j) mean_usec = (float) mean_usec * 0.9 + (float) tdata[0].tv_usec * 0.1; /* check errors */ errors[j] += bit_diff(data_tx, data_rx, frame_length); if (j < MAX_ITERATIONS) { ber[j][i] = (float) errors[j] / (frame_cnt * frame_length); } } frame_cnt++; printf("Eb/No: %3.2f %10d/%d ", SNR_MIN + i * ebno_inc, frame_cnt, nof_frames); printf("BER: %.2e ", (float) errors[j - 1] / (frame_cnt * frame_length)); printf("%3.1f Mbps (%6.2f usec)", (float) frame_length / mean_usec, mean_usec); printf("\r"); } printf("\n"); if (snr_points == 1) { if (test_known_data && seed == KNOWN_DATA_SEED && ebno_db == KNOWN_DATA_EBNO && frame_cnt == KNOWN_DATA_NFRAMES) { for (j = 0; j < MAX_ITERATIONS; j++) { if (errors[j] > known_data_errors[j]) { fprintf(stderr, "Expected %d errors but got %d\n", known_data_errors[j], errors[j]); exit(-1); } else { printf("Iter %d ok\n", j + 1); } } } else { for (j = 0; j < MAX_ITERATIONS; j++) { printf("BER: %g\t%u errors\n", (float) errors[j] / (frame_cnt * frame_length), errors[j]); if (test_errors) { if (errors[j] > get_expected_errors(frame_cnt, seed, j + 1, frame_length, ebno_db)) { fprintf(stderr, "Expected %d errors but got %d\n", get_expected_errors(frame_cnt, seed, j + 1, frame_length, ebno_db), errors[j]); exit(-1); } else { printf("Iter %d ok\n", j + 1); } } } } } } free(data_tx); free(symbols); free(llr); free(llr_c); free(data_rx); tdec_free(&tdec); tcod_free(&tcod); printf("\n"); output_matlab(ber, snr_points); printf("Done\n"); exit(0); }
char *test_bit_operation() { bit_t tmp; int i; bit_clear(a, 0, 255); bit_clear(b, 0, 255); bit_set(a, 5, 99); bit_set(b, 100, 222); tmp = bit_union(a, b); for (i=5; i<=222; i++) { mu_assert(bit_get(tmp, i) == 1, "bit_union is wrong.\n"); } mu_assert(bit_lt(a, tmp), "bit_union is wrong.\n"); mu_assert(bit_lt(b, tmp), "bit_union is wrong.\n"); bit_free(&tmp); mu_assert(tmp == NULL, "bit_free gets wrong.\n"); bit_clear(a, 0, 255); bit_clear(b, 0, 255); bit_set(a, 7, 99); bit_set(b, 7, 98); tmp = bit_union(a, b); for (i=7; i<=99; i++) { mu_assert(bit_get(tmp, i) == 1, "bit_union is wrong.\n"); } mu_assert(bit_eq(a, tmp), "bit_union is wrong.\n"); mu_assert(bit_lt(b, tmp), "bit_union is wrong.\n"); bit_free(&tmp); mu_assert(tmp == NULL, "bit_free gets wrong.\n"); bit_clear(a, 0, 255); bit_clear(b, 0, 255); bit_set(a, 7, 88); bit_set(b, 50, 98); tmp = bit_union(a, b); for (i=7; i<=98; i++) { mu_assert(bit_get(tmp, i) == 1, "bit_union is wrong.\n"); } mu_assert(bit_lt(a, tmp), "bit_union is wrong.\n"); mu_assert(bit_lt(b, tmp), "bit_union is wrong.\n"); bit_free(&tmp); mu_assert(tmp == NULL, "bit_free gets wrong.\n"); /* test bit_inter */ bit_clear(a, 0, 255); bit_clear(b, 0, 255); bit_set(a, 7, 88); bit_set(b, 50, 98); tmp = bit_inter(a, b); for (i=50; i<=88; i++) { mu_assert(bit_get(tmp, i) == 1, "bit_inter is wrong.\n"); } mu_assert(bit_lt(tmp, a), "bit_inter is wrong.\n"); mu_assert(bit_lt(tmp, b), "bit_inter is wrong.\n"); bit_free(&tmp); mu_assert(tmp == NULL, "bit_free gets wrong.\n"); bit_clear(a, 0, 255); bit_clear(b, 0, 255); bit_set(a, 18, 200); bit_set(b, 18, 200); tmp = bit_inter(a, b); mu_assert(bit_eq(tmp, a), "bit_inter is wrong.\n"); mu_assert(bit_eq(tmp, b), "bit_inter is wrong.\n"); bit_free(&tmp); mu_assert(tmp == NULL, "bit_free gets wrong.\n"); bit_clear(a, 0, 255); bit_clear(b, 0, 255); bit_set(a, 18, 100); bit_set(b, 111, 200); tmp = bit_inter(a, b); bit_clear(a, 0, 255); mu_assert(bit_eq(tmp, a), "bit_inter is wrong.\n"); bit_free(&tmp); mu_assert(tmp == NULL, "bit_free gets wrong.\n"); /* test of bit_minus */ bit_clear(a, 0, 255); bit_clear(b, 0, 255); bit_set(a, 20, 201); bit_set(b, 111, 200); tmp = bit_minus(a, b); for (i=20; i<=110; i++) { mu_assert(bit_get(tmp, i) == 1, "bit_minus is wrong.\n"); } for (i=111; i<=200; i++) { mu_assert(bit_get(tmp, i) == 0, "bit_minus is wrong.\n"); } mu_assert(bit_get(tmp, 201) == 1, "bit_minus is wrong.\n"); bit_free(&tmp); mu_assert(tmp == NULL, "bit_free gets wrong.\n"); tmp = bit_minus(b, a); bit_clear(a, 0, 255); mu_assert(bit_eq(tmp, a), "bit_minus is wrong.\n"); bit_clear(a, 0, 255); bit_clear(b, 0, 255); bit_set(a, 20, 110); bit_set(b, 111, 200); tmp = bit_minus(a, b); mu_assert(bit_eq(tmp, a), "bit_minus is wrong.\n"); bit_free(&tmp); mu_assert(tmp == NULL, "bit_free gets wrong.\n"); bit_clear(a, 0, 255); bit_clear(b, 0, 255); bit_set(a, 20, 120); bit_set(b, 111, 200); tmp = bit_minus(a, b); for (i=20; i<=110; i++) { mu_assert(bit_get(tmp, i) == 1, "bit_minus is wrong.\n"); } for (i=111; i<=200; i++) { mu_assert(bit_get(tmp, i) == 0, "bit_minus is wrong.\n"); } bit_free(&tmp); mu_assert(tmp == NULL, "bit_free gets wrong.\n"); /* test bit_diff */ bit_clear(a, 0, 255); bit_clear(b, 0, 255); bit_set(a, 20, 222); bit_set(b, 111, 200); tmp = bit_diff(a, b); for (i=20; i<=110; i++) { mu_assert(bit_get(tmp, i) == 1, "bit_diff is wrong.\n"); } for (i=111; i<=200; i++) { mu_assert(bit_get(tmp, i) == 0, "bit_diff is wrong.\n"); } for (i=201; i<=222; i++) { mu_assert(bit_get(tmp, i) == 1, "bit_diff is wrong.\n"); } bit_free(&tmp); mu_assert(tmp == NULL, "bit_free gets wrong.\n"); tmp = bit_diff(b, a); for (i=20; i<=110; i++) { mu_assert(bit_get(tmp, i) == 1, "bit_diff is wrong.\n"); } for (i=111; i<=200; i++) { mu_assert(bit_get(tmp, i) == 0, "bit_diff is wrong.\n"); } for (i=201; i<=222; i++) { mu_assert(bit_get(tmp, i) == 1, "bit_diff is wrong.\n"); } bit_free(&tmp); mu_assert(tmp == NULL, "bit_free gets wrong.\n"); bit_clear(a, 0, 255); bit_clear(b, 0, 255); bit_set(a, 20, 110); bit_set(b, 111, 200); tmp = bit_diff(a, b); for (i = 20; i <= 200; i++) { mu_assert(bit_get(tmp, i) == 1, "bit_diff is wrong.\n"); } bit_free(&tmp); mu_assert(tmp == NULL, "bit_free gets wrong.\n"); bit_clear(a, 0, 255); bit_clear(b, 0, 255); bit_set(a, 20, 158); bit_set(b, 111, 200); tmp = bit_diff(a, b); for (i = 20; i <= 110; i++) { mu_assert(bit_get(tmp, i) == 1, "bit_diff is wrong.\n"); } for (i = 111; i <= 158; i++) { mu_assert(bit_get(tmp, i) == 0, "bit_diff is wrong.\n"); } for (i = 159; i <= 200; i++) { mu_assert(bit_get(tmp, i) == 1, "bit_diff is wrong.\n"); } bit_free(&tmp); mu_assert(tmp == NULL, "bit_free gets wrong.\n"); return NULL; }
int main(int argc, char **argv) { viterbi_t dec; convcoder_t cod; modem_table_t modem; demod_soft_t demod; int frame_cnt; float *llr; char *data_tx, *data_rx, *symbols; cf_t *iq; int i; parse_args(argc,argv); if (!seed) { seed = time(NULL); } srand(seed); int coded_length = 3 * (frame_length + ((tail_biting)?0:6)); printf("Convolutional Code 1/3 K=7 Test\n"); printf(" Frame length: %d\n", frame_length); printf(" Codeword length: %d\n", coded_length); printf(" Tail bitting: %s\n", tail_biting?"yes":"no"); printf(" EbNo: %.2f\n", ebno_db); data_tx = malloc(frame_length * sizeof(char)); if (!data_tx) { perror("malloc"); exit(-1); } data_rx = malloc(frame_length * sizeof(char)); if (!data_rx) { perror("malloc"); exit(-1); } symbols = malloc(coded_length * sizeof(char)); if (!symbols) { perror("malloc"); exit(-1); } llr = malloc(coded_length * sizeof(float)); if (!llr) { perror("malloc"); exit(-1); } iq = malloc(coded_length * sizeof(cf_t)); if (!iq) { perror("malloc"); exit(-1); } cod.K = 7; cod.R = 3; cod.tail_biting = tail_biting; cod.framelength = frame_length; cod.poly[0] = 0x6D; cod.poly[1] = 0x4F; cod.poly[2] = 0x57; float var = sqrt(pow(10,-ebno_db/10)); modem_table_init(&modem); modem_table_std(&modem, LTE_QPSK, true); demod_soft_init(&demod); demod_soft_table_set(&demod, &modem); demod_soft_alg_set(&demod, APPROX); demod_soft_sigma_set(&demod, var); viterbi_init(&dec, viterbi_37, cod.poly, frame_length, tail_biting); /* read all file or nof_frames */ frame_cnt = 0; unsigned int errors=0; while (frame_cnt < nof_slots) { /* generate data_tx */ for (i=0;i<frame_length;i++) { data_tx[i] = message[i]; } convcoder_encode(&cod, data_tx, symbols); bit_fprint(stdout, symbols, 120); mod_modulate(&modem, symbols, iq, coded_length); if (ebno_db < 100.0) { ch_awgn(iq, iq, var, coded_length/2); } demod_soft_demodulate(&demod, iq, llr, coded_length/2); viterbi_decode(&dec, llr, data_rx); errors += bit_diff(data_tx, data_rx, frame_length); frame_cnt++; } printf("BER:\t%g\t%u errors\n", (float) errors/(frame_cnt*frame_length), errors); viterbi_free(&dec); free(data_tx); free(symbols); free(iq); free(llr); free(data_rx); printf("Done\n"); exit(0); }
void test_bit(void) { int i; void* B = bit_create(10); fprintf(stdout, "call function : %s\n", __func__); bit_object_show(B); fprintf(stdout, "\ntest function - bit_set/bit_get ===>\n"); { srand((unsigned int)time(0)); for (i = 0; i < bit_size(B); ++i) bit_set(B, i, rand() % 2); bit_object_show(B); for (i = 0; i < bit_size(B); ++i) fprintf(stdout, "\tbit values [%02d] => %d\n", i, bit_get(B, i)); } fprintf(stdout, "\ntest function - bit_clear_range ===>\n"); { bit_clear_range(B, 0, 4); bit_object_show(B); bit_for_each(B, bit_object_bit_show, NULL); } fprintf(stdout, "\ntest function - bit_set_range ===>\n"); { bit_set_range(B, 5, 9); bit_object_show(B); bit_for_each(B, bit_object_bit_show, NULL); } fprintf(stdout, "\ntest function - bit_not_range ===>\n"); { bit_not_range(B, 0, 9); bit_object_show(B); bit_for_each(B, bit_object_bit_show, NULL); } fprintf(stdout, "\ntest function - bit_clear ===>\n"); { bit_clear(B); bit_object_show(B); } fprintf(stdout, "\ntest function - bit_release ===>\n"); bit_release(&B); bit_object_show(B); fprintf(stdout, "\ntest function - bit_lt/bit_eq/bit_leq ===>\n"); { void* B1 = bit_create(5); void* B2 = bit_create(5); srand((unsigned int)time(0)); for (i = 0; i < 5; ++i) { bit_set(B1, i, rand() % 2); bit_set(B2, i, rand() % 2); } fprintf(stdout, " B1 object show:\n"); bit_for_each(B1, bit_object_bit_show, NULL); fprintf(stdout, " B2 object show:\n"); bit_for_each(B2, bit_object_bit_show, NULL); fprintf(stdout, " B1 < B2 ? '%s'\n", bit_lt(B1, B2) ? "yes" : "no"); fprintf(stdout, " B1 = B2 ? '%s'\n", bit_eq(B1, B2) ? "yes" : "no"); fprintf(stdout, " B1 <= B2 ? '%s'\n", bit_leq(B1, B2) ? "yes" : "no"); bit_release(&B1); bit_release(&B2); } fprintf(stdout, "\ntest function - union/inter/minus/diff ===>\n"); { void* B1 = bit_create(5); void* B2 = bit_create(5); srand((unsigned int)time(0)); for (i = 0; i < 5; ++i) { bit_set(B1, i, rand() % 2); bit_set(B2, i, rand() % 2); } fprintf(stdout, " B1 object show:\n"); bit_for_each(B1, bit_object_bit_show, NULL); fprintf(stdout, " B2 object show:\n"); bit_for_each(B2, bit_object_bit_show, NULL); B = bit_union(B1, B2); fprintf(stdout, " B1 union B2 ->\n"); bit_for_each(B, bit_object_bit_show, NULL); bit_release(&B); B = bit_inter(B1, B2); fprintf(stdout, " B1 inter B2 ->\n"); bit_for_each(B, bit_object_bit_show, NULL); bit_release(&B); B = bit_minus(B1, B2); fprintf(stdout, " B1 minus B2 ->\n"); bit_for_each(B, bit_object_bit_show, NULL); bit_release(&B); B = bit_diff(B1, B2); fprintf(stdout, " B1 diff B2 ->\n"); bit_for_each(B, bit_object_bit_show, NULL); bit_release(&B); bit_release(&B1); bit_release(&B2); } }