qam edits

This commit is contained in:
2025-10-07 12:58:52 +02:00
parent a4ad553067
commit 876d37d1ab
7 changed files with 1341 additions and 1 deletions

79
FFT/ffttp.c Normal file
View File

@ -0,0 +1,79 @@
#include <math.h>
#include <stdio.h>
#include <complex.h>
#include <stdint.h>
#include <stdlib.h>
complex float* fft(complex float* p, uint32_t N) {
complex float w = cexpf(-2 * I * M_PI / N);
if (N == 1)
return p;
complex float* pe = (complex float*)malloc(sizeof(complex float) * (N / 2));
complex float* po = (complex float*)malloc(sizeof(complex float) * (N / 2));
for (int i = 0; i < N - 1; i += 2) {
pe[i / 2] = p[i];
po[i / 2] = p[i + 1];
}
complex float* xe = fft(pe, N / 2);
complex float* xo = fft(po, N / 2);
complex float* ps = (complex float*)malloc(sizeof(complex float) * N);
for (int i = 0; i < N / 2; i++) {
ps[i] = xe[i] + cpowf(w, (complex float)i) * xo[i];
ps[i + N / 2] = xe[i] - cpowf(w, (complex float)i) * xo[i];
}
return ps;
}
int main() {
FILE *f = fopen("signal.csv","r");
if (!f) { perror("signal.csv"); return 1; }
double t, a;
int capacity = 1024, n = 0;
complex float *samples = malloc(sizeof(complex float) * capacity);
while (fscanf(f, "%lf;%lf", &t, &a) == 2) {
if (n >= capacity) {
capacity *= 2;
samples = realloc(samples, sizeof(complex float)*capacity);
}
samples[n++] = a;
}
fclose(f);
int fsize = 1 << (int)floorf(log2f((float)n));
complex float* cwav_data = (complex float*)malloc(sizeof(complex float) * fsize);
for (int i = 0; i < fsize; i++)
cwav_data[i] = samples[i];
complex float* ft = fft(cwav_data, fsize);
double Fe = 400.0;
FILE *gnuplot = popen("gnuplot -persistent", "w");
fprintf(gnuplot, "set title 'fft'\n");
fprintf(gnuplot, "set logscale x\n");
fprintf(gnuplot, "set logscale y\n");
fprintf(gnuplot, "plot '-' with linespoints title 'fft'\n");
for (int i = 0; i < fsize/2; i++) {
double freq = (double)i * Fe / fsize;
fprintf(gnuplot, "%f %f\n", freq ,cabsf(ft[i]));
}
fprintf(gnuplot, "e\n");
pclose(gnuplot);
free(samples);
free(cwav_data);
free(ft);
return 0;
}

View File

@ -3,7 +3,7 @@
#include <complex.h> #include <complex.h>
#include <stdint.h> #include <stdint.h>
#include <stdlib.h> #include <stdlib.h>
#include "../WAV/wav.h" #include "../wav/wav.h"
complex float* fft(complex float* p, uint32_t N) { complex float* fft(complex float* p, uint32_t N) {
complex float w = cexpf(-2 * I * M_PI / N); complex float w = cexpf(-2 * I * M_PI / N);

476
FFT/signal.csv Normal file
View File

@ -0,0 +1,476 @@
0;0.164159775
0.000315;0.164159775
0.00063;0.164159775
0.000945;0.164159775
0.00126;0.164159775
0.001575;0.164159775
0.00189;1.60616973
0.002205;1.60616973
0.00252;1.60616973
0.002835;1.60616973
0.00315;1.601180077
0.003465;1.60616973
0.00378;1.60616973
0.004095;2.47935915
0.00441;2.439441919
0.004725;2.439441919
0.00504;2.439441919
0.005355;2.434452266
0.00567;2.434452266
0.005985;2.434452266
0.0063;2.439441919
0.006615;2.34962815
0.00693;2.34962815
0.007245;2.34962815
0.00756;2.34962815
0.007875;2.34962815
0.00819;2.34962815
0.008505;2.34962815
0.00882;2.34962815
0.009135;1.371656001
0.00945;1.371656001
0.009765;1.376645654
0.01008;1.371656001
0.010395;1.371656001
0.01071;1.376645654
0.011025;1.371656001
0.01134;1.371656001
0.011655;-0.120250493
0.01197;-0.115260839
0.012285;-0.110271186
0.0126;-0.110271186
0.012915;-0.115260839
0.01323;-0.110271186
0.013545;-0.115260839
0.01386;-0.110271186
0.014175;-1.552281141
0.01449;-1.547291487
0.014805;-1.552281141
0.01512;-1.547291487
0.015435;-1.547291487
0.01575;-1.547291487
0.016065;-1.547291487
0.01638;-1.547291487
0.016695;-2.395532638
0.01701;-2.390542984
0.017325;-2.390542984
0.01764;-2.390542984
0.017955;-2.390542984
0.01827;-2.390542984
0.018585;-2.390542984
0.0189;-2.390542984
0.019215;-2.305718869
0.01953;-2.300729215
0.019845;-2.300729215
0.02016;-2.300729215
0.020475;-2.305718869
0.02079;-2.305718869
0.021105;-2.300729215
0.02142;-2.300729215
0.021735;-1.322757065
0.02205;-1.322757065
0.022365;-1.322757065
0.02268;-1.322757065
0.022995;-1.322757065
0.02331;-1.322757065
0.023625;-1.322757065
0.02394;-1.322757065
0.024255;0.169149429
0.02457;0.164159775
0.024885;0.164159775
0.0252;0.169149429
0.025515;0.164159775
0.02583;0.164159775
0.026145;0.164159775
0.02646;0.164159775
0.026775;1.60616973
0.02709;1.60616973
0.027405;1.60616973
0.02772;1.60616973
0.028035;1.60616973
0.02835;1.601180077
0.028665;1.601180077
0.02898;1.601180077
0.029295;2.439441919
0.02961;2.439441919
0.029925;2.439441919
0.03024;2.439441919
0.030555;2.439441919
0.03087;2.439441919
0.031185;2.439441919
0.0315;2.444431573
0.031815;2.34962815
0.03213;2.34962815
0.032445;2.34962815
0.03276;2.34962815
0.033075;2.34962815
0.03339;2.34962815
0.033705;2.34962815
0.03402;2.34962815
0.034335;1.371656001
0.03465;1.371656001
0.034965;1.371656001
0.03528;1.371656001
0.035595;1.371656001
0.03591;1.371656001
0.036225;1.371656001
0.03654;1.371656001
0.036855;-0.115260839
0.03717;-0.115260839
0.037485;-0.115260839
0.0378;-0.110271186
0.038115;-0.110271186
0.03843;-0.110271186
0.038745;-0.110271186
0.03906;-0.110271186
0.039375;-1.557270795
0.03969;-1.557270795
0.040005;-1.557270795
0.04032;-1.552281141
0.040635;-1.557270795
0.04095;-1.552281141
0.041265;-1.552281141
0.04158;-1.552281141
0.041895;-2.390542984
0.04221;-2.390542984
0.042525;-2.38555333
0.04284;-2.390542984
0.043155;-2.390542984
0.04347;-2.390542984
0.043785;-2.390542984
0.0441;-2.295739561
0.044415;-2.300729215
0.04473;-2.300729215
0.045045;-2.300729215
0.04536;-2.300729215
0.045675;-2.300729215
0.04599;-2.305718869
0.046305;-2.300729215
0.04662;-1.317767411
0.046935;-1.322757065
0.04725;-1.322757065
0.047565;-1.322757065
0.04788;-1.322757065
0.048195;-1.317767411
0.04851;-1.322757065
0.048825;-1.322757065
0.04914;0.174139082
0.049455;0.169149429
0.04977;0.164159775
0.050085;0.164159775
0.0504;0.169149429
0.050715;0.164159775
0.05103;0.164159775
0.051345;0.164159775
0.05166;1.60616973
0.051975;1.601180077
0.05229;1.601180077
0.052605;1.601180077
0.05292;1.601180077
0.053235;1.601180077
0.05355;1.596190423
0.053865;1.601180077
0.05418;2.439441919
0.054495;2.439441919
0.05481;2.439441919
0.055125;2.434452266
0.05544;2.434452266
0.055755;2.439441919
0.05607;2.434452266
0.056385;2.434452266
0.0567;2.34962815
0.057015;2.34962815
0.05733;2.34962815
0.057645;2.34962815
0.05796;2.34962815
0.058275;2.34962815
0.05859;2.34962815
0.058905;2.34962815
0.05922;1.366666347
0.059535;1.371656001
0.05985;1.371656001
0.060165;1.371656001
0.06048;1.371656001
0.060795;1.376645654
0.06111;1.371656001
0.061425;1.371656001
0.06174;-0.115260839
0.062055;-0.115260839
0.06237;-0.115260839
0.062685;-0.115260839
0.063;-0.110271186
0.063315;-0.115260839
0.06363;-0.110271186
0.063945;-0.110271186
0.06426;-1.552281141
0.064575;-1.552281141
0.06489;-1.552281141
0.065205;-1.547291487
0.06552;-1.547291487
0.065835;-1.547291487
0.06615;-1.547291487
0.066465;-1.547291487
0.06678;-2.390542984
0.067095;-2.390542984
0.06741;-2.390542984
0.067725;-2.380563676
0.06804;-2.390542984
0.068355;-2.38555333
0.06867;-2.38555333
0.068985;-2.390542984
0.0693;-2.305718869
0.069615;-2.300729215
0.06993;-2.305718869
0.070245;-2.300729215
0.07056;-2.305718869
0.070875;-2.305718869
0.07119;-2.305718869
0.071505;-2.300729215
0.07182;-1.322757065
0.072135;-1.322757065
0.07245;-1.317767411
0.072765;-1.322757065
0.07308;-1.322757065
0.073395;-1.322757065
0.07371;-1.332736373
0.074025;-1.322757065
0.07434;0.169149429
0.074655;0.169149429
0.07497;0.169149429
0.075285;0.164159775
0.0756;0.169149429
0.075915;0.164159775
0.07623;0.164159775
0.076545;0.164159775
0.07686;1.60616973
0.077175;1.601180077
0.07749;1.601180077
0.077805;1.601180077
0.07812;1.601180077
0.078435;1.601180077
0.07875;1.601180077
0.079065;1.601180077
0.07938;2.439441919
0.079695;2.439441919
0.08001;2.439441919
0.080325;2.434452266
0.08064;2.439441919
0.080955;2.434452266
0.08127;2.434452266
0.081585;2.314700574
0.0819;2.34962815
0.082215;2.34962815
0.08253;2.34962815
0.082845;2.34962815
0.08316;2.34962815
0.083475;2.34962815
0.08379;2.34962815
0.084105;1.361676693
0.08442;1.371656001
0.084735;1.371656001
0.08505;1.371656001
0.085365;1.371656001
0.08568;1.376645654
0.085995;1.371656001
0.08631;1.371656001
0.086625;-0.120250493
0.08694;-0.115260839
0.087255;-0.115260839
0.08757;-0.115260839
0.087885;-0.110271186
0.0882;-0.110271186
0.088515;-0.110271186
0.08883;-0.115260839
0.089145;-1.557270795
0.08946;-1.552281141
0.089775;-1.547291487
0.09009;-1.547291487
0.090405;-1.547291487
0.09072;-1.547291487
0.091035;-1.547291487
0.09135;-1.552281141
0.091665;-2.395532638
0.09198;-2.390542984
0.092295;-2.390542984
0.09261;-2.390542984
0.092925;-2.390542984
0.09324;-2.390542984
0.093555;-2.38555333
0.09387;-2.390542984
0.094185;-2.300729215
0.0945;-2.300729215
0.094815;-2.300729215
0.09513;-2.300729215
0.095445;-2.300729215
0.09576;-2.300729215
0.096075;-2.300729215
0.09639;-2.300729215
0.096705;-1.317767411
0.09702;-1.317767411
0.097335;-1.322757065
0.09765;-1.322757065
0.097965;-1.322757065
0.09828;-1.322757065
0.098595;-1.327746719
0.09891;-1.322757065
0.099225;0.169149429
0.09954;0.169149429
0.099855;0.164159775
0.10017;0.164159775
0.100485;0.164159775
0.1008;0.164159775
0.101115;0.159170121
0.10143;0.169149429
0.101745;1.601180077
0.10206;1.596190423
0.102375;1.601180077
0.10269;1.601180077
0.103005;1.601180077
0.10332;1.601180077
0.103635;1.596190423
0.10395;1.596190423
0.104265;2.434452266
0.10458;2.439441919
0.104895;2.439441919
0.10521;2.434452266
0.105525;2.434452266
0.10584;2.434452266
0.106155;2.434452266
0.10647;2.429462612
0.106785;2.354617804
0.1071;2.34962815
0.107415;2.34962815
0.10773;2.34962815
0.108045;2.34962815
0.10836;2.354617804
0.108675;2.34962815
0.10899;2.34962815
0.109305;1.371656001
0.10962;1.376645654
0.109935;1.371656001
0.11025;1.371656001
0.110565;1.371656001
0.11088;1.371656001
0.111195;1.376645654
0.11151;1.371656001
0.111825;-0.115260839
0.11214;-0.115260839
0.112455;-0.110271186
0.11277;-0.110271186
0.113085;-0.110271186
0.1134;-0.115260839
0.113715;-0.110271186
0.11403;-0.115260839
0.114345;-1.552281141
0.11466;-1.557270795
0.114975;-1.552281141
0.11529;-1.552281141
0.115605;-1.552281141
0.11592;-1.552281141
0.116235;-1.552281141
0.11655;-1.552281141
0.116865;-2.390542984
0.11718;-2.390542984
0.117495;-2.390542984
0.11781;-2.390542984
0.118125;-2.390542984
0.11844;-2.390542984
0.118755;-2.390542984
0.11907;-2.390542984
0.119385;-2.305718869
0.1197;-2.300729215
0.120015;-2.300729215
0.12033;-2.305718869
0.120645;-2.300729215
0.12096;-2.300729215
0.121275;-2.305718869
0.12159;-1.277850181
0.121905;-1.322757065
0.12222;-1.322757065
0.122535;-1.322757065
0.12285;-1.322757065
0.123165;-1.322757065
0.12348;-1.322757065
0.123795;-1.327746719
0.12411;0.18411839
0.124425;0.164159775
0.12474;0.164159775
0.125055;0.164159775
0.12537;0.164159775
0.125685;0.164159775
0.126;0.164159775
0.126315;0.164159775
0.12663;1.616149038
0.126945;1.60616973
0.12726;1.60616973
0.127575;1.60616973
0.12789;1.601180077
0.128205;1.601180077
0.12852;1.601180077
0.128835;1.601180077
0.12915;2.439441919
0.129465;2.439441919
0.12978;2.434452266
0.130095;2.439441919
0.13041;2.439441919
0.130725;2.439441919
0.13104;2.434452266
0.131355;2.434452266
0.13167;2.34962815
0.131985;2.34962815
0.1323;2.34962815
0.132615;2.34962815
0.13293;2.34962815
0.133245;2.34962815
0.13356;2.34962815
0.133875;2.34962815
0.13419;1.371656001
0.134505;1.371656001
0.13482;1.371656001
0.135135;1.371656001
0.13545;1.371656001
0.135765;1.371656001
0.13608;1.376645654
0.136395;1.371656001
0.13671;-0.120250493
0.137025;-0.115260839
0.13734;-0.115260839
0.137655;-0.115260839
0.13797;-0.115260839
0.138285;-0.110271186
0.1386;-0.110271186
0.138915;-0.115260839
0.13923;-1.552281141
0.139545;-1.547291487
0.13986;-1.552281141
0.140175;-1.547291487
0.14049;-1.547291487
0.140805;-1.552281141
0.14112;-1.552281141
0.141435;-1.552281141
0.14175;-2.390542984
0.142065;-2.390542984
0.14238;-2.390542984
0.142695;-2.390542984
0.14301;-2.390542984
0.143325;-2.390542984
0.14364;-2.390542984
0.143955;-2.390542984
0.14427;-2.300729215
0.144585;-2.300729215
0.1449;-2.305718869
0.145215;-2.300729215
0.14553;-2.300729215
0.145845;-2.300729215
0.14616;-2.300729215
0.146475;-2.300729215
0.14679;-1.317767411
0.147105;-1.317767411
0.14742;-1.322757065
0.147735;-1.322757065
0.14805;-1.322757065
0.148365;-1.317767411
0.14868;-1.322757065
0.148995;-1.322757065
0.14931;0.169149429
0.149625;0.169149429
1 0 0.164159775
2 0.000315 0.164159775
3 0.00063 0.164159775
4 0.000945 0.164159775
5 0.00126 0.164159775
6 0.001575 0.164159775
7 0.00189 1.60616973
8 0.002205 1.60616973
9 0.00252 1.60616973
10 0.002835 1.60616973
11 0.00315 1.601180077
12 0.003465 1.60616973
13 0.00378 1.60616973
14 0.004095 2.47935915
15 0.00441 2.439441919
16 0.004725 2.439441919
17 0.00504 2.439441919
18 0.005355 2.434452266
19 0.00567 2.434452266
20 0.005985 2.434452266
21 0.0063 2.439441919
22 0.006615 2.34962815
23 0.00693 2.34962815
24 0.007245 2.34962815
25 0.00756 2.34962815
26 0.007875 2.34962815
27 0.00819 2.34962815
28 0.008505 2.34962815
29 0.00882 2.34962815
30 0.009135 1.371656001
31 0.00945 1.371656001
32 0.009765 1.376645654
33 0.01008 1.371656001
34 0.010395 1.371656001
35 0.01071 1.376645654
36 0.011025 1.371656001
37 0.01134 1.371656001
38 0.011655 -0.120250493
39 0.01197 -0.115260839
40 0.012285 -0.110271186
41 0.0126 -0.110271186
42 0.012915 -0.115260839
43 0.01323 -0.110271186
44 0.013545 -0.115260839
45 0.01386 -0.110271186
46 0.014175 -1.552281141
47 0.01449 -1.547291487
48 0.014805 -1.552281141
49 0.01512 -1.547291487
50 0.015435 -1.547291487
51 0.01575 -1.547291487
52 0.016065 -1.547291487
53 0.01638 -1.547291487
54 0.016695 -2.395532638
55 0.01701 -2.390542984
56 0.017325 -2.390542984
57 0.01764 -2.390542984
58 0.017955 -2.390542984
59 0.01827 -2.390542984
60 0.018585 -2.390542984
61 0.0189 -2.390542984
62 0.019215 -2.305718869
63 0.01953 -2.300729215
64 0.019845 -2.300729215
65 0.02016 -2.300729215
66 0.020475 -2.305718869
67 0.02079 -2.305718869
68 0.021105 -2.300729215
69 0.02142 -2.300729215
70 0.021735 -1.322757065
71 0.02205 -1.322757065
72 0.022365 -1.322757065
73 0.02268 -1.322757065
74 0.022995 -1.322757065
75 0.02331 -1.322757065
76 0.023625 -1.322757065
77 0.02394 -1.322757065
78 0.024255 0.169149429
79 0.02457 0.164159775
80 0.024885 0.164159775
81 0.0252 0.169149429
82 0.025515 0.164159775
83 0.02583 0.164159775
84 0.026145 0.164159775
85 0.02646 0.164159775
86 0.026775 1.60616973
87 0.02709 1.60616973
88 0.027405 1.60616973
89 0.02772 1.60616973
90 0.028035 1.60616973
91 0.02835 1.601180077
92 0.028665 1.601180077
93 0.02898 1.601180077
94 0.029295 2.439441919
95 0.02961 2.439441919
96 0.029925 2.439441919
97 0.03024 2.439441919
98 0.030555 2.439441919
99 0.03087 2.439441919
100 0.031185 2.439441919
101 0.0315 2.444431573
102 0.031815 2.34962815
103 0.03213 2.34962815
104 0.032445 2.34962815
105 0.03276 2.34962815
106 0.033075 2.34962815
107 0.03339 2.34962815
108 0.033705 2.34962815
109 0.03402 2.34962815
110 0.034335 1.371656001
111 0.03465 1.371656001
112 0.034965 1.371656001
113 0.03528 1.371656001
114 0.035595 1.371656001
115 0.03591 1.371656001
116 0.036225 1.371656001
117 0.03654 1.371656001
118 0.036855 -0.115260839
119 0.03717 -0.115260839
120 0.037485 -0.115260839
121 0.0378 -0.110271186
122 0.038115 -0.110271186
123 0.03843 -0.110271186
124 0.038745 -0.110271186
125 0.03906 -0.110271186
126 0.039375 -1.557270795
127 0.03969 -1.557270795
128 0.040005 -1.557270795
129 0.04032 -1.552281141
130 0.040635 -1.557270795
131 0.04095 -1.552281141
132 0.041265 -1.552281141
133 0.04158 -1.552281141
134 0.041895 -2.390542984
135 0.04221 -2.390542984
136 0.042525 -2.38555333
137 0.04284 -2.390542984
138 0.043155 -2.390542984
139 0.04347 -2.390542984
140 0.043785 -2.390542984
141 0.0441 -2.295739561
142 0.044415 -2.300729215
143 0.04473 -2.300729215
144 0.045045 -2.300729215
145 0.04536 -2.300729215
146 0.045675 -2.300729215
147 0.04599 -2.305718869
148 0.046305 -2.300729215
149 0.04662 -1.317767411
150 0.046935 -1.322757065
151 0.04725 -1.322757065
152 0.047565 -1.322757065
153 0.04788 -1.322757065
154 0.048195 -1.317767411
155 0.04851 -1.322757065
156 0.048825 -1.322757065
157 0.04914 0.174139082
158 0.049455 0.169149429
159 0.04977 0.164159775
160 0.050085 0.164159775
161 0.0504 0.169149429
162 0.050715 0.164159775
163 0.05103 0.164159775
164 0.051345 0.164159775
165 0.05166 1.60616973
166 0.051975 1.601180077
167 0.05229 1.601180077
168 0.052605 1.601180077
169 0.05292 1.601180077
170 0.053235 1.601180077
171 0.05355 1.596190423
172 0.053865 1.601180077
173 0.05418 2.439441919
174 0.054495 2.439441919
175 0.05481 2.439441919
176 0.055125 2.434452266
177 0.05544 2.434452266
178 0.055755 2.439441919
179 0.05607 2.434452266
180 0.056385 2.434452266
181 0.0567 2.34962815
182 0.057015 2.34962815
183 0.05733 2.34962815
184 0.057645 2.34962815
185 0.05796 2.34962815
186 0.058275 2.34962815
187 0.05859 2.34962815
188 0.058905 2.34962815
189 0.05922 1.366666347
190 0.059535 1.371656001
191 0.05985 1.371656001
192 0.060165 1.371656001
193 0.06048 1.371656001
194 0.060795 1.376645654
195 0.06111 1.371656001
196 0.061425 1.371656001
197 0.06174 -0.115260839
198 0.062055 -0.115260839
199 0.06237 -0.115260839
200 0.062685 -0.115260839
201 0.063 -0.110271186
202 0.063315 -0.115260839
203 0.06363 -0.110271186
204 0.063945 -0.110271186
205 0.06426 -1.552281141
206 0.064575 -1.552281141
207 0.06489 -1.552281141
208 0.065205 -1.547291487
209 0.06552 -1.547291487
210 0.065835 -1.547291487
211 0.06615 -1.547291487
212 0.066465 -1.547291487
213 0.06678 -2.390542984
214 0.067095 -2.390542984
215 0.06741 -2.390542984
216 0.067725 -2.380563676
217 0.06804 -2.390542984
218 0.068355 -2.38555333
219 0.06867 -2.38555333
220 0.068985 -2.390542984
221 0.0693 -2.305718869
222 0.069615 -2.300729215
223 0.06993 -2.305718869
224 0.070245 -2.300729215
225 0.07056 -2.305718869
226 0.070875 -2.305718869
227 0.07119 -2.305718869
228 0.071505 -2.300729215
229 0.07182 -1.322757065
230 0.072135 -1.322757065
231 0.07245 -1.317767411
232 0.072765 -1.322757065
233 0.07308 -1.322757065
234 0.073395 -1.322757065
235 0.07371 -1.332736373
236 0.074025 -1.322757065
237 0.07434 0.169149429
238 0.074655 0.169149429
239 0.07497 0.169149429
240 0.075285 0.164159775
241 0.0756 0.169149429
242 0.075915 0.164159775
243 0.07623 0.164159775
244 0.076545 0.164159775
245 0.07686 1.60616973
246 0.077175 1.601180077
247 0.07749 1.601180077
248 0.077805 1.601180077
249 0.07812 1.601180077
250 0.078435 1.601180077
251 0.07875 1.601180077
252 0.079065 1.601180077
253 0.07938 2.439441919
254 0.079695 2.439441919
255 0.08001 2.439441919
256 0.080325 2.434452266
257 0.08064 2.439441919
258 0.080955 2.434452266
259 0.08127 2.434452266
260 0.081585 2.314700574
261 0.0819 2.34962815
262 0.082215 2.34962815
263 0.08253 2.34962815
264 0.082845 2.34962815
265 0.08316 2.34962815
266 0.083475 2.34962815
267 0.08379 2.34962815
268 0.084105 1.361676693
269 0.08442 1.371656001
270 0.084735 1.371656001
271 0.08505 1.371656001
272 0.085365 1.371656001
273 0.08568 1.376645654
274 0.085995 1.371656001
275 0.08631 1.371656001
276 0.086625 -0.120250493
277 0.08694 -0.115260839
278 0.087255 -0.115260839
279 0.08757 -0.115260839
280 0.087885 -0.110271186
281 0.0882 -0.110271186
282 0.088515 -0.110271186
283 0.08883 -0.115260839
284 0.089145 -1.557270795
285 0.08946 -1.552281141
286 0.089775 -1.547291487
287 0.09009 -1.547291487
288 0.090405 -1.547291487
289 0.09072 -1.547291487
290 0.091035 -1.547291487
291 0.09135 -1.552281141
292 0.091665 -2.395532638
293 0.09198 -2.390542984
294 0.092295 -2.390542984
295 0.09261 -2.390542984
296 0.092925 -2.390542984
297 0.09324 -2.390542984
298 0.093555 -2.38555333
299 0.09387 -2.390542984
300 0.094185 -2.300729215
301 0.0945 -2.300729215
302 0.094815 -2.300729215
303 0.09513 -2.300729215
304 0.095445 -2.300729215
305 0.09576 -2.300729215
306 0.096075 -2.300729215
307 0.09639 -2.300729215
308 0.096705 -1.317767411
309 0.09702 -1.317767411
310 0.097335 -1.322757065
311 0.09765 -1.322757065
312 0.097965 -1.322757065
313 0.09828 -1.322757065
314 0.098595 -1.327746719
315 0.09891 -1.322757065
316 0.099225 0.169149429
317 0.09954 0.169149429
318 0.099855 0.164159775
319 0.10017 0.164159775
320 0.100485 0.164159775
321 0.1008 0.164159775
322 0.101115 0.159170121
323 0.10143 0.169149429
324 0.101745 1.601180077
325 0.10206 1.596190423
326 0.102375 1.601180077
327 0.10269 1.601180077
328 0.103005 1.601180077
329 0.10332 1.601180077
330 0.103635 1.596190423
331 0.10395 1.596190423
332 0.104265 2.434452266
333 0.10458 2.439441919
334 0.104895 2.439441919
335 0.10521 2.434452266
336 0.105525 2.434452266
337 0.10584 2.434452266
338 0.106155 2.434452266
339 0.10647 2.429462612
340 0.106785 2.354617804
341 0.1071 2.34962815
342 0.107415 2.34962815
343 0.10773 2.34962815
344 0.108045 2.34962815
345 0.10836 2.354617804
346 0.108675 2.34962815
347 0.10899 2.34962815
348 0.109305 1.371656001
349 0.10962 1.376645654
350 0.109935 1.371656001
351 0.11025 1.371656001
352 0.110565 1.371656001
353 0.11088 1.371656001
354 0.111195 1.376645654
355 0.11151 1.371656001
356 0.111825 -0.115260839
357 0.11214 -0.115260839
358 0.112455 -0.110271186
359 0.11277 -0.110271186
360 0.113085 -0.110271186
361 0.1134 -0.115260839
362 0.113715 -0.110271186
363 0.11403 -0.115260839
364 0.114345 -1.552281141
365 0.11466 -1.557270795
366 0.114975 -1.552281141
367 0.11529 -1.552281141
368 0.115605 -1.552281141
369 0.11592 -1.552281141
370 0.116235 -1.552281141
371 0.11655 -1.552281141
372 0.116865 -2.390542984
373 0.11718 -2.390542984
374 0.117495 -2.390542984
375 0.11781 -2.390542984
376 0.118125 -2.390542984
377 0.11844 -2.390542984
378 0.118755 -2.390542984
379 0.11907 -2.390542984
380 0.119385 -2.305718869
381 0.1197 -2.300729215
382 0.120015 -2.300729215
383 0.12033 -2.305718869
384 0.120645 -2.300729215
385 0.12096 -2.300729215
386 0.121275 -2.305718869
387 0.12159 -1.277850181
388 0.121905 -1.322757065
389 0.12222 -1.322757065
390 0.122535 -1.322757065
391 0.12285 -1.322757065
392 0.123165 -1.322757065
393 0.12348 -1.322757065
394 0.123795 -1.327746719
395 0.12411 0.18411839
396 0.124425 0.164159775
397 0.12474 0.164159775
398 0.125055 0.164159775
399 0.12537 0.164159775
400 0.125685 0.164159775
401 0.126 0.164159775
402 0.126315 0.164159775
403 0.12663 1.616149038
404 0.126945 1.60616973
405 0.12726 1.60616973
406 0.127575 1.60616973
407 0.12789 1.601180077
408 0.128205 1.601180077
409 0.12852 1.601180077
410 0.128835 1.601180077
411 0.12915 2.439441919
412 0.129465 2.439441919
413 0.12978 2.434452266
414 0.130095 2.439441919
415 0.13041 2.439441919
416 0.130725 2.439441919
417 0.13104 2.434452266
418 0.131355 2.434452266
419 0.13167 2.34962815
420 0.131985 2.34962815
421 0.1323 2.34962815
422 0.132615 2.34962815
423 0.13293 2.34962815
424 0.133245 2.34962815
425 0.13356 2.34962815
426 0.133875 2.34962815
427 0.13419 1.371656001
428 0.134505 1.371656001
429 0.13482 1.371656001
430 0.135135 1.371656001
431 0.13545 1.371656001
432 0.135765 1.371656001
433 0.13608 1.376645654
434 0.136395 1.371656001
435 0.13671 -0.120250493
436 0.137025 -0.115260839
437 0.13734 -0.115260839
438 0.137655 -0.115260839
439 0.13797 -0.115260839
440 0.138285 -0.110271186
441 0.1386 -0.110271186
442 0.138915 -0.115260839
443 0.13923 -1.552281141
444 0.139545 -1.547291487
445 0.13986 -1.552281141
446 0.140175 -1.547291487
447 0.14049 -1.547291487
448 0.140805 -1.552281141
449 0.14112 -1.552281141
450 0.141435 -1.552281141
451 0.14175 -2.390542984
452 0.142065 -2.390542984
453 0.14238 -2.390542984
454 0.142695 -2.390542984
455 0.14301 -2.390542984
456 0.143325 -2.390542984
457 0.14364 -2.390542984
458 0.143955 -2.390542984
459 0.14427 -2.300729215
460 0.144585 -2.300729215
461 0.1449 -2.305718869
462 0.145215 -2.300729215
463 0.14553 -2.300729215
464 0.145845 -2.300729215
465 0.14616 -2.300729215
466 0.146475 -2.300729215
467 0.14679 -1.317767411
468 0.147105 -1.317767411
469 0.14742 -1.322757065
470 0.147735 -1.322757065
471 0.14805 -1.322757065
472 0.148365 -1.317767411
473 0.14868 -1.322757065
474 0.148995 -1.322757065
475 0.14931 0.169149429
476 0.149625 0.169149429

BIN
QAM/qam

Binary file not shown.

273
QAM/qam.c Normal file
View File

@ -0,0 +1,273 @@
#include <math.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <complex.h>
#include <string.h>
#define A 1
struct qam_system_s {
int M; // Nombre de symboles M-QAM
int k; // Nombre de bits/symboles
double Fs; // Fréquence d'échantillionage
double Ts; // Temps d'échantillionage
int N; // Nombre d'échantillions
double Fc; // Fréquence de la porteuse
double complex** constellation; // Tableau de symboles I + j Q
};
typedef struct qam_system_s qam_system;
// Initialisation de la constellation (double tableau de taille sqrt(M)),
// ToDo : changer à un tableau à 1 dimension pour éviter de calculer sqrt(M)
void init_constellation (qam_system* qam) {
int sm = (int)sqrt(qam->M);
qam->constellation = (double complex**)malloc(sizeof(double complex*) * sm);
for (int i = 0; i < sm; i++) {
qam->constellation[i] = (double complex*)malloc(sizeof(double complex) * sm);
}
double norm_factor = sqrt((double)(qam->M - 1) / 3.0); // Pour puissance unitaire
for (int i = 0; i < sm; i++) {
double complex ip = -(sm - 1) + 2 * i;
for (int j = 0; j < sm; j++) {
double complex qp = -(sm - 1) + 2 * j;
qam->constellation[i][j] = (ip + I * qp);
}
}
}
// Calcul du bruit gaussien pour un sigma donné
// Formule de Box-Muller
double gaussian_noise (double sigma) {
double u1 = (rand() + 1) / ((double)RAND_MAX + 2);
double u2 = (rand() + 1) / ((double)RAND_MAX + 2);
return sigma * sqrt(-2 * log(u1)) * cos(2 * M_PI * u2);
}
// Ajout du bruit
void add_noise (double complex* s, int len, double sigma) {
for (int i = 0; i < len; i++) {
double nr = gaussian_noise(sigma);
double ni = gaussian_noise(sigma);
s[i] += nr + I * ni;
}
}
// Changer le tableau de bits en boolen ou alors la represenation binaire et shifter pour extraire les bits (pas bien si M plus grand)
void bits_to_symbols (qam_system* qam, uint8_t* bits, int nb_bits, double complex* symbols) {
int nb_symbols = nb_bits / qam->k;
int sm = sqrt(qam->M);
for (int k = 0; k < nb_symbols; k++) {
int id = 0;
for (int b = 0 ; b < qam->k; b++) {
id = id * 2 + bits[k * qam->k + b];
}
int i = id / sm;
int j = id % sm;
symbols[k] = qam->constellation[i][j];
}
}
// Modulation QAM
void modulate (qam_system* qam, double complex* symbols, int nb_symbols, double complex* s) {
for (int k = 0; k < nb_symbols; k++) {
double complex iq = symbols[k];
for (int n = 0; n < qam->N; n++) {
s[k * qam->N + n] = iq * cexp(2 * I * M_PI * qam->Fc * ((double)n / qam->Fs));
}
}
}
// Demodulation QAM
void demodulate(qam_system* qam, double complex* s, int nb_symbols, uint8_t* bits_hat) {
for (int k = 0; k < nb_symbols; k++) {
double complex r = 0;
for (int n = 0; n < qam->N; n++) {
r += s[k * qam->N + n] * cexp(-2 * I * M_PI * qam->Fc * ((double)n / qam->Fs));
}
r /= qam->N;
// Distance euclidien de Ir et Qr pour avoir le point le plus proche de la constellation (lent)
int sm = (int)sqrt(qam->M);
double min_d = INFINITY;
int i_cl, j_cl = 0;
for (int i = 0; i < sm; i++) {
for (int j = 0; j < sm; j++) {
double d = cabs(r - qam->constellation[i][j]);
if (d < min_d) {
min_d = d;
i_cl = i;
j_cl = j;
}
}
}
// index du symbole (id) : même mappage que dans bits_to_symbols()
int id = i_cl * sm + j_cl;
for (int b = 0; b < qam->k; b++) {
bits_hat[k * qam->k + b] = (id >> (qam->k - 1 - b)) & 1;
}
}
}
// Libération de la mémoire
void free_constellation(qam_system* qam) {
int sm = (int)sqrt(qam->M);
for (int i = 0; i < sm; i++)
free(qam->constellation[i]);
free(qam->constellation);
}
double compare_bits(uint8_t* bits1, uint8_t* bits2, int nb_bits) {
int errors = 0;
for (int i = 0; i < nb_bits; i++) {
if (bits1[i] != bits2[i]) errors++;
}
return (double)errors / nb_bits;
}
void symbol_timing_recovery(double complex* r, int r_len, double complex* preamble, int preamble_len, int N_max, int* offset_est, int* N_est) {
double max_corr = 0;
int best_offset = 0;
int best_N = 1;
for(int N_try = 1; N_try <= N_max; N_try++) {
for(int off = 0; off <= r_len - preamble_len * N_try; off++) {
double complex corr = 0;
for(int k = 0; k < preamble_len; k++) {
for(int n = 0; n < N_try; n++) {
corr += r[off + k * N_try + n] * conj(preamble[k]);
}
}
double mag = cabs(corr);
if(mag > max_corr) {
max_corr = mag;
best_offset = off;
best_N = N_try;
}
}
}
*offset_est = best_offset;
*N_est = best_N;
}
int main () {
qam_system qam;
qam.M = 16;
qam.k = (int)log2((double)(qam.M));
qam.Fs = 44100;
qam.Ts = 0.0003;
qam.N = (int)qam.Fs * qam.Ts;
qam.Fc = 2000;
init_constellation(&qam);
//int nb_bits = 1000;
//int nb_symbols = nb_bits / qam.k;
//uint8_t* input_bits = malloc(nb_bits * sizeof(uint8_t));
//for (int i = 0; i < nb_bits; i++) {
// input_bits[i] = rand() % 2;
//}
char* texte = "Bonjour tout le monde salut !!";
int nb_chars = strlen(texte);
int nb_bits = nb_chars * 8;
int nb_symbols = (nb_bits + qam.k - 1) / qam.k;
// Conversion du texte en bits
uint8_t* input_bits = malloc(nb_bits * sizeof(uint8_t));
for(int i = 0; i < nb_chars; i++){
for(int b = 0; b < 8; b++){
input_bits[i*8 + b] = (texte[i] >> (7-b)) & 1;
}
}
// Conversion en symboles
double complex* symbols = malloc(sizeof(double complex) * nb_symbols);
bits_to_symbols(&qam, input_bits, nb_bits, symbols);
// Modulation
int total_samples = qam.N * nb_symbols;
double complex* s = malloc(sizeof(double complex) * total_samples);
modulate(&qam, symbols, nb_symbols, s);
// Ajout du bruit
double signal_power = (2.0/3.0)*(qam.M-1); // puissance moyenne
double snr_dB = 5; // SNR en dB
double snr_lin = pow(10.0, snr_dB / 10.0);
double sigma = sqrt(signal_power / snr_lin);
add_noise(s, total_samples, 0);
// Démodulation
//uint8_t* output_bits = malloc(nb_bits * sizeof(uint8_t));
//demodulate(&qam, s, nb_symbols, output_bits);
// Calcul du taux d'erreur
//double ber = compare_bits(input_bits, output_bits, nb_bits);
//printf("Taux d'erreur : %.4f\n", ber * 100);
// Blind QAM
int preamble_symbols = 32;
uint8_t* preamble_bits = malloc(preamble_symbols * qam.k * sizeof(uint8_t));
// Genere un préambule aléatoire
for(int i = 0; i < preamble_symbols * qam.k; i++) {
preamble_bits[i] = rand() % 2;
}
double complex* preamble_symbols_complex = (double complex*)malloc(sizeof(double complex) * preamble_symbols);
bits_to_symbols(&qam, preamble_bits, preamble_symbols * qam.k, preamble_symbols_complex);
// Ajout du préambule dans les données
int total_symbols = preamble_symbols + nb_symbols;
double complex* all_symbols = malloc(sizeof(double complex) * total_symbols);
// Copier le préambule
for(int i = 0; i < preamble_symbols; i++) {
all_symbols[i] = preamble_symbols_complex[i];
}
// Copier les symboles réels
for(int i = 0; i < nb_symbols; i++) {
all_symbols[i + preamble_symbols] = symbols[i];
}
int total_samples_with_preamble = total_symbols * qam.N;
double complex* s_with_preamble = malloc(sizeof(double complex) * total_samples_with_preamble);
modulate(&qam, all_symbols, total_symbols, s_with_preamble);
// Symbol Timing Recovery blind
int offset_est = 0;
int N_est = 0;
symbol_timing_recovery(s_with_preamble, total_samples_with_preamble, preamble_symbols_complex, preamble_symbols, qam.N*2, &offset_est, &N_est);
printf("Symbol Timing Recovery : offset=%d, N_est=%d (%d)\n", offset_est, N_est, qam.N);
/*
// Calcul du BER
double ber = compare_bits(input_bits, output_bits, nb_bits);
printf("Taux d'erreur blind QAM: %.4f\n", ber * 100);
// Reconstruction du texte
char* texte_recup = malloc(nb_chars + 1);
for(int i = 0; i < nb_chars; i++){
char c = 0;
for(int b = 0; b < 8; b++){
c |= output_bits[i*8 + b] << (7-b);
}
texte_recup[i] = c;
}
texte_recup[nb_chars] = '\0';
printf("Texte original : %s\n", texte);
printf("Texte demodulé : %s\n", texte_recup);
*/
// Libération mémoire
free(input_bits);
//free(output_bits);
free(symbols);
free(s);
free_constellation(&qam);
return 0;
}

184
QAM/qamold/qamclean.c Normal file
View File

@ -0,0 +1,184 @@
#include <math.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <complex.h>
#include <string.h>
#define A 1
struct qam_system_s {
int M; // Nombre de symboles M-QAM
int k; // Nombre de bits/symboles
double Fs; // Fréquence d'échantillionage
double Ts; // Temps d'échantillionage
int N; // Nombre d'échantillions
double Fc; // Fréquence de la porteuse
double complex** constellation; // Tableau de symboles I + j Q
};
typedef struct qam_system_s qam_system;
// Initialisation de la constellation (double tableau de taille sqrt(M)),
// ToDo : changer à un tableau à 1 dimension pour éviter de calculer sqrt(M)
void init_constellation (qam_system* qam) {
int sm = (int)sqrt(qam->M);
qam->constellation = (double complex**)malloc(sizeof(double complex*) * sm);
for (int i = 0; i < sm; i++) {
qam->constellation[i] = (double complex*)malloc(sizeof(double complex) * sm);
}
double norm_factor = sqrt((double)(qam->M - 1) / 3.0); // Pour puissance unitaire
for (int i = 0; i < sm; i++) {
double complex ip = -(sm - 1) + 2 * i;
for (int j = 0; j < sm; j++) {
double complex qp = -(sm - 1) + 2 * j;
qam->constellation[i][j] = (ip + I * qp);
}
}
}
// Calcul du bruit gaussien pour un sigma donné
// Formule de Box-Muller
double gaussian_noise (double sigma) {
double u1 = (rand() + 1) / ((double)RAND_MAX + 2);
double u2 = (rand() + 1) / ((double)RAND_MAX + 2);
return sigma * sqrt(-2 * log(u1)) * cos(2 * M_PI * u2);
}
// Ajout du bruit
void add_noise (double complex* s, int len, double sigma) {
for (int i = 0; i < len; i++) {
double nr = gaussian_noise(sigma);
double ni = gaussian_noise(sigma);
s[i] += nr + I * ni;
}
}
// Changer le tableau de bits en boolen ou alors la represenation binaire et shifter pour extraire les bits (pas bien si M plus grand)
void bits_to_symbols (qam_system* qam, uint8_t* bits, int nb_bits, double complex* symbols) {
int nb_symbols = nb_bits / qam->k;
int sm = sqrt(qam->M);
for (int k = 0; k < nb_symbols; k++) {
int id = 0;
for (int b = 0 ; b < qam->k; b++) {
id = id * 2 + bits[k * qam->k + b];
}
int i = id / sm;
int j = id % sm;
symbols[k] = qam->constellation[i][j];
}
}
// Modulation QAM
void modulate (qam_system* qam, double complex* symbols, int nb_symbols, double complex* s) {
for (int k = 0; k < nb_symbols; k++) {
double complex iq = symbols[k];
for (int n = 0; n < qam->N; n++) {
s[k * qam->N + n] = iq * cexp(2 * I * M_PI * qam->Fc * ((double)n / qam->Fs));
}
}
}
// Demodulation QAM
void demodulate(qam_system* qam, double complex* s, int nb_symbols, uint8_t* bits_hat) {
for (int k = 0; k < nb_symbols; k++) {
double complex r = 0;
for (int n = 0; n < qam->N; n++) {
r += s[k * qam->N + n] * cexp(-2 * I * M_PI * qam->Fc * ((double)n / qam->Fs));
}
r /= qam->N;
// Distance euclidien de Ir et Qr pour avoir le point le plus proche de la constellation (lent)
int sm = (int)sqrt(qam->M);
double min_d = INFINITY;
int i_cl, j_cl = 0;
for (int i = 0; i < sm; i++) {
for (int j = 0; j < sm; j++) {
double d = cabs(r - qam->constellation[i][j]);
if (d < min_d) {
min_d = d;
i_cl = i;
j_cl = j;
}
}
}
// index du symbole (id) : même mappage que dans bits_to_symbols()
int id = i_cl * sm + j_cl;
for (int b = 0; b < qam->k; b++) {
bits_hat[k * qam->k + b] = (id >> (qam->k - 1 - b)) & 1;
}
}
}
// Libération de la mémoire
void free_constellation(qam_system* qam) {
int sm = (int)sqrt(qam->M);
for (int i = 0; i < sm; i++)
free(qam->constellation[i]);
free(qam->constellation);
}
double compare_bits(uint8_t* bits1, uint8_t* bits2, int nb_bits) {
int errors = 0;
for (int i = 0; i < nb_bits; i++) {
if (bits1[i] != bits2[i]) errors++;
}
return (double)errors / nb_bits;
}
int main () {
qam_system qam;
qam.M = 16;
qam.k = (int)log2((double)(qam.M));
qam.Fs = 44100;
qam.Ts = 0.0003;
qam.N = (int)qam.Fs * qam.Ts;
qam.Fc = 2000;
init_constellation(&qam);
int nb_bits = 1000;
int nb_symbols = nb_bits / qam.k;
uint8_t* input_bits = malloc(nb_bits * sizeof(uint8_t));
for (int i = 0; i < nb_bits; i++) {
input_bits[i] = rand() % 2;
}
// Conversion en symboles
double complex* symbols = malloc(sizeof(double complex) * nb_symbols);
bits_to_symbols(&qam, input_bits, nb_bits, symbols);
// Modulation
int total_samples = qam.N * nb_symbols;
double complex* s = malloc(sizeof(double complex) * total_samples);
modulate(&qam, symbols, nb_symbols, s);
// Ajout du bruit
double signal_power = (2.0/3.0)*(qam.M-1); // puissance moyenne
double snr_dB = 10; // SNR en dB
double snr_lin = pow(10.0, snr_dB / 10.0);
double sigma = sqrt(signal_power / snr_lin);
add_noise(s, total_samples, sigma);
// Démodulation
uint8_t* output_bits = malloc(nb_bits * sizeof(uint8_t));
demodulate(&qam, s, nb_symbols, output_bits);
// Calcul du taux d'erreur
double ber = compare_bits(input_bits, output_bits, nb_bits);
printf("Taux d'erreur : %.4f\n", ber);
// Libération mémoire
free(input_bits);
free(output_bits);
free(symbols);
free(s);
free_constellation(&qam);
return 0;
}

328
QAM/qamold/qamtest.c Normal file
View File

@ -0,0 +1,328 @@
#include <math.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <complex.h>
#include "../files/files.h"
#include <string.h>
#define A 1
struct qam_system_s {
int M; // Nombre de symboles M-QAM
int k; // Nombre de bits/symboles
double Fs; // Fréquence d'échantillionage
double Ts; // Temps d'échantillionage
int N; // Nombre d'échantillions
double Fc; // Fréquence de la porteuse
double complex** constellation; // Tableau de symboles I + j Q
};
typedef struct qam_system_s qam_system;
// Initialisation de la constellation (double tableau de taille sqrt(M)),
// ToDo : changer à un tableau à 1 dimension pour éviter de calculer sqrt(M)
void init_constellation (qam_system* qam) {
int sm = (int)sqrt(qam->M);
qam->constellation = (double complex**)malloc(sizeof(double complex*) * sm);
for (int i = 0; i < sm; i++) {
qam->constellation[i] = (double complex*)malloc(sizeof(double complex) * sm);
}
double norm_factor = sqrt((double)(qam->M - 1) / 3.0); // Pour puissance unitaire
for (int i = 0; i < sm; i++) {
double complex ip = -(sm - 1) + 2 * i;
for (int j = 0; j < sm; j++) {
double complex qp = -(sm - 1) + 2 * j;
qam->constellation[i][j] = (ip + I * qp);
}
}
}
// Calcul du bruit gaussien pour un sigma donné
// Formule de Box-Muller
double gaussian_noise (double sigma) {
double u1 = (rand() + 1) / ((double)RAND_MAX + 2);
double u2 = (rand() + 1) / ((double)RAND_MAX + 2);
return sigma * sqrt(-2 * log(u1)) * cos(2 * M_PI * u2);
}
// Ajout du bruit
void add_noise (double complex* s, int len, double sigma) {
for (int i = 0; i < len; i++) {
double nr = gaussian_noise(sigma);
double ni = gaussian_noise(sigma);
s[i] += nr + I * ni;
}
}
// Changer le tableau de bits en boolen ou alors la represenation binaire et shifter pour extraire les bits (pas bien si M plus grand)
void bits_to_symbols (qam_system* qam, uint8_t* bits, int nb_bits, double complex* symbols) {
int nb_symbols = nb_bits / qam->k;
int sm = sqrt(qam->M);
for (int k = 0; k < nb_symbols; k++) {
int id = 0;
for (int b = 0 ; b < qam->k; b++) {
id = id * 2 + bits[k * qam->k + b];
}
int i = id / sm;
int j = id % sm;
symbols[k] = qam->constellation[i][j];
}
}
// Modulation QAM
void modulate (qam_system* qam, double complex* symbols, int nb_symbols, double complex* s) {
for (int k = 0; k < nb_symbols; k++) {
double complex iq = symbols[k];
for (int n = 0; n < qam->N; n++) {
s[k * qam->N + n] = iq * cexp(2 * I * M_PI * qam->Fc * ((double)n / qam->Fs));
}
}
}
// Demodulation QAM
void demodulate(qam_system* qam, double complex* s, int nb_symbols, uint8_t* bits_hat) {
for (int k = 0; k < nb_symbols; k++) {
double complex r = 0;
for (int n = 0; n < qam->N; n++) {
r += s[k * qam->N + n] * cexp(-2 * I * M_PI * qam->Fc * ((double)n / qam->Fs));
}
r /= qam->N;
// Distance euclidien de Ir et Qr pour avoir le point le plus proche de la constellation (lent)
int sm = (int)sqrt(qam->M);
double min_d = INFINITY;
int i_cl, j_cl = 0;
for (int i = 0; i < sm; i++) {
for (int j = 0; j < sm; j++) {
double d = cabs(r - qam->constellation[i][j]);
if (d < min_d) {
min_d = d;
i_cl = i;
j_cl = j;
}
}
}
// index du symbole (id) : même mappage que dans bits_to_symbols()
int id = i_cl * sm + j_cl;
for (int b = 0; b < qam->k; b++) {
bits_hat[k * qam->k + b] = (id >> (qam->k - 1 - b)) & 1;
}
}
}
// Demodulation QAM avec porteuse estimé
void demodulate2(qam_system* qam, double complex* s, int nb_symbols, uint8_t* bits_hat) {
for (int k = 0; k < nb_symbols; k++) {
double complex r = 0;
for (int n = 0; n < qam->N; n++) {
r += s[k * qam->N + n];
}
r /= qam->N;
// Distance euclidien de Ir et Qr pour avoir le point le plus proche de la constellation (lent)
int sm = (int)sqrt(qam->M);
double min_d = INFINITY;
int i_cl, j_cl = 0;
for (int i = 0; i < sm; i++) {
for (int j = 0; j < sm; j++) {
double d = cabs(r - qam->constellation[i][j]);
if (d < min_d) {
min_d = d;
i_cl = i;
j_cl = j;
}
}
}
// index du symbole (id) : même mappage que dans bits_to_symbols()
int id = i_cl * sm + j_cl;
for (int b = 0; b < qam->k; b++) {
bits_hat[k * qam->k + b] = (id >> (qam->k - 1 - b)) & 1;
}
}
}
/*
// Pour j = 1 dans la def de wiki sur l'autocorrelation
double fc_autocorrelation_1_rad(double complex* s, int N) {
double complex r = 0;
for (int n = 0; n < N - 1; n++) {
r += s[n] * conj(s[n + 1]);
}
r /= (N - 1);
double om = -carg(r); // rad / sample
return om;
}
// Autocorrelation pour trouver la Fc (fréquence de la porteuse)
double fc_autocorrelation_multilag_rad(double complex* s, int N, int max_lag) {
double sum_phase = 0;
for (int k = 1; k <= max_lag; k++) {
double complex rk = 0;
for (int n = 0; n < N - k; n++) {
rk += s[n] * conj(s[n + k]);
}
rk /= (double)(N - k);
sum_phase += -carg(rk) / k;
}
return sum_phase / max_lag; // rad/sample
}
// Correction du signal pour enlever l'offset de la porteuse
void signal_correction(double complex* s, int total_samples, double om_hat) {
for (int n = 0; n < total_samples; n++) {
s[n] *= cexp(-I * om_hat * n);
}
}
*/
void blind_carrier(double complex* s, int N, int M) {
int k = (int)sqrt(M); // puissance à élever
double complex sum = 0;
for(int n = 0; n < N; n++)
sum += cpow(s[n], k);
double phi_hat = carg(sum) / k;
for(int n = 0; n < N; n++)
s[n] *= cexp(-I * phi_hat);
}
// Libération de la mémoire
void free_constellation(qam_system* qam) {
int sm = (int)sqrt(qam->M);
for (int i = 0; i < sm; i++)
free(qam->constellation[i]);
free(qam->constellation);
}
// Compare deux tableaux de bits (0/1) et retourne le pourcentage de fiabilité.
double taux_erreur_bits(const uint8_t *in_bits, size_t nb_bits_in,
const uint8_t *out_bits, size_t nb_bits_out) {
if (!in_bits || !out_bits)
return 1.0;
size_t n_min = nb_bits_in < nb_bits_out ? nb_bits_in : nb_bits_out;
size_t n_max = nb_bits_in > nb_bits_out ? nb_bits_in : nb_bits_out;
size_t err = n_max - n_min;
for (size_t i = 0; i < n_min; i++)
err += ((in_bits[i] ^ out_bits[i]) & 1);
return n_max ? (double)err / n_max : 0.0;
}
int main (int argc, char *argv[]) {
if (argc < 2) {
fprintf(stderr, "Utilisation: %s <fichier_entree>\n", argv[0]);
return 1;
}
qam_system qam;
qam.M = 16;
qam.k = (int)log2((double)(qam.M));
qam.Fs = 44100;
qam.Ts = 0.3;
qam.N = (int)qam.Fs * qam.Ts;
qam.Fc = 2000;
init_constellation(&qam);
printf("Lecture du fichier...\n");
// Lecture du fichier et conversion en bits
const char *input_filename = argv[1];
bit_array input_bits = file_to_bits(input_filename);
size_t nb_symbols = input_bits.nb_bits / qam.k;
printf("Mise en forme des symboles...\n");
// Mise en forme des symboles
double complex *symbols = malloc(sizeof(double complex) * nb_symbols);
bits_to_symbols(&qam, input_bits.bits, input_bits.nb_bits, symbols);
printf("Modulation...\n");
// Modulation QAM
int total_samples = qam.N * nb_symbols;
double complex* s = (double complex*)malloc(sizeof(double complex) * total_samples);
modulate(&qam, symbols, nb_symbols, s);
// Ajout du bruit
double signal_power = (2.0/3.0)*(qam.M-1); // puissance moyenne avant échelle
double snr_dB = 10; // Signal to noise ratio
double snr_lin = pow(10.0, snr_dB / 10.0);
double sigma = sqrt(signal_power / snr_lin);
printf("Ajout du bruit... \n puissance du signal : %f\n SNR db : %f\n sigma : %f\n", signal_power, snr_dB, sigma);
add_noise(s, total_samples, 0);
// Demodulation QAM
//printf("Demodulation...\n");
//bit_array output_bits;
//output_bits.nb_bits = input_bits.nb_bits;
//output_bits.bits = (uint8_t*)malloc(output_bits.nb_bits * sizeof(uint8_t));
//demodulate(&qam, s, nb_symbols, output_bits.bits);
//printf("Ecriture...\n");
// Ecriture du fichier de Demodulation
//char *output_filename = make_output_filename(input_filename);
//bits_to_file(output_filename, &output_bits);
//double erreurs = taux_erreur_bits(input_bits.bits, input_bits.nb_bits, output_bits.bits, output_bits.nb_bits);
//printf("Comparaison :\n");
//printf(" Erreurs : %f\n", erreurs * 100);
/*
double om_hat = fc_autocorrelation_1_rad(s, total_samples);
printf("Estimation de fc 1: %f\n", (om_hat * qam.Fs) / (2 * M_PI));
om_hat = fc_autocorrelation_multilag_rad(s, total_samples, 10);
printf("Estimation de fc multilag: %f\n", (om_hat * qam.Fs) / (2 * M_PI));
// Correction du signal avec Fc (en rad/sample) trouvé
signal_correction(s, total_samples, om_hat);
printf("Demodulation...\n");
demodulate2(&qam, s, nb_symbols, output_bits.bits);
*/
// Avant la demodulation
printf("Test de blind carrier correction...\n");
// Paramètres CMA simples
double mu = 0.001; // pas d'adaptation
int num_iter = 100; // nombre d'itérations
// Appel de la fonction blind carrier correction
blind_carrier(s, total_samples, qam.M);
// Ensuite, utilise ton démodulateur actuel
bit_array output_bits;
output_bits.nb_bits = input_bits.nb_bits;
output_bits.bits = (uint8_t*)malloc(output_bits.nb_bits * sizeof(uint8_t));
demodulate2(&qam, s, nb_symbols, output_bits.bits);
// Comparaison avec bits originaux
double erreurs = taux_erreur_bits(input_bits.bits, input_bits.nb_bits, output_bits.bits, output_bits.nb_bits);
printf("Taux d'erreur après blind carrier correction: %f %%\n", erreurs * 100);
// Ecriture du fichier de Demodulation
printf("Ecriture...\n");
char *output_filename = make_output_filename(input_filename);
bits_to_file(output_filename, &output_bits);
// Libération mémoire
free_bit_array(&input_bits);
free_bit_array(&output_bits);
free(symbols);
free(s);
free_constellation(&qam);
free(output_filename);
return 0;
}