Skip to content

Commit

Permalink
Version 20220313-1: roll back FM AFC code with unwanted pop noise
Browse files Browse the repository at this point in the history
  • Loading branch information
jj1bdx committed Mar 13, 2022
1 parent 9724965 commit b0de87e
Show file tree
Hide file tree
Showing 3 changed files with 6 additions and 37 deletions.
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@

## Changes (including requirement changes)

* 20220313-1: Removed experimental FM AFC code due to periodical noise generation. `-A` option is removed as well.
* 20220313-0: Moved FineTuner object into independent files. Added experimental 10Hz-step IF AFC for FM broadcast (use `-A` option to enable). Simplified INSTALL-latest-libvolk.md.
* 20220221-0: Shortened polling periods for Airspy R2/Mini and Airspy HF+ from 1 second to 100 milliseconds. Also reduced AGC output levels for CW and WSPR to prevent output overdrive.
* 20220206-0: Rolled back the workaround of exit(0) in 20220205-1, because this is no longer necessary when a proper fix is done on Airspy HF+ driver.
Expand Down
3 changes: 1 addition & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

# airspy-fmradion

* Version 20220313-0
* Version 20220313-1
* For MacOS (both Intel and Apple Silicon) and Linux

## Contributing
Expand Down Expand Up @@ -200,7 +200,6 @@ Compile and install
- `-l dB` Enable IF squelch, set the level to minus given value of dB
- `-E stages` Enable multipath filter for FM (For stable reception only: turn off if reception becomes unstable)
- `-r ppm` Set IF offset in ppm (range: +-1000000ppm) (Note: this option affects output pitch and timing: *use for the output timing compensation only!*
- `-A` (For FM only) Experimental 10Hz-step IF AFC

## Major changes

Expand Down
39 changes: 4 additions & 35 deletions main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
// define this for enabling coefficient monitor functions
// #undef COEFF_MONITOR

#define AIRSPY_FMRADION_VERSION "20220313-0"
#define AIRSPY_FMRADION_VERSION "20220313-1"

// Flag to set graceful termination
// in process_signals()
Expand Down Expand Up @@ -156,7 +156,6 @@ void usage() {
" -r ppm Set IF offset in ppm (range: +-1000000ppm)\n"
" (This option affects output pitch and timing:\n"
" use for the output timing compensation only!)\n"
" -A (FM only) experimental 10Hz-step IF AFC\n"
"\n"
"Configuration options for RTL-SDR devices\n"
" freq=<int> Frequency of radio station in Hz (default 100000000)\n"
Expand Down Expand Up @@ -346,7 +345,6 @@ int main(int argc, char **argv) {
int multipathfilter_stages = 0;
bool ifrate_offset_enable = false;
double ifrate_offset_ppm = 0;
bool enable_fm_afc = false;
std::string config_str;
std::string devtype_str;
DevType devtype;
Expand Down Expand Up @@ -402,11 +400,10 @@ int main(int argc, char **argv) {
{"squelch", required_argument, nullptr, 'l'},
{"multipathfilter", required_argument, nullptr, 'E'},
{"ifrateppm", optional_argument, nullptr, 'r'},
{"afc", optional_argument, nullptr, 'A'},
{nullptr, no_argument, nullptr, 0}};

int c, longindex;
while ((c = getopt_long(argc, argv, "m:t:c:d:MR:F:W:G:f:l:P:T:b:qXUE:r:A",
while ((c = getopt_long(argc, argv, "m:t:c:d:MR:F:W:G:f:l:P:T:b:qXUE:r:",
longopts, &longindex)) >= 0) {
switch (c) {
case 'm':
Expand Down Expand Up @@ -490,9 +487,6 @@ int main(int argc, char **argv) {
badarg("-r");
}
break;
case 'A':
enable_fm_afc = true;
break;
default:
usage();
fprintf(stderr, "ERROR: Invalid command line options\n");
Expand Down Expand Up @@ -899,16 +893,6 @@ int main(int argc, char **argv) {
: ppm_average_stages,
0.0f);

// Initialize moving average object for FM AFC.
const unsigned int fm_afc_average_stages = 1000;
MovingAverage<float> fm_afc_average(
enable_predownsampling ? fm_afc_average_stages * predownsample_ratio
: fm_afc_average_stages,
0.0f);
const unsigned int fm_afc_hz_step = 10;
FineTuner fm_afc_finetuner((unsigned int)fm_target_rate / fm_afc_hz_step);
float fm_afc_offset_sum = 0.0;

unsigned int nchannel = stereo ? 2 : 1;

// If buffering enabled, start background output thread.
Expand Down Expand Up @@ -960,7 +944,6 @@ int main(int argc, char **argv) {
// Pull next block from source buffer.
IQSampleVector iqsamples = source_buffer.pull();

IQSampleVector if_afc_samples;
IQSampleVector if_shifted_samples;
IQSampleVector if_downsampled_samples;
IQSampleVector if_samples;
Expand All @@ -976,27 +959,13 @@ int main(int argc, char **argv) {
// so long as the stability of the receiver device is
// within the range of +- 1ppm (~100Hz or less).

// Experimental FM broadcast AFC code
if (modtype == ModType::FM && enable_fm_afc) {
// get the frequency offset
fm_afc_average.feed(fm.get_tuning_offset());
if ((block % fm_afc_average_stages) == 0) {
fm_afc_offset_sum += 0.7 * fm_afc_average.average();
fm_afc_finetuner.set_freq_shift(
-((unsigned int)std::round(fm_afc_offset_sum / fm_afc_hz_step)));
}
fm_afc_finetuner.process(iqsamples, if_afc_samples);
} else {
if_afc_samples = std::move(iqsamples);
}

if (enable_fs_fourth_downconverter) {
// Fs/4 downconvering is required
// to avoid frequency zero offset
// because Airspy HF+ and RTL-SDR are Zero IF receivers
fourth_downconverter.process(if_afc_samples, if_shifted_samples);
fourth_downconverter.process(iqsamples, if_shifted_samples);
} else {
if_shifted_samples = std::move(if_afc_samples);
if_shifted_samples = std::move(iqsamples);
}

// Downsample if pre-downsampling is enable_downsampling
Expand Down

0 comments on commit b0de87e

Please sign in to comment.