File: modem_arb_example.c

package info (click to toggle)
liquid-dsp 1.3.1-1
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 7,376 kB
  • sloc: ansic: 93,650; sh: 3,208; makefile: 1,171; python: 95; asm: 11
file content (131 lines) | stat: -rw-r--r-- 3,610 bytes parent folder | download | duplicates (3)
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;
}