1 //
2 // scramble_example.c
3 //
4 // Data-scrambling example. Physical layer synchronization of
5 // received waveforms relies on independent and identically
6 // distributed underlying data symbols. If the message sequence,
7 // however, is '00000....' and the modulation scheme is BPSK,
8 // the synchronizer probably won't be able to recover the symbol
9 // timing. It is imperative to increase the entropy of the data
10 // for this to happen. The data scrambler routine attempts to
11 // 'whiten' the data sequence with a bit mask in order to achieve
12 // maximum entropy. This example demonstrates the interface.
13 //
14
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <string.h>
18 #include <math.h>
19 #include "liquid.h"
20
21 float compute_entropy(unsigned char * _x,
22 unsigned int _n);
23
main()24 int main() {
25 unsigned int n=32; // number of data bytes
26
27 unsigned char x[n]; // input data
28 unsigned char y[n]; // scrambled data
29 unsigned char z[n]; // unscrambled data
30
31 unsigned int i;
32
33 // generate data
34 for (i=0; i<n; i++)
35 x[i] = rand() % 2 ? 0x0f : 0xc8;
36
37 // scramble input
38 memmove(y,x,n);
39 scramble_data(y,n);
40
41 // unscramble result
42 memmove(z,y,n);
43 unscramble_data(z,n);
44
45 float Hx = compute_entropy(x,n);
46 float Hy = compute_entropy(y,n);
47
48 // print results
49 printf("i\tx\ty\tz\n");
50 printf("--\t--\t--\t--\n");
51 for (i=0; i<n; i++)
52 printf("%u\t%.2x\t%.2x\t%.2x\n", i, x[i], y[i], z[i]);
53
54 printf("H(x) = %12.8f\n", Hx);
55 printf("H(y) = %12.8f\n", Hy);
56
57 printf("done.\n");
58 return 0;
59 }
60
61 // raw entropy calculation, orders 1, 2, 4, 8
compute_entropy(unsigned char * _x,unsigned int _n)62 float compute_entropy(unsigned char * _x,
63 unsigned int _n)
64 {
65 unsigned int i;
66 unsigned int j;
67
68 // initialize counter arrays
69 unsigned int c1[2]; // 1-bit symbols
70 unsigned int c2[4]; // 2-bit symbols
71 unsigned int c4[16]; // 4-bit symbols
72 unsigned int c8[256]; // 8-bit symbols
73
74 for (i=0; i<2; i++) c1[i] = 0;
75 for (i=0; i<4; i++) c2[i] = 0;
76 for (i=0; i<16; i++) c4[i] = 0;
77 for (i=0; i<256; i++) c8[i] = 0;
78
79 for (i=0; i<_n; i++) {
80 // b:1
81 for (j=0; j<8; j++) c1[ (_x[i] >> j) & 0x01 ]++;
82
83 // b:2
84 for (j=0; j<8; j+=2) c2[ (_x[i] >> j) & 0x03 ]++;
85
86 // b:4
87 for (j=0; j<8; j+=4) c4[ (_x[i] >> j) & 0x0f ]++;
88
89 // b:8
90 c8[ _x[i] ]++;
91 }
92
93 // compute entropy
94 float H1 = 0.0f;
95 float H2 = 0.0f;
96 float H4 = 0.0f;
97 float H8 = 0.0f;
98
99 float p;
100 for (i=0; i<2; i++) {
101 p = (float) c1[i] / (float)(8*_n);
102 H1 -= p * log2f(p+1e-12f);
103 }
104 H1 /= 1.0f;
105
106 for (i=0; i<4; i++) {
107 p = (float) c2[i] / (float)(4*_n);
108 H2 -= p * log2f(p+1e-12f);
109 }
110 H2 /= 2.0f;
111
112 for (i=0; i<16; i++) {
113 p = (float) c4[i] / (float)(2*_n);
114 H4 -= p * log2f(p+1e-12f);
115 }
116 H4 /= 4.0f;
117
118 for (i=0; i<256; i++) {
119 p = (float) c8[i] / (float)(_n);
120 H8 -= p * log2f(p+1e-12f);
121 }
122 H8 /= 8.0f;
123
124 #if 0
125 printf("H1 : %12.8f\n", H1);
126 printf("H2 : %12.8f\n", H2);
127 printf("H4 : %12.8f\n", H4);
128 printf("H8 : %12.8f\n", H8);
129 #endif
130
131 // not sure if product is truly the entropy, but
132 // it is a fair assessment
133 return H1 * H2 * H4 * H8;
134 }
135
136