From 971a2e45cdb56c3b5c889b54e44603cb98f4fa1d Mon Sep 17 00:00:00 2001 From: KubaPro010 Date: Sat, 21 Jun 2025 15:57:52 +0200 Subject: [PATCH] malloc!??!?!?! --- src/modulator.c | 34 +++++++++++++++++++++++----------- src/modulator.h | 10 ++++++---- src/rds95.c | 48 +++++++++++++++++++++++++++++++++++++++--------- 3 files changed, 68 insertions(+), 24 deletions(-) diff --git a/src/modulator.c b/src/modulator.c index 15771bc..24c4426 100644 --- a/src/modulator.c +++ b/src/modulator.c @@ -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; -} +} \ No newline at end of file diff --git a/src/modulator.h b/src/modulator.h index 4fed62c..63817a7 100644 --- a/src/modulator.h +++ b/src/modulator.h @@ -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); \ No newline at end of file diff --git a/src/rds95.c b/src/rds95.c index 8c6483f..135f8b0 100644 --- a/src/rds95.c +++ b/src/rds95.c @@ -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);