0
1
mirror of https://github.com/radio95-rnt/rds95.git synced 2026-02-26 20:33:53 +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;
}
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));
rdsMod->params.level = 1.0f;
rdsMod->params.rdsgen = 1;
rdsMod->num_streams = num_streams;
rdsMod->enc = enc;
#if STREAMS > 1
rdsMod->data[1].symbol_shift = M_PI/2;
#if STREAMS > 2
rdsMod->data[2].symbol_shift = M_PI;
#if STREAMS > 3
rdsMod->data[3].symbol_shift = 3*M_PI/2;
#endif
#endif
#endif
rdsMod->data = (RDSModulatorModulationData*)calloc(num_streams, sizeof(RDSModulatorModulationData));
if (rdsMod->data == NULL) {
fprintf(stderr, "Error: Could not allocate memory for RDS modulation data\n");
return;
}
for (uint8_t i = 0; i < num_streams; i++) {
rdsMod->data[i].symbol_shift = i * M_PI / 2.0f;
}
if(modulatorsaved()) Modulator_loadFromFile(&rdsMod->params);
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) {
if (stream >= rdsMod->num_streams) {
return 0.0f;
}
rdsMod->data[stream].phase += 1187.5 / RDS_SAMPLE_RATE;
if (rdsMod->data[stream].phase >= 1.0f) {
@@ -118,4 +130,4 @@ float get_rds_sample(RDSModulator* rdsMod, uint8_t stream) {
uint8_t tooutput = rdsMod->params.rdsgen > stream ? 1 : 0;
return sample*rdsMod->params.level*tooutput;
}
}

View File

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

View File

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