mirror of
https://github.com/eried/portapack-mayhem.git
synced 2025-06-23 06:14:13 -04:00
Fix hang in Audio when switching from Capture app, & bug fixes. (#1167)
* Fix hang in Audio when switching from Capture app * Bug fixes
This commit is contained in:
parent
5daa0dfbb1
commit
7ebf3d3cdd
10 changed files with 78 additions and 89 deletions
|
@ -22,21 +22,19 @@
|
||||||
|
|
||||||
#include "analog_audio_app.hpp"
|
#include "analog_audio_app.hpp"
|
||||||
|
|
||||||
|
#include "audio.hpp"
|
||||||
#include "baseband_api.hpp"
|
#include "baseband_api.hpp"
|
||||||
|
#include "file.hpp"
|
||||||
|
#include "freqman.hpp"
|
||||||
#include "portapack.hpp"
|
#include "portapack.hpp"
|
||||||
#include "portapack_persistent_memory.hpp"
|
#include "portapack_persistent_memory.hpp"
|
||||||
using namespace portapack;
|
#include "string_format.hpp"
|
||||||
using namespace tonekey;
|
|
||||||
|
|
||||||
#include "audio.hpp"
|
|
||||||
#include "file.hpp"
|
|
||||||
|
|
||||||
#include "utility.hpp"
|
#include "utility.hpp"
|
||||||
|
|
||||||
#include "string_format.hpp"
|
#include "debug.hpp"
|
||||||
|
|
||||||
#include "freqman.hpp"
|
using namespace portapack;
|
||||||
|
using namespace tonekey;
|
||||||
|
|
||||||
namespace ui {
|
namespace ui {
|
||||||
|
|
||||||
|
@ -45,8 +43,8 @@ namespace ui {
|
||||||
static const Style& style_options_group = Styles::bg_blue;
|
static const Style& style_options_group = Styles::bg_blue;
|
||||||
|
|
||||||
AMOptionsView::AMOptionsView(
|
AMOptionsView::AMOptionsView(
|
||||||
const Rect parent_rect,
|
Rect parent_rect,
|
||||||
const Style* const style)
|
const Style* style)
|
||||||
: View{parent_rect} {
|
: View{parent_rect} {
|
||||||
set_style(style);
|
set_style(style);
|
||||||
|
|
||||||
|
@ -65,8 +63,8 @@ AMOptionsView::AMOptionsView(
|
||||||
/* NBFMOptionsView *******************************************************/
|
/* NBFMOptionsView *******************************************************/
|
||||||
|
|
||||||
NBFMOptionsView::NBFMOptionsView(
|
NBFMOptionsView::NBFMOptionsView(
|
||||||
const Rect parent_rect,
|
Rect parent_rect,
|
||||||
const Style* const style)
|
const Style* style)
|
||||||
: View{parent_rect} {
|
: View{parent_rect} {
|
||||||
set_style(style);
|
set_style(style);
|
||||||
|
|
||||||
|
@ -90,8 +88,8 @@ NBFMOptionsView::NBFMOptionsView(
|
||||||
/* WFMOptionsView *******************************************************/
|
/* WFMOptionsView *******************************************************/
|
||||||
|
|
||||||
WFMOptionsView::WFMOptionsView(
|
WFMOptionsView::WFMOptionsView(
|
||||||
const Rect parent_rect,
|
Rect parent_rect,
|
||||||
const Style* const style)
|
const Style* style)
|
||||||
: View{parent_rect} {
|
: View{parent_rect} {
|
||||||
set_style(style);
|
set_style(style);
|
||||||
|
|
||||||
|
@ -111,8 +109,8 @@ WFMOptionsView::WFMOptionsView(
|
||||||
|
|
||||||
SPECOptionsView::SPECOptionsView(
|
SPECOptionsView::SPECOptionsView(
|
||||||
AnalogAudioView* view,
|
AnalogAudioView* view,
|
||||||
const Rect parent_rect,
|
Rect parent_rect,
|
||||||
const Style* const style)
|
const Style* style)
|
||||||
: View{parent_rect} {
|
: View{parent_rect} {
|
||||||
set_style(style);
|
set_style(style);
|
||||||
|
|
||||||
|
@ -137,6 +135,10 @@ SPECOptionsView::SPECOptionsView(
|
||||||
AnalogAudioView::AnalogAudioView(
|
AnalogAudioView::AnalogAudioView(
|
||||||
NavigationView& nav)
|
NavigationView& nav)
|
||||||
: nav_(nav) {
|
: nav_(nav) {
|
||||||
|
// A baseband image _must_ be running before
|
||||||
|
// interacting with the waterfall view.
|
||||||
|
baseband::run_image(portapack::spi_flash::image_tag_wideband_spectrum);
|
||||||
|
|
||||||
add_children({&rssi,
|
add_children({&rssi,
|
||||||
&channel,
|
&channel,
|
||||||
&audio,
|
&audio,
|
||||||
|
@ -164,9 +166,12 @@ AnalogAudioView::AnalogAudioView(
|
||||||
this->on_show_options_rf_gain();
|
this->on_show_options_rf_gain();
|
||||||
};
|
};
|
||||||
|
|
||||||
const auto modulation = receiver_model.modulation();
|
auto modulation = receiver_model.modulation();
|
||||||
options_modulation.set_by_value(toUType(modulation));
|
// This app doesn't handle "Capture" mode.
|
||||||
|
if (modulation > ReceiverModel::Mode::SpectrumAnalysis)
|
||||||
|
modulation = ReceiverModel::Mode::SpectrumAnalysis;
|
||||||
|
|
||||||
|
options_modulation.set_by_value(toUType(modulation));
|
||||||
options_modulation.on_change = [this](size_t, OptionsField::value_t v) {
|
options_modulation.on_change = [this](size_t, OptionsField::value_t v) {
|
||||||
this->on_modulation_changed(static_cast<ReceiverModel::Mode>(v));
|
this->on_modulation_changed(static_cast<ReceiverModel::Mode>(v));
|
||||||
};
|
};
|
||||||
|
@ -184,8 +189,9 @@ AnalogAudioView::AnalogAudioView(
|
||||||
|
|
||||||
audio::output::start();
|
audio::output::start();
|
||||||
|
|
||||||
update_modulation(static_cast<ReceiverModel::Mode>(modulation));
|
// This call starts the correct baseband image to run
|
||||||
on_modulation_changed(static_cast<ReceiverModel::Mode>(modulation));
|
// and sets the radio up as necessary for the given modulation.
|
||||||
|
on_modulation_changed(modulation);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t AnalogAudioView::get_spec_bw_index() {
|
size_t AnalogAudioView::get_spec_bw_index() {
|
||||||
|
@ -212,40 +218,15 @@ void AnalogAudioView::set_spec_trigger(uint16_t trigger) {
|
||||||
}
|
}
|
||||||
|
|
||||||
AnalogAudioView::~AnalogAudioView() {
|
AnalogAudioView::~AnalogAudioView() {
|
||||||
// // save app settings
|
|
||||||
// app_settings.rx_frequency = field_frequency.value();
|
|
||||||
// app_settings.lna = receiver_model.lna();
|
|
||||||
// app_settings.vga = receiver_model.vga();
|
|
||||||
// app_settings.rx_amp = receiver_model.rf_amp();
|
|
||||||
// app_settings.step = receiver_model.frequency_step();
|
|
||||||
// app_settings.modulation = (uint8_t)receiver_model.modulation();
|
|
||||||
// app_settings.am_config_index = receiver_model.am_configuration();
|
|
||||||
// app_settings.nbfm_config_index = receiver_model.nbfm_configuration();
|
|
||||||
// app_settings.wfm_config_index = receiver_model.wfm_configuration();
|
|
||||||
// app_settings.squelch = receiver_model.squelch_level();
|
|
||||||
// settings.save("rx_audio", &app_settings);
|
|
||||||
|
|
||||||
// TODO: Manipulating audio codec here, and in ui_receiver.cpp. Good to do
|
|
||||||
// both?
|
|
||||||
audio::output::stop();
|
audio::output::stop();
|
||||||
|
|
||||||
receiver_model.set_sampling_rate(3072000); // Just a hack to avoid hanging other apps if the last modulation was SPEC
|
|
||||||
receiver_model.disable();
|
receiver_model.disable();
|
||||||
|
|
||||||
baseband::shutdown();
|
baseband::shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AnalogAudioView::on_hide() {
|
void AnalogAudioView::set_parent_rect(Rect new_parent_rect) {
|
||||||
// TODO: Terrible kludge because widget system doesn't notify Waterfall that
|
|
||||||
// it's being shown or hidden.
|
|
||||||
waterfall.on_hide();
|
|
||||||
View::on_hide();
|
|
||||||
}
|
|
||||||
|
|
||||||
void AnalogAudioView::set_parent_rect(const Rect new_parent_rect) {
|
|
||||||
View::set_parent_rect(new_parent_rect);
|
View::set_parent_rect(new_parent_rect);
|
||||||
|
|
||||||
const ui::Rect waterfall_rect{0, header_height, new_parent_rect.width(), new_parent_rect.height() - header_height};
|
ui::Rect waterfall_rect{0, header_height, new_parent_rect.width(), new_parent_rect.height() - header_height};
|
||||||
waterfall.set_parent_rect(waterfall_rect);
|
waterfall.set_parent_rect(waterfall_rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -257,13 +238,15 @@ void AnalogAudioView::on_baseband_bandwidth_changed(uint32_t bandwidth_hz) {
|
||||||
receiver_model.set_baseband_bandwidth(bandwidth_hz);
|
receiver_model.set_baseband_bandwidth(bandwidth_hz);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AnalogAudioView::on_modulation_changed(const ReceiverModel::Mode modulation) {
|
void AnalogAudioView::on_modulation_changed(ReceiverModel::Mode modulation) {
|
||||||
// TODO: Terrible kludge because widget system doesn't notify Waterfall that
|
// This app doesn't know what to do with "Capture" mode.
|
||||||
// it's being shown or hidden.
|
if (modulation > ReceiverModel::Mode::SpectrumAnalysis)
|
||||||
waterfall.on_hide();
|
modulation = ReceiverModel::Mode::SpectrumAnalysis;
|
||||||
|
|
||||||
|
baseband::spectrum_streaming_stop();
|
||||||
update_modulation(modulation);
|
update_modulation(modulation);
|
||||||
on_show_options_modulation();
|
on_show_options_modulation();
|
||||||
waterfall.on_show();
|
baseband::spectrum_streaming_start();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AnalogAudioView::remove_options_widget() {
|
void AnalogAudioView::remove_options_widget() {
|
||||||
|
@ -315,7 +298,7 @@ void AnalogAudioView::on_show_options_rf_gain() {
|
||||||
void AnalogAudioView::on_show_options_modulation() {
|
void AnalogAudioView::on_show_options_modulation() {
|
||||||
std::unique_ptr<Widget> widget;
|
std::unique_ptr<Widget> widget;
|
||||||
|
|
||||||
const auto modulation = static_cast<ReceiverModel::Mode>(receiver_model.modulation());
|
const auto modulation = receiver_model.modulation();
|
||||||
switch (modulation) {
|
switch (modulation) {
|
||||||
case ReceiverModel::Mode::AMAudio:
|
case ReceiverModel::Mode::AMAudio:
|
||||||
widget = std::make_unique<AMOptionsView>(options_view_rect, &style_options_group);
|
widget = std::make_unique<AMOptionsView>(options_view_rect, &style_options_group);
|
||||||
|
@ -342,6 +325,7 @@ void AnalogAudioView::on_show_options_modulation() {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
chDbgPanic("Unhandled Mode");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -358,7 +342,7 @@ void AnalogAudioView::on_reference_ppm_correction_changed(int32_t v) {
|
||||||
persistent_memory::set_correction_ppb(v * 1000);
|
persistent_memory::set_correction_ppb(v * 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AnalogAudioView::update_modulation(const ReceiverModel::Mode modulation) {
|
void AnalogAudioView::update_modulation(ReceiverModel::Mode modulation) {
|
||||||
audio::output::mute();
|
audio::output::mute();
|
||||||
record_view.stop();
|
record_view.stop();
|
||||||
|
|
||||||
|
@ -379,7 +363,8 @@ void AnalogAudioView::update_modulation(const ReceiverModel::Mode modulation) {
|
||||||
image_tag = portapack::spi_flash::image_tag_wideband_spectrum;
|
image_tag = portapack::spi_flash::image_tag_wideband_spectrum;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return;
|
chDbgPanic("Unhandled Mode");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
baseband::run_image(image_tag);
|
baseband::run_image(image_tag);
|
||||||
|
@ -418,7 +403,7 @@ void AnalogAudioView::update_modulation(const ReceiverModel::Mode modulation) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AnalogAudioView::handle_coded_squelch(const uint32_t value) {
|
void AnalogAudioView::handle_coded_squelch(uint32_t value) {
|
||||||
float diff, min_diff = value;
|
float diff, min_diff = value;
|
||||||
size_t min_idx{0};
|
size_t min_idx{0};
|
||||||
size_t c;
|
size_t c;
|
||||||
|
|
|
@ -38,7 +38,7 @@ namespace ui {
|
||||||
|
|
||||||
class AMOptionsView : public View {
|
class AMOptionsView : public View {
|
||||||
public:
|
public:
|
||||||
AMOptionsView(const Rect parent_rect, const Style* const style);
|
AMOptionsView(Rect parent_rect, const Style* style);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Text label_config{
|
Text label_config{
|
||||||
|
@ -56,7 +56,7 @@ class AMOptionsView : public View {
|
||||||
|
|
||||||
class NBFMOptionsView : public View {
|
class NBFMOptionsView : public View {
|
||||||
public:
|
public:
|
||||||
NBFMOptionsView(const Rect parent_rect, const Style* const style);
|
NBFMOptionsView(Rect parent_rect, const Style* style);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Text label_config{
|
Text label_config{
|
||||||
|
@ -84,7 +84,7 @@ class NBFMOptionsView : public View {
|
||||||
|
|
||||||
class WFMOptionsView : public View {
|
class WFMOptionsView : public View {
|
||||||
public:
|
public:
|
||||||
WFMOptionsView(const Rect parent_rect, const Style* const style);
|
WFMOptionsView(Rect parent_rect, const Style* style);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Text label_config{
|
Text label_config{
|
||||||
|
@ -103,7 +103,7 @@ class AnalogAudioView;
|
||||||
|
|
||||||
class SPECOptionsView : public View {
|
class SPECOptionsView : public View {
|
||||||
public:
|
public:
|
||||||
SPECOptionsView(AnalogAudioView* view, const Rect parent_rect, const Style* const style);
|
SPECOptionsView(AnalogAudioView* view, Rect parent_rect, const Style* style);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Text label_config{
|
Text label_config{
|
||||||
|
@ -140,10 +140,7 @@ class AnalogAudioView : public View {
|
||||||
AnalogAudioView(NavigationView& nav);
|
AnalogAudioView(NavigationView& nav);
|
||||||
~AnalogAudioView();
|
~AnalogAudioView();
|
||||||
|
|
||||||
void on_hide() override;
|
void set_parent_rect(Rect new_parent_rect) override;
|
||||||
|
|
||||||
void set_parent_rect(const Rect new_parent_rect) override;
|
|
||||||
|
|
||||||
void focus() override;
|
void focus() override;
|
||||||
|
|
||||||
std::string title() const override { return "Audio RX"; };
|
std::string title() const override { return "Audio RX"; };
|
||||||
|
@ -170,8 +167,6 @@ class AnalogAudioView : public View {
|
||||||
uint32_t spec_bw = 20000000;
|
uint32_t spec_bw = 20000000;
|
||||||
uint16_t spec_trigger = 63;
|
uint16_t spec_trigger = 63;
|
||||||
|
|
||||||
// bool exit_on_squelch { false };
|
|
||||||
|
|
||||||
RSSI rssi{
|
RSSI rssi{
|
||||||
{21 * 8, 0, 6 * 8, 4}};
|
{21 * 8, 0, 6 * 8, 4}};
|
||||||
|
|
||||||
|
@ -221,7 +216,7 @@ class AnalogAudioView : public View {
|
||||||
spectrum::WaterfallWidget waterfall{true};
|
spectrum::WaterfallWidget waterfall{true};
|
||||||
|
|
||||||
void on_baseband_bandwidth_changed(uint32_t bandwidth_hz);
|
void on_baseband_bandwidth_changed(uint32_t bandwidth_hz);
|
||||||
void on_modulation_changed(const ReceiverModel::Mode modulation);
|
void on_modulation_changed(ReceiverModel::Mode modulation);
|
||||||
void on_show_options_frequency();
|
void on_show_options_frequency();
|
||||||
void on_show_options_rf_gain();
|
void on_show_options_rf_gain();
|
||||||
void on_show_options_modulation();
|
void on_show_options_modulation();
|
||||||
|
@ -231,22 +226,13 @@ class AnalogAudioView : public View {
|
||||||
void remove_options_widget();
|
void remove_options_widget();
|
||||||
void set_options_widget(std::unique_ptr<Widget> new_widget);
|
void set_options_widget(std::unique_ptr<Widget> new_widget);
|
||||||
|
|
||||||
void update_modulation(const ReceiverModel::Mode modulation);
|
void update_modulation(ReceiverModel::Mode modulation);
|
||||||
|
|
||||||
// void squelched();
|
void handle_coded_squelch(uint32_t value);
|
||||||
void handle_coded_squelch(const uint32_t value);
|
|
||||||
|
|
||||||
/*MessageHandlerRegistration message_handler_squelch_signal {
|
|
||||||
Message::ID::RequestSignal,
|
|
||||||
[this](const Message* const p) {
|
|
||||||
(void)p;
|
|
||||||
this->squelched();
|
|
||||||
}
|
|
||||||
};*/
|
|
||||||
|
|
||||||
MessageHandlerRegistration message_handler_coded_squelch{
|
MessageHandlerRegistration message_handler_coded_squelch{
|
||||||
Message::ID::CodedSquelch,
|
Message::ID::CodedSquelch,
|
||||||
[this](const Message* const p) {
|
[this](const Message* p) {
|
||||||
const auto message = *reinterpret_cast<const CodedSquelchMessage*>(p);
|
const auto message = *reinterpret_cast<const CodedSquelchMessage*>(p);
|
||||||
this->handle_coded_squelch(message.value);
|
this->handle_coded_squelch(message.value);
|
||||||
}};
|
}};
|
||||||
|
|
|
@ -113,6 +113,8 @@ CaptureAppView::CaptureAppView(NavigationView& nav)
|
||||||
}
|
}
|
||||||
|
|
||||||
CaptureAppView::~CaptureAppView() {
|
CaptureAppView::~CaptureAppView() {
|
||||||
|
// Most other apps can't handle "Capture" mode, set to something standard.
|
||||||
|
receiver_model.set_modulation(ReceiverModel::Mode::WidebandFMAudio);
|
||||||
receiver_model.disable();
|
receiver_model.disable();
|
||||||
baseband::shutdown();
|
baseband::shutdown();
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
|
|
||||||
#include "ui.hpp"
|
#include "ui.hpp"
|
||||||
#include "portapack.hpp"
|
#include "portapack.hpp"
|
||||||
|
#include "app_settings.hpp"
|
||||||
#include "baseband_api.hpp"
|
#include "baseband_api.hpp"
|
||||||
#include "radio_state.hpp"
|
#include "radio_state.hpp"
|
||||||
#include "receiver_model.hpp"
|
#include "receiver_model.hpp"
|
||||||
|
@ -71,6 +72,8 @@ class GlassView : public View {
|
||||||
private:
|
private:
|
||||||
NavigationView& nav_;
|
NavigationView& nav_;
|
||||||
RxRadioState radio_state_{};
|
RxRadioState radio_state_{};
|
||||||
|
app_settings::SettingsManager settings_{
|
||||||
|
"rx_glass", app_settings::Mode::RX};
|
||||||
|
|
||||||
struct preset_entry {
|
struct preset_entry {
|
||||||
rf::Frequency min{};
|
rf::Frequency min{};
|
||||||
|
|
|
@ -595,12 +595,6 @@ MicTXView::MicTXView(
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// These shouldn't be necessary, but because
|
|
||||||
// this app uses both transmitter_model and directly
|
|
||||||
// configures the baseband, these end up being required.
|
|
||||||
transmitter_model.set_sampling_rate(sampling_rate);
|
|
||||||
transmitter_model.set_baseband_bandwidth(1750000);
|
|
||||||
|
|
||||||
set_tx(false);
|
set_tx(false);
|
||||||
|
|
||||||
audio::set_rate(audio::Rate::Hz_24000);
|
audio::set_rate(audio::Rate::Hz_24000);
|
||||||
|
|
|
@ -142,7 +142,9 @@ bool PlaylistView::next_track() {
|
||||||
|
|
||||||
/* Transmits the current_entry_ */
|
/* Transmits the current_entry_ */
|
||||||
void PlaylistView::send_current_track() {
|
void PlaylistView::send_current_track() {
|
||||||
|
// Prepare to send a file.
|
||||||
replay_thread_.reset();
|
replay_thread_.reset();
|
||||||
|
transmitter_model.disable();
|
||||||
ready_signal_ = false;
|
ready_signal_ = false;
|
||||||
|
|
||||||
if (!current_entry_)
|
if (!current_entry_)
|
||||||
|
@ -172,6 +174,10 @@ void PlaylistView::send_current_track() {
|
||||||
transmitter_model.set_baseband_bandwidth(baseband_bandwidth);
|
transmitter_model.set_baseband_bandwidth(baseband_bandwidth);
|
||||||
transmitter_model.enable();
|
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());
|
||||||
|
|
||||||
// Use the ReplayThread class to send the data.
|
// Use the ReplayThread class to send the data.
|
||||||
replay_thread_ = std::make_unique<ReplayThread>(
|
replay_thread_ = std::make_unique<ReplayThread>(
|
||||||
std::move(reader),
|
std::move(reader),
|
||||||
|
|
|
@ -96,7 +96,7 @@ class ScannerView : public View {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
app_settings::SettingsManager settings_{
|
app_settings::SettingsManager settings_{
|
||||||
"scanner", app_settings::Mode::RX};
|
"rx_scanner", app_settings::Mode::RX};
|
||||||
|
|
||||||
NavigationView& nav_;
|
NavigationView& nav_;
|
||||||
RxRadioState radio_state_{};
|
RxRadioState radio_state_{};
|
||||||
|
|
|
@ -30,6 +30,12 @@
|
||||||
|
|
||||||
/* Stashes current radio bandwidth and sampling rate.
|
/* Stashes current radio bandwidth and sampling rate.
|
||||||
* Inits to defaults, and restores previous when destroyed.
|
* Inits to defaults, and restores previous when destroyed.
|
||||||
|
* The idea here is that an app will eventually call enable
|
||||||
|
* on the model which will sync all of the model state into
|
||||||
|
* the radio. We tried lazily setting these using the
|
||||||
|
* set_configuration_without_update function, but there are
|
||||||
|
* still various UI components (mainly Waterfall) that need
|
||||||
|
* the radio set in order to load properly.
|
||||||
* NB: This member must be added before SettingsManager. */
|
* NB: This member must be added before SettingsManager. */
|
||||||
template <typename TModel, TModel* model>
|
template <typename TModel, TModel* model>
|
||||||
class RadioState {
|
class RadioState {
|
||||||
|
@ -41,8 +47,9 @@ class RadioState {
|
||||||
RadioState(uint32_t new_bandwidth, uint32_t new_sampling_rate)
|
RadioState(uint32_t new_bandwidth, uint32_t new_sampling_rate)
|
||||||
: prev_bandwidth_{model->baseband_bandwidth()},
|
: prev_bandwidth_{model->baseband_bandwidth()},
|
||||||
prev_sampling_rate_{model->sampling_rate()} {
|
prev_sampling_rate_{model->sampling_rate()} {
|
||||||
model->set_configuration_without_update(
|
// Update the new settings in the radio.
|
||||||
new_bandwidth, new_sampling_rate);
|
model->set_sampling_rate(new_sampling_rate);
|
||||||
|
model->set_baseband_bandwidth(new_bandwidth);
|
||||||
}
|
}
|
||||||
|
|
||||||
~RadioState() {
|
~RadioState() {
|
||||||
|
|
|
@ -311,10 +311,12 @@ WaterfallWidget::WaterfallWidget(const bool cursor) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void WaterfallWidget::on_show() {
|
void WaterfallWidget::on_show() {
|
||||||
|
// TODO: Assert that baseband is not shutdown.
|
||||||
baseband::spectrum_streaming_start();
|
baseband::spectrum_streaming_start();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WaterfallWidget::on_hide() {
|
void WaterfallWidget::on_hide() {
|
||||||
|
// TODO: Assert that baseband is not shutdown.
|
||||||
baseband::spectrum_streaming_stop();
|
baseband::spectrum_streaming_stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -104,6 +104,10 @@ class FrequencyScale : public Widget {
|
||||||
void draw_filter_ranges(Painter& painter, const Rect r);
|
void draw_filter_ranges(Painter& painter, const Rect r);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* NB: These visualizations rely on having a baseband image running.
|
||||||
|
* If the baseband is shutdown or otherwise not running when interacting
|
||||||
|
* with these, they will almost certainly hang the device. */
|
||||||
|
|
||||||
class WaterfallView : public Widget {
|
class WaterfallView : public Widget {
|
||||||
public:
|
public:
|
||||||
void on_show() override;
|
void on_show() override;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue