mirror of
https://github.com/radio95-rnt/rds95.git
synced 2026-02-27 12:53:53 +01:00
this is gonna fail to compile
This commit is contained in:
@@ -78,13 +78,13 @@ void init_rds_modulator(RDSModulator* rdsMod, RDSEncoder* enc) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
float get_rds_sample(RDSModulator* rdsMod) {
|
float get_rds_sample(RDSModulator* rdsMod, bool rds2) {
|
||||||
uint16_t idx;
|
uint16_t idx;
|
||||||
float *cur_waveform;
|
float *cur_waveform;
|
||||||
float sample;
|
float sample;
|
||||||
if (rdsMod->sample_count == SAMPLES_PER_BIT) {
|
if (rdsMod->sample_count == SAMPLES_PER_BIT) {
|
||||||
if (rdsMod->bit_pos == BITS_PER_GROUP) {
|
if (rdsMod->bit_pos == BITS_PER_GROUP) {
|
||||||
get_rds_bits(rdsMod->enc, rdsMod->bit_buffer);
|
get_rds_bits(rdsMod->enc, rdsMod->bit_buffer, rds2);
|
||||||
rdsMod->bit_pos = 0;
|
rdsMod->bit_pos = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -29,4 +29,4 @@ 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);
|
||||||
float get_rds_sample(RDSModulator* rdsMod);
|
float get_rds_sample(RDSModulator* rdsMod, bool rds2);
|
||||||
|
|||||||
23
src/rds.c
23
src/rds.c
@@ -112,7 +112,7 @@ void saveToFile(RDSEncoder *emp, const char *option) {
|
|||||||
memcpy(&(tempEncoder.rtpData[emp->program]), &(emp->rtpData[emp->program]), sizeof(RDSRTPlusData));
|
memcpy(&(tempEncoder.rtpData[emp->program]), &(emp->rtpData[emp->program]), sizeof(RDSRTPlusData));
|
||||||
memcpy(&(tempEncoder.odas[emp->program]), &(emp->odas[emp->program]), sizeof(RDSODA)*MAX_ODAS);
|
memcpy(&(tempEncoder.odas[emp->program]), &(emp->odas[emp->program]), sizeof(RDSODA)*MAX_ODAS);
|
||||||
memcpy(&(tempEncoder.oda_state[emp->program]), &(emp->oda_state[emp->program]), sizeof(RDSODAState));
|
memcpy(&(tempEncoder.oda_state[emp->program]), &(emp->oda_state[emp->program]), sizeof(RDSODAState));
|
||||||
memcpy(&(tempEncoder.encoder_data[emp->program]), &(emp->encoder_data[emp->program]), sizeof(RDSODAState));
|
memcpy(&(tempEncoder.encoder_data), &(emp->encoder_data), sizeof(RDSEncoderData));
|
||||||
tempEncoder.program = emp->program;
|
tempEncoder.program = emp->program;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -124,7 +124,7 @@ void saveToFile(RDSEncoder *emp, const char *option) {
|
|||||||
memcpy(&(rdsEncoderfile.rtpData[emp->program]), &(tempEncoder.rtpData[emp->program]), sizeof(RDSRTPlusData));
|
memcpy(&(rdsEncoderfile.rtpData[emp->program]), &(tempEncoder.rtpData[emp->program]), sizeof(RDSRTPlusData));
|
||||||
memcpy(&(rdsEncoderfile.odas[emp->program]), &(tempEncoder.odas[emp->program]), sizeof(RDSODA)*MAX_ODAS);
|
memcpy(&(rdsEncoderfile.odas[emp->program]), &(tempEncoder.odas[emp->program]), sizeof(RDSODA)*MAX_ODAS);
|
||||||
memcpy(&(rdsEncoderfile.oda_state[emp->program]), &(tempEncoder.oda_state[emp->program]), sizeof(RDSODAState));
|
memcpy(&(rdsEncoderfile.oda_state[emp->program]), &(tempEncoder.oda_state[emp->program]), sizeof(RDSODAState));
|
||||||
memcpy(&(rdsEncoderfile.encoder_data[emp->program]), &(tempEncoder.encoder_data[emp->program]), sizeof(RDSODAState));
|
memcpy(&(rdsEncoderfile.encoder_data), &(tempEncoder.encoder_data), sizeof(RDSEncoderData));
|
||||||
rdsEncoderfile.program = tempEncoder.program;
|
rdsEncoderfile.program = tempEncoder.program;
|
||||||
|
|
||||||
file = fopen(encoderPath, "wb");
|
file = fopen(encoderPath, "wb");
|
||||||
@@ -159,8 +159,8 @@ void loadFromFile(RDSEncoder *enc) {
|
|||||||
memcpy(&(enc->rtpData[i]), &(rdsEncoderfile.rtpData[i]), sizeof(RDSRTPlusData));
|
memcpy(&(enc->rtpData[i]), &(rdsEncoderfile.rtpData[i]), sizeof(RDSRTPlusData));
|
||||||
memcpy(&(enc->odas[i]), &(rdsEncoderfile.odas[i]), sizeof(RDSODA) * MAX_ODAS);
|
memcpy(&(enc->odas[i]), &(rdsEncoderfile.odas[i]), sizeof(RDSODA) * MAX_ODAS);
|
||||||
memcpy(&(enc->oda_state[i]), &(rdsEncoderfile.oda_state[i]), sizeof(RDSODAState));
|
memcpy(&(enc->oda_state[i]), &(rdsEncoderfile.oda_state[i]), sizeof(RDSODAState));
|
||||||
memcpy(&(enc->encoder_data[i]), &(rdsEncoderfile.encoder_data[i]), sizeof(RDSODAState));
|
|
||||||
}
|
}
|
||||||
|
memcpy(&(enc->encoder_data), &(rdsEncoderfile.encoder_data), sizeof(RDSODAState));
|
||||||
enc->program = rdsEncoderfile.program;
|
enc->program = rdsEncoderfile.program;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -546,8 +546,13 @@ static uint8_t get_rds_custom_groups(RDSEncoder* enc, uint16_t *blocks) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void get_rds_group(RDSEncoder* enc, uint16_t *blocks) {
|
static void get_rds_group(RDSEncoder* enc, uint16_t *blocks, bool rds2) {
|
||||||
blocks[0] = enc->data[enc->program].pi;
|
blocks[0] = enc->data[enc->program].pi;
|
||||||
|
if(rds2 && !enc->encoder_data.rds2_mode) blocks[0] = 0; // tunneling
|
||||||
|
else if(rds2 && enc->encoder_data.rds2_mode) {
|
||||||
|
// TODO: add rds2 only stuff
|
||||||
|
return;
|
||||||
|
}
|
||||||
blocks[1] = 0;
|
blocks[1] = 0;
|
||||||
blocks[2] = 0;
|
blocks[2] = 0;
|
||||||
blocks[3] = 0;
|
blocks[3] = 0;
|
||||||
@@ -726,9 +731,9 @@ group_coded:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void get_rds_bits(RDSEncoder* enc, uint8_t *bits) {
|
void get_rds_bits(RDSEncoder* enc, uint8_t *bits, bool rds2) {
|
||||||
static uint16_t out_blocks[GROUP_LENGTH];
|
static uint16_t out_blocks[GROUP_LENGTH];
|
||||||
get_rds_group(enc, out_blocks);
|
get_rds_group(enc, out_blocks, rds2);
|
||||||
add_checkwords(out_blocks, bits);
|
add_checkwords(out_blocks, bits);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -775,10 +780,10 @@ void set_rds_defaults(RDSEncoder* enc, uint8_t program) {
|
|||||||
memset(&(enc->oda_state[program]), 0, sizeof(RDSODAState));
|
memset(&(enc->oda_state[program]), 0, sizeof(RDSODAState));
|
||||||
memset(&(enc->odas[program]), 0, sizeof(RDSODA)*MAX_ODAS);
|
memset(&(enc->odas[program]), 0, sizeof(RDSODA)*MAX_ODAS);
|
||||||
memset(&(enc->rtpData[program]), 0, sizeof(RDSRTPlusData));
|
memset(&(enc->rtpData[program]), 0, sizeof(RDSRTPlusData));
|
||||||
memset(&(enc->encoder_data[program]), 0, sizeof(RDSEncoderData));
|
memset(&(enc->encoder_data), 0, sizeof(RDSEncoderData));
|
||||||
|
|
||||||
enc->encoder_data[program].encoder_addr[0] = 255;
|
enc->encoder_data.encoder_addr[0] = 255;
|
||||||
enc->encoder_data[program].encoder_addr[1] = 255;
|
enc->encoder_data.encoder_addr[1] = 255;
|
||||||
|
|
||||||
enc->data[program].ct = 1;
|
enc->data[program].ct = 1;
|
||||||
enc->data[program].di = 1;
|
enc->data[program].di = 1;
|
||||||
|
|||||||
@@ -241,10 +241,11 @@ typedef struct {
|
|||||||
uint16_t special_features;
|
uint16_t special_features;
|
||||||
RDSScheduler schedule;
|
RDSScheduler schedule;
|
||||||
RDSMessages messages;
|
RDSMessages messages;
|
||||||
|
uint8_t rds2_mode : 1;
|
||||||
// uint8_t rds2_buffer[16384];
|
// uint8_t rds2_buffer[16384];
|
||||||
} RDSEncoderData;
|
} RDSEncoderData;
|
||||||
typedef struct {
|
typedef struct {
|
||||||
RDSEncoderData encoder_data[PROGRAMS];
|
RDSEncoderData encoder_data;
|
||||||
RDSData data[PROGRAMS];
|
RDSData data[PROGRAMS];
|
||||||
RDSState state[PROGRAMS];
|
RDSState state[PROGRAMS];
|
||||||
RDSODA odas[PROGRAMS][MAX_ODAS];
|
RDSODA odas[PROGRAMS][MAX_ODAS];
|
||||||
@@ -260,7 +261,7 @@ typedef struct {
|
|||||||
RDSODA odas[PROGRAMS][MAX_ODAS];
|
RDSODA odas[PROGRAMS][MAX_ODAS];
|
||||||
uint8_t file_middle; // Always is 160, average of both
|
uint8_t file_middle; // Always is 160, average of both
|
||||||
RDSODAState oda_state[PROGRAMS];
|
RDSODAState oda_state[PROGRAMS];
|
||||||
RDSEncoderData encoder_data[PROGRAMS];
|
RDSEncoderData encoder_data;
|
||||||
uint8_t program : 3;
|
uint8_t program : 3;
|
||||||
uint8_t file_ender; // Always is 95 my freq
|
uint8_t file_ender; // Always is 95 my freq
|
||||||
} RDSEncoderFile;
|
} RDSEncoderFile;
|
||||||
@@ -332,7 +333,7 @@ int rdssaved();
|
|||||||
void reset_rds_state(RDSEncoder* enc, uint8_t program);
|
void reset_rds_state(RDSEncoder* enc, uint8_t program);
|
||||||
void set_rds_defaults(RDSEncoder* enc, uint8_t program);
|
void set_rds_defaults(RDSEncoder* enc, uint8_t program);
|
||||||
void init_rds_encoder(RDSEncoder* enc);
|
void init_rds_encoder(RDSEncoder* enc);
|
||||||
void get_rds_bits(RDSEncoder* enc, uint8_t *bits);
|
void get_rds_bits(RDSEncoder* enc, uint8_t *bits, bool rds2);
|
||||||
void set_rds_rt1(RDSEncoder* enc, char *rt1);
|
void set_rds_rt1(RDSEncoder* enc, char *rt1);
|
||||||
void set_rds_rt2(RDSEncoder* enc, char *rt2);
|
void set_rds_rt2(RDSEncoder* enc, char *rt2);
|
||||||
void set_rds_dps1(RDSEncoder* enc, char *dps1);
|
void set_rds_dps1(RDSEncoder* enc, char *dps1);
|
||||||
|
|||||||
67
src/rds95.c
67
src/rds95.c
@@ -11,6 +11,9 @@
|
|||||||
#include "lib.h"
|
#include "lib.h"
|
||||||
#include "ascii_cmd.h"
|
#include "ascii_cmd.h"
|
||||||
|
|
||||||
|
#define RDS_DEVICE "RDS"
|
||||||
|
#define RDS2_DEVICE "RDS2"
|
||||||
|
|
||||||
#define NUM_MPX_FRAMES 512
|
#define NUM_MPX_FRAMES 512
|
||||||
|
|
||||||
static uint8_t stop_rds;
|
static uint8_t stop_rds;
|
||||||
@@ -53,7 +56,11 @@ int main(int argc, char **argv) {
|
|||||||
char control_pipe[51] = "\0";
|
char control_pipe[51] = "\0";
|
||||||
|
|
||||||
pa_simple *device;
|
pa_simple *device;
|
||||||
|
#ifdef RDS2_DEVICE
|
||||||
|
pa_simple *rds2_device;
|
||||||
|
#endif
|
||||||
pa_sample_spec format;
|
pa_sample_spec format;
|
||||||
|
pa_buffer_attr buffer;
|
||||||
|
|
||||||
pthread_attr_t attr;
|
pthread_attr_t attr;
|
||||||
pthread_t control_pipe_thread;
|
pthread_t control_pipe_thread;
|
||||||
@@ -91,21 +98,42 @@ int main(int argc, char **argv) {
|
|||||||
format.channels = 1;
|
format.channels = 1;
|
||||||
format.rate = RDS_SAMPLE_RATE;
|
format.rate = RDS_SAMPLE_RATE;
|
||||||
|
|
||||||
|
buffer.prebuf = 0;
|
||||||
|
buffer.tlength = 8192;
|
||||||
|
buffer.maxlength = 8192;
|
||||||
|
|
||||||
device = pa_simple_new(
|
device = pa_simple_new(
|
||||||
NULL, // Default PulseAudio server
|
NULL,
|
||||||
"rds95", // Application name
|
"rds95",
|
||||||
PA_STREAM_PLAYBACK, // Direction (playback)
|
PA_STREAM_PLAYBACK,
|
||||||
"RDS", // Default device
|
RDS_DEVICE,
|
||||||
"RDS Generator", // Stream description
|
"RDS Generator",
|
||||||
&format, // Sample format
|
&format,
|
||||||
NULL, // Default channel map
|
NULL,
|
||||||
NULL, // Default buffering attributes
|
&buffer,
|
||||||
NULL // Error variable
|
NULL
|
||||||
);
|
);
|
||||||
if (device == NULL) {
|
if (device == NULL) {
|
||||||
fprintf(stderr, "Error: cannot open sound device.\n");
|
fprintf(stderr, "Error: cannot open sound device.\n");
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
#ifdef RDS2_DEVICE
|
||||||
|
rds2_device = pa_simple_new(
|
||||||
|
NULL,
|
||||||
|
"rds95",
|
||||||
|
PA_STREAM_PLAYBACK,
|
||||||
|
RDS2_DEVICE,
|
||||||
|
"RDS2 Generator",
|
||||||
|
&format,
|
||||||
|
NULL,
|
||||||
|
&buffer,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
if(rds2_device == NULL) {
|
||||||
|
fprintf(stderr, "Error: cannot open sound device.\n");
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
RDSEncoder rdsEncoder;
|
RDSEncoder rdsEncoder;
|
||||||
RDSModulator rdsModulator;
|
RDSModulator rdsModulator;
|
||||||
@@ -132,17 +160,29 @@ int main(int argc, char **argv) {
|
|||||||
|
|
||||||
int pulse_error;
|
int pulse_error;
|
||||||
|
|
||||||
static float mpx_buffer[NUM_MPX_FRAMES];
|
float rds1_buffer[NUM_MPX_FRAMES];
|
||||||
|
#ifdef RDS2_DEVICE
|
||||||
|
float rds2_buffer[NUM_MPX_FRAMES];
|
||||||
|
#endif
|
||||||
|
|
||||||
while(!stop_rds) {
|
while(!stop_rds) {
|
||||||
for (uint16_t i = 0; i < NUM_MPX_FRAMES; i++) {
|
for (uint16_t i = 0; i < NUM_MPX_FRAMES; i++) {
|
||||||
mpx_buffer[i] = get_rds_sample(&rdsModulator);
|
rds1_buffer[i] = get_rds_sample(&rdsModulator, false);
|
||||||
|
#ifdef RDS2_DEVICE
|
||||||
|
rds2_buffer[i] = get_rds_sample(&rdsModulator, true);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pa_simple_write(device, mpx_buffer, sizeof(mpx_buffer), &pulse_error) != 0) {
|
if (pa_simple_write(device, rds1_buffer, sizeof(rds1_buffer), &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;
|
||||||
}
|
}
|
||||||
|
#ifdef RDS2_DEVICE
|
||||||
|
if (pa_simple_write(rds2_device, rds2_buffer, sizeof(rds2_buffer), &pulse_error) != 0) {
|
||||||
|
fprintf(stderr, "Error: could not play audio. (%s : %d)\n", pa_strerror(pulse_error), pulse_error);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
@@ -153,6 +193,9 @@ exit:
|
|||||||
|
|
||||||
pthread_attr_destroy(&attr);
|
pthread_attr_destroy(&attr);
|
||||||
pa_simple_free(device);
|
pa_simple_free(device);
|
||||||
|
#ifdef RDS2_DEVICE
|
||||||
|
pa_simple_free(rds2_device);
|
||||||
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user