mirror of
https://github.com/eried/portapack-mayhem.git
synced 2024-10-01 01:26:06 -04:00
Pocsag UX Revamp (#1408)
* Set bandwidth_filter in pogsac * WIP pocsag UI revamp * Settings UI, better console, UI Revamp * Add baud rate to error messages * Reset last_addr in error cases * Show malformed messages as different color vs hiding * Use light grey to indicate low quality decode --------- Co-authored-by: kallanreed <kallanreed@noreply.github.com>
This commit is contained in:
parent
f4496d8f45
commit
9af1308e29
@ -22,15 +22,15 @@
|
|||||||
|
|
||||||
#include "pocsag_app.hpp"
|
#include "pocsag_app.hpp"
|
||||||
|
|
||||||
|
#include "audio.hpp"
|
||||||
#include "baseband_api.hpp"
|
#include "baseband_api.hpp"
|
||||||
#include "portapack_persistent_memory.hpp"
|
#include "portapack_persistent_memory.hpp"
|
||||||
|
#include "string_format.hpp"
|
||||||
|
#include "utility.hpp"
|
||||||
|
|
||||||
using namespace portapack;
|
using namespace portapack;
|
||||||
using namespace pocsag;
|
using namespace pocsag;
|
||||||
|
namespace pmem = portapack::persistent_memory;
|
||||||
#include "string_format.hpp"
|
|
||||||
#include "utility.hpp"
|
|
||||||
#include "audio.hpp"
|
|
||||||
|
|
||||||
void POCSAGLogger::log_raw_data(const pocsag::POCSAGPacket& packet, const uint32_t frequency) {
|
void POCSAGLogger::log_raw_data(const pocsag::POCSAGPacket& packet, const uint32_t frequency) {
|
||||||
std::string entry = "Raw: F:" + to_string_dec_uint(frequency) + "Hz " +
|
std::string entry = "Raw: F:" + to_string_dec_uint(frequency) + "Hz " +
|
||||||
@ -51,44 +51,73 @@ void POCSAGLogger::log_decoded(
|
|||||||
|
|
||||||
namespace ui {
|
namespace ui {
|
||||||
|
|
||||||
|
POCSAGSettingsView::POCSAGSettingsView(
|
||||||
|
NavigationView& nav,
|
||||||
|
POCSAGSettings& settings)
|
||||||
|
: settings_{settings} {
|
||||||
|
add_children(
|
||||||
|
{&check_log,
|
||||||
|
&check_log_raw,
|
||||||
|
&check_small_font,
|
||||||
|
&check_ignore,
|
||||||
|
&field_ignore,
|
||||||
|
&button_save});
|
||||||
|
|
||||||
|
check_log.set_value(settings_.enable_logging);
|
||||||
|
check_log_raw.set_value(settings_.enable_raw_log);
|
||||||
|
check_small_font.set_value(settings_.enable_small_font);
|
||||||
|
check_ignore.set_value(settings_.enable_ignore);
|
||||||
|
field_ignore.set_value(settings_.address_to_ignore);
|
||||||
|
|
||||||
|
button_save.on_select = [this, &nav](Button&) {
|
||||||
|
settings_.enable_logging = check_log.value();
|
||||||
|
settings_.enable_raw_log = check_log_raw.value();
|
||||||
|
settings_.enable_small_font = check_small_font.value();
|
||||||
|
settings_.enable_ignore = check_ignore.value();
|
||||||
|
settings_.address_to_ignore = field_ignore.value();
|
||||||
|
|
||||||
|
nav.pop();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
POCSAGAppView::POCSAGAppView(NavigationView& nav)
|
POCSAGAppView::POCSAGAppView(NavigationView& nav)
|
||||||
: nav_{nav} {
|
: nav_{nav} {
|
||||||
baseband::run_image(portapack::spi_flash::image_tag_pocsag);
|
baseband::run_image(portapack::spi_flash::image_tag_pocsag);
|
||||||
|
|
||||||
add_children({&rssi,
|
add_children(
|
||||||
&channel,
|
{&rssi,
|
||||||
&audio,
|
&audio,
|
||||||
&field_rf_amp,
|
&field_rf_amp,
|
||||||
&field_lna,
|
&field_lna,
|
||||||
&field_vga,
|
&field_vga,
|
||||||
&field_frequency,
|
&field_frequency,
|
||||||
&check_log,
|
|
||||||
&field_volume,
|
&field_volume,
|
||||||
&check_ignore,
|
&image_status,
|
||||||
&sym_ignore,
|
&button_ignore_last,
|
||||||
|
&button_config,
|
||||||
&console});
|
&console});
|
||||||
|
|
||||||
if (!settings_.loaded())
|
// No app settings, use fallbacks.
|
||||||
|
if (!app_settings_.loaded()) {
|
||||||
field_frequency.set_value(initial_target_frequency);
|
field_frequency.set_value(initial_target_frequency);
|
||||||
|
settings_.address_to_ignore = pmem::pocsag_ignore_address();
|
||||||
check_log.set_value(enable_logging);
|
settings_.enable_ignore = settings_.address_to_ignore > 0;
|
||||||
|
|
||||||
receiver_model.enable();
|
|
||||||
|
|
||||||
// TODO: app setting instead?
|
|
||||||
uint32_t ignore_address;
|
|
||||||
ignore_address = persistent_memory::pocsag_ignore_address();
|
|
||||||
|
|
||||||
// TODO: is this common enough for a helper?
|
|
||||||
for (size_t c = 0; c < 7; c++) {
|
|
||||||
sym_ignore.set_sym(6 - c, ignore_address % 10);
|
|
||||||
ignore_address /= 10;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
logger = std::make_unique<POCSAGLogger>();
|
logger.append(LOG_ROOT_DIR "/POCSAG.TXT");
|
||||||
if (logger)
|
|
||||||
logger->append(LOG_ROOT_DIR "/POCSAG.TXT");
|
|
||||||
|
|
||||||
|
button_ignore_last.on_select = [this](Button&) {
|
||||||
|
settings_.enable_ignore = true;
|
||||||
|
settings_.address_to_ignore = last_address;
|
||||||
|
};
|
||||||
|
|
||||||
|
button_config.on_select = [this](Button&) {
|
||||||
|
nav_.push<POCSAGSettingsView>(settings_);
|
||||||
|
nav_.set_on_pop([this]() { refresh_ui(); });
|
||||||
|
};
|
||||||
|
|
||||||
|
refresh_ui();
|
||||||
|
receiver_model.enable();
|
||||||
audio::output::start();
|
audio::output::start();
|
||||||
baseband::set_pocsag();
|
baseband::set_pocsag();
|
||||||
}
|
}
|
||||||
@ -99,82 +128,101 @@ void POCSAGAppView::focus() {
|
|||||||
|
|
||||||
POCSAGAppView::~POCSAGAppView() {
|
POCSAGAppView::~POCSAGAppView() {
|
||||||
audio::output::stop();
|
audio::output::stop();
|
||||||
|
|
||||||
// Save settings.
|
|
||||||
persistent_memory::set_pocsag_ignore_address(sym_ignore.value_dec_u32());
|
|
||||||
enable_logging = check_log.value();
|
|
||||||
|
|
||||||
receiver_model.disable();
|
receiver_model.disable();
|
||||||
baseband::shutdown();
|
baseband::shutdown();
|
||||||
|
|
||||||
|
// Save pmem settings. TODO: Even needed anymore?
|
||||||
|
pmem::set_pocsag_ignore_address(settings_.address_to_ignore);
|
||||||
|
pmem::set_pocsag_last_address(pocsag_state.address); // For POCSAG TX.
|
||||||
|
}
|
||||||
|
|
||||||
|
void POCSAGAppView::refresh_ui() {
|
||||||
|
console.set_style(
|
||||||
|
settings_.enable_small_font
|
||||||
|
? &Styles::white_small
|
||||||
|
: &Styles::white);
|
||||||
}
|
}
|
||||||
|
|
||||||
void POCSAGAppView::on_packet(const POCSAGPacketMessage* message) {
|
void POCSAGAppView::on_packet(const POCSAGPacketMessage* message) {
|
||||||
std::string alphanum_text = "";
|
packet_toggle = !packet_toggle;
|
||||||
|
image_status.set_foreground(packet_toggle
|
||||||
|
? Color::dark_grey()
|
||||||
|
: Color::white());
|
||||||
|
|
||||||
if (message->packet.flag() != NORMAL)
|
const uint32_t roundVal = 50;
|
||||||
console.writeln("\n\x1B\x0CRC ERROR: " + pocsag::flag_str(message->packet.flag()));
|
const uint32_t bitrate_rounded = roundVal * ((message->packet.bitrate() + (roundVal / 2)) / roundVal);
|
||||||
else {
|
auto bitrate = to_string_dec_uint(bitrate_rounded);
|
||||||
|
auto timestamp = to_string_datetime(message->packet.timestamp(), HM);
|
||||||
|
auto prefix = timestamp + " " + bitrate;
|
||||||
|
|
||||||
|
if (logging_raw())
|
||||||
|
logger.log_raw_data(message->packet, receiver_model.target_frequency());
|
||||||
|
|
||||||
|
if (message->packet.flag() != NORMAL) {
|
||||||
|
console.writeln("\n\x1B\x04" + prefix + " CRC ERROR: " + pocsag::flag_str(message->packet.flag()));
|
||||||
|
last_address = 0;
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
pocsag_decode_batch(message->packet, &pocsag_state);
|
pocsag_decode_batch(message->packet, &pocsag_state);
|
||||||
|
|
||||||
if ((ignore()) && (pocsag_state.address == sym_ignore.value_dec_u32())) {
|
/*
|
||||||
// Ignore (inform, but no log)
|
// Too many errors for reliable decode.
|
||||||
// console.write("\n\x1B\x03" + to_string_time(message->packet.timestamp()) +
|
if (pocsag_state.errors >= 3) {
|
||||||
// " Ignored address " + to_string_dec_uint(pocsag_state.address));
|
console.write("\n\x1B\x0D" + prefix + " Too many decode errors.");
|
||||||
|
last_address = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Too many errors for reliable decode
|
*/
|
||||||
if ((ignore()) && (pocsag_state.errors >= 3)) {
|
|
||||||
|
// Ignored address.
|
||||||
|
if (ignore() && pocsag_state.address == settings_.address_to_ignore) {
|
||||||
|
console.write("\n\x1B\x03" + prefix + " Ignored: " + to_string_dec_uint(pocsag_state.address));
|
||||||
|
last_address = pocsag_state.address;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string console_info;
|
// Color indicates the message has lots of decoding errors.
|
||||||
const uint32_t roundVal = 50;
|
std::string color = pocsag_state.errors >= 3 ? "\x1B\x07" : "";
|
||||||
const uint32_t bitrate = roundVal * ((message->packet.bitrate() + (roundVal / 2)) / roundVal);
|
|
||||||
console_info = "\n" + to_string_datetime(message->packet.timestamp(), HM);
|
std::string console_info = "\n" + color + prefix;
|
||||||
console_info += " " + to_string_dec_uint(bitrate);
|
console_info += " #" + to_string_dec_uint(pocsag_state.address);
|
||||||
console_info += " ADDR:" + to_string_dec_uint(pocsag_state.address);
|
|
||||||
console_info += " F" + to_string_dec_uint(pocsag_state.function);
|
console_info += " F" + to_string_dec_uint(pocsag_state.function);
|
||||||
|
|
||||||
// Store last received address for POCSAG TX
|
|
||||||
persistent_memory::set_pocsag_last_address(pocsag_state.address);
|
|
||||||
|
|
||||||
if (pocsag_state.out_type == ADDRESS) {
|
if (pocsag_state.out_type == ADDRESS) {
|
||||||
// Address only
|
last_address = pocsag_state.address;
|
||||||
|
|
||||||
console.write(console_info);
|
console.write(console_info);
|
||||||
|
|
||||||
if (logger && logging()) {
|
if (logging()) {
|
||||||
logger->log_decoded(
|
logger.log_decoded(
|
||||||
message->packet, to_string_dec_uint(pocsag_state.address) +
|
message->packet,
|
||||||
|
to_string_dec_uint(pocsag_state.address) +
|
||||||
" F" + to_string_dec_uint(pocsag_state.function) +
|
" F" + to_string_dec_uint(pocsag_state.function) +
|
||||||
" Address only");
|
" Address only");
|
||||||
}
|
}
|
||||||
|
|
||||||
last_address = pocsag_state.address;
|
|
||||||
} else if (pocsag_state.out_type == MESSAGE) {
|
} else if (pocsag_state.out_type == MESSAGE) {
|
||||||
if (pocsag_state.address != last_address) {
|
if (pocsag_state.address != last_address) {
|
||||||
// New message
|
// New message
|
||||||
console.writeln(console_info);
|
|
||||||
console.write(pocsag_state.output);
|
|
||||||
|
|
||||||
last_address = pocsag_state.address;
|
last_address = pocsag_state.address;
|
||||||
|
console.writeln(console_info);
|
||||||
|
console.write(color + pocsag_state.output);
|
||||||
} else {
|
} else {
|
||||||
// Message continues...
|
// Message continues...
|
||||||
console.write(pocsag_state.output);
|
console.write(color + pocsag_state.output);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (logger && logging())
|
if (logging()) {
|
||||||
logger->log_decoded(
|
logger.log_decoded(
|
||||||
message->packet, to_string_dec_uint(pocsag_state.address) +
|
message->packet,
|
||||||
|
to_string_dec_uint(pocsag_state.address) +
|
||||||
" F" + to_string_dec_uint(pocsag_state.function) +
|
" F" + to_string_dec_uint(pocsag_state.function) +
|
||||||
" Alpha: " + pocsag_state.output);
|
" > " + pocsag_state.output);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: make setting.
|
void POCSAGAppView::on_stats(const POCSAGStatsMessage*) {
|
||||||
// Log raw data whatever it contains
|
|
||||||
/*if (logger && logging())
|
|
||||||
logger->log_raw_data(message->packet, receiver_model.target_frequency());*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} /* namespace ui */
|
} /* namespace ui */
|
||||||
|
@ -27,12 +27,15 @@
|
|||||||
#include "ui_freq_field.hpp"
|
#include "ui_freq_field.hpp"
|
||||||
#include "ui_receiver.hpp"
|
#include "ui_receiver.hpp"
|
||||||
#include "ui_rssi.hpp"
|
#include "ui_rssi.hpp"
|
||||||
|
#include "ui_styles.hpp"
|
||||||
|
|
||||||
#include "log_file.hpp"
|
|
||||||
#include "app_settings.hpp"
|
#include "app_settings.hpp"
|
||||||
#include "radio_state.hpp"
|
#include "log_file.hpp"
|
||||||
#include "pocsag.hpp"
|
#include "pocsag.hpp"
|
||||||
#include "pocsag_packet.hpp"
|
#include "pocsag_packet.hpp"
|
||||||
|
#include "radio_state.hpp"
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
class POCSAGLogger {
|
class POCSAGLogger {
|
||||||
public:
|
public:
|
||||||
@ -49,6 +52,59 @@ class POCSAGLogger {
|
|||||||
|
|
||||||
namespace ui {
|
namespace ui {
|
||||||
|
|
||||||
|
struct POCSAGSettings {
|
||||||
|
bool enable_small_font = false;
|
||||||
|
bool enable_logging = false;
|
||||||
|
bool enable_raw_log = false;
|
||||||
|
bool enable_ignore = false;
|
||||||
|
uint32_t address_to_ignore = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class POCSAGSettingsView : public View {
|
||||||
|
public:
|
||||||
|
POCSAGSettingsView(NavigationView& nav, POCSAGSettings& settings);
|
||||||
|
|
||||||
|
std::string title() const override { return "POCSAG Config"; };
|
||||||
|
|
||||||
|
private:
|
||||||
|
POCSAGSettings& settings_;
|
||||||
|
|
||||||
|
Checkbox check_log{
|
||||||
|
{2 * 8, 2 * 16},
|
||||||
|
10,
|
||||||
|
"Enable Log",
|
||||||
|
false};
|
||||||
|
|
||||||
|
Checkbox check_log_raw{
|
||||||
|
{2 * 8, 4 * 16},
|
||||||
|
12,
|
||||||
|
"Log Raw Data",
|
||||||
|
false};
|
||||||
|
|
||||||
|
Checkbox check_small_font{
|
||||||
|
{2 * 8, 6 * 16},
|
||||||
|
4,
|
||||||
|
"Use Small Font",
|
||||||
|
false};
|
||||||
|
|
||||||
|
Checkbox check_ignore{
|
||||||
|
{2 * 8, 8 * 16},
|
||||||
|
22,
|
||||||
|
"Enable Ignored Address",
|
||||||
|
false};
|
||||||
|
|
||||||
|
NumberField field_ignore{
|
||||||
|
{7 * 8, 9 * 16 + 8},
|
||||||
|
7,
|
||||||
|
{0, 9999999},
|
||||||
|
1,
|
||||||
|
'0'};
|
||||||
|
|
||||||
|
Button button_save{
|
||||||
|
{12 * 8, 16 * 16, 10 * 8, 2 * 16},
|
||||||
|
"Save"};
|
||||||
|
};
|
||||||
|
|
||||||
class POCSAGAppView : public View {
|
class POCSAGAppView : public View {
|
||||||
public:
|
public:
|
||||||
POCSAGAppView(NavigationView& nav);
|
POCSAGAppView(NavigationView& nav);
|
||||||
@ -58,21 +114,36 @@ class POCSAGAppView : public View {
|
|||||||
void focus() override;
|
void focus() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static constexpr uint32_t initial_target_frequency = 466175000;
|
static constexpr uint32_t initial_target_frequency = 466'175'000;
|
||||||
bool logging() const { return check_log.value(); };
|
bool logging() const { return settings_.enable_logging; };
|
||||||
bool ignore() const { return check_ignore.value(); };
|
bool logging_raw() const { return settings_.enable_raw_log; };
|
||||||
|
bool ignore() const { return settings_.enable_ignore; };
|
||||||
|
|
||||||
NavigationView& nav_;
|
NavigationView& nav_;
|
||||||
RxRadioState radio_state_{};
|
RxRadioState radio_state_{
|
||||||
|
12'500, // POCSAG is FSK +/- 4.5MHz, 12k5 is a good filter.
|
||||||
|
3'072'000, // Match baseband_fs in proc_pocsag.
|
||||||
|
};
|
||||||
|
|
||||||
// Settings
|
// Settings
|
||||||
bool enable_logging = false;
|
POCSAGSettings settings_{};
|
||||||
app_settings::SettingsManager settings_{
|
app_settings::SettingsManager app_settings_{
|
||||||
"rx_pocsag"sv,
|
"rx_pocsag"sv,
|
||||||
app_settings::Mode::RX,
|
app_settings::Mode::RX,
|
||||||
{{"enable_logging"sv, &enable_logging}}};
|
{
|
||||||
|
{"small_font"sv, &settings_.enable_small_font},
|
||||||
|
{"enable_logging"sv, &settings_.enable_logging},
|
||||||
|
{"enable_ignore"sv, &settings_.enable_ignore},
|
||||||
|
}};
|
||||||
|
|
||||||
|
void refresh_ui();
|
||||||
|
void on_packet(const POCSAGPacketMessage* message);
|
||||||
|
void on_stats(const POCSAGStatsMessage* stats);
|
||||||
|
|
||||||
uint32_t last_address = 0xFFFFFFFF;
|
uint32_t last_address = 0xFFFFFFFF;
|
||||||
pocsag::POCSAGState pocsag_state{};
|
pocsag::POCSAGState pocsag_state{};
|
||||||
|
POCSAGLogger logger{};
|
||||||
|
bool packet_toggle = false;
|
||||||
|
|
||||||
RFAmpField field_rf_amp{
|
RFAmpField field_rf_amp{
|
||||||
{13 * 8, 0 * 16}};
|
{13 * 8, 0 * 16}};
|
||||||
@ -81,41 +152,32 @@ class POCSAGAppView : public View {
|
|||||||
VGAGainField field_vga{
|
VGAGainField field_vga{
|
||||||
{18 * 8, 0 * 16}};
|
{18 * 8, 0 * 16}};
|
||||||
RSSI rssi{
|
RSSI rssi{
|
||||||
{21 * 8, 0, 6 * 8, 4}};
|
{21 * 8, 3, 6 * 8, 4}};
|
||||||
Channel channel{
|
|
||||||
{21 * 8, 5, 6 * 8, 4}};
|
|
||||||
Audio audio{
|
Audio audio{
|
||||||
{21 * 8, 10, 6 * 8, 4}};
|
{21 * 8, 8, 6 * 8, 4}};
|
||||||
|
|
||||||
RxFrequencyField field_frequency{
|
RxFrequencyField field_frequency{
|
||||||
{0 * 8, 0 * 8},
|
{0 * 8, 0 * 8},
|
||||||
nav_};
|
nav_};
|
||||||
|
|
||||||
AudioVolumeField field_volume{
|
AudioVolumeField field_volume{
|
||||||
{28 * 8, 0 * 16}};
|
{28 * 8, 0 * 16}};
|
||||||
|
|
||||||
Checkbox check_ignore{
|
Image image_status{
|
||||||
{0 * 8, 21},
|
{7 * 8, 1 * 16 + 2, 16, 16},
|
||||||
8,
|
&bitmap_icon_pocsag,
|
||||||
"Ign addr",
|
Color::white(),
|
||||||
false};
|
Color::black()};
|
||||||
SymField sym_ignore{
|
|
||||||
{13 * 8, 25},
|
|
||||||
7,
|
|
||||||
SymField::SYMFIELD_DEC};
|
|
||||||
|
|
||||||
Checkbox check_log{
|
Button button_ignore_last{
|
||||||
{240 - 8 * 8, 21},
|
{10 * 8, 1 * 16, 12 * 8, 20},
|
||||||
3,
|
"Ignore Last"};
|
||||||
"Log",
|
|
||||||
false};
|
Button button_config{
|
||||||
|
{22 * 8, 1 * 16, 8 * 8, 20},
|
||||||
|
"Config"};
|
||||||
|
|
||||||
Console console{
|
Console console{
|
||||||
{0, 3 * 16, 240, 256}};
|
{0, 2 * 16 + 6, screen_width, screen_height - 56}};
|
||||||
|
|
||||||
std::unique_ptr<POCSAGLogger> logger{};
|
|
||||||
|
|
||||||
void on_packet(const POCSAGPacketMessage* message);
|
|
||||||
|
|
||||||
MessageHandlerRegistration message_handler_packet{
|
MessageHandlerRegistration message_handler_packet{
|
||||||
Message::ID::POCSAGPacket,
|
Message::ID::POCSAGPacket,
|
||||||
@ -123,6 +185,13 @@ class POCSAGAppView : public View {
|
|||||||
const auto message = static_cast<const POCSAGPacketMessage*>(p);
|
const auto message = static_cast<const POCSAGPacketMessage*>(p);
|
||||||
this->on_packet(message);
|
this->on_packet(message);
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
MessageHandlerRegistration message_handler_stats{
|
||||||
|
Message::ID::POCSAGStats,
|
||||||
|
[this](Message* const p) {
|
||||||
|
const auto stats = static_cast<const POCSAGStatsMessage*>(p);
|
||||||
|
this->on_stats(stats);
|
||||||
|
}};
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace ui */
|
} /* namespace ui */
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <algorithm> // std::max
|
#include <algorithm>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
void POCSAGProcessor::execute(const buffer_c8_t& buffer) {
|
void POCSAGProcessor::execute(const buffer_c8_t& buffer) {
|
||||||
@ -90,10 +90,13 @@ void POCSAGProcessor::configure() {
|
|||||||
decim_0.configure(taps_11k0_decim_0.taps, 33554432);
|
decim_0.configure(taps_11k0_decim_0.taps, 33554432);
|
||||||
decim_1.configure(taps_11k0_decim_1.taps, 131072);
|
decim_1.configure(taps_11k0_decim_1.taps, 131072);
|
||||||
channel_filter.configure(taps_11k0_channel.taps, 2);
|
channel_filter.configure(taps_11k0_channel.taps, 2);
|
||||||
demod.configure(demod_input_fs, 4500);
|
demod.configure(demod_input_fs, 4'500); // FSK +/- 4k5Hz.
|
||||||
// Smoothing should be roughly sample rate over max baud
|
// Smoothing should be roughly sample rate over max baud
|
||||||
// 24k / 3.2k is 7.5
|
// 24k / 3.2k is 7.5
|
||||||
smooth.SetSize(8);
|
smooth.SetSize(8);
|
||||||
|
|
||||||
|
// TODO: support squelch?
|
||||||
|
// audio_output.configure(message.audio_hpf_config, message.audio_deemph_config, (float)message.squelch_level / 100.0);
|
||||||
audio_output.configure(false);
|
audio_output.configure(false);
|
||||||
|
|
||||||
// Set up the frame extraction, limits of baud
|
// Set up the frame extraction, limits of baud
|
||||||
|
@ -48,7 +48,7 @@ using namespace std;
|
|||||||
template <class ValType, class CalcType>
|
template <class ValType, class CalcType>
|
||||||
class SmoothVals {
|
class SmoothVals {
|
||||||
protected:
|
protected:
|
||||||
ValType* m_lastVals; // Previoius N values
|
ValType* m_lastVals; // Previous N values
|
||||||
int m_size; // The size N
|
int m_size; // The size N
|
||||||
CalcType m_sumVal; // Running sum of lastVals
|
CalcType m_sumVal; // Running sum of lastVals
|
||||||
int m_pos; // Current position in last vals ring buffer
|
int m_pos; // Current position in last vals ring buffer
|
||||||
|
@ -111,6 +111,7 @@ class Message {
|
|||||||
APRSRxConfigure = 54,
|
APRSRxConfigure = 54,
|
||||||
SpectrumPainterBufferRequestConfigure = 55,
|
SpectrumPainterBufferRequestConfigure = 55,
|
||||||
SpectrumPainterBufferResponseConfigure = 56,
|
SpectrumPainterBufferResponseConfigure = 56,
|
||||||
|
POCSAGStats = 57,
|
||||||
MAX
|
MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -340,6 +341,17 @@ class POCSAGPacketMessage : public Message {
|
|||||||
pocsag::POCSAGPacket packet;
|
pocsag::POCSAGPacket packet;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class POCSAGStatsMessage : public Message {
|
||||||
|
public:
|
||||||
|
constexpr POCSAGStatsMessage(
|
||||||
|
uint16_t baud_rate)
|
||||||
|
: Message{ID::POCSAGStats},
|
||||||
|
baud_rate_{baud_rate} {
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t baud_rate_;
|
||||||
|
};
|
||||||
|
|
||||||
class ACARSPacketMessage : public Message {
|
class ACARSPacketMessage : public Message {
|
||||||
public:
|
public:
|
||||||
constexpr ACARSPacketMessage(
|
constexpr ACARSPacketMessage(
|
||||||
|
Loading…
Reference in New Issue
Block a user