mirror of
https://github.com/portapack-mayhem/mayhem-firmware.git
synced 2025-02-28 23:47:21 +00:00
Using new CPLD data (fixes spectrum mirroring)
Scanner bugfix for wide ranges Added squelch parameter for NFM receiver Adjustment to Vumeter widget rendering
This commit is contained in:
parent
042d271a9f
commit
e2f0a03460
@ -28,7 +28,7 @@ set(CHIBIOS_PORTAPACK ${PROJECT_SOURCE_DIR}/chibios-portapack)
|
|||||||
set(HACKRF_FIRMWARE_FILENAME hackrf_one_usb.dfu)
|
set(HACKRF_FIRMWARE_FILENAME hackrf_one_usb.dfu)
|
||||||
set(HACKRF_FIRMWARE_IMAGE ${PROJECT_SOURCE_DIR}/${HACKRF_FIRMWARE_FILENAME})
|
set(HACKRF_FIRMWARE_IMAGE ${PROJECT_SOURCE_DIR}/${HACKRF_FIRMWARE_FILENAME})
|
||||||
|
|
||||||
set(HACKRF_CPLD_SVF_FILENAME hackrf_cpld_default.svf)
|
set(HACKRF_CPLD_SVF_FILENAME hackrf_cpld_portapack.svf)
|
||||||
set(HACKRF_CPLD_SVF_PATH ${PROJECT_SOURCE_DIR}/${HACKRF_CPLD_SVF_FILENAME})
|
set(HACKRF_CPLD_SVF_PATH ${PROJECT_SOURCE_DIR}/${HACKRF_CPLD_SVF_FILENAME})
|
||||||
|
|
||||||
set(EXTRACT_CPLD_DATA ${PROJECT_SOURCE_DIR}/tools/extract_cpld_data.py)
|
set(EXTRACT_CPLD_DATA ${PROJECT_SOURCE_DIR}/tools/extract_cpld_data.py)
|
||||||
|
@ -66,12 +66,19 @@ NBFMOptionsView::NBFMOptionsView(
|
|||||||
add_children({
|
add_children({
|
||||||
&label_config,
|
&label_config,
|
||||||
&options_config,
|
&options_config,
|
||||||
|
&text_squelch,
|
||||||
|
&field_squelch
|
||||||
});
|
});
|
||||||
|
|
||||||
options_config.set_selected_index(receiver_model.nbfm_configuration());
|
options_config.set_selected_index(receiver_model.nbfm_configuration());
|
||||||
options_config.on_change = [this](size_t n, OptionsField::value_t) {
|
options_config.on_change = [this](size_t n, OptionsField::value_t) {
|
||||||
receiver_model.set_nbfm_configuration(n);
|
receiver_model.set_nbfm_configuration(n);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
field_squelch.set_value(receiver_model.squelch_level());
|
||||||
|
field_squelch.on_change = [this](int32_t v) {
|
||||||
|
receiver_model.set_squelch_level(v);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/* AnalogAudioView *******************************************************/
|
/* AnalogAudioView *******************************************************/
|
||||||
|
@ -78,6 +78,19 @@ private:
|
|||||||
{ "16k ", 0 },
|
{ "16k ", 0 },
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Text text_squelch {
|
||||||
|
{ 9 * 8, 0 * 16, 7 * 8, 1 * 16 },
|
||||||
|
"SQ /100"
|
||||||
|
};
|
||||||
|
|
||||||
|
NumberField field_squelch {
|
||||||
|
{ 12 * 8, 0 * 16 },
|
||||||
|
3,
|
||||||
|
{ 0, 100 },
|
||||||
|
1,
|
||||||
|
' ',
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
class AnalogAudioView : public View {
|
class AnalogAudioView : public View {
|
||||||
|
@ -52,7 +52,7 @@ void AMConfig::apply() const {
|
|||||||
audio::set_rate(audio::Rate::Hz_12000);
|
audio::set_rate(audio::Rate::Hz_12000);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NBFMConfig::apply() const {
|
void NBFMConfig::apply(const uint8_t squelch_level) const {
|
||||||
const NBFMConfigureMessage message {
|
const NBFMConfigureMessage message {
|
||||||
decim_0,
|
decim_0,
|
||||||
decim_1,
|
decim_1,
|
||||||
@ -60,7 +60,8 @@ void NBFMConfig::apply() const {
|
|||||||
2,
|
2,
|
||||||
deviation,
|
deviation,
|
||||||
audio_24k_hpf_300hz_config,
|
audio_24k_hpf_300hz_config,
|
||||||
audio_24k_deemph_300_6_config
|
audio_24k_deemph_300_6_config,
|
||||||
|
squelch_level
|
||||||
};
|
};
|
||||||
send_message(&message);
|
send_message(&message);
|
||||||
audio::set_rate(audio::Rate::Hz_24000);
|
audio::set_rate(audio::Rate::Hz_24000);
|
||||||
|
@ -48,7 +48,7 @@ struct NBFMConfig {
|
|||||||
const fir_taps_real<32> channel;
|
const fir_taps_real<32> channel;
|
||||||
const size_t deviation;
|
const size_t deviation;
|
||||||
|
|
||||||
void apply() const;
|
void apply(const uint8_t squelch_level) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct WFMConfig {
|
struct WFMConfig {
|
||||||
|
@ -153,6 +153,15 @@ void ReceiverModel::set_headphone_volume(volume_t v) {
|
|||||||
update_headphone_volume();
|
update_headphone_volume();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t ReceiverModel::squelch_level() const {
|
||||||
|
return squelch_level_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReceiverModel::set_squelch_level(uint8_t v) {
|
||||||
|
squelch_level_ = v;
|
||||||
|
update_modulation();
|
||||||
|
}
|
||||||
|
|
||||||
void ReceiverModel::enable() {
|
void ReceiverModel::enable() {
|
||||||
enabled_ = true;
|
enabled_ = true;
|
||||||
radio::set_direction(rf::Direction::Receive);
|
radio::set_direction(rf::Direction::Receive);
|
||||||
@ -286,7 +295,7 @@ size_t ReceiverModel::nbfm_configuration() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ReceiverModel::update_nbfm_configuration() {
|
void ReceiverModel::update_nbfm_configuration() {
|
||||||
nbfm_configs[nbfm_config_index].apply();
|
nbfm_configs[nbfm_config_index].apply(squelch_level_);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t ReceiverModel::wfm_configuration() const {
|
size_t ReceiverModel::wfm_configuration() const {
|
||||||
|
@ -72,6 +72,9 @@ public:
|
|||||||
volume_t headphone_volume() const;
|
volume_t headphone_volume() const;
|
||||||
void set_headphone_volume(volume_t v);
|
void set_headphone_volume(volume_t v);
|
||||||
|
|
||||||
|
uint8_t squelch_level() const;
|
||||||
|
void set_squelch_level(uint8_t v);
|
||||||
|
|
||||||
void enable();
|
void enable();
|
||||||
void disable();
|
void disable();
|
||||||
|
|
||||||
@ -99,6 +102,7 @@ private:
|
|||||||
size_t nbfm_config_index = 0;
|
size_t nbfm_config_index = 0;
|
||||||
size_t wfm_config_index = 0;
|
size_t wfm_config_index = 0;
|
||||||
volume_t headphone_volume_ { -43.0_dB };
|
volume_t headphone_volume_ { -43.0_dB };
|
||||||
|
uint8_t squelch_level_ { 80 };
|
||||||
|
|
||||||
int32_t tuning_offset();
|
int32_t tuning_offset();
|
||||||
|
|
||||||
|
@ -66,6 +66,14 @@ void ScannerView::do_detection() {
|
|||||||
rtc::RTC datetime;
|
rtc::RTC datetime;
|
||||||
std::string str_approx, str_timestamp;
|
std::string str_approx, str_timestamp;
|
||||||
|
|
||||||
|
// Display spectrum
|
||||||
|
bin_skip_acc = 0;
|
||||||
|
pixel_index = 0;
|
||||||
|
display.draw_pixels(
|
||||||
|
{ { 0, 88 }, { (Dim)spectrum_row.size(), 1 } },
|
||||||
|
spectrum_row
|
||||||
|
);
|
||||||
|
|
||||||
mean_power = mean_acc / (SCAN_BIN_NB_NO_DC * slices_nb);
|
mean_power = mean_acc / (SCAN_BIN_NB_NO_DC * slices_nb);
|
||||||
mean_acc = 0;
|
mean_acc = 0;
|
||||||
|
|
||||||
@ -79,8 +87,8 @@ void ScannerView::do_detection() {
|
|||||||
|
|
||||||
if ((power >= mean_power + power_threshold) && (power > power_max)) {
|
if ((power >= mean_power + power_threshold) && (power > power_max)) {
|
||||||
power_max = power;
|
power_max = power;
|
||||||
bin_max_pixel = slices[slice].max_index;
|
bin_max = slices[slice].max_index + (slice * SCAN_BIN_NB);
|
||||||
bin_max = bin_max_pixel + (slice * SCAN_BIN_NB);
|
bin_max_pixel = bin_max / slices_nb;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -157,63 +165,65 @@ void ScannerView::do_detection() {
|
|||||||
scan_counter++;
|
scan_counter++;
|
||||||
|
|
||||||
// Refresh red tick
|
// Refresh red tick
|
||||||
portapack::display.fill_rectangle({last_pos, 90, 1, 6}, Color::black());
|
portapack::display.fill_rectangle({last_tick_pos, 90, 1, 6}, Color::black());
|
||||||
if (bin_max > -1) {
|
if (bin_max > -1) {
|
||||||
if (bin_max_pixel < 120)
|
//if (bin_max_pixel < 120)
|
||||||
bin_max_pixel += 2;
|
// bin_max_pixel += 2;
|
||||||
//else
|
//else
|
||||||
// bin_max_pixel -= 0;
|
// bin_max_pixel -= 0;
|
||||||
last_pos = (ui::Coord)bin_max_pixel;
|
last_tick_pos = (Coord)bin_max_pixel;
|
||||||
portapack::display.fill_rectangle({last_pos, 90, 1, 6}, Color::red());
|
portapack::display.fill_rectangle({last_tick_pos, 90, 1, 6}, Color::red());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ScannerView::add_spectrum_pixel(Color color) {
|
||||||
|
// Is avoiding floats really needed ?
|
||||||
|
bin_skip_acc += bin_skip_frac;
|
||||||
|
if (bin_skip_acc < 0x10000)
|
||||||
|
return;
|
||||||
|
|
||||||
|
bin_skip_acc -= 0x10000;
|
||||||
|
|
||||||
|
if (pixel_index < 240)
|
||||||
|
spectrum_row[pixel_index++] = color;
|
||||||
|
}
|
||||||
|
|
||||||
void ScannerView::on_channel_spectrum(const ChannelSpectrum& spectrum) {
|
void ScannerView::on_channel_spectrum(const ChannelSpectrum& spectrum) {
|
||||||
uint8_t power_max = 0;
|
uint8_t max_power = 0;
|
||||||
int16_t bin_max = 0;
|
int16_t max_bin = 0;
|
||||||
uint8_t power;
|
uint8_t power;
|
||||||
size_t bin;
|
size_t bin;
|
||||||
std::array<Color, 240> pixel_row;
|
|
||||||
|
|
||||||
baseband::spectrum_streaming_stop();
|
baseband::spectrum_streaming_stop();
|
||||||
|
|
||||||
// Draw spectrum line
|
// Add pixels to spectrum row, and find max power for this slice
|
||||||
|
// Leftmost and rightmost 2 bins are ignored
|
||||||
|
// Center 12 bins are ignored
|
||||||
|
// 256-2-2-12 = 240 bins used
|
||||||
for (bin = 0; bin < 120; bin++) {
|
for (bin = 0; bin < 120; bin++) {
|
||||||
const auto pixel_color = spectrum_rgb3_lut[spectrum.db[134 + bin]]; // 134~253 in 0~119
|
add_spectrum_pixel(spectrum_rgb3_lut[spectrum.db[134 + bin]]); // 134~253 goes in 0~119
|
||||||
pixel_row[bin] = pixel_color;
|
|
||||||
}
|
|
||||||
for (bin = 120; bin < 240; bin++) {
|
|
||||||
const auto pixel_color = spectrum_rgb3_lut[spectrum.db[bin - 118]]; // 2~121 in 120~239
|
|
||||||
pixel_row[bin] = pixel_color;
|
|
||||||
}
|
|
||||||
display.draw_pixels(
|
|
||||||
{ { 0, 88 + slice_counter * 2 }, { pixel_row.size(), 1 } },
|
|
||||||
pixel_row
|
|
||||||
);
|
|
||||||
|
|
||||||
// Find max power for this slice
|
|
||||||
for (bin = 0 ; bin < 120; bin++) {
|
|
||||||
power = spectrum.db[134 + bin];
|
power = spectrum.db[134 + bin];
|
||||||
mean_acc += power;
|
mean_acc += power;
|
||||||
if (power > power_max) {
|
if (power > max_power) {
|
||||||
power_max = power;
|
max_power = power;
|
||||||
bin_max = bin - 2;
|
max_bin = bin - 2; // To check
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (bin = 120; bin < 240; bin++) {
|
for (bin = 120; bin < 240; bin++) {
|
||||||
|
add_spectrum_pixel(spectrum_rgb3_lut[spectrum.db[bin - 118]]); // 2~121 goes in 120~239
|
||||||
power = spectrum.db[bin - 118];
|
power = spectrum.db[bin - 118];
|
||||||
mean_acc += power;
|
mean_acc += power;
|
||||||
if (power > power_max) {
|
if (power > max_power) {
|
||||||
power_max = power;
|
max_power = power;
|
||||||
bin_max = bin + 2;
|
max_bin = bin + 2; // To check
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
slices[slice_counter].max_power = power_max;
|
slices[slice_counter].max_power = max_power;
|
||||||
slices[slice_counter].max_index = bin_max;
|
slices[slice_counter].max_index = max_bin;
|
||||||
|
|
||||||
// Slice update
|
|
||||||
if (slices_nb > 1) {
|
if (slices_nb > 1) {
|
||||||
|
// Slice sequence
|
||||||
slice_counter++;
|
slice_counter++;
|
||||||
if (slice_counter >= slices_nb) {
|
if (slice_counter >= slices_nb) {
|
||||||
do_detection();
|
do_detection();
|
||||||
@ -221,6 +231,7 @@ void ScannerView::on_channel_spectrum(const ChannelSpectrum& spectrum) {
|
|||||||
}
|
}
|
||||||
receiver_model.set_tuning_frequency(slices[slice_counter].center_frequency);
|
receiver_model.set_tuning_frequency(slices[slice_counter].center_frequency);
|
||||||
} else {
|
} else {
|
||||||
|
// Unique slice
|
||||||
do_detection();
|
do_detection();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -273,6 +284,8 @@ void ScannerView::on_range_changed() {
|
|||||||
text_slices.set(" 1");
|
text_slices.set(" 1");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bin_skip_frac = 0x10000 / slices_nb;
|
||||||
|
|
||||||
slice_counter = 0;
|
slice_counter = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -353,7 +366,7 @@ ScannerView::ScannerView(
|
|||||||
&recent_entries_view
|
&recent_entries_view
|
||||||
});
|
});
|
||||||
|
|
||||||
baseband::set_spectrum(SCAN_SLICE_WIDTH, 32);
|
baseband::set_spectrum(SCAN_SLICE_WIDTH, 31);
|
||||||
|
|
||||||
recent_entries_view.set_parent_rect({ 0, 28 * 8, 240, 12 * 8 });
|
recent_entries_view.set_parent_rect({ 0, 28 * 8, 240, 12 * 8 });
|
||||||
recent_entries_view.on_select = [this, &nav](const ScannerRecentEntry& entry) {
|
recent_entries_view.on_select = [this, &nav](const ScannerRecentEntry& entry) {
|
||||||
|
@ -112,6 +112,9 @@ private:
|
|||||||
int16_t index;
|
int16_t index;
|
||||||
} slices[32];
|
} slices[32];
|
||||||
|
|
||||||
|
uint32_t bin_skip_acc { 0 }, bin_skip_frac { };
|
||||||
|
uint32_t pixel_index { 0 };
|
||||||
|
std::array<Color, 240> spectrum_row { 0 };
|
||||||
ChannelSpectrumFIFO* fifo { nullptr };
|
ChannelSpectrumFIFO* fifo { nullptr };
|
||||||
rf::Frequency f_min { 0 }, f_max { 0 };
|
rf::Frequency f_min { 0 }, f_max { 0 };
|
||||||
uint8_t detect_timer { 0 }, release_timer { 0 }, timing_div { 0 };
|
uint8_t detect_timer { 0 }, release_timer { 0 }, timing_div { 0 };
|
||||||
@ -123,7 +126,7 @@ private:
|
|||||||
uint8_t slices_nb { 0 };
|
uint8_t slices_nb { 0 };
|
||||||
uint8_t slice_counter { 0 };
|
uint8_t slice_counter { 0 };
|
||||||
int16_t last_bin { 0 };
|
int16_t last_bin { 0 };
|
||||||
Coord last_pos { 0 };
|
Coord last_tick_pos { 0 };
|
||||||
rf::Frequency scan_span { 0 }, resolved_frequency { 0 };
|
rf::Frequency scan_span { 0 }, resolved_frequency { 0 };
|
||||||
uint16_t locked_bin { 0 };
|
uint16_t locked_bin { 0 };
|
||||||
uint8_t scan_counter { 0 };
|
uint8_t scan_counter { 0 };
|
||||||
@ -135,6 +138,7 @@ private:
|
|||||||
void on_lna_changed(int32_t v_db);
|
void on_lna_changed(int32_t v_db);
|
||||||
void on_vga_changed(int32_t v_db);
|
void on_vga_changed(int32_t v_db);
|
||||||
void do_timers();
|
void do_timers();
|
||||||
|
void add_spectrum_pixel(Color color);
|
||||||
|
|
||||||
const RecentEntriesColumns columns { {
|
const RecentEntriesColumns columns { {
|
||||||
{ "Frequency", 9 },
|
{ "Frequency", 9 },
|
||||||
@ -149,7 +153,7 @@ private:
|
|||||||
{ { 1 * 8, 4 * 8 }, "Trig: /255 Mean: /255", Color::light_grey() },
|
{ { 1 * 8, 4 * 8 }, "Trig: /255 Mean: /255", Color::light_grey() },
|
||||||
{ { 1 * 8, 6 * 8 }, "Slices: /32 Rate: Hz", Color::light_grey() },
|
{ { 1 * 8, 6 * 8 }, "Slices: /32 Rate: Hz", Color::light_grey() },
|
||||||
{ { 6 * 8, 10 * 8 }, "Timer Status", Color::light_grey() },
|
{ { 6 * 8, 10 * 8 }, "Timer Status", Color::light_grey() },
|
||||||
{ { 1 * 8, 25 * 8 }, "Accuracy: +/-4.9kHz", Color::light_grey() },
|
{ { 1 * 8, 25 * 8 }, "Accuracy +/-4.9kHz", Color::light_grey() },
|
||||||
{ { 26 * 8, 25 * 8 }, "MHz", Color::light_grey() }
|
{ { 26 * 8, 25 * 8 }, "MHz", Color::light_grey() }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -188,12 +192,12 @@ private:
|
|||||||
|
|
||||||
VuMeter vu_max {
|
VuMeter vu_max {
|
||||||
{ 1 * 8, 11 * 8 - 4, 3 * 8, 48 },
|
{ 1 * 8, 11 * 8 - 4, 3 * 8, 48 },
|
||||||
16,
|
18,
|
||||||
false
|
false
|
||||||
};
|
};
|
||||||
|
|
||||||
ProgressBar progress_timers {
|
ProgressBar progress_timers {
|
||||||
{ 6 * 8, 12 * 8, 5 * 8, 16 }
|
{ 6 * 8, 12 * 8, 6 * 8, 16 }
|
||||||
};
|
};
|
||||||
Text text_infos {
|
Text text_infos {
|
||||||
{ 13 * 8, 12 * 8, 15 * 8, 16 },
|
{ 13 * 8, 12 * 8, 15 * 8, 16 },
|
||||||
@ -203,11 +207,11 @@ private:
|
|||||||
Checkbox check_snap {
|
Checkbox check_snap {
|
||||||
{ 6 * 8, 15 * 8 },
|
{ 6 * 8, 15 * 8 },
|
||||||
7,
|
7,
|
||||||
"Adjust:",
|
"Snap to:",
|
||||||
true
|
true
|
||||||
};
|
};
|
||||||
OptionsField options_snap {
|
OptionsField options_snap {
|
||||||
{ 15 * 8, 15 * 8 },
|
{ 17 * 8, 15 * 8 },
|
||||||
7,
|
7,
|
||||||
{
|
{
|
||||||
{ "25kHz ", 25000 },
|
{ "25kHz ", 25000 },
|
||||||
|
@ -112,8 +112,7 @@ void NarrowbandFMAudio::configure(const NBFMConfigureMessage& message) {
|
|||||||
channel_filter_pass_f = message.channel_filter.pass_frequency_normalized * channel_filter_input_fs;
|
channel_filter_pass_f = message.channel_filter.pass_frequency_normalized * channel_filter_input_fs;
|
||||||
channel_filter_stop_f = message.channel_filter.stop_frequency_normalized * channel_filter_input_fs;
|
channel_filter_stop_f = message.channel_filter.stop_frequency_normalized * channel_filter_input_fs;
|
||||||
channel_spectrum.set_decimation_factor(std::floor(channel_filter_output_fs / (channel_filter_pass_f + channel_filter_stop_f)));
|
channel_spectrum.set_decimation_factor(std::floor(channel_filter_output_fs / (channel_filter_pass_f + channel_filter_stop_f)));
|
||||||
// TODO: Configurable squelch threshold
|
audio_output.configure(message.audio_hpf_config, message.audio_deemph_config, (float)message.squelch_level / 100.0);
|
||||||
audio_output.configure(message.audio_hpf_config, message.audio_deemph_config, 0.8f);
|
|
||||||
|
|
||||||
synth_acc = 0;
|
synth_acc = 0;
|
||||||
|
|
||||||
|
@ -23,8 +23,6 @@
|
|||||||
|
|
||||||
#include "event_m4.hpp"
|
#include "event_m4.hpp"
|
||||||
|
|
||||||
#include "dsp_fft.hpp"
|
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
|
||||||
|
@ -356,7 +356,8 @@ public:
|
|||||||
const size_t channel_decimation,
|
const size_t channel_decimation,
|
||||||
const size_t deviation,
|
const size_t deviation,
|
||||||
const iir_biquad_config_t audio_hpf_config,
|
const iir_biquad_config_t audio_hpf_config,
|
||||||
const iir_biquad_config_t audio_deemph_config
|
const iir_biquad_config_t audio_deemph_config,
|
||||||
|
const uint8_t squelch_level
|
||||||
) : Message { ID::NBFMConfigure },
|
) : Message { ID::NBFMConfigure },
|
||||||
decim_0_filter(decim_0_filter),
|
decim_0_filter(decim_0_filter),
|
||||||
decim_1_filter(decim_1_filter),
|
decim_1_filter(decim_1_filter),
|
||||||
@ -364,7 +365,8 @@ public:
|
|||||||
channel_decimation { channel_decimation },
|
channel_decimation { channel_decimation },
|
||||||
deviation { deviation },
|
deviation { deviation },
|
||||||
audio_hpf_config(audio_hpf_config),
|
audio_hpf_config(audio_hpf_config),
|
||||||
audio_deemph_config(audio_deemph_config)
|
audio_deemph_config(audio_deemph_config),
|
||||||
|
squelch_level(squelch_level)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -375,6 +377,7 @@ public:
|
|||||||
const size_t deviation;
|
const size_t deviation;
|
||||||
const iir_biquad_config_t audio_hpf_config;
|
const iir_biquad_config_t audio_hpf_config;
|
||||||
const iir_biquad_config_t audio_deemph_config;
|
const iir_biquad_config_t audio_deemph_config;
|
||||||
|
const uint8_t squelch_level;
|
||||||
};
|
};
|
||||||
|
|
||||||
class WFMConfigureMessage : public Message {
|
class WFMConfigureMessage : public Message {
|
||||||
|
@ -1461,7 +1461,7 @@ VuMeter::VuMeter(
|
|||||||
show_max_ { show_max }
|
show_max_ { show_max }
|
||||||
{
|
{
|
||||||
//set_focusable(false);
|
//set_focusable(false);
|
||||||
LED_height = parent_rect.size().height() / LEDs;
|
LED_height = std::max(1UL, parent_rect.size().height() / LEDs);
|
||||||
split = 256 / LEDs;
|
split = 256 / LEDs;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1507,7 +1507,7 @@ void VuMeter::paint(Painter& painter) {
|
|||||||
else
|
else
|
||||||
color = lit ? Color::green() : Color::dark_green();
|
color = lit ? Color::green() : Color::dark_green();
|
||||||
|
|
||||||
painter.fill_rectangle({ pos.x(), pos.y() + (Coord)(bar * LED_height), width, (Coord)LED_height - 2 }, color);
|
painter.fill_rectangle({ pos.x(), pos.y() + (Coord)(bar * (LED_height + 1)), width, (Coord)LED_height }, color);
|
||||||
}
|
}
|
||||||
prev_value = value_;
|
prev_value = value_;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user