This commit is contained in:
2025-10-18 19:34:07 +02:00
parent 967f691be6
commit 41fa5065a0
12 changed files with 4103 additions and 11768 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,16 +1,16 @@
-3.00000000 -3.00000000
-3.00000000 -1.00000000
-3.00000000 1.00000000
-3.00000000 3.00000000
-1.00000000 -3.00000000
-1.00000000 -1.00000000
-1.00000000 1.00000000
-1.00000000 3.00000000
1.00000000 -3.00000000
1.00000000 -1.00000000
1.00000000 1.00000000
1.00000000 3.00000000
3.00000000 -3.00000000
3.00000000 -1.00000000
3.00000000 1.00000000
3.00000000 3.00000000
-1.34164079 -1.34164079
-1.34164079 -0.44721360
-1.34164079 0.44721360
-1.34164079 1.34164079
-0.44721360 -1.34164079
-0.44721360 -0.44721360
-0.44721360 0.44721360
-0.44721360 1.34164079
0.44721360 -1.34164079
0.44721360 -0.44721360
0.44721360 0.44721360
0.44721360 1.34164079
1.34164079 -1.34164079
1.34164079 -0.44721360
1.34164079 0.44721360
1.34164079 1.34164079

32
QAM/debug.py Normal file
View File

@ -0,0 +1,32 @@
import numpy as np
import matplotlib.pyplot as plt
def plot_constellations(ref_file, rx_file, title="Constellation comparison"):
# Charger et forcer 2D
ref_data = np.atleast_2d(np.loadtxt(ref_file))
rx_data = np.atleast_2d(np.loadtxt(rx_file))
x_ref, y_ref = ref_data[:,0], ref_data[:,1]
x_rx, y_rx = rx_data[:,0], rx_data[:,1]
plt.figure(figsize=(6,6))
plt.scatter(x_ref, y_ref, color='blue', s=50, marker='o', label='Référence')
plt.scatter(x_rx, y_rx, color='red', s=50, marker='x', label='Reçu')
# Ajustement automatique des limites
all_x = np.concatenate([x_ref, x_rx])
all_y = np.concatenate([y_ref, y_rx])
margin = 0.1 * max(np.ptp(all_x), np.ptp(all_y))
plt.xlim(min(all_x)-margin, max(all_x)+margin)
plt.ylim(min(all_y)-margin, max(all_y)+margin)
plt.xlabel('In-phase (I)')
plt.ylabel('Quadrature (Q)')
plt.title(title)
plt.grid(False)
plt.gca().set_aspect('equal', adjustable='box')
plt.legend()
plt.show()
plot_constellations("constellation_ref.dat", "constellation.dat", title="Constellation QAM")

1440
QAM/old2/constellation.dat Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,16 @@
-3.00000000 -3.00000000
-3.00000000 -1.00000000
-3.00000000 1.00000000
-3.00000000 3.00000000
-1.00000000 -3.00000000
-1.00000000 -1.00000000
-1.00000000 1.00000000
-1.00000000 3.00000000
1.00000000 -3.00000000
1.00000000 -1.00000000
1.00000000 1.00000000
1.00000000 3.00000000
3.00000000 -3.00000000
3.00000000 -1.00000000
3.00000000 1.00000000
3.00000000 3.00000000

View File

@ -9,7 +9,7 @@ set yrange [-5:5]
while (1) {
plot \
'constellation_ref.dat' using 1:2 with points pt 7 ps 2.5 lc rgb "yellow", \
'constellation_ref.dat' using 1:2 with points pt 7 ps 2.5 lc rgb "red", \
'constellation.dat' using 1:2 with points pt 7 ps 1 lc rgb "blue"
pause 0.15
}

226
QAM/old2/qam.c Normal file
View File

@ -0,0 +1,226 @@
#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, FILE *fp_constel) {
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;
if (fp_constel) {
fprintf(fp_constel, "% .8f % .8f\n", creal(r), cimag(r));
fflush(fp_constel);
}
// 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;
//}
char* texte = "Vif juge, trempez ce blond whisky aqueux";
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, sigma);
FILE *fp_ref = fopen("constellation_ref.dat", "w");
int sm = (int)sqrt(qam.M);
for (int i = 0; i < sm; i++) {
for (int j = 0; j < sm; j++) {
fprintf(fp_ref, "% .8f % .8f\n", creal(qam.constellation[i][j]), cimag(qam.constellation[i][j]));
}
}
fclose(fp_ref);
FILE *fp_constel = fopen("constellation.dat", "w");
// Démodulation
uint8_t* output_bits = (uint8_t*)malloc(nb_bits * sizeof(uint8_t));
demodulate(&qam, s, nb_symbols, output_bits, fp_constel);
fclose(fp_constel);
// 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);
// Calcul du BER
double ber = compare_bits(input_bits, output_bits, nb_bits);
printf("Taux d'erreur blind QAM: %.4f\n", ber * 100);
// Libération mémoire
free(input_bits);
free(output_bits);
free(symbols);
free(s);
free_constellation(&qam);
return 0;
}

880
QAM/old3/constellation.dat Normal file
View File

@ -0,0 +1,880 @@
-0.31202845 -0.36308093
-0.21403073 0.38857646
-0.38530118 -0.24484730
-0.44021783 0.07284252
-0.34501041 0.34872590
0.35857538 -0.40045539
-0.25176904 0.40377600
-0.10377581 0.43578972
-1.01896226 0.14271390
-1.15718524 -1.07104846
-0.40883880 0.30174936
0.26396095 0.48082155
-0.31654178 1.26105861
-0.33255136 -0.17032596
-0.41545553 0.38068746
-0.23973431 1.32252511
-0.49928116 0.40812210
-0.60891702 -0.47180571
-0.98044772 0.33254717
1.23532760 -1.08284043
-1.01739273 0.23195386
-0.95909631 -1.27747201
-0.18344231 0.97172160
-0.36005886 -1.19561767
-0.38733224 1.03655789
-1.14703959 0.49592443
-0.34627477 0.37436581
-0.32594570 -0.36576269
-0.33047672 0.45166025
1.03227135 -0.26600616
-0.24368430 1.13277766
-1.10409800 -1.13670229
-0.27024330 0.45950443
-0.43012606 -0.49137862
-0.42938643 0.96752310
0.29460881 0.46255766
-1.12981200 0.36271133
-1.06546596 -0.99914698
-0.32964627 0.54802267
-0.97768436 1.05949598
-0.40125588 0.35060801
-0.14555788 -0.29516627
-1.16824437 0.33042499
-1.38177121 -1.02828516
-0.36030711 0.53502663
-0.99270774 0.38492966
-0.34180208 0.46901106
1.02021653 -1.03189533
-0.38784460 0.27839052
0.98525087 1.10441090
-0.37064093 0.37855671
0.92249275 0.38692346
-0.37782815 0.26512776
-0.38059680 -1.10559455
-1.08779693 0.25242918
-1.31058915 -0.99926776
-0.32423909 1.22001515
-0.25335804 1.00836191
-0.50573269 0.31900345
0.42698256 -0.94413229
-0.39166269 0.41072366
0.25755208 -0.39660996
-0.33022334 1.05502122
-1.12361886 0.95444663
-0.37428566 0.38306311
0.21248197 1.04776058
-0.47434424 0.99247118
0.43507446 -0.36697818
-0.95021817 0.15733583
-0.99554159 -1.14130590
-0.25435034 0.50150512
-1.13525219 -0.27992447
-0.54906403 0.94151150
-1.17729844 -0.37677613
-0.29075006 1.14107781
-0.55423390 -0.31265259
-0.32086652 0.46332639
-0.27004284 -0.25876856
-0.56225634 0.99336544
-0.32896397 -0.32120490
-0.42109267 1.09730148
0.16066972 -1.09133678
-0.46397415 -0.26636357
-0.48496755 0.28388862
-0.36968179 0.36567458
0.26521387 -0.29984385
-0.33480946 0.46485409
-0.36463789 0.26204947
-1.18759281 0.26015798
-0.96596592 -0.93117220
-0.33784886 0.39164206
0.43769194 0.69739352
-0.43032293 0.84413229
-0.23774796 -0.28911962
-0.33130118 0.41821511
-0.50013585 0.97965454
-0.34689709 0.35409852
-0.23010782 -0.12586032
-0.97858139 0.38056045
1.08280742 -1.25403467
-1.08716964 0.37903094
-1.06816096 -1.26485276
-0.29749093 1.08244304
-0.36919521 -1.24051895
-0.41806929 1.02179014
-0.87352398 0.31284450
-0.32826699 0.34535817
-0.52300831 -0.18727837
-0.25032100 0.44847978
0.91304423 -0.42961637
-0.13446642 1.15022408
-1.15680622 -1.21068591
-0.36015459 0.38355671
-0.41281658 -0.28563836
-0.28095750 1.17150443
0.44841940 0.22784693
-1.20991785 0.43888552
-1.26949348 -1.09066654
-0.49699144 0.41646383
-1.10251223 1.15954894
-0.35344943 0.42981020
-0.35460879 -0.40159958
-0.96881406 0.42432504
-1.12683149 -0.94337597
-0.34090486 0.45009494
-1.30640116 0.33027100
-0.21513225 0.30060400
1.23753084 -1.09859072
-0.17778666 0.45746800
0.98283097 1.00470073
-0.44060208 0.46320487
1.21931561 0.58300444
-0.34443300 0.35025224
-0.20455252 -1.20751826
-1.05565774 0.30209405
-0.90794063 -0.99564640
-0.37062355 1.18006149
-0.36830585 1.05842914
-0.28829158 0.37278172
0.51701024 -1.17362256
-0.28685147 0.17704574
0.43894598 -0.41798899
-0.61389745 1.18724310
-1.14959160 1.08955659
-0.43773208 0.40961614
0.00657211 1.11721014
-0.45242309 1.04238246
0.28752062 -0.13222957
-1.29550622 0.31509320
-1.06884344 -1.03394430
-0.42241401 0.35919199
-1.08379928 -0.57802668
-0.41458484 0.83139690
-1.05365813 -0.42116548
-0.41745035 1.19305593
-0.44639650 -0.27576769
-0.44621577 0.17412965
-0.23004430 -0.32898997
-0.36165151 1.20449839
-0.55117142 -0.48984181
-0.16798699 1.04071241
0.31011770 -1.36217467
-0.46631118 -0.32516904
-0.15805322 0.44809717
-0.35860554 0.16913916
0.41178134 -0.34124789
-0.30074668 0.40714965
-0.38017496 0.39131278
-0.96741058 0.67253560
-1.24569648 -0.72436186
-0.27101990 0.38548867
0.28420613 0.25890492
-0.42278819 1.11012306
-0.28250890 -0.32853298
-0.28400818 0.27501319
-0.17076321 1.11189064
-0.45023807 0.37402836
-0.22213671 -0.41960172
-0.94141884 0.30789514
1.05357821 -1.01149325
-1.05482103 0.52764631
-0.99859625 -0.87049613
-0.28261505 1.09640290
-0.49015364 -1.08402523
-0.14498054 1.09090615
-0.94911979 0.42267368
-0.34357322 0.44569840
-0.34921322 -0.35138845
-0.31748827 0.31627969
1.11463777 -0.28394406
-0.46326050 0.89279233
-1.06477639 -1.08022949
-0.42836832 0.39212624
-0.16028271 -0.37561196
-0.45372092 1.09581520
-0.04101846 0.41543315
-1.24776237 0.50372052
-1.01046209 -1.20203071
-0.34264731 0.39036274
-1.19551204 1.04588443
-0.35012639 0.43429116
-0.36476204 -0.24929817
-1.23662846 0.23121207
-1.08869701 -1.09800513
-0.35657338 0.32142876
-1.16706471 0.40350355
-0.47757543 0.33968056
1.12643846 -1.03342793
-0.40429544 0.51235936
0.92993726 1.04386743
-0.27921326 0.12895368
1.07057147 0.41675044
-0.45781543 0.34530738
-0.15550368 -1.15290701
-1.24474912 0.22373701
-1.01636406 -1.15984020
-0.45241277 0.94067451
-0.39666102 1.01551504
-0.30415407 0.52966388
0.42242219 -1.04720736
-0.48521314 0.34940459
0.23494422 -0.47659414
-0.39947228 1.05426259
-1.18041855 1.15411420
-0.24193544 0.39310208
0.33862100 1.02349548
-0.54773004 1.23503633
0.10818630 -0.25533904
-0.96224435 0.40891113
-0.97643294 -1.01562261
-0.42844287 0.45214473
-1.00810432 -0.28926920
-0.40737767 0.96829636
-0.89918110 -0.45258226
-0.33496466 1.06184687
-0.38077794 -0.20763689
-0.40201285 0.36673030
-0.45952525 -0.25742302
-0.25045162 1.07737031
-0.50752572 -0.27866299
-0.23083068 1.29397369
0.39199302 -1.20171519
-0.38433807 -0.37865898
-0.55990357 0.41664491
-0.29794709 0.51366410
0.37475812 -0.43001268
-0.27729731 0.29944694
-0.47488383 0.35239836
-0.96654000 0.69215033
-1.11110431 -0.82416572
-0.20368948 0.49057982
0.52308494 0.33483727
-0.24850933 1.07443686
-0.34791805 -0.32007730
-0.25853676 0.51115807
-0.17941734 1.20519231
-0.11342097 0.25102777
-0.27670160 -0.19012193
-1.03994582 0.54908843
0.86407132 -1.35562044
-0.94185647 0.43008755
-1.22186569 -0.88452692
-0.32106283 1.09166980
-0.53694980 -0.85871688
-0.24383048 1.07474394
-1.05491406 0.53824228
-0.27060332 0.34516662
-0.32232377 -0.58146394
-0.30486319 0.32528566
0.90500008 -0.34391269
-0.45103429 1.14989139
-0.99391132 -1.09294192
-0.38275270 0.33166196
-0.35915102 -0.54143680
-0.32318896 1.00574008
0.40764212 0.45276816
-1.11114012 0.15238414
-0.92815560 -1.22164919
-0.43174187 0.15685803
-1.14341183 0.99562192
-0.41415278 0.22841552
-0.35771155 -0.46436053
-1.16822694 0.23892475
-0.67346115 -1.18765414
-0.42589250 0.14605392
-1.09038520 0.17955477
-0.49389893 0.24608462
1.22544028 -0.75196104
-0.41209167 0.21904591
0.72389705 1.31839934
-0.49661047 0.29730266
1.22685896 0.67502585
-0.35135181 0.25325888
-0.00620830 -1.14363823
-1.05333122 0.10254708
-0.69867409 -1.13965865
-0.53128392 1.07896460
-0.45948404 1.13887059
-0.29932935 0.38962638
0.31620505 -1.34874423
-0.35708404 0.43969553
0.54695336 -0.41951872
-0.36976770 0.99489550
-1.00577935 1.04650656
-0.31839248 0.32966467
0.27710048 1.14046577
-0.34954991 0.89579091
0.46003161 -0.38668754
-1.09483649 0.45558599
-1.32749255 -1.08655702
-0.41384999 0.53388335
-0.92586659 -0.23732743
-0.11461978 1.22614317
-1.13476543 -0.15516704
-0.03625266 0.88792143
-0.36426959 -0.31917900
-0.17525306 0.13101065
-0.29878850 -0.40565286
0.06367635 1.21715588
-0.30032239 -0.25475547
0.09898865 1.02720529
-0.06611431 -1.15194721
-0.39215060 -0.30150449
-0.38680782 0.31314671
-0.06247327 0.36132059
0.20109728 -0.64570689
-0.23945673 0.64085696
-0.13446949 0.70075405
-0.75243730 0.91726734
-1.45028028 -0.43988942
-0.07926376 0.54618428
0.35151647 0.12328557
-0.00043103 1.20547449
-0.41878158 -0.11462993
-0.13188202 0.60069882
0.33204624 1.19833977
-0.15340704 0.41633354
-0.41617623 -0.17790618
-0.56285739 0.88577465
0.39265124 -1.47117966
-0.57457171 0.94599611
-1.57813091 -0.27615434
0.25275661 1.03110215
-0.84474420 -0.90311830
0.25303978 1.04767460
-0.63961834 1.02757341
-0.15838839 0.44901836
-0.48000317 -0.10596114
-0.25937394 0.42590391
0.84493295 -0.70805225
0.24423362 1.01963863
-1.48665793 -0.14370221
0.07376786 0.42983815
-0.59202645 -0.01731182
0.18705556 1.24782046
0.56661178 -0.02647487
-0.60722140 0.86222403
-1.48738136 -0.43921204
-0.15651173 0.61619336
-0.19885992 1.58694503
0.07385597 0.42852972
-0.41682070 -0.14784924
-0.77195688 0.87679915
-1.40503884 -0.15440256
-0.14103875 0.68667030
-0.76379382 0.85984795
-0.12619804 0.52072503
0.12570952 -1.63658614
0.09358821 0.46519043
1.51702274 0.10571578
-0.15718465 0.55544646
1.12819516 -0.37212082
-0.01459698 0.53777689
-1.07351142 -0.64113878
-0.57369112 0.88411436
-1.46870106 -0.19352991
0.35927911 1.03440056
0.30424108 1.10045036
0.02981222 0.51366749
-0.16684004 -1.23339544
0.05097045 0.26090896
0.09668531 -0.54237611
0.38772762 1.03212178
-0.30759050 1.47875603
-0.02502066 0.42910717
0.94844497 0.80507692
0.28830246 1.24135339
0.14865732 -0.40934806
-0.64849870 1.02545190
-1.64220884 -0.23073861
-0.04115289 0.50218823
-1.06285152 0.11311046
0.16416052 1.04673165
-1.11102027 0.08544000
0.30091542 1.08688638
-0.54551043 -0.18095572
-0.23788564 0.53265900
-0.49872342 -0.26678921
0.22270801 0.99856952
-0.60363472 -0.05824273
0.13204250 1.13170488
-0.26664132 -1.21950767
-0.56062165 -0.26617337
0.00727415 0.21197638
-0.10690293 0.56904332
-0.12173691 -0.55223481
-0.13609125 0.38164037
-0.22226458 0.71446498
-0.74245911 0.85892687
-1.55972244 -0.41484829
-0.20334295 0.61970357
0.31700129 0.07079464
0.13449857 1.02302289
-0.54238275 -0.31894746
-0.28133418 0.52067079
0.28060094 1.12630923
-0.12162546 0.36634303
-0.34561133 -0.17827835
-1.03931702 0.70751582
0.59423681 -1.29911937
-0.75843257 0.81139880
-1.57730446 -0.68556803
0.10310968 1.03335362
-0.67400306 -0.84700429
0.06054034 1.15025742
-0.77286167 0.47557829
-0.29028847 0.54276291
-0.27482760 -0.19772142
-0.11994968 0.36408189
0.78035295 -0.81713160
0.21737616 1.09857289
-1.18254850 -0.66539897
-0.35210721 0.39493518
-0.50975569 -0.29188620
0.07661012 1.15470996
0.35848649 0.26022851
-0.77485063 0.69526899
-1.22207178 -0.46175769
-0.18692438 0.60206436
-0.62741906 1.33494975
-0.17855601 0.34009484
-0.42621663 -0.13057148
-0.83850938 0.63075363
-1.47199973 -0.51955942
-0.23964524 0.59891281
-1.01720429 0.84543467
-0.25567097 0.34493172
0.65782207 -1.35499684
-0.13645103 0.42344955
1.42139339 0.70402143
-0.14134279 0.58163801
1.26429849 -0.05123437
-0.15573860 0.66425208
-0.84664093 -0.89746670
-0.66765526 0.65188491
-1.33946979 -0.68336950
-0.13547805 1.33391456
-0.01311918 1.08381016
-0.26885915 0.39044922
-0.09629192 -1.12985380
-0.18477312 0.41780574
0.11788432 -0.36930565
-0.11400622 1.14616969
-0.71164575 1.14762749
-0.19434913 0.51072915
0.57606657 0.96776987
-0.02115547 1.18705119
-0.03177567 -0.52325305
-1.03661648 0.39131082
-1.19200246 -1.02791732
-0.44145789 0.43868764
-0.96775095 -0.11064332
-0.35379494 1.18148992
-1.00698678 -0.48198386
-0.26498858 1.12476012
-0.26143369 -0.37768083
-0.51512946 0.36354685
-0.19957862 -0.31824547
-0.66653588 0.85918826
-0.37520507 -0.35376709
-0.44493040 0.93295373
0.55064254 -1.23389527
-0.28115978 -0.30295983
-0.54907227 0.21053437
-0.50793530 0.37345227
0.37024987 -0.25310419
-0.35959453 0.11118461
-0.50281000 0.16548987
-1.26322433 0.05900470
-0.64710033 -1.49218071
-0.51790185 0.28396723
0.31222570 0.27090413
-0.71499001 0.96604950
-0.16468815 -0.42049513
-0.52287459 0.23433390
-0.87932719 0.71816438
-0.43828506 0.00462493
0.02218342 -0.60768376
-1.20981804 -0.13172407
1.39808402 -0.43885489
-0.97813323 -0.26248931
-0.25206935 -1.34281904
-0.75325400 0.81961764
0.14422066 -1.34191266
-0.79582225 0.96136586
-1.16155513 -0.26329434
-0.86013035 0.06741854
-0.00965300 -0.55094971
-0.49391380 0.00109182
1.11157602 0.40557103
-1.11950886 0.76793436
-0.11150682 -1.78154507
-0.43682487 0.08305273
-0.12393961 -0.55946423
-0.98192766 0.78343527
-0.06091643 0.58229269
-1.03669652 -0.42149417
-0.21401098 -1.64487810
-0.50680768 0.13930195
-1.33574727 0.14706836
-0.55714862 0.12537793
0.13380015 -0.61643711
-1.09488278 -0.08747533
-0.21066788 -1.44769192
-0.50229181 -0.04011964
-1.13638894 -0.23384381
-0.43836050 0.11383238
1.39228950 -0.10799639
-0.48802878 0.20264974
0.47588619 1.62192837
-0.27340939 0.19361598
0.68448629 0.80864114
-0.47195792 0.05420133
0.34477091 -1.07786560
-0.92004004 -0.25424321
-0.37760272 -1.39721129
-0.87787868 0.89426868
-0.79267036 0.75520147
-0.48065034 0.07817515
0.85184258 -0.83563910
-0.47239528 0.12627174
0.48277009 -0.18180439
-0.71997171 0.75293982
-1.29153937 0.42384830
-0.32613062 0.17402085
0.10202947 1.04593394
-0.71125374 0.74980584
0.50484731 -0.16738092
-1.16256423 -0.00470142
-0.58952940 -1.43917961
-0.71851513 0.20431374
-0.82581369 -0.70146519
-0.43309512 1.05489748
-0.87632697 -0.63470868
-0.56174046 0.94078784
-0.36343466 -0.74030249
-0.47009920 0.32511040
-0.28949047 -0.46301691
-0.61098971 0.83197266
-0.30513604 -0.52105098
-0.75061540 0.87475951
0.50974994 -1.08883784
-0.28154826 -0.52078296
-0.34873231 0.28167771
-0.41149750 0.26937057
0.19007326 -0.31381309
-0.39222476 0.35812278
-0.40291930 0.24467795
-1.10924908 0.34485345
-0.98085212 -1.05744586
-0.27406176 0.26544570
0.35012828 0.35381774
-0.40087355 1.19550172
-0.44650037 -0.43294378
-0.29257517 0.33133304
-0.13780562 1.23531423
-0.51645492 0.53254651
-0.45365730 -0.41872486
-1.03611147 0.47877429
0.79832435 -1.32896077
-1.11551489 0.40800484
-1.11975639 -0.79847563
-0.20611406 1.00724166
-0.69838131 -1.03603068
-0.23096181 1.08306487
-1.07023457 0.66243075
-0.15173137 0.52598993
-0.38361285 -0.38311364
-0.34378062 0.47000297
1.03804857 -0.51402522
-0.09490212 1.19969154
-1.27634648 -0.70130648
-0.42548178 0.45803214
-0.33217760 -0.25636176
-0.36035026 1.01323624
0.58868663 0.21384701
-1.12508238 0.78429355
-1.32778013 -0.87805779
-0.31778980 0.37782146
-0.88447401 1.32004993
-0.31173481 0.18936826
-0.46230529 -0.38937533
-0.93875591 0.40586591
-1.19880808 -0.88001421
-0.33507246 0.41148662
-1.02904286 0.47779753
-0.30145877 0.41586993
0.86851117 -1.10918688
-0.50406166 0.13349449
1.00458594 0.99686515
-0.38307432 0.36008430
1.00433321 0.37749771
-0.50953245 0.15792285
-0.39888021 -1.18812231
-1.08444469 0.41794647
-1.00859605 -1.36982347
-0.39929721 1.00858598
-0.57043925 0.94134680
-0.45270563 0.30986828
0.64740169 -0.87173231
-0.34851350 0.43318799
0.50373214 -0.46736993
-0.49324614 0.90839987
-1.16083187 0.85756541
-0.37995838 0.30665239
0.14942910 1.19252524
-0.45750199 1.00124895
0.39533489 -0.24618649
-1.09194749 0.30059665
-0.53064464 -1.29745411
-0.32829564 0.19645699
-1.00491093 -0.49180643
-0.69388058 0.98571285
-1.07327052 -0.52013451
-0.49550616 0.92068615
-0.28149445 -0.44098059
-0.42975495 0.38440311
-0.34010936 -0.33895185
-0.54740262 1.13529512
-0.25928445 -0.47033113
-0.58739701 1.01800468
0.48617337 -1.07609991
-0.40499489 -0.57781754
-0.40174748 0.55155045
-0.32286706 0.26588019
0.53629286 -0.42122792
-0.39920489 0.51713042
-0.45359370 0.40737035
-0.84548899 0.27785657
-1.00667459 -0.96613366
-0.26828484 0.25976331
0.25295097 0.37607576
-0.46126431 1.03260901
-0.40279099 -0.24657659
-0.37987717 0.12352906
-0.44628748 0.86769292
-0.29637438 0.45896986
-0.39936855 -0.08745092
-0.95340646 0.37842294
0.90178683 -1.14345809
-0.80646092 0.53265844
-1.27088485 -0.89749663
-0.24802130 0.91333138
-0.36572702 -0.99916742
-0.36641645 1.05426660
-1.10837220 0.52275107
-0.44607592 0.15779324
-0.23228534 -0.24406293
-0.36384164 0.45002486
1.03058155 -0.56498483
-0.14187980 1.07303759
-1.15376965 -1.13637382
-0.36264501 0.52815460
-0.39051068 -0.24438521
-0.07492065 1.14349287
0.51684344 0.08621823
-0.96172276 0.52619069
-1.04576540 -1.11777830
-0.34938487 0.45655008
-1.02766240 1.18495194
-0.52997885 0.55748157
-0.15364100 -0.44508072
-1.14329676 0.23788243
-1.21779719 -1.11349751
-0.38546200 0.42075026
-1.17918179 0.52604491
-0.28574420 0.52199428
1.08330303 -0.98066820
-0.24802582 0.27160918
1.04853566 1.08102404
-0.29313743 0.42485423
0.96260308 0.26803572
-0.51912360 0.34420975
-0.11292000 -1.14400559
-1.04739492 0.17540820
-1.11441406 -1.22883010
-0.52639594 0.84986367
-0.52710069 1.01735010
-0.30885479 0.27388498
0.44574757 -0.74425968
-0.46382300 0.44814634
0.44904213 -0.30813329
-0.63767229 1.21418607
-1.22556632 0.86395503
-0.34214451 0.30574735
0.17259234 0.86496400
-0.32480619 1.05612537
0.43889334 -0.51933604
-1.02674349 0.35609282
-0.89393514 -1.21049417
-0.36846369 0.37941633
-0.98641807 -0.47559413
-0.44755679 1.21960269
-1.03122128 -0.33682392
-0.35318795 1.12940664
-0.36331006 -0.32896336
-0.28306541 0.38647142
-0.21812509 -0.27670337
-0.44729084 1.10887448
-0.52859975 -0.36404097
-0.24010453 0.91605871
0.41984611 -1.15062846
-0.34248795 -0.24005071
-0.33397378 0.35878522
-0.39831462 0.50795634
0.41702786 -0.62163274
-0.33805101 0.45650539
-0.27859581 0.40216109
-1.05774569 0.53779507
-1.42415680 -0.87055713
-0.27654375 0.38928806
0.25901039 0.35652859
-0.33082657 1.15409645
-0.40685393 -0.20407365
-0.23686438 0.56633035
-0.26193902 1.21365439
-0.20260600 0.49133397
-0.45165163 -0.45751703
-1.18346583 0.31810438
0.89802934 -0.95013768
-1.16309863 0.26604245
-1.18386506 -1.10311721
-0.16784287 1.05364788
-0.49077470 -0.99025124
0.00171671 1.15509224
-0.86606100 0.28942709
-0.30559667 0.49226883
-0.39902748 -0.41785924
-0.33112115 0.32495728
0.94443664 -0.36892219
-0.38348413 1.14426380
-1.18058683 -1.05089383
-0.39125284 0.36801023
-0.35680139 -0.41245427
-0.25121134 1.15931919
0.36056736 0.40619567
-1.09116775 0.36957303
-1.13642958 -1.11281056
-0.34056852 0.38007119
-1.21838730 0.91970197
-0.17884434 0.42245022
-0.27551533 -0.38898298
-1.25507508 0.38253654
-1.21026313 -0.87005343
-0.39228963 0.62309083
-1.16448806 0.36472580
-0.24315635 0.34112968
1.07454905 -0.99510410
-0.35416482 0.42511567
1.03604010 1.07082031
-0.39485070 0.40169023
1.02018178 0.32303944
-0.24714138 0.27513322
-0.25443819 -1.04224213
-1.00335985 0.33336367
-0.95167241 -1.13384472
-0.47178371 1.10380719
-0.44347102 0.89865945
-0.35612593 0.24575863
0.59544992 -0.97082846
-0.33079820 0.18842791
0.24063116 -0.40954664
-0.54597573 1.11706897
-1.09356272 0.86551165
-0.25644651 0.42451965
0.31590044 1.01547745
-0.57685164 1.03765963
0.26467495 -0.26793133
-1.02806397 0.49413336
-1.07742309 -1.17025750
-0.33545549 0.24268994
-1.03818129 -0.41749668
-0.37066685 0.90622096
-1.13805168 -0.46375121
-0.41169235 1.07307811
-0.47517936 -0.31180552
-0.36701432 0.38670108
-0.41929830 -0.47138018
-0.34942081 1.04098519
-0.47106518 -0.32153553
-0.37195463 1.05910723
0.14637113 -1.06527293
-0.10291353 0.42424225
0.26947551 -0.43055636
-0.40148014 0.38862774
-0.40945108 0.39705641
-1.04244368 0.49395299
-1.27365240 -0.86786814
-0.26467394 0.31488035
0.31891504 0.35451162
-0.04344638 1.10074605
-0.39683701 -0.29984324
-0.21146179 0.57934039
-0.18430679 1.20083875
-0.34647055 0.21374240
-0.36800694 -0.20463353
-0.96803254 0.36613104
1.00439662 -1.14286191
-1.08184906 0.38984420
-0.86737954 -0.96935370
-0.21922013 1.04052779
-0.45758990 -1.02426336
-0.21924203 1.16949224
-0.91730740 0.13145528
-0.35857284 0.25584683
-0.30528757 -0.35552063
-0.45500790 0.29050995
1.09478106 -0.29988615
-0.36959306 0.95649714
-0.91490210 -1.26214271
-0.38509185 0.39302859
-0.35739352 -0.34429725
-0.31262994 0.82016967
0.38738991 0.37644184
-0.98502444 0.18314526
-1.05050547 -1.20645447
-0.33670658 0.36506942
-1.21343766 0.93698166
-0.09855738 0.24705256
-0.33113277 -0.38521955
-0.89739483 0.08841987
-0.89465442 -0.94690980
-0.42145584 0.28343312
-1.06849193 0.47108899
-0.39732226 0.44606233
1.06930625 -1.11142101
-0.29206820 0.39997851
0.78073372 0.90899737
-0.25421280 0.32608096
0.91519669 0.45997640
-0.38956838 0.39409618
-0.26364644 -1.24426066
-1.05191054 0.38146703
-1.01747304 -1.08036571
-0.38768865 1.09525211
-0.38096670 1.04466527
-0.36889228 0.35087106
0.39210062 -1.23945201
-0.24018273 0.20336419
0.40875677 -0.57228107
-0.41285536 1.16986380
-0.98056291 0.94739535
-0.26388705 0.51398988
0.27895279 1.06031029
-0.27752604 1.15191683
0.33890427 -0.48476732
-1.09037791 0.46464290
-1.33508329 -0.81219355
-0.39158408 0.44958947
-1.24108745 -0.16653263
-0.17524396 1.04890332
-1.13377063 -0.37194277
-0.44164358 1.11606653
-0.50379533 -0.21441051
-0.42550406 0.40402679
-0.41738928 -0.50437718
-0.20289748 0.96368079
-0.29945932 -0.41636288
-0.37797060 0.94457881
0.39310239 -1.29272896

View File

@ -0,0 +1,16 @@
-1.02899151 -1.02899151
-1.02899151 -0.34299717
-1.02899151 0.34299717
-1.02899151 1.02899151
-0.34299717 -1.02899151
-0.34299717 -0.34299717
-0.34299717 0.34299717
-0.34299717 1.02899151
0.34299717 -1.02899151
0.34299717 -0.34299717
0.34299717 0.34299717
0.34299717 1.02899151
1.02899151 -1.02899151
1.02899151 -0.34299717
1.02899151 0.34299717
1.02899151 1.02899151

361
QAM/old3/qam.c Normal file
View File

@ -0,0 +1,361 @@
#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
double norm_factor = sqrt((double)(1.7*(qam->M - 1)/3.0));
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) / norm_factor;
}
}
}
// 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] = A * iq * cexp(2 * I * M_PI * qam->Fc * ((double)n / qam->Fs));
int idx = k * qam->N + n;
s[idx] = A * iq * cexp(2 * I * M_PI * qam->Fc * ((double)idx / qam->Fs));
}
}
}
// Demodulation QAM
void demodulate(qam_system* qam, double complex* s, int nb_symbols, uint8_t* bits_hat, FILE *fp_constel) {
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 += s[k * qam->N + n] * cexp(-2 * I * M_PI * qam->Fc * ((double)(k * qam->N + n) / qam->Fs));
}
r /= qam->N;
r /= A;
if (fp_constel) {
fprintf(fp_constel, "% .8f % .8f\n", creal(r), cimag(r));
fflush(fp_constel);
}
// 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;
}
// ---------- Helpers ----------
static inline double complex interp_linear(double complex *x, int N, double t) {
// t: position en échantillons (peut être fractionnaire). On suppose 0 <= t <= N-2
int i = (int)floor(t);
double mu = t - (double)i;
if (i < 0) i = 0;
if (i >= N-1) return x[N-1];
return (1.0 - mu) * x[i] + mu * x[i+1];
}
static int nearest_constellation_index(qam_system* qam, double complex z, int *out_i, int *out_j) {
int sm = (int)sqrt(qam->M);
double min_d = INFINITY;
int best_i = 0, best_j = 0;
for (int i = 0; i < sm; i++) {
for (int j = 0; j < sm; j++) {
double d = cabs(z - qam->constellation[i][j]);
if (d < min_d) {
min_d = d; best_i = i; best_j = j;
}
}
}
if (out_i) *out_i = best_i;
if (out_j) *out_j = best_j;
return best_i * sm + best_j;
}
// --- Démodulation avec M&M + PLL et écriture dans fichier ---
void demodulate_real(qam_system* qam, double complex* rx_samples, int total_samples,
uint8_t* bits_hat, const char* filename)
{
double sps = (double) qam->N; // échantillons par symbole
double Kp_t = 0.005, Ki_t = 0.001;
double Kp_c = 0.01, Ki_c = 0.01; // PLL porteur
double timing_integrator = 0.0;
double phase_integrator = 0.0, phase_est = 0.0;
double t = sps/2.0;
int max_symbols = (int)(total_samples / sps) + 10;
double complex* syms = malloc(sizeof(double complex) * max_symbols);
int sym_count = 0;
double power = 0.0;
for(int i = 0; i < total_samples; i++) power += pow(cabs(rx_samples[i]), 2);
power /= total_samples;
double agc_gain = 1.0;
if(power > 0) agc_gain = 1.0 / sqrt(power);
// Ouverture du fichier pour écrire les symboles reçus
FILE* fp = fopen(filename, "w");
if(!fp) {
perror("Erreur ouverture fichier .dat");
free(syms);
return;
}
while((int)floor(t) + 1 < total_samples) {
double complex yk = interp_linear(rx_samples, total_samples, t) * agc_gain;
double complex z = yk * cexp(-I * phase_est);
syms[sym_count++] = z;
// Écriture de chaque symbole reçu dans le fichier
fprintf(fp, "% .8f % .8f\n", creal(z), cimag(z));
if(sym_count >= 3){
double complex y_k = syms[sym_count-1];
double complex y_k_1 = syms[sym_count-2];
double complex y_k_2 = syms[sym_count-3];
double e_t = creal((y_k - y_k_2) * conj(y_k_1));
timing_integrator += Ki_t * e_t;
double timing_adjust = Kp_t * e_t + timing_integrator;
t += sps + timing_adjust;
} else t += sps;
// PLL carrier
if(sym_count >= 1) {
int ii, jj;
int idx = nearest_constellation_index(qam, z, &ii, &jj);
double complex d = qam->constellation[ii][jj];
double e_phase = cimag(z * conj(d));
phase_integrator += Ki_c * e_phase;
double phase_adj = Kp_c * e_phase + phase_integrator;
phase_est += phase_adj;
if(phase_est > M_PI) phase_est -= 2*M_PI;
if(phase_est < -M_PI) phase_est += 2*M_PI;
}
}
// Décision finale et reconstruction bits
int nb_symbols = sym_count;
int sm = (int)sqrt(qam->M);
int nb_bits = nb_symbols * qam->k;
for(int k = 0; k < nb_symbols; k++) {
double complex z = syms[k];
int ii, jj;
int id = nearest_constellation_index(qam, z, &ii, &jj);
for(int b = 0; b < qam->k; b++) {
int bit = (id >> (qam->k - 1 - b)) & 1;
if(k * qam->k + b < nb_bits) bits_hat[k * qam->k + b] = (uint8_t)bit;
}
}
fclose(fp);
free(syms);
}
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.N = 100;
qam.Ts = qam.N / qam.Fs;
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 = "VVif juge, trempez ce blond whisky aqueuxVif juge, trempez ce blond whisky aqueuxVif juge, trempez ce blond whisky aqueuxVif juge, trempez ce blond whisky aqueuxVif juge, trempez ce blond whisky aqueuxVif juge, trempez ce blond whisky aqueuxVif juge, trempez ce blond whisky aqueuxVif juge, trempez ce blond whisky aqueuxVif juge, trempez ce blond whisky aqueuxVif juge, trempez ce blond whisky aqueuxif juge, trempez ce blond whisky aqueux";
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);
//double phase_offset = M_PI / 6.0; // 30 degrés
//for (int i = 0; i < total_samples; i++) {
// s[i] *= cexp(I * phase_offset);
//}
//double freq_offset = 0; // Hz de décalage
//for (int i = 0; i < total_samples; i++) {
// double t = (double)i / qam.Fs;
// s[i] *= cexp(I * 2 * M_PI * freq_offset * t);
//}
//int offset_samples = (int)(0.3 * qam.N); // décalage de 30% dun symbole
//memmove(s + offset_samples, s, (total_samples - offset_samples) * sizeof(double complex));
// Ajout du bruit
//double snr_dB = 5; // SNR en dB
//double signal_power = 1.0; // puissance moyenne unitaire après normalisation
//double snr_lin = pow(10.0, snr_dB / 10.0);
//double sigma = sqrt(signal_power / (2.0 * snr_lin)); // /2 car bruit sur I et Q
add_noise(s, total_samples, 0.1);
FILE *fp_ref = fopen("constellation_ref.dat", "w");
int sm = (int)sqrt(qam.M);
for (int i = 0; i < sm; i++) {
for (int j = 0; j < sm; j++) {
fprintf(fp_ref, "% .8f % .8f\n", creal(qam.constellation[i][j]), cimag(qam.constellation[i][j]));
}
}
fclose(fp_ref);
FILE *fp_constel = fopen("constellation.dat", "w");
// Démodulation
uint8_t* output_bits = (uint8_t*)malloc(nb_bits * sizeof(uint8_t));
//demodulate(&qam, s, nb_symbols, output_bits, fp_constel);
for (int i = 0; i < total_samples; i++) {
s[i] *= cexp(-2 * I * M_PI * qam.Fc * (i / qam.Fs));
}
demodulate_real(&qam, s, total_samples, output_bits, "constellation.dat");
fclose(fp_constel);
// 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\n", texte);
printf("Texte demodulé : %s\n", texte_recup);
// Calcul du BER
double ber = compare_bits(input_bits, output_bits, nb_bits);
printf("Taux d'erreur blind QAM: %.4f\n", ber * 100);
// Libération mémoire
free(input_bits);
free(output_bits);
free(symbols);
free(s);
free_constellation(&qam);
return 0;
}

BIN
QAM/qam

Binary file not shown.

View File

@ -4,9 +4,8 @@
#include <stdlib.h>
#include <complex.h>
#include <string.h>
#include "../wav/wav.h"
#define A 3000
#define A 10
struct qam_system_s {
int M; // Nombre de symboles M-QAM
@ -35,7 +34,7 @@ void init_constellation (qam_system* qam) {
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);
qam->constellation[i][j] = (ip + I * qp) / norm_factor;
}
}
}
@ -77,7 +76,8 @@ void modulate (qam_system* qam, double complex* symbols, int nb_symbols, double
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));
int idx = k * qam->N + n;
s[idx] = A * iq * cexp(2 * I * M_PI * qam->Fc * ((double)idx / qam->Fs));
}
}
}
@ -87,7 +87,7 @@ void demodulate(qam_system* qam, double complex* s, int nb_symbols, uint8_t* bit
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 += s[k * qam->N + n] * cexp(-2 * I * M_PI * qam->Fc * ((double)(k * qam->N + n) / qam->Fs)) / A;
}
r /= qam->N;
@ -141,7 +141,7 @@ int main () {
qam.M = 16;
qam.k = (int)log2((double)(qam.M));
qam.Fs = 44100;
qam.Ts = 0.05;
qam.Ts = 0.0003;
qam.N = (int)qam.Fs * qam.Ts;
qam.Fc = 2000;
init_constellation(&qam);
@ -153,7 +153,7 @@ int main () {
//for (int i = 0; i < nb_bits; i++) {
// input_bits[i] = rand() % 2;
//}
char* texte = "Test du test";
char* texte = "Vif juge, trempez ce blond whisky aqueux, Vif juge, trempez ce blond whisky aqueux, Vif juge, trempez ce blond whisky aqueux, Vif juge, trempez ce blond whisky aqueux, Vif juge, trempez ce blond whisky aqueux, Vif juge, trempez ce blond whisky aqueux, Vif juge, trempez ce blond whisky aqueux, Vif juge, trempez ce blond whisky aqueux, Vif juge, trempez ce blond whisky aqueux, Vif juge, trempez ce blond whisky aqueux, Vif juge, trempez ce blond whisky aqueux, Vif juge, trempez ce blond whisky aqueux, Vif juge, trempez ce blond whisky aqueux, ";
int nb_chars = strlen(texte);
int nb_bits = nb_chars * 8;
int nb_symbols = (nb_bits + qam.k - 1) / qam.k;
@ -180,28 +180,38 @@ int main () {
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, sigma + 3);
add_noise(s, total_samples, sigma);
FILE *fp_ref = fopen("constellation_ref.dat", "w");
int sm = (int)sqrt(qam.M);
for (int i = 0; i < sm; i++) {
for (int j = 0; j < sm; j++) {
fprintf(fp_ref, "% .8f % .8f\n",
creal(qam.constellation[i][j]),
cimag(qam.constellation[i][j]));
fprintf(fp_ref, "% .8f % .8f\n", creal(qam.constellation[i][j]), cimag(qam.constellation[i][j]));
}
}
fclose(fp_ref);
FILE *fp_constel = fopen("constellation.dat", "w");
double phase_offset = M_PI / 6.0; // 30 degrés
for (int i = 0; i < total_samples; i++) {
s[i] *= cexp(I * phase_offset);
}
double freq_offset = 0; // Hz de décalage
for (int i = 0; i < total_samples; i++) {
double t = (double)i / qam.Fs;
s[i] *= cexp(I * 2 * M_PI * freq_offset * t);
}
//int offset_samples = (int)(0.3 * qam.N); // décalage de 30% dun symbole
//memmove(s + offset_samples, s, (total_samples - offset_samples) * sizeof(double complex));
// Démodulation
uint8_t* output_bits = malloc(nb_bits * sizeof(uint8_t));
uint8_t* output_bits = (uint8_t*)malloc(nb_bits * sizeof(uint8_t));
demodulate(&qam, s, nb_symbols, output_bits, fp_constel);
fclose(fp_constel);
// Reconstruction du texte
char* texte_recup = malloc(nb_chars + 1);
for(int i = 0; i < nb_chars; i++){
@ -219,14 +229,6 @@ int main () {
double ber = compare_bits(input_bits, output_bits, nb_bits);
printf("Taux d'erreur blind QAM: %.4f\n", ber * 100);
// Affichage du signal dans un .wav
double* si = (double*)malloc(sizeof(double) * total_samples);
for (int i = 0; i < total_samples; i++) {
si[i] = cimag(s[i]);
}
write_wav("output.wav", si, total_samples);
// Libération mémoire
free(input_bits);
free(output_bits);