This commit is contained in:
2025-12-20 10:17:16 +01:00
parent 61215725e5
commit eb0f11b962
11 changed files with 111 additions and 120 deletions
+1 -1
View File
@@ -317,7 +317,7 @@ static void handle_level(char *arg, RDSModulator* mod, char* output) {
static void handle_reset(char *arg, RDSModulator* mod, char* output) { static void handle_reset(char *arg, RDSModulator* mod, char* output) {
(void)arg; (void)arg;
loadFromFile(mod->enc); encoder_loadFromFile(mod->enc);
for(int i = 0; i < PROGRAMS; i++) reset_rds_state(mod->enc, i); for(int i = 0; i < PROGRAMS; i++) reset_rds_state(mod->enc, i);
Modulator_loadFromFile(&mod->params); Modulator_loadFromFile(&mod->params);
strcpy(output, "+"); strcpy(output, "+");
+1 -1
View File
@@ -1,6 +1,6 @@
#include "common.h" #include "common.h"
#include "rds.h" #include "rds.h"
#include "rds_fs.h" #include "fs.h"
#include "modulator.h" #include "modulator.h"
#include "lib.h" #include "lib.h"
#define CMD_BUFFER_SIZE 255 #define CMD_BUFFER_SIZE 255
+77 -4
View File
@@ -1,6 +1,6 @@
#include "rds_fs.h" #include "fs.h"
void saveToFile(RDSEncoder *enc) { void encoder_saveToFile(RDSEncoder *enc) {
char encoderPath[128]; char encoderPath[128];
snprintf(encoderPath, sizeof(encoderPath), "%s/.rdsEncoder", getenv("HOME")); snprintf(encoderPath, sizeof(encoderPath), "%s/.rdsEncoder", getenv("HOME"));
@@ -32,7 +32,7 @@ void saveToFile(RDSEncoder *enc) {
fclose(file); fclose(file);
} }
void loadFromFile(RDSEncoder *enc) { void encoder_loadFromFile(RDSEncoder *enc) {
char encoderPath[128]; char encoderPath[128];
snprintf(encoderPath, sizeof(encoderPath), "%s/.rdsEncoder", getenv("HOME")); snprintf(encoderPath, sizeof(encoderPath), "%s/.rdsEncoder", getenv("HOME"));
@@ -63,7 +63,7 @@ void loadFromFile(RDSEncoder *enc) {
enc->program = rdsEncoderfile.program; enc->program = rdsEncoderfile.program;
} }
int isFileSaved() { int encoder_saved() {
char encoderPath[128]; char encoderPath[128];
snprintf(encoderPath, sizeof(encoderPath), "%s/.rdsEncoder", getenv("HOME")); snprintf(encoderPath, sizeof(encoderPath), "%s/.rdsEncoder", getenv("HOME"));
FILE *file = fopen(encoderPath, "rb"); FILE *file = fopen(encoderPath, "rb");
@@ -71,3 +71,76 @@ int isFileSaved() {
fclose(file); fclose(file);
return 1; return 1;
} }
void Modulator_saveToFile(RDSModulatorParameters *emp) {
char modulatorPath[128];
snprintf(modulatorPath, sizeof(modulatorPath), "%s/.rdsModulator", getenv("HOME"));
FILE *file;
RDSModulatorParameters tempMod;
RDSModulatorParametersFile tempFile;
memset(&tempFile, 0, sizeof(tempFile));
file = fopen(modulatorPath, "rb");
if (file != NULL) {
fread(&tempFile, sizeof(RDSModulatorParametersFile), 1, file);
fclose(file);
} else {
memset(&tempFile, 0, sizeof(RDSModulatorParametersFile));
tempFile.check = 160;
memcpy(&tempFile.params, emp, sizeof(RDSModulatorParameters));
tempFile.crc = crc16_ccitt((char*)&tempFile, offsetof(RDSModulatorParametersFile, crc));
}
memcpy(&tempMod, &tempFile.params, sizeof(RDSModulatorParameters));
tempMod.level = emp->level;
tempMod.rdsgen = emp->rdsgen;
memcpy(&tempFile.params, &tempMod, sizeof(RDSModulatorParameters));
tempFile.check = 160;
tempFile.crc = crc16_ccitt((char*)&tempFile, offsetof(RDSModulatorParametersFile, crc));
file = fopen(modulatorPath, "wb");
if (file == NULL) {
perror("Error opening file");
return;
}
fwrite(&tempFile, sizeof(RDSModulatorParametersFile), 1, file);
fclose(file);
}
void Modulator_loadFromFile(RDSModulatorParameters *emp) {
char modulatorPath[128];
snprintf(modulatorPath, sizeof(modulatorPath), "%s/.rdsModulator", getenv("HOME"));
FILE *file = fopen(modulatorPath, "rb");
if (file == NULL) {
perror("Error opening file");
return;
}
RDSModulatorParametersFile tempFile;
memset(&tempFile, 0, sizeof(tempFile));
fread(&tempFile, sizeof(RDSModulatorParametersFile), 1, file);
if (tempFile.check != 160) {
fprintf(stderr, "[RDSMODULATOR-FILE] Invalid file format\n");
fclose(file);
return;
}
uint16_t calculated_crc = crc16_ccitt((char*)&tempFile, offsetof(RDSModulatorParametersFile, crc));
if (calculated_crc != tempFile.crc) {
fprintf(stderr, "[RDSMODULATOR-FILE] CRC mismatch! Data may be corrupted\n");
fclose(file);
return;
}
memcpy(emp, &tempFile.params, sizeof(RDSModulatorParameters));
fclose(file);
}
int modulatorsaved() {
char encoderPath[128];
snprintf(encoderPath, sizeof(encoderPath), "%s/.rdsModulator", getenv("HOME"));
FILE *file = fopen(encoderPath, "rb");
if (file) {
fclose(file);
return 1;
}
return 0;
}
+12
View File
@@ -0,0 +1,12 @@
#include "common.h"
#include "rds.h"
#include "modulator.h"
#include "lib.h"
void encoder_saveToFile(RDSEncoder *emp);
void encoder_loadFromFile(RDSEncoder *emp);
int encoder_saved();
void Modulator_saveToFile(RDSModulatorParameters *emp);
void Modulator_loadFromFile(RDSModulatorParameters *emp);
int modulatorsaved();
+2 -76
View File
@@ -1,77 +1,5 @@
#include "modulator.h" #include "modulator.h"
#include "fs.h"
void Modulator_saveToFile(RDSModulatorParameters *emp) {
char modulatorPath[128];
snprintf(modulatorPath, sizeof(modulatorPath), "%s/.rdsModulator", getenv("HOME"));
FILE *file;
RDSModulatorParameters tempMod;
RDSModulatorParametersFile tempFile;
memset(&tempFile, 0, sizeof(tempFile));
file = fopen(modulatorPath, "rb");
if (file != NULL) {
fread(&tempFile, sizeof(RDSModulatorParametersFile), 1, file);
fclose(file);
} else {
memset(&tempFile, 0, sizeof(RDSModulatorParametersFile));
tempFile.check = 160;
memcpy(&tempFile.params, emp, sizeof(RDSModulatorParameters));
tempFile.crc = crc16_ccitt((char*)&tempFile, offsetof(RDSModulatorParametersFile, crc));
}
memcpy(&tempMod, &tempFile.params, sizeof(RDSModulatorParameters));
tempMod.level = emp->level;
tempMod.rdsgen = emp->rdsgen;
memcpy(&tempFile.params, &tempMod, sizeof(RDSModulatorParameters));
tempFile.check = 160;
tempFile.crc = crc16_ccitt((char*)&tempFile, offsetof(RDSModulatorParametersFile, crc));
file = fopen(modulatorPath, "wb");
if (file == NULL) {
perror("Error opening file");
return;
}
fwrite(&tempFile, sizeof(RDSModulatorParametersFile), 1, file);
fclose(file);
}
void Modulator_loadFromFile(RDSModulatorParameters *emp) {
char modulatorPath[128];
snprintf(modulatorPath, sizeof(modulatorPath), "%s/.rdsModulator", getenv("HOME"));
FILE *file = fopen(modulatorPath, "rb");
if (file == NULL) {
perror("Error opening file");
return;
}
RDSModulatorParametersFile tempFile;
memset(&tempFile, 0, sizeof(tempFile));
fread(&tempFile, sizeof(RDSModulatorParametersFile), 1, file);
if (tempFile.check != 160) {
fprintf(stderr, "[RDSMODULATOR-FILE] Invalid file format\n");
fclose(file);
return;
}
uint16_t calculated_crc = crc16_ccitt((char*)&tempFile, offsetof(RDSModulatorParametersFile, crc));
if (calculated_crc != tempFile.crc) {
fprintf(stderr, "[RDSMODULATOR-FILE] CRC mismatch! Data may be corrupted\n");
fclose(file);
return;
}
memcpy(emp, &tempFile.params, sizeof(RDSModulatorParameters));
fclose(file);
}
int modulatorsaved() {
char encoderPath[128];
snprintf(encoderPath, sizeof(encoderPath), "%s/.rdsModulator", getenv("HOME"));
FILE *file = fopen(encoderPath, "rb");
if (file) {
fclose(file);
return 1;
}
return 0;
}
void init_rds_modulator(RDSModulator* rdsMod, RDSEncoder* enc, uint8_t num_streams) { void init_rds_modulator(RDSModulator* rdsMod, RDSEncoder* enc, uint8_t num_streams) {
memset(rdsMod, 0, sizeof(*rdsMod)); memset(rdsMod, 0, sizeof(*rdsMod));
@@ -87,9 +15,7 @@ void init_rds_modulator(RDSModulator* rdsMod, RDSEncoder* enc, uint8_t num_strea
return; return;
} }
for (uint8_t i = 0; i < num_streams; i++) { for (uint8_t i = 0; i < num_streams; i++) rdsMod->data[i].symbol_shift = i * M_PI / 2.0f;
rdsMod->data[i].symbol_shift = i * M_PI / 2.0f;
}
if(modulatorsaved()) Modulator_loadFromFile(&rdsMod->params); if(modulatorsaved()) Modulator_loadFromFile(&rdsMod->params);
else Modulator_saveToFile(&rdsMod->params); else Modulator_saveToFile(&rdsMod->params);
-3
View File
@@ -34,9 +34,6 @@ typedef struct {
uint8_t num_streams; uint8_t num_streams;
} RDSModulator; } RDSModulator;
void Modulator_saveToFile(RDSModulatorParameters *emp);
void Modulator_loadFromFile(RDSModulatorParameters *emp);
int modulatorsaved();
void init_rds_modulator(RDSModulator* rdsMod, RDSEncoder* enc, uint8_t num_streams); void init_rds_modulator(RDSModulator* rdsMod, RDSEncoder* enc, uint8_t num_streams);
void cleanup_rds_modulator(RDSModulator* rdsMod); void cleanup_rds_modulator(RDSModulator* rdsMod);
float get_rds_sample(RDSModulator* rdsMod, uint8_t stream); float get_rds_sample(RDSModulator* rdsMod, uint8_t stream);
+9 -9
View File
@@ -1,6 +1,6 @@
#include "common.h" #include "common.h"
#include "rds.h" #include "rds.h"
#include "rds_fs.h" #include "fs.h"
#include "modulator.h" #include "modulator.h"
#include "lib.h" #include "lib.h"
#include <time.h> #include <time.h>
@@ -138,26 +138,26 @@ static void get_rds_rt_group(RDSEncoder* enc, RDSGroup *group) {
enc->state[enc->program].rt_state++; enc->state[enc->program].rt_state++;
if (enc->state[enc->program].rt_state == segments) enc->state[enc->program].rt_state = 0; if (enc->state[enc->program].rt_state == segments) enc->state[enc->program].rt_state = 0;
} }
static void get_rdsp_rtp_oda_group(RDSGroup *group) { inline static void get_rdsp_rtp_oda_group(RDSGroup *group) {
group->b |= 3 << 12; group->b |= 3 << 12;
group->b |= 11 << 1; group->b |= 11 << 1;
group->d = ODA_AID_RTPLUS; group->d = ODA_AID_RTPLUS;
} }
static void get_rdsp_ertp_oda_group(RDSGroup *group) { inline static void get_rdsp_ertp_oda_group(RDSGroup *group) {
group->b |= 3 << 12; group->b |= 3 << 12;
group->b |= 13 << 1; group->b |= 13 << 1;
group->d = ODA_AID_ERTPLUS; group->d = ODA_AID_ERTPLUS;
} }
static void get_rdsp_ert_oda_group(RDSGroup *group) { inline static void get_rdsp_ert_oda_group(RDSGroup *group) {
group->b |= 3 << 12; group->b |= 3 << 12;
group->b |= 12 << 1; group->b |= 12 << 1;
group->c = 1; // UTF-8 group->c = 1; // UTF-8
group->d = ODA_AID_ERT; group->d = ODA_AID_ERT;
} }
static void get_rdsp_oda_af_oda_group(RDSGroup *group) { inline static void get_rdsp_oda_af_oda_group(RDSGroup *group) {
group->b |= 3 << 12; group->b |= 3 << 12;
group->b |= 7 << 1; group->b |= 7 << 1;
group->d = ODA_AID_ODAAF; group->d = ODA_AID_ODAAF;
@@ -234,13 +234,13 @@ static void get_rds_lps_group(RDSEncoder* enc, RDSGroup *group) {
if (enc->state[enc->program].lps_state == enc->state[enc->program].lps_segments) enc->state[enc->program].lps_state = 0; if (enc->state[enc->program].lps_state == enc->state[enc->program].lps_segments) enc->state[enc->program].lps_state = 0;
} }
static void get_rds_ecc_group(RDSEncoder* enc, RDSGroup *group) { inline static void get_rds_ecc_group(RDSEncoder* enc, RDSGroup *group) {
group->b |= 1 << 12; group->b |= 1 << 12;
group->c = enc->state[enc->program].eon_linkage << 15; group->c = enc->state[enc->program].eon_linkage << 15;
group->c |= enc->data[enc->program].ecc; group->c |= enc->data[enc->program].ecc;
} }
static void get_rds_slcdata_group(RDSEncoder* enc, RDSGroup *group) { inline static void get_rds_slcdata_group(RDSEncoder* enc, RDSGroup *group) {
group->b |= 1 << 12; group->b |= 1 << 12;
group->c = enc->state[enc->program].eon_linkage << 15; group->c = enc->state[enc->program].eon_linkage << 15;
group->c |= 0x6000; group->c |= 0x6000;
@@ -702,8 +702,8 @@ void set_rds_defaults(RDSEncoder* enc, uint8_t program) {
void init_rds_encoder(RDSEncoder* enc) { void init_rds_encoder(RDSEncoder* enc) {
for(int i = 0; i < PROGRAMS; i++) set_rds_defaults(enc, i); for(int i = 0; i < PROGRAMS; i++) set_rds_defaults(enc, i);
if (isFileSaved()) loadFromFile(enc); if (encoder_saved()) encoder_loadFromFile(enc);
else saveToFile(enc); else encoder_saveToFile(enc);
for(int i = 0; i < PROGRAMS; i++) reset_rds_state(enc, i); for(int i = 0; i < PROGRAMS; i++) reset_rds_state(enc, i);
} }
+4 -6
View File
@@ -7,7 +7,7 @@
#include "../inih/ini.h" #include "../inih/ini.h"
#include "rds.h" #include "rds.h"
#include "rds_fs.h" #include "fs.h"
#include "modulator.h" #include "modulator.h"
#include "udp_server.h" #include "udp_server.h"
#include "lib.h" #include "lib.h"
@@ -133,12 +133,11 @@ int main(int argc, char **argv) {
signal(SIGTERM, stop); signal(SIGTERM, stop);
format.format = PA_SAMPLE_FLOAT32NE; format.format = PA_SAMPLE_FLOAT32NE;
format.channels = config.num_streams; // Use dynamic stream count format.channels = config.num_streams;
format.rate = RDS_SAMPLE_RATE; format.rate = RDS_SAMPLE_RATE;
buffer.prebuf = 0; buffer.prebuf = 0;
buffer.tlength = NUM_MPX_FRAMES * config.num_streams; buffer.tlength = buffer.maxlength = NUM_MPX_FRAMES * config.num_streams;
buffer.maxlength = NUM_MPX_FRAMES * config.num_streams;
rds_device = pa_simple_new( rds_device = pa_simple_new(
NULL, NULL,
@@ -178,7 +177,6 @@ int main(int argc, char **argv) {
int pulse_error; int pulse_error;
// Dynamically allocate buffer based on stream count
float *rds_buffer = (float*)malloc(NUM_MPX_FRAMES * config.num_streams * sizeof(float)); float *rds_buffer = (float*)malloc(NUM_MPX_FRAMES * config.num_streams * sizeof(float));
if (rds_buffer == NULL) { if (rds_buffer == NULL) {
fprintf(stderr, "Error: Could not allocate memory for RDS buffer\n"); fprintf(stderr, "Error: Could not allocate memory for RDS buffer\n");
@@ -202,7 +200,7 @@ exit:
pthread_join(udp_server_thread, NULL); pthread_join(udp_server_thread, NULL);
} }
saveToFile(&rdsEncoder); encoder_saveToFile(&rdsEncoder);
Modulator_saveToFile(&rdsModulator.params); Modulator_saveToFile(&rdsModulator.params);
cleanup_rds_modulator(&rdsModulator); cleanup_rds_modulator(&rdsModulator);
-7
View File
@@ -1,7 +0,0 @@
#include "common.h"
#include "rds.h"
#include "lib.h"
void saveToFile(RDSEncoder *emp);
void loadFromFile(RDSEncoder *emp);
int isFileSaved();
+5 -11
View File
@@ -30,7 +30,7 @@ int open_udp_server(int port, RDSModulator* rds_mod) {
poller.fd = sockfd; poller.fd = sockfd;
poller.events = POLLIN; poller.events = POLLIN;
mod = rds_mod; // Save mod pointer mod = rds_mod;
return 0; return 0;
} }
@@ -38,7 +38,7 @@ int open_udp_server(int port, RDSModulator* rds_mod) {
void poll_udp_server() { void poll_udp_server() {
static char buf[BUF_SIZE]; static char buf[BUF_SIZE];
static char cmd_buf[BUF_SIZE]; static char cmd_buf[BUF_SIZE];
static char cmd_output[BUF_SIZE]; // Buffer to collect output from process_ascii_cmd static char cmd_output[BUF_SIZE];
ssize_t bytes_read; ssize_t bytes_read;
if (poll(&poller, 1, UDP_READ_TIMEOUT_MS) <= 0) return; if (poll(&poller, 1, UDP_READ_TIMEOUT_MS) <= 0) return;
@@ -46,8 +46,7 @@ void poll_udp_server() {
memset(buf, 0, BUF_SIZE); memset(buf, 0, BUF_SIZE);
client_len = sizeof(client_addr); client_len = sizeof(client_addr);
bytes_read = recvfrom(sockfd, buf, BUF_SIZE - 1, 0, bytes_read = recvfrom(sockfd, buf, BUF_SIZE - 1, 0, (struct sockaddr *)&client_addr, &client_len);
(struct sockaddr *)&client_addr, &client_len);
if (bytes_read <= 0) return; if (bytes_read <= 0) return;
buf[bytes_read] = '\0'; buf[bytes_read] = '\0';
@@ -60,17 +59,12 @@ void poll_udp_server() {
strncpy(cmd_buf, token, BUF_SIZE - 1); strncpy(cmd_buf, token, BUF_SIZE - 1);
memset(cmd_output, 0, BUF_SIZE); memset(cmd_output, 0, BUF_SIZE);
// Pass cmd_output buffer to collect output from the command processor
process_ascii_cmd(mod, cmd_buf, cmd_output); process_ascii_cmd(mod, cmd_buf, cmd_output);
// Send cmd_output back to client (even if empty, send it)
size_t out_len = strlen(cmd_output); size_t out_len = strlen(cmd_output);
if (out_len > 0) { if (out_len > 0) {
ssize_t sent = sendto(sockfd, cmd_output, out_len, 0, ssize_t sent = sendto(sockfd, cmd_output, out_len, 0, (struct sockaddr *)&client_addr, client_len);
(struct sockaddr *)&client_addr, client_len); if (sent == -1) perror("sendto");
if (sent == -1) {
perror("sendto");
}
} }
} }
token = strtok(NULL, "\r\n"); token = strtok(NULL, "\r\n");
-2
View File
@@ -13,7 +13,5 @@
#include "ascii_cmd.h" #include "ascii_cmd.h"
int open_udp_server(int port, RDSModulator *rds_mod); int open_udp_server(int port, RDSModulator *rds_mod);
void poll_udp_server(); void poll_udp_server();
void close_udp_server(); void close_udp_server();