diff --git a/dsp/delay.c b/dsp/delay.c index ee7e54e..33863da 100644 --- a/dsp/delay.c +++ b/dsp/delay.c @@ -1,21 +1,25 @@ +#include +#include #include "delay.h" -void init_delay_line(delay_line_t *delay_line, uint32_t sample_rate) { - delay_line->buffer = malloc(sample_rate * sizeof(float)); - memset(delay_line->buffer, 0, sample_rate * sizeof(float)); +void init_delay_line(delay_line_t *dl, uint32_t delay_samples) { + dl->delay = delay_samples; + dl->idx = 0; + dl->buffer = calloc(delay_samples, sizeof(float)); } -void set_delay_line(delay_line_t *delay_line, uint32_t new_delay) { - delay_line->delay = new_delay; +float delay_line(delay_line_t *dl, float in) { + float out = dl->buffer[dl->idx]; // read delayed sample + + dl->buffer[dl->idx] = in; // write new input + + dl->idx++; + if (dl->idx >= dl->delay) dl->idx = 0; + + return out; } -float delay_line(delay_line_t *delay_line, float in) { - delay_line->buffer[delay_line->idx++] = in; - if (delay_line->idx >= delay_line->delay) delay_line->idx = 0; - return delay_line->buffer[delay_line->idx]; -} - -void exit_delay_line(delay_line_t *delay_line) { - if(delay_line->buffer != NULL) free(delay_line->buffer); - delay_line->buffer = NULL; +void exit_delay_line(delay_line_t *dl) { + if(dl->buffer != NULL) free(dl->buffer); + dl->buffer = NULL; } \ No newline at end of file diff --git a/dsp/delay.h b/dsp/delay.h index 940b94c..90f1763 100644 --- a/dsp/delay.h +++ b/dsp/delay.h @@ -8,7 +8,6 @@ typedef struct delay_line_t { uint32_t idx; } delay_line_t; -void init_delay_line(delay_line_t *delay_line, uint32_t sample_rate); -void set_delay_line(delay_line_t *delay_line, uint32_t new_delay); -float delay_line(delay_line_t *delay_line, float in); -void exit_delay_line(delay_line_t *delay_line); +void init_delay_line(delay_line_t *dl, uint32_t delay_samples); +float delay_line(delay_line_t *dl, float in); +void exit_delay_line(delay_line_t *dl); diff --git a/modulation/stereo_encoder.c b/modulation/stereo_encoder.c index f28b1bc..e8bc3c8 100644 --- a/modulation/stereo_encoder.c +++ b/modulation/stereo_encoder.c @@ -7,10 +7,8 @@ void init_stereo_encoder(StereoEncoder* st, uint8_t multiplier, Oscillator* osc, st->pilot_volume = pilot_volume; st->audio_volume = audio_volume; #ifdef STEREO_SSB - init_delay_line(&st->delay_pilot, osc->sample_rate); - init_delay_line(&st->delay, osc->sample_rate); - set_delay_line(&st->delay_pilot, STEREO_SSB*2+1); - set_delay_line(&st->delay, STEREO_SSB*2+1); + init_delay_line(&st->delay_pilot, STEREO_SSB*2+1); + init_delay_line(&st->delay, STEREO_SSB*2+1); #endif } diff --git a/src/fm95.c b/src/fm95.c index e975bf9..88745fe 100644 --- a/src/fm95.c +++ b/src/fm95.c @@ -83,13 +83,12 @@ typedef struct float* rds_in; Oscillator osc; iirfilt_rrrf lpf_l, lpf_r; - #ifdef STEREO_SSB firhilbf stereo_hilbert; - #endif ResistorCapacitor preemp_l, preemp_r; BS412Compressor bs412; StereoEncoder stencode; AGC agc; + delay_line_t rds_delays[4]; } FM95_Runtime; typedef struct { @@ -238,11 +237,7 @@ int run_fm95(const FM95_Config config, FM95_Runtime* runtime) { mod_r = apply_preemphasis(&runtime->preemp_r, mod_r); } -#ifdef STEREO_SSB mpx = stereo_encode(&runtime->stencode, config.stereo, mod_l, mod_r, &runtime->stereo_hilbert); -#else - mpx = stereo_encode(&runtime->stencode, config.stereo, mod_l, mod_r); -#endif if(rds_on) { float rds_level = config.volumes.rds; @@ -250,7 +245,11 @@ int run_fm95(const FM95_Config config, FM95_Runtime* runtime) { uint8_t osc_stream = 12 + stream; if(osc_stream >= 13) osc_stream++; +#ifdef STEREO_SSB + mpx += (runtime->rds_in[config.rds_streams * i + stream] * delay_line(&runtime->rds_delays[stream], get_oscillator_cos_multiplier_ni(&runtime->osc, osc_stream))) * rds_level; +#else mpx += (runtime->rds_in[config.rds_streams * i + stream] * get_oscillator_cos_multiplier_ni(&runtime->osc, osc_stream)) * rds_level; +#endif rds_level *= config.volumes.rds_step; // Prepare level for the next stream } @@ -494,6 +493,8 @@ void init_runtime(FM95_Runtime* runtime, const FM95_Config config) { #ifdef STEREO_SSB runtime->stereo_hilbert = firhilbf_create(STEREO_SSB, 80); + + for(int i = 0; i < config.rds_streams; i++) init_delay_line(&runtime->rds_delays[i], STEREO_SSB*2+1); #endif if(config.preemphasis != 0) {