Oversample (#1336)

* WIP Oversample cleanup

* WIP

* WIP

* WIP dynamic interpolation

* WIP cleanup

* Fix math errors

* Add some optional assertions

* Add support for x32 interpolation

* Update proc_replay.cpp

Typo
This commit is contained in:
Kyle Reed
2023-08-02 12:59:26 -07:00
committed by GitHub
parent e2ad0a1b1a
commit 37386c29cb
20 changed files with 272 additions and 169 deletions

View File

@@ -60,25 +60,28 @@ CaptureAppView::CaptureAppView(NavigationView& nav)
};
freqman_set_bandwidth_option(SPEC_MODULATION, option_bandwidth);
option_bandwidth.on_change = [this](size_t, uint32_t base_rate) {
/* base_rate is used for FFT calculation and display LCD, and also in recording writing SD Card rate. */
option_bandwidth.on_change = [this](size_t, uint32_t bandwidth) {
/* Nyquist would imply a sample rate of 2x bandwidth, but because the ADC
* provides 2 values (I,Q), the sample_rate is equal to bandwidth here. */
auto sample_rate = bandwidth;
/* base_rate (bandwidth) is used for FFT calculation and display LCD, and also in recording writing SD Card rate. */
/* ex. sampling_rate values, 4Mhz, when recording 500 kHz (BW) and fs 8 Mhz, when selected 1 Mhz BW ... */
/* ex. recording 500kHz BW to .C16 file, base_rate clock 500kHz x2(I,Q) x 2 bytes (int signed) =2MB/sec rate SD Card */
// For lower bandwidths, (12k5, 16k, 20k), increase the oversample rate to get a higher sample rate.
OversampleRate oversample_rate = base_rate >= 25'000 ? OversampleRate::Rate8x : OversampleRate::Rate16x;
// HackRF suggests a minimum sample rate of 2M.
// Oversampling helps get to higher sample rates when recording lower bandwidths.
uint32_t sampling_rate = toUType(oversample_rate) * base_rate;
// Set up proper anti aliasing BPF bandwidth in MAX2837 before ADC sampling according to the new added BW Options.
auto anti_alias_baseband_bandwidth_filter = filter_bandwidth_for_sampling_rate(sampling_rate);
/* ex. recording 500kHz BW to .C16 file, base_rate clock 500kHz x2(I,Q) x 2 bytes (int signed) =2MB/sec rate SD Card. */
waterfall.stop();
record_view.set_sampling_rate(sampling_rate, oversample_rate); // NB: Actually updates the baseband.
receiver_model.set_sampling_rate(sampling_rate);
receiver_model.set_baseband_bandwidth(anti_alias_baseband_bandwidth_filter);
// record_view determines the correct oversampling to apply and returns the actual sample rate.
// NB: record_view is what actually updates proc_capture baseband settings.
auto actual_sample_rate = record_view.set_sampling_rate(sample_rate);
// Update the radio model with the actual sampling rate.
receiver_model.set_sampling_rate(actual_sample_rate);
// Get suitable anti-aliasing BPF bandwidth for MAX2837 given the actual sample rate.
auto anti_alias_filter_bandwidth = filter_bandwidth_for_sampling_rate(actual_sample_rate);
receiver_model.set_baseband_bandwidth(anti_alias_filter_bandwidth);
waterfall.start();
};

View File

@@ -124,7 +124,7 @@ void ReplayAppView::start() {
if (reader) {
button_play.set_bitmap(&bitmap_stop);
baseband::set_sample_rate(sample_rate * 8);
baseband::set_sample_rate(sample_rate, OversampleRate::x8);
replay_thread = std::make_unique<ReplayThread>(
std::move(reader),
@@ -136,7 +136,7 @@ void ReplayAppView::start() {
});
}
transmitter_model.set_sampling_rate(sample_rate * 8);
transmitter_model.set_sampling_rate(sample_rate * toUType(OversampleRate::x8));
transmitter_model.set_baseband_bandwidth(baseband_bandwidth);
transmitter_model.enable();

View File

@@ -24,18 +24,18 @@
#include "ui_playlist.hpp"
#include "baseband_api.hpp"
#include "convert.hpp"
#include "file_reader.hpp"
#include "io_file.hpp"
#include "io_convert.hpp"
#include "oversample.hpp"
#include "portapack.hpp"
#include "portapack_persistent_memory.hpp"
#include "string_format.hpp"
#include "ui_fileman.hpp"
#include "utility.hpp"
#include "baseband_api.hpp"
#include "portapack.hpp"
#include "portapack_persistent_memory.hpp"
#include <unistd.h>
#include <fstream>
@@ -266,17 +266,16 @@ void PlaylistView::send_current_track() {
return;
}
// ReplayThread starts immediately on construction so
// these need to be set before creating the ReplayThread.
// Update the sample rate in proc_replay baseband.
baseband::set_sample_rate(current()->metadata.sample_rate,
get_oversample_rate(current()->metadata.sample_rate));
// ReplayThread starts immediately on construction; must be set before creating.
transmitter_model.set_target_frequency(current()->metadata.center_frequency);
transmitter_model.set_sampling_rate(current()->metadata.sample_rate * 8);
transmitter_model.set_sampling_rate(get_actual_sample_rate(current()->metadata.sample_rate));
transmitter_model.set_baseband_bandwidth(baseband_bandwidth);
transmitter_model.enable();
// Set baseband sample rate too for waterfall to be correct.
// TODO: Why doesn't the transmitter_model just handle this?
baseband::set_sample_rate(transmitter_model.sampling_rate());
// Reset the transmit progress bar.
progressbar_transmit.set_value(0);