Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove the resampler. #95

Merged
merged 1 commit into from
Oct 27, 2017
Merged

Remove the resampler. #95

merged 1 commit into from
Oct 27, 2017

Conversation

argilo
Copy link
Collaborator

@argilo argilo commented Oct 24, 2017

Currently nrsc5 uses an arbitrary resampler to maintain time synchronization. This approach has some significant drawbacks:

  • The resampler is computationally expensive. According to gprof, nrsc5 spends more than two thirds of its time in resamp_q15_execute.
  • Determining the resampling rate is a slow process. Currently acquire_process spends more than three seconds estimating the resampling rate before it starts passing samples through to sync_push.

The resampler can be eliminated simply by modifying acquire_process to skip or re-use samples as necessary to maintain synchronization. It already carries over one symbol's worth of samples from one invocation to the next, so I modified it to carry over anywhere from 0.5 to 1.5 symbols depending on the value of samperr. It chooses the number of samples so as to target a samperr value of FFTCP / 2 on the following invocation.

A couple other small changes were necessary to make this work with RTL-SDRs that have ±100 ppm crystals. I'll note those in the code.

I tested this by changing the sample rate in main.c to 1488375 - 200 and 1488375 + 200 (thus simulating an error of 134 ppm) and using a couple old non-TCXO RTL-SDR's I had lying around. I also processed about 15 recordings I had made of stations at various signal strengths, and found that the reported MER values were comparable before & after the change.

@argilo argilo requested a review from awesie October 24, 2017 22:03
mink = st->samperr - 10;
maxk = st->samperr + 10;
mink = FFTCP / 2 - 25;
maxk = FFTCP / 2 + 25;
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had to widen the search range here to account for ppm error. Each invocation of acquire_process processes 64 * 2160 samples, so 100 ppm error causes a 14-sample offset between invocations.

float phase, slope;
float complex sum;

sum = 0;
for (int r = 0; r < BLKSZ; r++)
sum += buf[ref * BLKSZ + r] * buf[ref * BLKSZ + r];
phase = cargf(sum) * 0.5;
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method of calculating the phase only works when the slope is very small. Error in the sampling frequency increases the slope, so I had to change it to take the slope into account.

sum = 0;
for (int r = 0; r < BLKSZ; r++)
sum += buf[ref * BLKSZ + r] * buf[ref * BLKSZ + r] * cexpf(-I * 2 * slope * r);
phase = cargf(sum) * 0.5;
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The phase calculation now takes place after the slope is calculated, so that the slope can be subtracted out.

I merged calc_phase into adjust_ref because this method needs to use the averaged slope. (I tried with the raw slope, but that reduced the receiver's weak-signal performance.)

@argilo
Copy link
Collaborator Author

argilo commented Oct 24, 2017

The changes to acquire.c are simpler to review with whitespace changes ignored: https://github.com/theori-io/nrsc5/pull/95/files?w=1

@argilo
Copy link
Collaborator Author

argilo commented Oct 24, 2017

@classicjazz @pclov3r You may be interested in testing this out. It should reduce the acquisition time by about 3 seconds.

@mrbubble62 I expect this change will improve ARM performance significantly.

@pclov3r
Copy link

pclov3r commented Oct 25, 2017

@argilo This is a great change!

When the gain is set or if you set it manually around 6 seconds until actual audio playback.

@argilo argilo merged commit 7d7d764 into experimental Oct 27, 2017
@argilo argilo deleted the remove-resamp branch October 27, 2017 23:10
@argilo argilo mentioned this pull request Nov 14, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants