From a4ad553067b7b98c1f0df921d41a8e78f59636bf Mon Sep 17 00:00:00 2001 From: zeefaad Date: Wed, 1 Oct 2025 09:49:27 +0200 Subject: [PATCH] Little changes and debug --- QAM/qam | Bin 26472 -> 21408 bytes QAM/{ => qamold}/qam.c | 95 ++++++------ QAM/qamold/qambis.c | 237 ++++++++++++++++++++++++++++++ QAM/qamold/qambisbis.c | 324 +++++++++++++++++++++++++++++++++++++++++ files/files.c | 35 ++--- files/files.h | 1 + 6 files changed, 624 insertions(+), 68 deletions(-) rename QAM/{ => qamold}/qam.c (76%) create mode 100644 QAM/qamold/qambis.c create mode 100644 QAM/qamold/qambisbis.c diff --git a/QAM/qam b/QAM/qam index 8f1a68baf2fd59163ee921852101425809f8c6e5..470d3b124bb1ac21d085f85183bae8f1213cae4f 100755 GIT binary patch literal 21408 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 #include "../wav/wav.h" #include "../files/files.h" -#include "../plot/plot_constellation.h" #include -#include -#define A 10000 +#define A 1 struct qam_system_s { int M; // Nombre de symboles M-QAM @@ -38,7 +36,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] = A * (ip + I * qp) / norm_factor; + qam->constellation[i][j] = (ip + I * qp); } } } @@ -94,10 +92,9 @@ void demodulate(qam_system* qam, double complex* s, int nb_symbols, uint8_t* bit } r /= qam->N; - // Distance euclidien de Ir et Qr pour avoir le point le plus proche de la constellation + // Distance euclidien de Ir et Qr pour avoir le point le plus proche de la constellation (lent) int sm = (int)sqrt(qam->M); - /* TEMPS INFINI double min_d = INFINITY; int i_cl, j_cl = 0; for (int i = 0; i < sm; i++) { @@ -110,39 +107,16 @@ void demodulate(qam_system* qam, double complex* s, int nb_symbols, uint8_t* bit } } } - */ - double norm_factor = sqrt((double)(qam->M - 1) / 3.0); - double Ir = creal(r) * norm_factor / A; - double Qr = cimag(r) * norm_factor / A; - int i = (int)round((Ir + (sm - 1)) / 2.0); - int j = (int)round((Qr + (sm - 1)) / 2.0); + // index du symbole (id) : même mappage que dans bits_to_symbols() + int id = i_cl * sm + j_cl; - i = (i < 0) ? 0 : ((i >= sm) ? sm - 1 : i); - j = (j < 0) ? 0 : ((j >= sm) ? sm - 1 : j); - - int id = i * sm + j; - - //int id = i_cl * sm + j_cl; for (int b = 0; b < qam->k; b++) { - bits_hat[k * qam->k + (qam->k - 1 - b)] = (id >> b) & 1; + bits_hat[k * qam->k + b] = (id >> (qam->k - 1 - b)) & 1; } } } -double complex* demodulate_points(qam_system* qam, double complex* s, int nb_symbols) { - double complex* points = malloc(sizeof(double complex) * nb_symbols); - 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; - points[k] = r; - } - return points; -} - // Libération de la mémoire void free_constellation(qam_system* qam) { int sm = (int)sqrt(qam->M); @@ -151,6 +125,36 @@ void free_constellation(qam_system* qam) { free(qam->constellation); } +// Compare deux tableaux de bits (0/1) et retourne le pourcentage de fiabilité. +double compare_bits(const uint8_t *in_bits, size_t nb_bits_in, const uint8_t *out_bits, size_t nb_bits_out, size_t *erreurs) { + if (!in_bits || !out_bits) { + if (erreurs) *erreurs = (nb_bits_in < nb_bits_out) ? nb_bits_out : nb_bits_in; + return 0.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 = 0; + for (size_t i = 0; i < n_min; ++i) { + if ((in_bits[i] & 1) != (out_bits[i] & 1)) err++; + } + + if (n_max != n_min) { + err += (n_max - n_min); + } + + if (erreurs) *erreurs = err; + + double total_compared = (double)n_max; + if (total_compared == 0.0) return 0.0; + + double ber = (double)err / total_compared; + double reliability_percent = (1.0 - ber) * 100.0; + return reliability_percent; +} + + int main (int argc, char *argv[]) { if (argc < 2) { fprintf(stderr, "Utilisation: %s \n", argv[0]); @@ -158,7 +162,7 @@ int main (int argc, char *argv[]) { } qam_system qam; - qam.M = 64; + qam.M = 16; qam.k = (int)log2((double)(qam.M)); qam.Fs = 44100; qam.Ts = 0.0003; @@ -185,18 +189,18 @@ int main (int argc, char *argv[]) { // Ajout du bruit double signal_power = (2.0/3.0)*(qam.M-1); // puissance moyenne avant échelle - double snr_dB = -27; // Signal to noise ratio + 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, 1875); + add_noise(s, total_samples, 0); printf("Demodulation...\n"); // Demodulation QAM bit_array output_bits; output_bits.nb_bits = input_bits.nb_bits; - output_bits.bits = (uint8_t*)malloc(output_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"); @@ -204,24 +208,25 @@ int main (int argc, char *argv[]) { char *output_filename = make_output_filename(input_filename); bits_to_file(output_filename, &output_bits); - // 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); + */ - // Plot - printf("Ploting..."); - plot_t plot; - plot_init(&plot, 1400, 1400, 0.04); - plot_draw_constellation(&plot, qam.constellation, qam.M); - SDL_Color red = {255, 0, 0, 255}; - plot_draw_points_animated(&plot, demodulate_points(&qam, s, nb_symbols), nb_symbols, red, 5); + size_t erreurs = 0; + double fiabilite = compare_bits( input_bits.bits, input_bits.nb_bits, output_bits.bits, output_bits.nb_bits, &erreurs); + + printf("Comparaison :\n"); + printf(" Bits d'entrée : %zu\n", input_bits.nb_bits); + printf(" Bits de sortie: %zu\n", output_bits.nb_bits); + printf(" Erreurs : %zu\n", erreurs); + printf(" Fiabilité : %.4f %%\n", fiabilite); // Libération mémoire - plot_close(&plot); free_bit_array(&input_bits); free_bit_array(&output_bits); free(symbols); diff --git a/QAM/qamold/qambis.c b/QAM/qamold/qambis.c new file mode 100644 index 0000000..96daebb --- /dev/null +++ b/QAM/qamold/qambis.c @@ -0,0 +1,237 @@ +#include +#include +#include +#include +#include +#include "../wav/wav.h" +#include "../files/files.h" +#include "../plot/plot_constellation.h" +#include +#include + +#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 + + 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; + } + } + } + /* + double norm_factor = sqrt((double)(qam->M - 1) / 3.0); + double Ir = creal(r) * norm_factor / A; + double Qr = cimag(r) * norm_factor / A; + + int i = (int)round((Ir + (sm - 1)) / 2.0); + int j = (int)round((Qr + (sm - 1)) / 2.0); + + i = (i < 0) ? 0 : ((i >= sm) ? sm - 1 : i); + j = (j < 0) ? 0 : ((j >= sm) ? sm - 1 : j); + + int id = i * sm + j; + */ + + int id = i_cl * sm + j_cl; + for (int b = 0; b < qam->k; b++) { + bits_hat[k * qam->k + (qam->k - 1 - b)] = (id >> b) & 1; + } + } +} + +double complex* demodulate_points(qam_system* qam, double complex* s, int nb_symbols) { + double complex* points = malloc(sizeof(double complex) * nb_symbols); + 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; + double norm_factor = sqrt((double)(qam->M - 1) / 3.0); + double Ir = creal(r); + double Qr = cimag(r); + + points[k] = Ir + I * Qr; + } + return points; +} + +// 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); +} + +int main (int argc, char *argv[]) { + if (argc < 2) { + fprintf(stderr, "Utilisation: %s \n", argv[0]); + return 1; + } + + 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); + + 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, sigma); + + printf("Demodulation...\n"); + + // Demodulation QAM + bit_array output_bits; + output_bits.nb_bits = input_bits.nb_bits; + output_bits.bits = (uint8_t*)malloc(output_bits.nb_bits); + 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); + + + // 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); + + // Plot + printf("Ploting..."); + plot_t plot; + plot_init(&plot, 1400, 1400, 0.04); + plot_draw_constellation(&plot, qam.constellation, qam.M); + SDL_Color red = {255, 0, 0, 255}; + plot_draw_points_animated(&plot, demodulate_points(&qam, s, nb_symbols), nb_symbols, red, 5); + + // Libération mémoire + plot_close(&plot); + free_bit_array(&input_bits); + free_bit_array(&output_bits); + free(symbols); + free(s); + free_constellation(&qam); + free(output_filename); + + return 0; +} diff --git a/QAM/qamold/qambisbis.c b/QAM/qamold/qambisbis.c new file mode 100644 index 0000000..0e1c174 --- /dev/null +++ b/QAM/qamold/qambisbis.c @@ -0,0 +1,324 @@ +#include +#include +#include +#include +#include +#include "../wav/wav.h" +#include "../files/files.h" +#include + +#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)); + //int i = k * qam->N + n; + //r += s[i] * cexp(-2 * I * M_PI * qam->Fc * ((double)i / qam->Fs)); + } + r /= qam->N; + + // Distance euclidien de Ir et Qr pour avoir le point le plus proche de la constellation + + 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; + } + + /* + double norm_factor = sqrt((double)(qam->M - 1) / 3.0); + double Ir = creal(r) * norm_factor / A; + double Qr = cimag(r) * norm_factor / A; + + int i = (int)round((Ir + (sm - 1)) / 2.0); + int j = (int)round((Qr + (sm - 1)) / 2.0); + + i = (i < 0) ? 0 : ((i >= sm) ? sm - 1 : i); + j = (j < 0) ? 0 : ((j >= sm) ? sm - 1 : j); + + int id = i * sm + j; + + int id = i_cl * sm + j_cl; + for (int b = 0; b < qam->k; b++) { + bits_hat[k * qam->k + (qam->k - 1 - b)] = (id >> b) & 1; + } + */ + } +} + +double complex* demodulate_points(qam_system* qam, double complex* s, int nb_symbols) { + double complex* points = malloc(sizeof(double complex) * nb_symbols); + for (int k = 0; k < nb_symbols; k++) { + double complex r = 0; + for (int n = 0; n < qam->N; n++) { + int i = k * qam->N + n; + r += s[i] * cexp(-2 * I * M_PI * qam->Fc * ((double)i / qam->Fs)); + } + r /= qam->N; + double norm_factor = sqrt((double)(qam->M - 1) / 3.0); + double Ir = creal(r); + double Qr = cimag(r); + + + 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; + } + } + } + + double complex p = qam->constellation[i_cl][j_cl]; + points[k] = creal(p) + I * cimag(p); + + //points[k] = (int)Ir + I * (int)Qr; + } + return points; +} + +// 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); +} + +#include // pour size_t + +// Compare deux tableaux de bits (0/1) et retourne le pourcentage de fiabilité. +double compare_bits_and_get_reliability(const uint8_t *in_bits, size_t nb_bits_in, const uint8_t *out_bits, size_t nb_bits_out, size_t *erreurs) { + if (!in_bits || !out_bits) { + if (erreurs) *erreurs = (nb_bits_in < nb_bits_out) ? nb_bits_out : nb_bits_in; + return 0.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 = 0; + for (size_t i = 0; i < n_min; ++i) { + if ((in_bits[i] & 1) != (out_bits[i] & 1)) err++; + } + + if (n_max != n_min) { + err += (n_max - n_min); + } + + if (erreurs) *erreurs = err; + + double total_compared = (double)n_max; + if (total_compared == 0.0) return 0.0; + + double ber = (double)err / total_compared; + double reliability_percent = (1.0 - ber) * 100.0; + return reliability_percent; +} + + +void affiche_constellation(qam_system* qam) { + int sm = (int)sqrt(qam->M); + for (int i = 0; i < sm; i++) { + for (int j = 0; j < sm; j++) { + double complex p = qam->constellation[i][j]; + printf("(%d,%d) ", (int)creal(p), (int)cimag(p)); + } + printf("\n"); + } +} + +void affiche_points(double complex* r, int len, int len_samples) { + for (int i = 0; i < len; i += len_samples) { + for (int j = 0; j < len_samples; j++) { + double complex p = r[i + j]; + printf("(%f,%f) ", (float)creal(p), (float)cimag(p)); + } + printf("\n"); + } +} + +int main (int argc, char *argv[]) { + if (argc < 2) { + fprintf(stderr, "Utilisation: %s \n", argv[0]); + return 1; + } + + 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); + + 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, 5); + + printf("Demodulation...\n"); + + // Demodulation QAM + bit_array output_bits; + output_bits.nb_bits = input_bits.nb_bits; + output_bits.bits = (uint8_t*)malloc(output_bits.nb_bits); + 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); + + //printf("Constelattion :\n"); + //affiche_constellation(&qam); + //printf("Points de demodulation :\n"); + //affiche_points(demodulate_points(&qam, s, nb_symbols), nb_symbols, qam.N); + + // 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); + */ + + + size_t erreurs = 0; + double fiabilite = compare_bits_and_get_reliability( input_bits.bits, input_bits.nb_bits, output_bits.bits, output_bits.nb_bits, &erreurs); + + printf("Résultat de la comparaison :\n"); + printf(" Bits d'entrée : %zu\n", input_bits.nb_bits); + printf(" Bits de sortie: %zu\n", output_bits.nb_bits); + printf(" Erreurs : %zu\n", erreurs); + printf(" Fiabilité : %.4f %%\n", fiabilite); + + // 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; +} diff --git a/files/files.c b/files/files.c index 4dca179..e01d7be 100644 --- a/files/files.c +++ b/files/files.c @@ -3,7 +3,8 @@ #include #include -// Lire un fichier binaire et en faire un tableau de bits (0/1) +// files.c corrections : MSB-first within each byte + bit_array file_to_bits(const char *filename) { bit_array arr = {0}; @@ -13,7 +14,6 @@ bit_array file_to_bits(const char *filename) { return arr; } - // Taille fichier fseek(f, 0, SEEK_END); long file_size = ftell(f); rewind(f); @@ -23,27 +23,19 @@ bit_array file_to_bits(const char *filename) { return arr; } - // Lire tous les octets uint8_t *raw = (uint8_t*)malloc(file_size); - if (!raw) { - fclose(f); - return arr; - } + if (!raw) { fclose(f); return arr; } fread(raw, 1, file_size, f); fclose(f); - // Convertir en bits (0/1 dans uint8_t) arr.nb_bits = (size_t)file_size * 8; - arr.bits = (uint8_t*)malloc(arr.nb_bits); - if (!arr.bits) { - free(raw); - arr.nb_bits = 0; - return arr; - } + arr.bits = (uint8_t*)malloc(arr.nb_bits * sizeof(uint8_t)); + if (!arr.bits) { free(raw); arr.nb_bits = 0; return arr; } + // MSB-first in each byte: bit 7 -> index 0, bit 0 -> index 7 for (size_t i = 0; i < (size_t)file_size; i++) { for (int b = 0; b < 8; b++) { - arr.bits[i * 8 + b] = (raw[i] >> b) & 1u; + arr.bits[i * 8 + b] = (raw[i] >> (7 - b)) & 1u; } } @@ -51,7 +43,6 @@ bit_array file_to_bits(const char *filename) { return arr; } -// Transformer un tableau de bits (0/1) en fichier binaire int bits_to_file(const char *filename, const bit_array *arr) { if (!arr || !arr->bits) return -1; @@ -59,19 +50,17 @@ int bits_to_file(const char *filename, const bit_array *arr) { uint8_t *raw = (uint8_t*)calloc(nb_bytes, 1); if (!raw) return -1; + // MSB-first packing: index bit 0 -> place at position 7 of first byte for (size_t i = 0; i < arr->nb_bits; i++) { if (arr->bits[i]) { - raw[i / 8] |= (1u << (i % 8)); + size_t byte_idx = i / 8; + int bit_in_byte = i % 8; // 0..7 + raw[byte_idx] |= (1u << (7 - bit_in_byte)); } } FILE *f = fopen(filename, "wb"); - if (!f) { - perror("fopen"); - free(raw); - return -1; - } - + if (!f) { perror("fopen"); free(raw); return -1; } fwrite(raw, 1, nb_bytes, f); fclose(f); free(raw); diff --git a/files/files.h b/files/files.h index e62168f..e6f9c58 100644 --- a/files/files.h +++ b/files/files.h @@ -19,3 +19,4 @@ char* make_output_filename(const char *input_filename); // Libérer la mémoire du bit_array void free_bit_array(bit_array *arr); +