mirror of
https://github.com/radio95-rnt/rds95.git
synced 2026-02-26 20:33:53 +01:00
autosave on exit
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
80
src/rds.c
80
src/rds.c
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
19
src/rds95.c
19
src/rds95.c
@@ -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
73
src/rds_fs.c
Normal 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
5
src/rds_fs.h
Normal file
@@ -0,0 +1,5 @@
|
||||
#include "rds.h"
|
||||
|
||||
void saveToFile(RDSEncoder *emp);
|
||||
void loadFromFile(RDSEncoder *emp);
|
||||
int isFileSaved();
|
||||
Reference in New Issue
Block a user