0
1
mirror of https://github.com/radio95-rnt/rds95.git synced 2026-02-27 04:43:52 +01:00

malloc!??!?!?!

This commit is contained in:
2025-06-21 15:57:52 +02:00
parent f8ca7915ea
commit 971a2e45cd
3 changed files with 68 additions and 24 deletions

View File

@@ -77,28 +77,40 @@ int modulatorsaved() {
return 0; return 0;
} }
void init_rds_modulator(RDSModulator* rdsMod, RDSEncoder* enc) { void init_rds_modulator(RDSModulator* rdsMod, RDSEncoder* enc, uint8_t num_streams) {
memset(rdsMod, 0, sizeof(*rdsMod)); memset(rdsMod, 0, sizeof(*rdsMod));
rdsMod->params.level = 1.0f; rdsMod->params.level = 1.0f;
rdsMod->params.rdsgen = 1; rdsMod->params.rdsgen = 1;
rdsMod->num_streams = num_streams;
rdsMod->enc = enc; rdsMod->enc = enc;
#if STREAMS > 1 rdsMod->data = (RDSModulatorModulationData*)calloc(num_streams, sizeof(RDSModulatorModulationData));
rdsMod->data[1].symbol_shift = M_PI/2; if (rdsMod->data == NULL) {
#if STREAMS > 2 fprintf(stderr, "Error: Could not allocate memory for RDS modulation data\n");
rdsMod->data[2].symbol_shift = M_PI; return;
#if STREAMS > 3 }
rdsMod->data[3].symbol_shift = 3*M_PI/2;
#endif for (uint8_t i = 0; i < num_streams; i++) {
#endif rdsMod->data[i].symbol_shift = i * M_PI / 2.0f;
#endif }
if(modulatorsaved()) Modulator_loadFromFile(&rdsMod->params); if(modulatorsaved()) Modulator_loadFromFile(&rdsMod->params);
else Modulator_saveToFile(&rdsMod->params, "ALL"); else Modulator_saveToFile(&rdsMod->params, "ALL");
} }
void cleanup_rds_modulator(RDSModulator* rdsMod) {
if (rdsMod->data) {
free(rdsMod->data);
rdsMod->data = NULL;
}
}
float get_rds_sample(RDSModulator* rdsMod, uint8_t stream) { float get_rds_sample(RDSModulator* rdsMod, uint8_t stream) {
if (stream >= rdsMod->num_streams) {
return 0.0f;
}
rdsMod->data[stream].phase += 1187.5 / RDS_SAMPLE_RATE; rdsMod->data[stream].phase += 1187.5 / RDS_SAMPLE_RATE;
if (rdsMod->data[stream].phase >= 1.0f) { if (rdsMod->data[stream].phase >= 1.0f) {

View File

@@ -23,18 +23,20 @@ typedef struct
uint8_t prev_output : 1; uint8_t prev_output : 1;
uint8_t cur_output : 1; uint8_t cur_output : 1;
uint8_t cur_bit : 1; uint8_t cur_bit : 1;
uint8_t symbol_shift: 7; float symbol_shift;
float phase; float phase;
} RDSModulatorModulationData; } RDSModulatorModulationData;
typedef struct { typedef struct {
RDSModulatorModulationData data[STREAMS]; RDSModulatorModulationData *data;
RDSModulatorParameters params; RDSModulatorParameters params;
RDSEncoder* enc; RDSEncoder* enc;
uint8_t num_streams;
} RDSModulator; } RDSModulator;
void Modulator_saveToFile(RDSModulatorParameters *emp, const char *option); void Modulator_saveToFile(RDSModulatorParameters *emp, const char *option);
void Modulator_loadFromFile(RDSModulatorParameters *emp); void Modulator_loadFromFile(RDSModulatorParameters *emp);
int modulatorsaved(); int modulatorsaved();
void init_rds_modulator(RDSModulator* rdsMod, RDSEncoder* enc); void init_rds_modulator(RDSModulator* rdsMod, RDSEncoder* enc, uint8_t num_streams);
void cleanup_rds_modulator(RDSModulator* rdsMod);
float get_rds_sample(RDSModulator* rdsMod, uint8_t stream); float get_rds_sample(RDSModulator* rdsMod, uint8_t stream);

View File

@@ -12,6 +12,8 @@
#include "ascii_cmd.h" #include "ascii_cmd.h"
#define RDS_DEVICE "RDS" #define RDS_DEVICE "RDS"
#define DEFAULT_STREAMS 1
#define MAX_STREAMS 8
#define NUM_MPX_FRAMES 128 #define NUM_MPX_FRAMES 128
@@ -44,9 +46,12 @@ static inline void show_help(char *name) {
"\n" "\n"
"\t-C,--ctl\tFIFO control pipe\n" "\t-C,--ctl\tFIFO control pipe\n"
"\t-d,--device\tPulseAudio device to use (default: %s)\n" "\t-d,--device\tPulseAudio device to use (default: %s)\n"
"\t-s,--streams\tNumber of RDS streams (1-%d, default: %d)\n"
"\n", "\n",
name, name,
RDS_DEVICE RDS_DEVICE,
MAX_STREAMS,
DEFAULT_STREAMS
); );
} }
@@ -55,6 +60,7 @@ int main(int argc, char **argv) {
char control_pipe[51] = "\0"; char control_pipe[51] = "\0";
char rds_device_name[32] = RDS_DEVICE; char rds_device_name[32] = RDS_DEVICE;
uint8_t num_streams = DEFAULT_STREAMS;
pa_simple *rds_device = NULL; pa_simple *rds_device = NULL;
pa_sample_spec format; pa_sample_spec format;
@@ -63,12 +69,14 @@ int main(int argc, char **argv) {
pthread_attr_t attr; pthread_attr_t attr;
pthread_t control_pipe_thread; pthread_t control_pipe_thread;
const char *short_opt = "C:d:"; const char *short_opt = "C:d:s:h";
struct option long_opt[] = struct option long_opt[] =
{ {
{"ctl", required_argument, NULL, 'C'}, {"ctl", required_argument, NULL, 'C'},
{"device", required_argument, NULL, 'd'}, {"device", required_argument, NULL, 'd'},
{"streams", required_argument, NULL, 's'},
{"help", no_argument, NULL, 'h'},
{ 0, 0, 0, 0 } { 0, 0, 0, 0 }
}; };
@@ -82,24 +90,36 @@ int main(int argc, char **argv) {
memcpy(rds_device_name, optarg, 31); memcpy(rds_device_name, optarg, 31);
rds_device_name[31] = '\0'; rds_device_name[31] = '\0';
break; break;
case 's':
num_streams = (uint8_t)atoi(optarg);
if (num_streams < 1 || num_streams > MAX_STREAMS) {
fprintf(stderr, "Error: Number of streams must be between 1 and %d\n", MAX_STREAMS);
return 1;
}
break;
case 'h':
show_help(argv[0]);
return 0;
default: default:
show_help(argv[0]); show_help(argv[0]);
return 1; return 1;
} }
} }
printf("Using %d RDS stream(s)\n", num_streams);
pthread_attr_init(&attr); pthread_attr_init(&attr);
signal(SIGINT, stop); signal(SIGINT, stop);
signal(SIGTERM, stop); signal(SIGTERM, stop);
format.format = PA_SAMPLE_FLOAT32NE; format.format = PA_SAMPLE_FLOAT32NE;
format.channels = STREAMS; format.channels = num_streams; // Use dynamic stream count
format.rate = RDS_SAMPLE_RATE; format.rate = RDS_SAMPLE_RATE;
buffer.prebuf = 0; buffer.prebuf = 0;
buffer.tlength = NUM_MPX_FRAMES*STREAMS; buffer.tlength = NUM_MPX_FRAMES * num_streams;
buffer.maxlength = NUM_MPX_FRAMES*STREAMS; buffer.maxlength = NUM_MPX_FRAMES * num_streams;
rds_device = pa_simple_new( rds_device = pa_simple_new(
NULL, NULL,
@@ -120,7 +140,7 @@ int main(int argc, char **argv) {
RDSEncoder rdsEncoder; RDSEncoder rdsEncoder;
RDSModulator rdsModulator; RDSModulator rdsModulator;
init_rds_encoder(&rdsEncoder); init_rds_encoder(&rdsEncoder);
init_rds_modulator(&rdsModulator, &rdsEncoder); init_rds_modulator(&rdsModulator, &rdsEncoder, num_streams);
if (control_pipe[0]) { if (control_pipe[0]) {
if (open_control_pipe(control_pipe) == 0) { if (open_control_pipe(control_pipe) == 0) {
@@ -139,23 +159,33 @@ int main(int argc, char **argv) {
int pulse_error; int pulse_error;
float rds_buffer[NUM_MPX_FRAMES*STREAMS]; // Dynamically allocate buffer based on stream count
float *rds_buffer = (float*)malloc(NUM_MPX_FRAMES * num_streams * sizeof(float));
if (rds_buffer == NULL) {
fprintf(stderr, "Error: Could not allocate memory for RDS buffer\n");
goto exit;
}
while(!stop_rds) { while(!stop_rds) {
for (uint16_t i = 0; i < NUM_MPX_FRAMES * STREAMS; i++) rds_buffer[i] = get_rds_sample(&rdsModulator, i % STREAMS); for (uint16_t i = 0; i < NUM_MPX_FRAMES * num_streams; i++) {
rds_buffer[i] = get_rds_sample(&rdsModulator, i % num_streams);
}
if (pa_simple_write(rds_device, rds_buffer, sizeof(rds_buffer), &pulse_error) != 0) { if (pa_simple_write(rds_device, rds_buffer, NUM_MPX_FRAMES * num_streams * sizeof(float), &pulse_error) != 0) {
fprintf(stderr, "Error: could not play audio. (%s : %d)\n", pa_strerror(pulse_error), pulse_error); fprintf(stderr, "Error: could not play audio. (%s : %d)\n", pa_strerror(pulse_error), pulse_error);
break; break;
} }
} }
free(rds_buffer);
exit: exit:
if (control_pipe[0]) { if (control_pipe[0]) {
fprintf(stderr, "Waiting for pipe thread to shut down.\n"); fprintf(stderr, "Waiting for pipe thread to shut down.\n");
pthread_join(control_pipe_thread, NULL); pthread_join(control_pipe_thread, NULL);
} }
cleanup_rds_modulator(&rdsModulator); // Clean up dynamically allocated memory
pthread_attr_destroy(&attr); pthread_attr_destroy(&attr);
if (rds_device != NULL) pa_simple_free(rds_device); if (rds_device != NULL) pa_simple_free(rds_device);