0
1
mirror of https://github.com/radio95-rnt/rds95.git synced 2026-02-26 12:32:05 +01:00

autosave on exit

This commit is contained in:
2025-12-19 21:09:15 +01:00
parent cbc1152891
commit 86ace60034
8 changed files with 94 additions and 113 deletions

View File

@@ -569,18 +569,6 @@ void process_ascii_cmd(RDSModulator* mod, char *str, char *cmd_output) {
}
}
if (upper_str[0] == '*' && !strchr((const char*)upper_str, '=')) {
const char* option_str = upper_str + 1;
char option[32] = {0};
size_t copy_len = strlen(option_str);
if (copy_len >= sizeof(option)) copy_len = sizeof(option) - 1;
memcpy(option, option_str, copy_len);
option[copy_len] = 0;
saveToFile(mod->enc, option);
Modulator_saveToFile(&mod->params, option);
return;
}
char *equals_pos = strchr(upper_str, '=');
if (equals_pos != NULL) {
cmd = upper_str;

View File

@@ -1,6 +1,6 @@
#include "modulator.h"
void Modulator_saveToFile(RDSModulatorParameters *emp, const char *option) {
void Modulator_saveToFile(RDSModulatorParameters *emp) {
char modulatorPath[128];
snprintf(modulatorPath, sizeof(modulatorPath), "%s/.rdsModulator", getenv("HOME"));
FILE *file;
@@ -20,12 +20,8 @@ void Modulator_saveToFile(RDSModulatorParameters *emp, const char *option) {
}
memcpy(&tempMod, &tempFile.params, sizeof(RDSModulatorParameters));
if (strcmp(option, "LEVEL") == 0) tempMod.level = emp->level;
else if (strcmp(option, "RDSGEN") == 0) tempMod.rdsgen = emp->rdsgen;
else if (strcmp(option, "ALL") == 0) {
tempMod.level = emp->level;
tempMod.rdsgen = emp->rdsgen;
} else return;
tempMod.level = emp->level;
tempMod.rdsgen = emp->rdsgen;
memcpy(&tempFile.params, &tempMod, sizeof(RDSModulatorParameters));
tempFile.check = 160;
@@ -96,7 +92,7 @@ void init_rds_modulator(RDSModulator* rdsMod, RDSEncoder* enc, uint8_t num_strea
}
if(modulatorsaved()) Modulator_loadFromFile(&rdsMod->params);
else Modulator_saveToFile(&rdsMod->params, "ALL");
else Modulator_saveToFile(&rdsMod->params);
}
void cleanup_rds_modulator(RDSModulator* rdsMod) {

View File

@@ -34,7 +34,7 @@ typedef struct {
uint8_t num_streams;
} RDSModulator;
void Modulator_saveToFile(RDSModulatorParameters *emp, const char *option);
void Modulator_saveToFile(RDSModulatorParameters *emp);
void Modulator_loadFromFile(RDSModulatorParameters *emp);
int modulatorsaved();
void init_rds_modulator(RDSModulator* rdsMod, RDSEncoder* enc, uint8_t num_streams);

View File

@@ -1,86 +1,10 @@
#include "common.h"
#include "rds.h"
#include "rds_fs.h"
#include "modulator.h"
#include "lib.h"
#include <time.h>
void saveToFile(RDSEncoder *enc, const char *option) {
char encoderPath[128];
snprintf(encoderPath, sizeof(encoderPath), "%s/.rdsEncoder", getenv("HOME"));
RDSEncoder tempEncoder;
FILE *file = fopen(encoderPath, "rb");
if (file) {
fread(&tempEncoder, sizeof(RDSEncoder), 1, file);
fclose(file);
} else memcpy(&tempEncoder, enc, sizeof(RDSEncoder));
if (strcmp(option, "PROGRAM") == 0) {
memcpy(&tempEncoder.data[enc->program], &enc->data[enc->program], sizeof(RDSData));
memcpy(&tempEncoder.rtpData[enc->program], &enc->rtpData[enc->program], sizeof(RDSRTPlusData) * 2);
} else if (strcmp(option, "ALL") == 0) {
memcpy(tempEncoder.data, enc->data, sizeof(RDSData) * PROGRAMS);
memcpy(tempEncoder.rtpData, enc->rtpData, sizeof(RDSRTPlusData) * PROGRAMS * 2);
memcpy(&tempEncoder.encoder_data, &enc->encoder_data, sizeof(RDSEncoderData));
} else return;
tempEncoder.program = enc->program;
RDSEncoderFile rdsEncoderfile = {.file_starter = 225, .file_middle = 160, .file_ender = 95, .program = tempEncoder.program};
memcpy(&rdsEncoderfile.data[enc->program], &tempEncoder.data[enc->program], sizeof(RDSData));
memcpy(&rdsEncoderfile.rtpData[enc->program], &tempEncoder.rtpData[enc->program], sizeof(RDSRTPlusData) * 2);
memcpy(&rdsEncoderfile.encoder_data, &tempEncoder.encoder_data, sizeof(RDSEncoderData));
rdsEncoderfile.crc = crc16_ccitt((char *)&rdsEncoderfile, offsetof(RDSEncoderFile, crc));
file = fopen(encoderPath, "wb");
if (!file) {
perror("Error opening file");
return;
}
fwrite(&rdsEncoderfile, sizeof(RDSEncoderFile), 1, file);
fclose(file);
}
void loadFromFile(RDSEncoder *enc) {
char encoderPath[128];
snprintf(encoderPath, sizeof(encoderPath), "%s/.rdsEncoder", getenv("HOME"));
RDSEncoderFile rdsEncoderfile;
FILE *file = fopen(encoderPath, "rb");
if (!file) {
perror("Error opening file");
return;
}
fread(&rdsEncoderfile, sizeof(rdsEncoderfile), 1, file);
fclose(file);
if (rdsEncoderfile.file_starter != 225 || rdsEncoderfile.file_ender != 95 || rdsEncoderfile.file_middle != 160) {
fprintf(stderr, "[RDSENCODER-FILE] Invalid file format\n");
return;
}
if (crc16_ccitt((char*)&rdsEncoderfile, offsetof(RDSEncoderFile, crc)) != rdsEncoderfile.crc) {
fprintf(stderr, "[RDSENCODER-FILE] CRC mismatch! Data may be corrupted\n");
return;
}
for (int i = 0; i < PROGRAMS; i++) {
memcpy(&(enc->data[i]), &(rdsEncoderfile.data[i]), sizeof(RDSData));
memcpy(&(enc->rtpData[i]), &(rdsEncoderfile.rtpData[i]), sizeof(RDSRTPlusData)*2);
}
memcpy(&(enc->encoder_data), &(rdsEncoderfile.encoder_data), sizeof(RDSEncoderData));
enc->program = rdsEncoderfile.program;
}
int isFileSaved() {
char encoderPath[128];
snprintf(encoderPath, sizeof(encoderPath), "%s/.rdsEncoder", getenv("HOME"));
FILE *file = fopen(encoderPath, "rb");
if(!file) return 0;
fclose(file);
return 1;
}
static uint16_t get_next_af(RDSEncoder* enc) {
uint16_t out;
@@ -784,7 +708,7 @@ void init_rds_encoder(RDSEncoder* enc) {
for(int i = 0; i < PROGRAMS; i++) set_rds_defaults(enc, i);
if (isFileSaved()) loadFromFile(enc);
else saveToFile(enc, "ALL");
else saveToFile(enc);
for(int i = 0; i < PROGRAMS; i++) reset_rds_state(enc, i);
}

View File

@@ -234,10 +234,6 @@ typedef struct
#define IS_TYPE_B(b) (b & 0x0800)
void saveToFile(RDSEncoder *emp, const char *option);
void loadFromFile(RDSEncoder *emp);
int isFileSaved();
void reset_rds_state(RDSEncoder* enc, uint8_t program);
void set_rds_defaults(RDSEncoder* enc, uint8_t program);
void init_rds_encoder(RDSEncoder* enc);

View File

@@ -7,6 +7,7 @@
#include "../inih/ini.h"
#include "rds.h"
#include "rds_fs.h"
#include "modulator.h"
#include "udp_server.h"
#include "lib.h"
@@ -59,18 +60,15 @@ static int config_handler(void* user, const char* section, const char* name, con
#define MATCH(s, n) (strcmp(section, s) == 0 && strcmp(name, n) == 0)
if (MATCH("rds95", "udp_port")) {
config->udp_port = (uint16_t)atoi(value);
} else if (MATCH("devices", "rds95")) {
if (MATCH("rds95", "udp_port")) config->udp_port = (uint16_t)atoi(value);
else if (MATCH("devices", "rds95")) {
strncpy(config->rds_device_name, value, sizeof(config->rds_device_name) - 1);
config->rds_device_name[sizeof(config->rds_device_name) - 1] = '\0';
} else if (MATCH("rds95", "streams")) {
int streams = atoi(value);
if (streams > MAX_STREAMS || streams == 0) return 0;
config->num_streams = (uint8_t)streams;
} else {
return 0; // Unknown config key
}
} else return 0
return 1;
}
@@ -188,9 +186,7 @@ int main(int argc, char **argv) {
}
while(!stop_rds) {
for (uint16_t i = 0; i < NUM_MPX_FRAMES * config.num_streams; i++) {
rds_buffer[i] = get_rds_sample(&rdsModulator, i % config.num_streams);
}
for (uint16_t i = 0; i < NUM_MPX_FRAMES * config.num_streams; i++) rds_buffer[i] = get_rds_sample(&rdsModulator, i % config.num_streams);
if (pa_simple_write(rds_device, rds_buffer, NUM_MPX_FRAMES * config.num_streams * sizeof(float), &pulse_error) != 0) {
fprintf(stderr, "Error: could not play audio. (%s : %d)\n", pa_strerror(pulse_error), pulse_error);
@@ -206,7 +202,10 @@ exit:
pthread_join(udp_server_thread, NULL);
}
cleanup_rds_modulator(&rdsModulator); // Clean up dynamically allocated memory
saveToFile(rdsEncoder);
Modulator_saveToFile(&rdsModulator.params);
cleanup_rds_modulator(&rdsModulator);
pthread_attr_destroy(&attr);
if (rds_device != NULL) pa_simple_free(rds_device);

73
src/rds_fs.c Normal file
View File

@@ -0,0 +1,73 @@
#include "rds_fs.h"
void saveToFile(RDSEncoder *enc) {
char encoderPath[128];
snprintf(encoderPath, sizeof(encoderPath), "%s/.rdsEncoder", getenv("HOME"));
RDSEncoder tempEncoder;
FILE *file = fopen(encoderPath, "rb");
if (file) {
fread(&tempEncoder, sizeof(RDSEncoder), 1, file);
fclose(file);
} else memcpy(&tempEncoder, enc, sizeof(RDSEncoder));
memcpy(tempEncoder.data, enc->data, sizeof(RDSData) * PROGRAMS);
memcpy(tempEncoder.rtpData, enc->rtpData, sizeof(RDSRTPlusData) * PROGRAMS * 2);
memcpy(&tempEncoder.encoder_data, &enc->encoder_data, sizeof(RDSEncoderData));
tempEncoder.program = enc->program;
RDSEncoderFile rdsEncoderfile = {.file_starter = 225, .file_middle = 160, .file_ender = 95, .program = tempEncoder.program};
memcpy(&rdsEncoderfile.data[enc->program], &tempEncoder.data[enc->program], sizeof(RDSData));
memcpy(&rdsEncoderfile.rtpData[enc->program], &tempEncoder.rtpData[enc->program], sizeof(RDSRTPlusData) * 2);
memcpy(&rdsEncoderfile.encoder_data, &tempEncoder.encoder_data, sizeof(RDSEncoderData));
rdsEncoderfile.crc = crc16_ccitt((char *)&rdsEncoderfile, offsetof(RDSEncoderFile, crc));
file = fopen(encoderPath, "wb");
if (!file) {
perror("Error opening file");
return;
}
fwrite(&rdsEncoderfile, sizeof(RDSEncoderFile), 1, file);
fclose(file);
}
void loadFromFile(RDSEncoder *enc) {
char encoderPath[128];
snprintf(encoderPath, sizeof(encoderPath), "%s/.rdsEncoder", getenv("HOME"));
RDSEncoderFile rdsEncoderfile;
FILE *file = fopen(encoderPath, "rb");
if (!file) {
perror("Error opening file");
return;
}
fread(&rdsEncoderfile, sizeof(rdsEncoderfile), 1, file);
fclose(file);
if (rdsEncoderfile.file_starter != 225 || rdsEncoderfile.file_ender != 95 || rdsEncoderfile.file_middle != 160) {
fprintf(stderr, "[RDSENCODER-FILE] Invalid file format\n");
return;
}
if (crc16_ccitt((char*)&rdsEncoderfile, offsetof(RDSEncoderFile, crc)) != rdsEncoderfile.crc) {
fprintf(stderr, "[RDSENCODER-FILE] CRC mismatch! Data may be corrupted\n");
return;
}
for (int i = 0; i < PROGRAMS; i++) {
memcpy(&(enc->data[i]), &(rdsEncoderfile.data[i]), sizeof(RDSData));
memcpy(&(enc->rtpData[i]), &(rdsEncoderfile.rtpData[i]), sizeof(RDSRTPlusData)*2);
}
memcpy(&(enc->encoder_data), &(rdsEncoderfile.encoder_data), sizeof(RDSEncoderData));
enc->program = rdsEncoderfile.program;
}
int isFileSaved() {
char encoderPath[128];
snprintf(encoderPath, sizeof(encoderPath), "%s/.rdsEncoder", getenv("HOME"));
FILE *file = fopen(encoderPath, "rb");
if(!file) return 0;
fclose(file);
return 1;
}

5
src/rds_fs.h Normal file
View File

@@ -0,0 +1,5 @@
#include "rds.h"
void saveToFile(RDSEncoder *emp);
void loadFromFile(RDSEncoder *emp);
int isFileSaved();