1D constellation + precalculated sqrt(M)
This commit is contained in:
36
QAM/qam.c
36
QAM/qam.c
@ -10,6 +10,7 @@
|
|||||||
struct qam_system_s {
|
struct qam_system_s {
|
||||||
int M; // Nombre de symboles M-QAM
|
int M; // Nombre de symboles M-QAM
|
||||||
int k; // Nombre de bits/symboles
|
int k; // Nombre de bits/symboles
|
||||||
|
int sm; // sqrt M
|
||||||
double Fs; // Fréquence d'échantillionage
|
double Fs; // Fréquence d'échantillionage
|
||||||
double Ts; // Temps d'échantillionage
|
double Ts; // Temps d'échantillionage
|
||||||
int N; // Nombre d'échantillions
|
int N; // Nombre d'échantillions
|
||||||
@ -20,16 +21,15 @@ typedef struct qam_system_s qam_system;
|
|||||||
|
|
||||||
// Initialisation de la constellation (double tableau de taille sqrt(M)),
|
// Initialisation de la constellation (double tableau de taille sqrt(M)),
|
||||||
void init_constellation (qam_system* qam) {
|
void init_constellation (qam_system* qam) {
|
||||||
int sm = (int)sqrt(qam->M);
|
|
||||||
qam->constellation = (double complex*)malloc(sizeof(double complex) * qam->M);
|
qam->constellation = (double complex*)malloc(sizeof(double complex) * qam->M);
|
||||||
|
|
||||||
double norm_factor = sqrt((double)(qam->M - 1) / 3.0); // Pour puissance unitaire
|
double norm_factor = sqrt((double)(qam->M - 1) / 3.0); // Pour puissance unitaire
|
||||||
|
|
||||||
for (int i = 0; i < sm; i++) {
|
for (int i = 0; i < qam->sm; i++) {
|
||||||
double ip = -(sm - 1) + 2 * i;
|
double ip = -(qam->sm - 1) + 2 * i;
|
||||||
for (int j = 0; j < sm; j++) {
|
for (int j = 0; j < qam->sm; j++) {
|
||||||
double qp = -(sm - 1) + 2 * j;
|
double qp = -(qam->sm - 1) + 2 * j;
|
||||||
int idx = i * sm + j;
|
int idx = i * qam->sm + j;
|
||||||
qam->constellation[idx] = (ip + I * qp) / norm_factor;
|
qam->constellation[idx] = (ip + I * qp) / norm_factor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -73,7 +73,6 @@ void demodulate(qam_system* qam, double complex* s, int nb_symbols, uint8_t* bit
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Distance euclidien de Ir et Qr pour avoir le point le plus proche de la constellation (lent)
|
// 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;
|
double min_d = INFINITY;
|
||||||
int i_cl = 0;
|
int i_cl = 0;
|
||||||
int j_cl = 0;
|
int j_cl = 0;
|
||||||
@ -81,8 +80,8 @@ void demodulate(qam_system* qam, double complex* s, int nb_symbols, uint8_t* bit
|
|||||||
double d = cabs(r - qam->constellation[idx]);
|
double d = cabs(r - qam->constellation[idx]);
|
||||||
if (d < min_d) {
|
if (d < min_d) {
|
||||||
min_d = d;
|
min_d = d;
|
||||||
i_cl = idx / sm;
|
i_cl = idx / qam->sm;
|
||||||
j_cl = idx % sm;
|
j_cl = idx % qam->sm;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -127,7 +126,6 @@ void add_noise (double complex* s, int len, double sigma) {
|
|||||||
// Changer le tableau de bits en boolen ou alors la represenation binaire et shifter pour extraire les bits (pas bien si M plus grand)
|
// 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) {
|
void bits_to_symbols (qam_system* qam, uint8_t* bits, int nb_bits, double complex* symbols) {
|
||||||
int nb_symbols = nb_bits / qam->k;
|
int nb_symbols = nb_bits / qam->k;
|
||||||
int sm = (int)sqrt(qam->M);
|
|
||||||
|
|
||||||
// k pair
|
// k pair
|
||||||
if (qam->k % 2 != 0) {
|
if (qam->k % 2 != 0) {
|
||||||
@ -148,11 +146,11 @@ void bits_to_symbols (qam_system* qam, uint8_t* bits, int nb_bits, double comple
|
|||||||
int i_gray = bin_to_gray(i_bin);
|
int i_gray = bin_to_gray(i_bin);
|
||||||
int j_gray = bin_to_gray(j_bin);
|
int j_gray = bin_to_gray(j_bin);
|
||||||
|
|
||||||
if (i_gray < 0 || i_gray >= sm || j_gray < 0 || j_gray >= sm) {
|
if (i_gray < 0 || i_gray >= qam->sm || j_gray < 0 || j_gray >= qam->sm) {
|
||||||
printf("bits_to_symbols : IOOR i_gray = %d j_gray = %d sm = %d \n", i_gray, j_gray, sm);
|
printf("bits_to_symbols : IOOR i_gray = %d j_gray = %d sm = %d \n", i_gray, j_gray, qam->sm);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
symbols[sym] = qam->constellation[i_gray * sm + j_gray];
|
symbols[sym] = qam->constellation[i_gray * qam->sm + j_gray];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -178,10 +176,9 @@ void add_freq(qam_system* qam, double complex* s, double freq_offset, int total_
|
|||||||
}
|
}
|
||||||
|
|
||||||
void fill_constellation_data(qam_system* qam, FILE *fp_ref) {
|
void fill_constellation_data(qam_system* qam, FILE *fp_ref) {
|
||||||
int sm = (int)sqrt(qam->M);
|
for (int i = 0; i < qam->sm; i++) {
|
||||||
for (int i = 0; i < sm; i++) {
|
for (int j = 0; j < qam->sm; j++) {
|
||||||
for (int j = 0; j < sm; j++) {
|
int idx = i * qam->sm + j;
|
||||||
int idx = i * sm + j;
|
|
||||||
fprintf(fp_ref, "% .8f % .8f\n", creal(qam->constellation[idx]), cimag(qam->constellation[idx]));
|
fprintf(fp_ref, "% .8f % .8f\n", creal(qam->constellation[idx]), cimag(qam->constellation[idx]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -208,11 +205,7 @@ void text_to_bits(int nb_chars, int nb_bits, char* texte, uint8_t* input_bits) {
|
|||||||
|
|
||||||
// Libération de la mémoire
|
// Libération de la mémoire
|
||||||
void free_constellation(qam_system* qam) {
|
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);
|
free(qam->constellation);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int main () {
|
int main () {
|
||||||
@ -220,6 +213,7 @@ int main () {
|
|||||||
qam_system qam;
|
qam_system qam;
|
||||||
qam.M = 16;
|
qam.M = 16;
|
||||||
qam.k = (int)log2((double)(qam.M));
|
qam.k = (int)log2((double)(qam.M));
|
||||||
|
qam.sm = (int)sqrt(qam.M);
|
||||||
qam.Fs = 44100;
|
qam.Fs = 44100;
|
||||||
qam.Ts = 0.01;
|
qam.Ts = 0.01;
|
||||||
qam.N = (int)(qam.Fs * qam.Ts);
|
qam.N = (int)(qam.Fs * qam.Ts);
|
||||||
|
|||||||
Reference in New Issue
Block a user