mirror of
https://github.com/radio95-rnt/rds95.git
synced 2026-02-26 20:33:53 +01:00
malloc!??!?!?!
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
48
src/rds95.c
48
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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user