mirror of
https://github.com/radio95-rnt/fm95.git
synced 2026-02-26 19:23:51 +01:00
generate the 66.5 inside the pll via the pilot
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": 1742717063787,
|
"time": 1742742025054,
|
||||||
"version": "0.0.3"
|
"version": "0.0.3"
|
||||||
}
|
}
|
||||||
@@ -14,42 +14,46 @@ 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) {
|
void init_pll(PLL *pll, int interpolation, int decimation, float freq, float loop_filter_bandwidth, int quadrature_mode, int sample_rate) {
|
||||||
pll->phase = 0.0f;
|
pll->phase = 0.0f;
|
||||||
pll->freq = output_freq;
|
pll->freq = freq;
|
||||||
pll->ref_freq = reference_freq;
|
|
||||||
pll->loop_filter_state = 0.0f;
|
pll->loop_filter_state = 0.0f;
|
||||||
pll->kp = 2.0f * M_PI * loop_filter_bandwidth;
|
pll->kp = M_2PI * loop_filter_bandwidth;
|
||||||
pll->ki = 0.25f * pll->kp * pll->kp;
|
pll->ki = 0.25f * pll->kp * pll->kp;
|
||||||
pll->sample_rate = sample_rate;
|
pll->sample_rate = sample_rate;
|
||||||
pll->quadrature_mode = quadrature_mode;
|
pll->quadrature_mode = quadrature_mode;
|
||||||
|
pll->last_output = 0.0f;
|
||||||
|
pll->interpolation = interpolation;
|
||||||
|
pll->decimation = decimation;
|
||||||
}
|
}
|
||||||
|
|
||||||
float apply_pll(PLL *pll, float ref_sample, float input_sample) {
|
float apply_pll(PLL *pll, float ref_sample) {
|
||||||
float phase_error;
|
float phase_error;
|
||||||
|
|
||||||
float output = sinf(pll->phase);
|
float vco_phase = pll->phase;
|
||||||
|
if(pll->quadrature_mode) vco_phase += M_PI/2.0f;
|
||||||
|
|
||||||
if (pll->quadrature_mode) {
|
float vco_output = sinf(pll->phase);
|
||||||
output = sinf(pll->phase + (M_PI / 2.0f));
|
if (pll->quadrature_mode) vco_output = sinf(pll->phase + (M_PI / 2.0f)); // 90 degrees
|
||||||
}
|
|
||||||
|
|
||||||
phase_error = ref_sample * input_sample;
|
phase_error = ref_sample * pll->last_output;
|
||||||
|
|
||||||
pll->loop_filter_state += pll->ki * phase_error / pll->sample_rate;
|
pll->loop_filter_state += pll->ki * phase_error / pll->sample_rate;
|
||||||
float loop_output = pll->loop_filter_state + pll->kp * phase_error;
|
float loop_output = pll->loop_filter_state + pll->kp * phase_error;
|
||||||
|
|
||||||
float freq_adjustment = loop_output / (2.0f * M_PI);
|
float freq_adjustment = loop_output / M_2PI;
|
||||||
float instantaneous_freq = pll->freq + freq_adjustment;
|
float instantaneous_freq = pll->freq + freq_adjustment;
|
||||||
|
|
||||||
pll->phase += 2.0f * M_PI * instantaneous_freq / pll->sample_rate;
|
pll->phase += M_2PI * instantaneous_freq / pll->sample_rate;
|
||||||
|
|
||||||
while (pll->phase >= 2.0f * M_PI) {
|
while (pll->phase >= M_2PI) {
|
||||||
pll->phase -= 2.0f * M_PI;
|
pll->phase -= M_2PI;
|
||||||
}
|
}
|
||||||
while (pll->phase < 0.0f) {
|
while (pll->phase < 0.0f) {
|
||||||
pll->phase += 2.0f * M_PI;
|
pll->phase += M_2PI;
|
||||||
}
|
}
|
||||||
|
|
||||||
return output;
|
pll->last_output = sinf((vco_phase*pll->interpolation)/pll->decimation);
|
||||||
|
|
||||||
|
return pll->last_output;
|
||||||
}
|
}
|
||||||
@@ -19,12 +19,14 @@ float hard_clip(float sample, float threshold);
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
float phase;
|
float phase;
|
||||||
float freq;
|
float freq;
|
||||||
float ref_freq;
|
|
||||||
float loop_filter_state;
|
float loop_filter_state;
|
||||||
float kp;
|
float kp;
|
||||||
float ki;
|
float ki;
|
||||||
|
float last_output;
|
||||||
|
int interpolation;
|
||||||
|
int decimation;
|
||||||
int sample_rate;
|
int sample_rate;
|
||||||
int quadrature_mode;
|
int quadrature_mode;
|
||||||
} PLL;
|
} PLL;
|
||||||
void init_pll(PLL *pll, float output_freq, float refrence_freq, float loop_filter_bandwidth, int quadrature_mode, int sample_rate);
|
void init_pll(PLL *pll, int interpolation, int decimation, float freq, float loop_filter_bandwidth, int quadrature_mode, int sample_rate);
|
||||||
float apply_pll(PLL *pll, float ref_sample, float input_sample);
|
float apply_pll(PLL *pll, float ref_sample);
|
||||||
21
src/fm95.c
21
src/fm95.c
@@ -35,13 +35,13 @@
|
|||||||
#define DEFAULT_MASTER_VOLUME 1.0f // Volume of everything combined, for calibration
|
#define DEFAULT_MASTER_VOLUME 1.0f // Volume of everything combined, for calibration
|
||||||
#define DEFAULT_AUDIO_VOLUME 1.0f // Audio volume, before clipper
|
#define DEFAULT_AUDIO_VOLUME 1.0f // Audio volume, before clipper
|
||||||
|
|
||||||
#define MONO_VOLUME 0.45f // L+R Signal
|
#define MONO_VOLUME 0.45f
|
||||||
#define PILOT_VOLUME 0.09f // 19 KHz Pilot
|
#define PILOT_VOLUME 0.09f
|
||||||
#define STEREO_VOLUME 0.45f // L-R signal, should be same as MONO
|
#define STEREO_VOLUME 0.45f
|
||||||
#define RDS_VOLUME 0.075f // RDS Volume, after dsb-sc
|
#define RDS_VOLUME 0.075f
|
||||||
#define RDS2_VOLUME 0.075f // RDS2 Volume
|
#define RDS2_VOLUME 0.0675f
|
||||||
#define SCA_VOLUME 0.1f // FM SCA signal, 10%
|
#define SCA_VOLUME 0.1f
|
||||||
#define MPX_VOLUME 1.0f // Passtrough
|
#define MPX_VOLUME 1.0f
|
||||||
#define MPX_CLIPPER_THRESHOLD 1.0f
|
#define MPX_CLIPPER_THRESHOLD 1.0f
|
||||||
|
|
||||||
static volatile sig_atomic_t to_run = 1;
|
static volatile sig_atomic_t to_run = 1;
|
||||||
@@ -408,9 +408,6 @@ int main(int argc, char **argv) {
|
|||||||
Oscillator osc;
|
Oscillator osc;
|
||||||
init_oscillator(&osc, polar_stereo ? 31250.0 : 19000, sample_rate);
|
init_oscillator(&osc, polar_stereo ? 31250.0 : 19000, sample_rate);
|
||||||
|
|
||||||
Oscillator rds2_osc;
|
|
||||||
init_oscillator(&rds2_osc, 66500, sample_rate);
|
|
||||||
|
|
||||||
FMModulator sca_mod;
|
FMModulator sca_mod;
|
||||||
init_fm_modulator(&sca_mod, sca_frequency, sca_deviation, sample_rate);
|
init_fm_modulator(&sca_mod, sca_frequency, sca_deviation, sample_rate);
|
||||||
|
|
||||||
@@ -419,7 +416,7 @@ int main(int argc, char **argv) {
|
|||||||
init_preemphasis(&preemp_r, preemphasis_tau, sample_rate);
|
init_preemphasis(&preemp_r, preemphasis_tau, sample_rate);
|
||||||
|
|
||||||
PLL rds2_pll;
|
PLL rds2_pll;
|
||||||
init_pll(&rds2_pll, 66500, 19000, 100, 1, sample_rate);
|
init_pll(&rds2_pll, 7, 2, 19000, 100, 1, sample_rate);
|
||||||
// #endregion
|
// #endregion
|
||||||
|
|
||||||
signal(SIGINT, stop);
|
signal(SIGINT, stop);
|
||||||
@@ -498,7 +495,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 = apply_pll(&rds2_pll, get_oscillator_sin_multiplier_ni(&osc, 1), get_oscillator_cos_sample(&rds2_osc));
|
float rds2_carrier_66 = apply_pll(&rds2_pll, get_oscillator_sin_multiplier_ni(&osc, 1));
|
||||||
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