mirror of
https://github.com/radio95-rnt/rds95.git
synced 2026-02-26 20:33:53 +01:00
don't use malloc in the rds modulator
This commit is contained in:
2
.vscode/.server-controller-port.log
vendored
2
.vscode/.server-controller-port.log
vendored
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"port": 13452,
|
"port": 13452,
|
||||||
"time": 1741720487844,
|
"time": 1741789102822,
|
||||||
"version": "0.0.3"
|
"version": "0.0.3"
|
||||||
}
|
}
|
||||||
@@ -57,9 +57,9 @@ outc.write(header)
|
|||||||
outh.write(header)
|
outh.write(header)
|
||||||
|
|
||||||
def generate():
|
def generate():
|
||||||
offset = int(sample_rate*0.004) # 190 khz = 760 760/10/2 = 38 190000/10/2=9500
|
offset = int(sample_rate*0.004) # 190 khz = 760
|
||||||
count = int(offset / 10**(len(str(offset)) - 1)) # 760 / 100 = 7 38 / 10 = 3
|
count = int(offset / 10**(len(str(offset)) - 1)) # 760 / 100 = 7
|
||||||
l = int(sample_rate / 1187.5) // 2 # 16/2 = 8 8 / 2 = 4
|
l = int(sample_rate / 1187.5) // 2 # 16/2 = 8
|
||||||
if count*l > l*16: raise Exception("Sample rate too small")
|
if count*l > l*16: raise Exception("Sample rate too small")
|
||||||
print(f"{offset=} {count=} {l=}")
|
print(f"{offset=} {count=} {l=}")
|
||||||
|
|
||||||
|
|||||||
@@ -3,20 +3,14 @@
|
|||||||
#include "waveforms.h"
|
#include "waveforms.h"
|
||||||
#include "modulator.h"
|
#include "modulator.h"
|
||||||
|
|
||||||
static struct rds_t *rds;
|
static struct rds_t rds;
|
||||||
static float **waveform;
|
static float waveform[2][FILTER_SIZE];
|
||||||
|
|
||||||
void init_rds_objects() {
|
void init_rds_objects() {
|
||||||
rds = malloc(sizeof(struct rds_t));
|
memset(&rds, 0, sizeof(rds));
|
||||||
rds->bit_buffer = malloc(BITS_PER_GROUP);
|
|
||||||
rds->sample_buffer =
|
|
||||||
malloc(SAMPLE_BUFFER_SIZE * sizeof(float));
|
|
||||||
|
|
||||||
waveform = malloc(2 * sizeof(float));
|
|
||||||
|
|
||||||
for (uint8_t i = 0; i < 2; i++) {
|
for (uint8_t i = 0; i < 2; i++) {
|
||||||
// This is the bpsk, so waveform[0] is 0 degrees out of phase but waveform[1] is 180 degrees, bpsk
|
// This is the bpsk, so waveform[0] is 0 degrees out of phase but waveform[1] is 180 degrees, bpsk
|
||||||
waveform[i] = malloc(FILTER_SIZE * sizeof(float));
|
|
||||||
for (uint16_t j = 0; j < FILTER_SIZE; j++) {
|
for (uint16_t j = 0; j < FILTER_SIZE; j++) {
|
||||||
waveform[i][j] = i ?
|
waveform[i][j] = i ?
|
||||||
+waveform_biphase[j] : -waveform_biphase[j];
|
+waveform_biphase[j] : -waveform_biphase[j];
|
||||||
@@ -24,18 +18,6 @@ void init_rds_objects() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void exit_rds_objects() {
|
|
||||||
free(rds->sample_buffer);
|
|
||||||
free(rds->bit_buffer);
|
|
||||||
free(rds);
|
|
||||||
|
|
||||||
for (uint8_t i = 0; i < 2; i++) {
|
|
||||||
free(waveform[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
free(waveform);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get an RDS sample. This generates the envelope of the waveform using
|
/* Get an RDS sample. This generates the envelope of the waveform using
|
||||||
* pre-generated elementary waveform samples.
|
* pre-generated elementary waveform samples.
|
||||||
*/
|
*/
|
||||||
@@ -43,40 +25,39 @@ float get_rds_sample() {
|
|||||||
uint16_t idx;
|
uint16_t idx;
|
||||||
float *cur_waveform;
|
float *cur_waveform;
|
||||||
float sample;
|
float sample;
|
||||||
|
if (rds.sample_count == SAMPLES_PER_BIT) {
|
||||||
if (rds->sample_count == SAMPLES_PER_BIT) {
|
|
||||||
// New Sample
|
// New Sample
|
||||||
if (rds->bit_pos == BITS_PER_GROUP) {
|
if (rds.bit_pos == BITS_PER_GROUP) {
|
||||||
// New bit stream
|
// New bit stream
|
||||||
get_rds_bits(rds->bit_buffer);
|
get_rds_bits(rds.bit_buffer);
|
||||||
rds->bit_pos = 0;
|
rds.bit_pos = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Differentially encode, so 1111 becomes 1000 and 0001 becomes 0001
|
// Differentially encode, so 1111 becomes 1000 and 0001 becomes 0001
|
||||||
rds->cur_bit = rds->bit_buffer[rds->bit_pos++];
|
rds.cur_bit = rds.bit_buffer[rds.bit_pos++];
|
||||||
rds->prev_output = rds->cur_output;
|
rds.prev_output = rds.cur_output;
|
||||||
rds->cur_output = rds->prev_output ^ rds->cur_bit;
|
rds.cur_output = rds.prev_output ^ rds.cur_bit;
|
||||||
|
|
||||||
idx = rds->in_sample_index;
|
idx = rds.in_sample_index;
|
||||||
cur_waveform = waveform[rds->cur_output]; // get the waveform, this is the biphase in a 0/180 degree phase shift
|
cur_waveform = waveform[rds.cur_output]; // get the waveform, this is the biphase in a 0/180 degree phase shift
|
||||||
|
|
||||||
for (uint16_t i = 0; i < FILTER_SIZE; i++) {
|
for (uint16_t i = 0; i < FILTER_SIZE; i++) {
|
||||||
rds->sample_buffer[idx++] += *cur_waveform++;
|
rds.sample_buffer[idx++] += *cur_waveform++;
|
||||||
if (idx == SAMPLE_BUFFER_SIZE) idx = 0;
|
if (idx == SAMPLE_BUFFER_SIZE) idx = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
rds->in_sample_index += SAMPLES_PER_BIT;
|
rds.in_sample_index += SAMPLES_PER_BIT;
|
||||||
if (rds->in_sample_index == SAMPLE_BUFFER_SIZE)
|
if (rds.in_sample_index == SAMPLE_BUFFER_SIZE)
|
||||||
rds->in_sample_index = 0;
|
rds.in_sample_index = 0;
|
||||||
|
|
||||||
rds->sample_count = 0;
|
rds.sample_count = 0;
|
||||||
}
|
}
|
||||||
rds->sample_count++;
|
rds.sample_count++;
|
||||||
|
|
||||||
sample = rds->sample_buffer[rds->out_sample_index];
|
sample = rds.sample_buffer[rds.out_sample_index];
|
||||||
|
|
||||||
rds->sample_buffer[rds->out_sample_index++] = 0;
|
rds.sample_buffer[rds.out_sample_index++] = 0;
|
||||||
if (rds->out_sample_index == SAMPLE_BUFFER_SIZE)
|
if (rds.out_sample_index == SAMPLE_BUFFER_SIZE)
|
||||||
rds->out_sample_index = 0;
|
rds.out_sample_index = 0;
|
||||||
return sample;
|
return sample;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
/* RDS signal context */
|
/* RDS signal context */
|
||||||
typedef struct rds_t {
|
typedef struct rds_t {
|
||||||
uint8_t *bit_buffer; /* BITS_PER_GROUP */
|
uint8_t bit_buffer[BITS_PER_GROUP];
|
||||||
uint8_t bit_pos;
|
uint8_t bit_pos;
|
||||||
float *sample_buffer; /* SAMPLE_BUFFER_SIZE */
|
float sample_buffer[SAMPLE_BUFFER_SIZE];
|
||||||
uint8_t prev_output;
|
uint8_t prev_output;
|
||||||
uint8_t cur_output;
|
uint8_t cur_output;
|
||||||
uint8_t cur_bit;
|
uint8_t cur_bit;
|
||||||
@@ -12,5 +12,3 @@ typedef struct rds_t {
|
|||||||
} rds_t;
|
} rds_t;
|
||||||
|
|
||||||
extern void init_rds_objects();
|
extern void init_rds_objects();
|
||||||
extern void exit_rds_objects();
|
|
||||||
|
|
||||||
|
|||||||
@@ -547,10 +547,6 @@ void init_rds_encoder(struct rds_params_t rds_params) {
|
|||||||
init_rds_objects();
|
init_rds_objects();
|
||||||
}
|
}
|
||||||
|
|
||||||
void exit_rds_encoder() {
|
|
||||||
exit_rds_objects();
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_rds_pi(uint16_t pi_code) {
|
void set_rds_pi(uint16_t pi_code) {
|
||||||
rds_data.pi = pi_code;
|
rds_data.pi = pi_code;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
#define GROUP_LENGTH 4
|
#define GROUP_LENGTH 4
|
||||||
#define BITS_PER_GROUP (GROUP_LENGTH * (BLOCK_SIZE + POLY_DEG))
|
#define BITS_PER_GROUP (GROUP_LENGTH * (BLOCK_SIZE + POLY_DEG))
|
||||||
#define RDS_SAMPLE_RATE 9500
|
#define RDS_SAMPLE_RATE 9500
|
||||||
#define SAMPLES_PER_BIT 8
|
#define SAMPLES_PER_BIT 8 // (1/1187.5)*RDS_SAMPLE_RATE
|
||||||
#define FILTER_SIZE 24
|
#define FILTER_SIZE 24
|
||||||
#define SAMPLE_BUFFER_SIZE (SAMPLES_PER_BIT + FILTER_SIZE)
|
#define SAMPLE_BUFFER_SIZE (SAMPLES_PER_BIT + FILTER_SIZE)
|
||||||
|
|
||||||
@@ -263,7 +263,6 @@ typedef struct rds_oda_t {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern void init_rds_encoder(struct rds_params_t rds_params);
|
extern void init_rds_encoder(struct rds_params_t rds_params);
|
||||||
extern void exit_rds_encoder();
|
|
||||||
extern void get_rds_bits(uint8_t *bits);
|
extern void get_rds_bits(uint8_t *bits);
|
||||||
extern void set_rds_pi(uint16_t pi_code);
|
extern void set_rds_pi(uint16_t pi_code);
|
||||||
extern void set_rds_ecc(uint8_t ecc);
|
extern void set_rds_ecc(uint8_t ecc);
|
||||||
|
|||||||
@@ -206,7 +206,7 @@ int main(int argc, char **argv) {
|
|||||||
|
|
||||||
int pulse_error;
|
int pulse_error;
|
||||||
|
|
||||||
float mpx_buffer[NUM_MPX_FRAMES];
|
static float mpx_buffer[NUM_MPX_FRAMES];
|
||||||
|
|
||||||
while(!stop_rds) {
|
while(!stop_rds) {
|
||||||
for (size_t i = 0; i < NUM_MPX_FRAMES; i++) {
|
for (size_t i = 0; i < NUM_MPX_FRAMES; i++) {
|
||||||
@@ -227,7 +227,6 @@ exit:
|
|||||||
}
|
}
|
||||||
|
|
||||||
pthread_attr_destroy(&attr);
|
pthread_attr_destroy(&attr);
|
||||||
exit_rds_encoder();
|
|
||||||
pa_simple_free(device);
|
pa_simple_free(device);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user