mirror of
https://github.com/portapack-mayhem/mayhem-firmware.git
synced 2025-08-13 07:57:45 +00:00
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:
@@ -49,6 +49,7 @@ using Timestamp = lpc43xx::rtc::RTC;
|
||||
|
||||
template <typename T>
|
||||
struct buffer_t {
|
||||
using Type = T;
|
||||
T* const p;
|
||||
const size_t count;
|
||||
const uint32_t sampling_rate;
|
||||
|
@@ -78,7 +78,7 @@ class Message {
|
||||
ReplayThreadDone = 21,
|
||||
AFSKRxConfigure = 22,
|
||||
StatusRefresh = 23,
|
||||
SamplerateConfig = 24,
|
||||
SampleRateConfig = 24,
|
||||
BTLERxConfigure = 25,
|
||||
NRFRxConfigure = 26,
|
||||
TXProgress = 27,
|
||||
@@ -111,7 +111,6 @@ class Message {
|
||||
APRSRxConfigure = 54,
|
||||
SpectrumPainterBufferRequestConfigure = 55,
|
||||
SpectrumPainterBufferResponseConfigure = 56,
|
||||
OversampleRateConfig = 57,
|
||||
MAX
|
||||
};
|
||||
|
||||
@@ -799,32 +798,37 @@ class RetuneMessage : public Message {
|
||||
uint32_t range = 0;
|
||||
};
|
||||
|
||||
class SamplerateConfigMessage : public Message {
|
||||
public:
|
||||
constexpr SamplerateConfigMessage(
|
||||
const uint32_t sample_rate)
|
||||
: Message{ID::SamplerateConfig},
|
||||
sample_rate(sample_rate) {
|
||||
}
|
||||
|
||||
const uint32_t sample_rate = 0;
|
||||
};
|
||||
|
||||
/* Controls decimation handling in proc_capture. */
|
||||
/* Oversample/Interpolation sample rate multipliers. */
|
||||
enum class OversampleRate : uint8_t {
|
||||
Rate8x = 8,
|
||||
Rate16x = 16,
|
||||
/* Use either to indicate there's no oversampling needed. */
|
||||
None = 1,
|
||||
x1 = None,
|
||||
|
||||
// 4x would make sense to have, but need to ensure it doesn't
|
||||
// overrun the IQ read buffer in proc_replay.
|
||||
|
||||
/* Oversample rate of 8 times the sample rate. */
|
||||
x8 = 8,
|
||||
|
||||
/* Oversample rate of 16 times the sample rate. */
|
||||
x16 = 16,
|
||||
|
||||
/* Oversample rate of 32 times the sample rate. */
|
||||
x32 = 32,
|
||||
};
|
||||
|
||||
class OversampleRateConfigMessage : public Message {
|
||||
class SampleRateConfigMessage : public Message {
|
||||
public:
|
||||
constexpr OversampleRateConfigMessage(
|
||||
constexpr SampleRateConfigMessage(
|
||||
uint32_t sample_rate,
|
||||
OversampleRate oversample_rate)
|
||||
: Message{ID::OversampleRateConfig},
|
||||
: Message{ID::SampleRateConfig},
|
||||
sample_rate(sample_rate),
|
||||
oversample_rate(oversample_rate) {
|
||||
}
|
||||
|
||||
const OversampleRate oversample_rate{OversampleRate::Rate8x};
|
||||
const uint32_t sample_rate = 0;
|
||||
const OversampleRate oversample_rate = OversampleRate::None;
|
||||
};
|
||||
|
||||
class AudioLevelReportMessage : public Message {
|
||||
|
61
firmware/common/oversample.hpp
Normal file
61
firmware/common/oversample.hpp
Normal file
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Kyle Reed, zxkmm
|
||||
*
|
||||
* This file is part of PortaPack.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/* Helpers for handling oversampling and interpolation. */
|
||||
|
||||
#ifndef __OVERSAMPLE_H__
|
||||
#define __OVERSAMPLE_H__
|
||||
|
||||
#include "message.hpp"
|
||||
#include "utility.hpp"
|
||||
|
||||
/* TODO:
|
||||
* The decision to oversample/interpolate should only be a baseband concern.
|
||||
* However, the baseband can't set up the radio (M0 code), so the apps also
|
||||
* need to know about the "actual" sample rate so the radio settings can be
|
||||
* applied correctly. Ideally the baseband would tell the apps what the
|
||||
* actual sample rate is. Currently the apps are telling the baseband and
|
||||
* that feels like a separation of concerns problem. */
|
||||
|
||||
/* HackRF suggests a minimum sample rate of 2M so a oversample rate is applied
|
||||
* to the sample rate (pre-scale) to get the sample rate closer to that target.
|
||||
* The baseband needs to know how to correctly decimate (or interpolate) so
|
||||
* the set of allowed scalars is fixed (See OversampleRate enum).
|
||||
* In testing, a minimum rate of 400kHz seems to the functional minimum.
|
||||
*/
|
||||
|
||||
/* Gets the oversample rate for a given sample rate.
|
||||
* The oversample rate is used to increase the sample rate to improve SNR and quality.
|
||||
* This is also used as the interpolation rate when replaying captures. */
|
||||
inline OversampleRate get_oversample_rate(uint32_t sample_rate) {
|
||||
if (sample_rate < 25'000) return OversampleRate::x32;
|
||||
if (sample_rate < 50'000) return OversampleRate::x16;
|
||||
|
||||
return OversampleRate::x8;
|
||||
}
|
||||
|
||||
/* Gets the actual sample rate for a given sample rate.
|
||||
* This is the rate with the correct oversampling rate applied. */
|
||||
inline uint32_t get_actual_sample_rate(uint32_t sample_rate) {
|
||||
return sample_rate * toUType(get_oversample_rate(sample_rate));
|
||||
}
|
||||
|
||||
#endif /*__OVERSAMPLE_H__*/
|
Reference in New Issue
Block a user