1 //
2 // qpacketmodem_example.c
3 //
4 // This example demonstrates the basic packet modem encoder/decoder
5 // operation. A packet of data is encoded and modulated into symbols,
6 // channel noise is added, and the resulting packet is demodulated
7 // and decoded.
8 //
9
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include <math.h>
14 #include <time.h>
15 #include <getopt.h>
16 #include <assert.h>
17
18 #include "liquid.h"
19
usage()20 void usage()
21 {
22 printf("ofdmflexframesync_example [options]\n");
23 printf(" h : print usage\n");
24 printf(" n : payload length [bytes], default: 400\n");
25 printf(" m : modulation scheme (qpsk default)\n");
26 liquid_print_modulation_schemes();
27 printf(" v : data integrity check: crc32 default\n");
28 liquid_print_crc_schemes();
29 printf(" c : coding scheme (inner): g2412 default\n");
30 printf(" k : coding scheme (outer): none default\n");
31 liquid_print_fec_schemes();
32 printf(" s : signal-to-noise ratio [dB], default: 6\n");
33 }
34
main(int argc,char * argv[])35 int main(int argc, char *argv[])
36 {
37 //srand( time(NULL) );
38
39 // options
40 modulation_scheme ms = LIQUID_MODEM_QPSK; // mod. scheme
41 crc_scheme check = LIQUID_CRC_32; // data validity check
42 fec_scheme fec0 = LIQUID_FEC_GOLAY2412; // fec (inner)
43 fec_scheme fec1 = LIQUID_FEC_NONE; // fec (outer)
44 unsigned int payload_len = 400; // payload length
45 float SNRdB = 6.0f; // SNR [dB]
46 const char filename[] = "qpacketmodem_example.m"; // output filename
47
48 // get options
49 int dopt;
50 while((dopt = getopt(argc,argv,"hn:m:v:c:k:s:")) != EOF){
51 switch (dopt) {
52 case 'h': usage(); return 0;
53 case 'n': payload_len = atol(optarg); break;
54 case 'm': ms = liquid_getopt_str2mod(optarg); break;
55 case 'v': check = liquid_getopt_str2crc(optarg); break;
56 case 'c': fec0 = liquid_getopt_str2fec(optarg); break;
57 case 'k': fec1 = liquid_getopt_str2fec(optarg); break;
58 case 's': SNRdB = atof(optarg); break;
59 default:
60 exit(-1);
61 }
62 }
63 unsigned int i;
64
65 // derived values
66 float nstd = powf(10.0f, -SNRdB/20.0f);
67
68 // create and configure packet encoder/decoder object
69 qpacketmodem q = qpacketmodem_create();
70 qpacketmodem_configure(q, payload_len, check, fec0, fec1, ms);
71 qpacketmodem_print(q);
72
73 // initialize payload
74 unsigned char payload_tx[payload_len];
75 unsigned char payload_rx[payload_len];
76
77 // initialize payload
78 for (i=0; i<payload_len; i++) {
79 payload_tx[i] = rand() & 0xff;
80 payload_rx[i] = 0x00;
81 }
82
83 // get frame length
84 unsigned int frame_len = qpacketmodem_get_frame_len(q);
85
86 // allocate memory for frame samples
87 float complex frame_tx[frame_len];
88 float complex frame_rx[frame_len];
89
90 // encode frame
91 qpacketmodem_encode(q, payload_tx, frame_tx);
92
93 // add noise
94 for (i=0; i<frame_len; i++)
95 frame_rx[i] = frame_tx[i] + nstd*(randnf() + _Complex_I*randnf())*M_SQRT1_2;
96
97 // decode frame
98 int crc_pass = qpacketmodem_decode(q, frame_rx, payload_rx);
99
100 // count errors
101 unsigned int num_bit_errors = count_bit_errors_array(payload_tx, payload_rx, payload_len);
102
103 // print results
104 printf("payload pass ? %s, errors: %u / %u\n",
105 crc_pass ? "pass" : "FAIL",
106 num_bit_errors,
107 8*payload_len);
108
109 // destroy allocated objects
110 qpacketmodem_destroy(q);
111
112 // write symbols to output file for plotting
113 FILE * fid = fopen(filename,"w");
114 if (!fid) {
115 fprintf(stderr,"error: could not open '%s' for writing\n", filename);
116 return -1;
117 }
118 fprintf(fid,"%% %s : auto-generated file\n", filename);
119 fprintf(fid,"clear all;\n");
120 fprintf(fid,"close all;\n");
121 fprintf(fid,"frame_len = %u;\n", frame_len);
122 fprintf(fid,"y = zeros(1,frame_len);\n");
123 for (i=0; i<frame_len; i++)
124 fprintf(fid,"y(%6u) = %12.4e + 1i*%12.4e;\n", i+1, crealf(frame_rx[i]), cimagf(frame_rx[i]));
125 fprintf(fid,"figure('Color','white');\n");
126 fprintf(fid,"plot(real(y),imag(y),'x','MarkerSize',3);\n");
127 fprintf(fid,"axis([-1 1 -1 1]*1.5);\n");
128 fprintf(fid,"axis square;\n");
129 fprintf(fid,"grid on;\n");
130 fprintf(fid,"xlabel('real');\n");
131 fprintf(fid,"ylabel('imag');\n");
132
133 fclose(fid);
134 printf("results written to '%s'\n", filename);
135
136 printf("done.\n");
137 return 0;
138 }
139
140