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

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);