mirror of
https://github.com/radio95-rnt/fm95.git
synced 2026-02-26 19:23:51 +01:00
add pll
This commit is contained in:
@@ -12,4 +12,39 @@ float apply_preemphasis(ResistorCapacitor *filter, float sample) {
|
|||||||
|
|
||||||
float hard_clip(float sample, float threshold) {
|
float hard_clip(float sample, float threshold) {
|
||||||
return fmaxf(-threshold, fminf(threshold, sample));
|
return fmaxf(-threshold, fminf(threshold, sample));
|
||||||
|
}
|
||||||
|
|
||||||
|
void init_pll(PLL *pll, float output_freq, float reference_freq, float loop_filter_bandwidth, int quadrature_mode, int sample_rate) {
|
||||||
|
pll->phase = 0.0f;
|
||||||
|
pll->freq = output_freq;
|
||||||
|
pll->ref_freq = reference_freq;
|
||||||
|
pll->loop_filter_state = 0.0f;
|
||||||
|
|
||||||
|
float damping = 0.707;
|
||||||
|
pll->kp = 2.0f * damping * loop_filter_bandwidth;
|
||||||
|
pll->ki = loop_filter_bandwidth * loop_filter_bandwidth;
|
||||||
|
|
||||||
|
pll->sample_rate = sample_rate;
|
||||||
|
pll->quadrature_mode = quadrature_mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
float apply_pll(PLL *pll, float ref_sample, float input_sample) {
|
||||||
|
float phase_error;
|
||||||
|
if (pll->quadrature_mode) {
|
||||||
|
phase_error = ref_sample * sinf(pll->phase) - input_sample * cosf(pll->phase);
|
||||||
|
} else {
|
||||||
|
phase_error = ref_sample * input_sample * sinf(pll->phase);
|
||||||
|
}
|
||||||
|
|
||||||
|
float filter_output = pll->kp * phase_error + pll->loop_filter_state;
|
||||||
|
pll->loop_filter_state += pll->ki * phase_error * (1/pll->sample_rate);
|
||||||
|
|
||||||
|
pll->freq = pll->freq + filter_output;
|
||||||
|
|
||||||
|
pll->phase += M_2PI * pll->freq * (1.0f/pll->sample_rate);
|
||||||
|
if (pll->phase > M_2PI) {
|
||||||
|
pll->phase -= M_2PI;
|
||||||
|
}
|
||||||
|
|
||||||
|
return cosf(pll->phase);
|
||||||
}
|
}
|
||||||
@@ -14,4 +14,17 @@ typedef struct
|
|||||||
void init_preemphasis(ResistorCapacitor *filter, float tau, float sample_rate);
|
void init_preemphasis(ResistorCapacitor *filter, float tau, float sample_rate);
|
||||||
float apply_preemphasis(ResistorCapacitor *filter, float sample);
|
float apply_preemphasis(ResistorCapacitor *filter, float sample);
|
||||||
|
|
||||||
float hard_clip(float sample, float threshold);
|
float hard_clip(float sample, float threshold);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
float phase;
|
||||||
|
float freq;
|
||||||
|
float ref_freq;
|
||||||
|
float loop_filter_state;
|
||||||
|
float kp;
|
||||||
|
float ki;
|
||||||
|
int sample_rate;
|
||||||
|
int quadrature_mode;
|
||||||
|
} PLL;
|
||||||
|
void init_pll(PLL *pll, float output_freq, float refrence_freq, float loop_filter_bandwidth, int quadrature_mode, int sample_rate);
|
||||||
|
float apply_pll(PLL *pll, float ref_sample, float input_sample);
|
||||||
@@ -417,6 +417,9 @@ int main(int argc, char **argv) {
|
|||||||
ResistorCapacitor preemp_l, preemp_r;
|
ResistorCapacitor preemp_l, preemp_r;
|
||||||
init_preemphasis(&preemp_l, preemphasis_tau, sample_rate);
|
init_preemphasis(&preemp_l, preemphasis_tau, sample_rate);
|
||||||
init_preemphasis(&preemp_r, preemphasis_tau, sample_rate);
|
init_preemphasis(&preemp_r, preemphasis_tau, sample_rate);
|
||||||
|
|
||||||
|
PLL rds2_pll;
|
||||||
|
init_pll(&rds2_pll, 66500, 19000, 100, 1, sample_rate);
|
||||||
// #endregion
|
// #endregion
|
||||||
|
|
||||||
signal(SIGINT, stop);
|
signal(SIGINT, stop);
|
||||||
@@ -495,7 +498,7 @@ int main(int argc, char **argv) {
|
|||||||
float rds_carrier = get_oscillator_sin_multiplier_ni(&osc, 3);
|
float rds_carrier = get_oscillator_sin_multiplier_ni(&osc, 3);
|
||||||
output[i] += (current_rds_in*rds_carrier)*RDS_VOLUME;
|
output[i] += (current_rds_in*rds_carrier)*RDS_VOLUME;
|
||||||
if(!sca_on) {
|
if(!sca_on) {
|
||||||
float rds2_carrier_66 = get_oscillator_cos_sample(&rds2_osc);
|
float rds2_carrier_66 = apply_pll(&rds2_pll, get_oscillator_sin_multiplier_ni(&osc, 1), get_oscillator_cos_sample(&rds2_osc));
|
||||||
output[i] += (current_rds2_in*rds2_carrier_66)*RDS2_VOLUME;
|
output[i] += (current_rds2_in*rds2_carrier_66)*RDS2_VOLUME;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user