1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
|
//
// modem_arb_example.c
//
// This example demonstrates the functionality of the arbitrary
// modem, a digital modulator/demodulator object with signal
// constellation points chosen arbitrarily. A simple bit-error
// rate simulation is then run to test the performance of the
// modem. The results are written to a file.
// SEE ALSO: modem_example.c
//
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <getopt.h>
#include "liquid.h"
#define OUTPUT_FILENAME "modem_arb_example.m"
// print usage/help message
void usage()
{
printf("modem_arb_example [options]\n");
printf(" u/h : print usage\n");
printf(" p : modulation depth (default 4 bits/symbol)\n");
}
int main(int argc, char*argv[])
{
// options
unsigned int bps=6; // bits per symbol
unsigned int n=1024; // number of data points to evaluate
int dopt;
while ((dopt = getopt(argc,argv,"uhp:")) != EOF) {
switch (dopt) {
case 'u':
case 'h': usage(); return 0;
case 'p': bps = atoi(optarg); break;
default:
exit(1);
}
}
// validate input
if (bps == 0) {
fprintf(stderr,"error: %s, bits/symbol must be greater than zero\n", argv[0]);
exit(1);
}
// derived values
unsigned int i;
unsigned int M = 1<<bps; // constellation size
// initialize constellation table
float complex constellation[M];
// initialize constellation (spiral)
for (i=0; i<M; i++) {
float r = (float)i / logf((float)M) + 4.0f;
float phi = (float)i / logf((float)M);
constellation[i] = r * cexpf(_Complex_I*phi);
}
// create mod/demod objects
modem mod = modem_create_arbitrary(constellation, M);
modem demod = modem_create_arbitrary(constellation, M);
modem_print(mod);
// run simulation
float complex x[n];
unsigned int num_errors = 0;
// run simple BER simulation
num_errors = 0;
unsigned int sym_in;
unsigned int sym_out;
for (i=0; i<n; i++) {
// generate and modulate random symbol
sym_in = modem_gen_rand_sym(mod);
modem_modulate(mod, sym_in, &x[i]);
// add noise
x[i] += 0.05 * randnf() * cexpf(_Complex_I*M_PI*randf());
// demodulate
modem_demodulate(demod, x[i], &sym_out);
// accumulate errors
num_errors += count_bit_errors(sym_in,sym_out);
}
printf("num bit errors: %4u / %4u\n", num_errors, bps*n);
// destroy modem objects
modem_destroy(mod);
modem_destroy(demod);
//
// export output file
//
FILE * fid = fopen(OUTPUT_FILENAME,"w");
fprintf(fid,"%% %s : auto-generated file\n", OUTPUT_FILENAME);
fprintf(fid,"clear all;\n");
fprintf(fid,"close all;\n");
fprintf(fid,"bps = %u;\n", bps);
fprintf(fid,"M = %u;\n", M);
for (i=0; i<n; i++) {
fprintf(fid,"x(%3u) = %12.4e + j*%12.4e;\n", i+1,
crealf(x[i]),
cimagf(x[i]));
}
// plot results
fprintf(fid,"figure;\n");
fprintf(fid,"plot(x,'x','MarkerSize',1);\n");
fprintf(fid,"xlabel('in-phase');\n");
fprintf(fid,"ylabel('quadrature phase');\n");
fprintf(fid,"title(['Arbitrary ' num2str(M) '-QAM']);\n");
fprintf(fid,"axis([-1 1 -1 1]*1.9);\n");
fprintf(fid,"axis square;\n");
fprintf(fid,"grid on;\n");
fclose(fid);
printf("results written to '%s'\n", OUTPUT_FILENAME);
printf("done.\n");
return 0;
}
|