0
1
mirror of https://github.com/radio95-rnt/fm95.git synced 2026-02-26 19:23:51 +01:00

little optimizations

This commit is contained in:
2025-08-06 19:14:49 +02:00
parent 6b46716860
commit 3ff2ea3a3d
3 changed files with 36 additions and 32 deletions

View File

@@ -1,5 +1,5 @@
{ {
"port": 13452, "port": 13452,
"time": 1754390686374, "time": 1754499532735,
"version": "0.0.3" "version": "0.0.3"
} }

View File

@@ -14,11 +14,11 @@
#include "../dsp/oscillator.h" #include "../dsp/oscillator.h"
#define DEFAULT_FREQ 1000.0f #define DEFAULT_FREQ 1000.0f
#define DEFAULT_SAMPLE_RATE 4000 #define DEFAULT_SAMPLE_RATE 8000
#define OUTPUT_DEVICE "FM_MPX" #define OUTPUT_DEVICE "FM_MPX"
#define BUFFER_SIZE 256 #define BUFFER_SIZE 512
#include "../io/audio.h" #include "../io/audio.h"

View File

@@ -14,7 +14,7 @@
#include "../filter/bs412.h" #include "../filter/bs412.h"
#include "../filter/gain_control.h" #include "../filter/gain_control.h"
#define BUFFER_SIZE 2048 // This defines how many samples to process at a time, because the loop here is this: get signal -> process signal -> output signal, and when we get signal we actually get BUFFER_SIZE of them #define BUFFER_SIZE 3072 // This defines how many samples to process at a time, because the loop here is this: get signal -> process signal -> output signal, and when we get signal we actually get BUFFER_SIZE of them
#include "../io/audio.h" #include "../io/audio.h"
@@ -29,6 +29,11 @@ static volatile sig_atomic_t to_reload = 0;
inline float hard_clip(float sample, float threshold) { return fmaxf(-threshold, fminf(threshold, sample)); } inline float hard_clip(float sample, float threshold) { return fmaxf(-threshold, fminf(threshold, sample)); }
typedef struct
{
bool rds_on;
bool mpx_on;
} FM95_Options;
typedef struct typedef struct
{ {
float mono; float mono;
@@ -39,6 +44,8 @@ typedef struct
} FM95_Volumes; } FM95_Volumes;
typedef struct typedef struct
{ {
FM95_Options options;
FM95_Volumes volumes; FM95_Volumes volumes;
bool stereo; bool stereo;
@@ -126,17 +133,17 @@ void show_help(char *name) {
); );
} }
void cleanup_runtime(FM95_Runtime* runtime, FM95_Config config) { void cleanup_runtime(FM95_Runtime* runtime, const FM95_Config config) {
if(config.lpf_cutoff != 0) { if(config.lpf_cutoff != 0) {
iirfilt_rrrf_destroy(runtime->lpf_l); iirfilt_rrrf_destroy(runtime->lpf_l);
iirfilt_rrrf_destroy(runtime->lpf_r); iirfilt_rrrf_destroy(runtime->lpf_r);
} }
} }
void cleanup_audio_runtime(FM95_Runtime *rt, bool mpx_on, bool rds_on) { void cleanup_audio_runtime(FM95_Runtime *rt, const FM95_Options options) {
free_PulseDevice(&rt->input_device); free_PulseDevice(&rt->input_device);
if (mpx_on) free_PulseDevice(&rt->mpx_device); if (options.mpx_on) free_PulseDevice(&rt->mpx_device);
if (rds_on) { if (options.rds_on) {
free_PulseDevice(&rt->rds_device); free_PulseDevice(&rt->rds_device);
free(rt->rds_in); free(rt->rds_in);
} }
@@ -144,23 +151,19 @@ void cleanup_audio_runtime(FM95_Runtime *rt, bool mpx_on, bool rds_on) {
} }
int run_fm95(const FM95_Config config, FM95_Runtime* runtime) { int run_fm95(const FM95_Config config, FM95_Runtime* runtime) {
bool mpx_on = (runtime->mpx_device.initialized == 1);
bool rds_on = (runtime->rds_device.initialized == 1);
float output[BUFFER_SIZE]; float output[BUFFER_SIZE];
if(config.calibration != 0) { int pulse_error;
int pulse_error;
if(config.calibration != 0) {
while(to_run) { while(to_run) {
for (int i = 0; i < BUFFER_SIZE; i++) { for (int i = 0; i < BUFFER_SIZE; i++) {
float sample = get_oscillator_sin_sample(&runtime->osc); float sample = get_oscillator_sin_sample(&runtime->osc);
if(config.calibration == 2) sample = (sample > 0.0f) ? 1.0f : -1.0f; // Sine wave to square wave filter if(config.calibration == 2) sample = (sample > 0.0f) ? 1.0f : -1.0f; // Sine wave to square wave filter, 50% duty cycle
output[i] = sample*config.master_volume; output[i] = sample*config.master_volume;
} }
if((pulse_error = write_PulseOutputDevice(&runtime->output_device, output, sizeof(output)))) { // get output from the function and assign it into pulse_error, this comment to avoid confusion if((pulse_error = write_PulseOutputDevice(&runtime->output_device, output, sizeof(output)))) { // get output from the function and assign it into pulse_error, this comment to avoid confusion
if(pulse_error == -1) fprintf(stderr, "Main PulseOutputDevice reported as uninitialized."); fprintf(stderr, "Error writing to output device: %s\n", pa_strerror(pulse_error));
else fprintf(stderr, "Error writing to output device: %s\n", pa_strerror(pulse_error));
to_run = 0; to_run = 0;
break; break;
} }
@@ -168,12 +171,13 @@ int run_fm95(const FM95_Config config, FM95_Runtime* runtime) {
return 0; return 0;
} }
int pulse_error;
float audio_stereo_input[BUFFER_SIZE*2]; // Stereo float audio_stereo_input[BUFFER_SIZE*2]; // Stereo
float mpx_in[BUFFER_SIZE] = {0}; float mpx_in[BUFFER_SIZE] = {0};
bool mpx_on = config.options.mpx_on;
bool rds_on = config.options.rds_on;
while (to_run) { while (to_run) {
if((pulse_error = read_PulseInputDevice(&runtime->input_device, audio_stereo_input, sizeof(audio_stereo_input)))) { // get output from the function and assign it into pulse_error, this comment to avoid confusion if((pulse_error = read_PulseInputDevice(&runtime->input_device, audio_stereo_input, sizeof(audio_stereo_input)))) { // get output from the function and assign it into pulse_error, this comment to avoid confusion
fprintf(stderr, "Error reading from input device: %s\n", pa_strerror(pulse_error)); fprintf(stderr, "Error reading from input device: %s\n", pa_strerror(pulse_error));
@@ -376,7 +380,7 @@ int parse_config(FM95_Config* config, FM95_DeviceNames* dv) {
return ini_parse(config->ini_config_path, &config_handler, &ctx); return ini_parse(config->ini_config_path, &config_handler, &ctx);
} }
int setup_audio(FM95_Runtime* runtime, const FM95_DeviceNames dv_names, const FM95_Config config, bool mpx_on, bool rds_on) { int setup_audio(FM95_Runtime* runtime, const FM95_DeviceNames dv_names, const FM95_Config config) {
pa_buffer_attr input_buffer_atr = { pa_buffer_attr input_buffer_atr = {
.maxlength = buffer_maxlength, .maxlength = buffer_maxlength,
.fragsize = buffer_tlength_fragsize .fragsize = buffer_tlength_fragsize
@@ -396,7 +400,7 @@ int setup_audio(FM95_Runtime* runtime, const FM95_DeviceNames dv_names, const FM
return 1; return 1;
} }
if(mpx_on) { if(config.options.mpx_on) {
printf("Connecting to MPX device... (%s)\n", dv_names.mpx); printf("Connecting to MPX device... (%s)\n", dv_names.mpx);
opentime_pulse_error = init_PulseInputDevice(&runtime->mpx_device, config.sample_rate, 1, "fm95", "MPX Input", dv_names.mpx, &input_buffer_atr, PA_SAMPLE_FLOAT32NE); opentime_pulse_error = init_PulseInputDevice(&runtime->mpx_device, config.sample_rate, 1, "fm95", "MPX Input", dv_names.mpx, &input_buffer_atr, PA_SAMPLE_FLOAT32NE);
@@ -406,14 +410,14 @@ int setup_audio(FM95_Runtime* runtime, const FM95_DeviceNames dv_names, const FM
return 1; return 1;
} }
} }
if(rds_on) { if(config.options.rds_on) {
printf("Connecting to RDS95 device... (%s)\n", dv_names.rds); printf("Connecting to RDS95 device... (%s)\n", dv_names.rds);
opentime_pulse_error = init_PulseInputDevice(&runtime->rds_device, config.sample_rate, config.rds_streams, "fm95", "RDS95 Input", dv_names.rds, &input_buffer_atr, PA_SAMPLE_FLOAT32NE); opentime_pulse_error = init_PulseInputDevice(&runtime->rds_device, config.sample_rate, config.rds_streams, "fm95", "RDS95 Input", dv_names.rds, &input_buffer_atr, PA_SAMPLE_FLOAT32NE);
if (opentime_pulse_error) { if (opentime_pulse_error) {
fprintf(stderr, "Error: cannot open RDS device: %s\n", pa_strerror(opentime_pulse_error)); fprintf(stderr, "Error: cannot open RDS device: %s\n", pa_strerror(opentime_pulse_error));
free_PulseDevice(&runtime->input_device); free_PulseDevice(&runtime->input_device);
if(mpx_on) free_PulseDevice(&runtime->mpx_device); if(config.options.mpx_on) free_PulseDevice(&runtime->mpx_device);
return 1; return 1;
} }
runtime->rds_in = malloc(sizeof(float) * BUFFER_SIZE * config.rds_streams); runtime->rds_in = malloc(sizeof(float) * BUFFER_SIZE * config.rds_streams);
@@ -425,14 +429,14 @@ int setup_audio(FM95_Runtime* runtime, const FM95_DeviceNames dv_names, const FM
if (opentime_pulse_error) { if (opentime_pulse_error) {
fprintf(stderr, "Error: cannot open output device: %s\n", pa_strerror(opentime_pulse_error)); fprintf(stderr, "Error: cannot open output device: %s\n", pa_strerror(opentime_pulse_error));
free_PulseDevice(&runtime->input_device); free_PulseDevice(&runtime->input_device);
if(mpx_on) free_PulseDevice(&runtime->mpx_device); if(config.options.mpx_on) free_PulseDevice(&runtime->mpx_device);
if(rds_on) free_PulseDevice(&runtime->rds_device); if(config.options.rds_on) free_PulseDevice(&runtime->rds_device);
return 1; return 1;
} }
return 0; return 0;
} }
void init_runtime(FM95_Runtime* runtime, FM95_Config config, bool rds_on) { void init_runtime(FM95_Runtime* runtime, const FM95_Config config) {
if(config.calibration != 0) { if(config.calibration != 0) {
init_oscillator(&runtime->osc, (config.calibration == 2) ? 60 : 400, config.sample_rate); init_oscillator(&runtime->osc, (config.calibration == 2) ? 60 : 400, config.sample_rate);
return; return;
@@ -465,7 +469,7 @@ void init_runtime(FM95_Runtime* runtime, FM95_Config config, bool rds_on) {
runtime->agc.currentGain = last_gain; runtime->agc.currentGain = last_gain;
} }
if(rds_on) memset(runtime->rds_in, 0, sizeof(float) * BUFFER_SIZE * config.rds_streams); if(config.options.rds_on) memset(runtime->rds_in, 0, sizeof(float) * BUFFER_SIZE * config.rds_streams);
} }
int main(int argc, char **argv) { int main(int argc, char **argv) {
@@ -543,17 +547,17 @@ int main(int argc, char **argv) {
FM95_Runtime runtime; FM95_Runtime runtime;
memset(&runtime, 0, sizeof(runtime)); memset(&runtime, 0, sizeof(runtime));
bool mpx_on = (strlen(dv_names.mpx) != 0); config.options.mpx_on = (strlen(dv_names.mpx) != 0);
bool rds_on = (strlen(dv_names.rds) != 0 && config.rds_streams != 0); config.options.rds_on = (strlen(dv_names.rds) != 0 && config.rds_streams != 0);
err = setup_audio(&runtime, dv_names, config, mpx_on, rds_on); err = setup_audio(&runtime, dv_names, config);
if(err != 0) return err; if(err != 0) return err;
signal(SIGINT, stop); signal(SIGINT, stop);
signal(SIGTERM, stop); signal(SIGTERM, stop);
signal(SIGHUP, reload); signal(SIGHUP, reload);
init_runtime(&runtime, config, rds_on); init_runtime(&runtime, config);
int ret; int ret;
while(true) { while(true) {
@@ -572,13 +576,13 @@ int main(int argc, char **argv) {
if(config.rds_streams != old_streams) printf("Warning! change of rds_streams requires a restart, not a reload.\n"); if(config.rds_streams != old_streams) printf("Warning! change of rds_streams requires a restart, not a reload.\n");
config.rds_streams = old_streams; config.rds_streams = old_streams;
cleanup_runtime(&runtime, config); cleanup_runtime(&runtime, config);
init_runtime(&runtime, config, rds_on); init_runtime(&runtime, config);
to_run = 1; to_run = 1;
continue; continue;
} }
printf("Cleaning up...\n"); printf("Cleaning up...\n");
cleanup_runtime(&runtime, config); cleanup_runtime(&runtime, config);
cleanup_audio_runtime(&runtime, mpx_on, rds_on); cleanup_audio_runtime(&runtime, config.options);
break; break;
} }
return ret; return ret;