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

@@ -30,6 +30,7 @@ using namespace portapack;
#include "baseband_api.hpp"
#include "metadata_file.hpp"
#include "oversample.hpp"
#include "rtc_time.hpp"
#include "string_format.hpp"
#include "utility.hpp"
@@ -101,27 +102,28 @@ void RecordView::focus() {
button_record.focus();
}
void RecordView::set_sampling_rate(size_t new_sampling_rate, OversampleRate new_oversample_rate) {
/* We are changing "REC" icon background to yellow in BW rec Options >600kHz
where we are NOT recording full IQ .C16 files (recorded files are decimated ones).
Those decimated recorded files, has not the full IQ samples.
are ok as recorded spectrum indication, but they should not be used by Replay app.
uint32_t RecordView::set_sampling_rate(uint32_t new_sampling_rate) {
// Determine the oversampling needed (if any) and the actual sampling rate.
auto oversample_rate = get_oversample_rate(new_sampling_rate);
auto actual_sampling_rate = new_sampling_rate * toUType(oversample_rate);
We keep original black background in all the correct IQ .C16 files BW's Options */
if (new_sampling_rate > 4'800'000) { // > BW >600kHz (fs=8*BW), (750kHz...2750kHz)
/* We are changing "REC" icon background to yellow in BW rec Options >600kHz
* where we are NOT recording full IQ .C16 files (recorded files are decimated ones).
* Those decimated recorded files, has not the full IQ samples.
* are ok as recorded spectrum indication, but they should not be used by Replay app.
* We keep original black background in all the correct IQ .C16 files BW's Options. */
if (actual_sampling_rate > 4'800'000) { // > BW >600kHz (fs=8*BW), (750kHz...2750kHz)
button_record.set_background(ui::Color::yellow());
} else {
button_record.set_background(ui::Color::black());
}
if (new_sampling_rate != sampling_rate ||
new_oversample_rate != oversample_rate) {
if (sampling_rate != new_sampling_rate) {
stop();
sampling_rate = new_sampling_rate;
oversample_rate = new_oversample_rate;
baseband::set_sample_rate(sampling_rate);
baseband::set_oversample_rate(oversample_rate);
baseband::set_sample_rate(sampling_rate, oversample_rate);
button_record.hidden(sampling_rate == 0);
text_record_filename.hidden(sampling_rate == 0);
@@ -131,6 +133,24 @@ void RecordView::set_sampling_rate(size_t new_sampling_rate, OversampleRate new_
update_status_display();
}
return actual_sampling_rate;
}
OversampleRate RecordView::get_oversample_rate(uint32_t sample_rate) {
// No oversampling necessary for baseband audio processors.
if (file_type == FileType::WAV)
return OversampleRate::None;
auto rate = ::get_oversample_rate(sample_rate);
// Currently proc_capture only supports x8 and x16 for decimation.
if (rate < OversampleRate::x8)
rate = OversampleRate::x8;
else if (rate > OversampleRate::x16)
rate = OversampleRate::x16;
return rate;
}
// Setter for datetime and frequency filename
@@ -202,8 +222,7 @@ void RecordView::start() {
case FileType::RawS8:
case FileType::RawS16: {
const auto metadata_file_error = write_metadata_file(
get_metadata_path(base_path),
{receiver_model.target_frequency(), sampling_rate / toUType(oversample_rate)});
get_metadata_path(base_path), {receiver_model.target_frequency(), sampling_rate});
if (metadata_file_error.is_valid()) {
handle_error(metadata_file_error.value());
return;
@@ -278,12 +297,7 @@ void RecordView::update_status_display() {
// - C8 captures 2 (I,Q) int8_t per sample or '2' bytes per sample.
// - C16 captures 2 (I,Q) int16_t per sample or '4' bytes per sample.
const auto bytes_per_sample = file_type == FileType::RawS16 ? 4 : 2;
// WAV files are not oversampled, but C8 and C16 are. Divide by the
// oversample rate to get the effective sample rate.
const auto effective_sampling_rate = file_type == FileType::WAV
? sampling_rate
: sampling_rate / toUType(oversample_rate);
const uint32_t bytes_per_second = effective_sampling_rate * bytes_per_sample;
const uint32_t bytes_per_second = sampling_rate * bytes_per_sample;
const uint32_t available_seconds = space_info.free / bytes_per_second;
const uint32_t seconds = available_seconds % 60;
const uint32_t available_minutes = available_seconds / 60;