Skip to content

Commit

Permalink
Looking glass beep (#2036)
Browse files Browse the repository at this point in the history
* first draft of looking beep
* fixed beep squelch range in percent
* took out steps 
* gui adjustements
* uniformize calculation and beep squelch in db
* uniformisation, fix 24/48 error
  • Loading branch information
gullradriel committed Mar 24, 2024
1 parent 6177b08 commit c078bac
Show file tree
Hide file tree
Showing 6 changed files with 121 additions and 12 deletions.
7 changes: 6 additions & 1 deletion firmware/application/apps/ui_level.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ using portapack::memory::map::backup_ram;

namespace ui {

// Function to map the value from one range to another
int32_t LevelView::map(int32_t value, int32_t fromLow, int32_t fromHigh, int32_t toLow, int32_t toHigh) {
return toLow + (value - fromLow) * (toHigh - toLow) / (fromHigh - fromLow);
}

void LevelView::m4_manage_stat_update() {
if (audio_mode) {
if (radio_mode == WFM_MODULATION || radio_mode == SPEC_MODULATION) {
Expand Down Expand Up @@ -192,7 +197,7 @@ void LevelView::on_statistics_update(const ChannelStatistics& statistics) {
}

if (beep && statistics.max_db > beep_squelch) {
baseband::request_audio_beep(((132 + statistics.max_db) * 2000) / 120, 24000, 250);
baseband::request_audio_beep(map(statistics.max_db, -100, 20, 400, 2600), 24000, 150);
}

// refresh sat
Expand Down
3 changes: 2 additions & 1 deletion firmware/application/apps/ui_level.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ class LevelView : public View {

RxRadioState radio_state_{};

int32_t map(int32_t value, int32_t fromLow, int32_t fromHigh, int32_t toLow, int32_t toHigh);
size_t change_mode(freqman_index_t mod_type);
void on_statistics_update(const ChannelStatistics& statistics);
void set_display_freq(int64_t freq);
Expand Down Expand Up @@ -128,7 +129,7 @@ class LevelView : public View {
NumberField field_beep_squelch{
{25 * 8, 3 * 16 + 4},
4,
{-120, 12},
{-100, 20},
1,
' ',
};
Expand Down
71 changes: 66 additions & 5 deletions firmware/application/apps/ui_looking_glass_app.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include "convert.hpp"
#include "file_reader.hpp"
#include "string_format.hpp"
#include "audio.hpp"

using namespace portapack;

Expand All @@ -34,11 +35,39 @@ void GlassView::focus() {
}

GlassView::~GlassView() {
audio::output::stop();
receiver_model.set_sampling_rate(3072000); // Just a hack to avoid hanging other apps
receiver_model.disable();
baseband::shutdown();
}

// Function to map the value from one range to another
int32_t GlassView::map(int32_t value, int32_t fromLow, int32_t fromHigh, int32_t toLow, int32_t toHigh) {
return toLow + (value - fromLow) * (toHigh - toLow) / (fromHigh - fromLow);
}

void GlassView::update_display_beep() {
if (beep_enabled) {
button_beep_squelch.set_style(&Styles::green);
// <bip:-XXXdb>
button_beep_squelch.set_text("[bip>" + to_string_dec_int(beep_squelch, 4) + "db]");
receiver_model.set_headphone_volume(receiver_model.headphone_volume()); // WM8731 hack.
} else {
button_beep_squelch.set_style(&Styles::white);
button_beep_squelch.set_text("[ beep OFF [");
}
}

void GlassView::manage_beep_audio() {
if (beep_enabled) {
audio::set_rate(audio::Rate::Hz_24000);
audio::output::start();
} else {
baseband::request_beep_stop();
audio::output::stop();
}
}

void GlassView::get_max_power(const ChannelSpectrum& spectrum, uint8_t bin, uint8_t& max_power) {
if (mode == LOOKING_GLASS_SINGLEPASS) {
// <20MHz spectrum mode
Expand Down Expand Up @@ -173,6 +202,8 @@ void GlassView::on_channel_spectrum(const ChannelSpectrum& spectrum) {
// we actually need SCREEN_W (240) of those bins
for (uint8_t bin = 0; bin < bin_length; bin++) {
get_max_power(spectrum, bin, max_power);
if (max_power > range_max_power)
range_max_power = max_power;
// process dc spike if enable
if (bin == 119) {
uint8_t next_max_power = 0;
Expand All @@ -184,14 +215,21 @@ void GlassView::on_channel_spectrum(const ChannelSpectrum& spectrum) {
}
}
// process actual bin
if (process_bins(&max_power) == true)
if (process_bins(&max_power)) {
int8_t power = map(range_max_power, 0, 255, -100, 20);
if (power >= beep_squelch) {
baseband::request_audio_beep(map(range_max_power, 0, 256, 400, 2600), 24000, 250);
}
range_max_power = 0;
return; // new line signaled, return
}
}
if (mode != LOOKING_GLASS_SINGLEPASS) {
f_center += looking_glass_step;
retune();
} else
} else {
baseband::spectrum_streaming_start();
}
}

void GlassView::on_hide() {
Expand Down Expand Up @@ -327,13 +365,15 @@ GlassView::GlassView(
&field_lna,
&field_vga,
&field_range,
&steps_config,
//&steps_config,
&scan_type,
&view_config,
&level_integration,
&field_volume,
&filter_config,
&field_rf_amp,
&range_presets,
&button_beep_squelch,
&field_marker,
&field_trigger,
&button_jump,
Expand Down Expand Up @@ -370,12 +410,12 @@ GlassView::GlassView(
};
};

steps_config.on_change = [this](size_t, OptionsField::value_t v) {
/*steps_config.on_change = [this](size_t, OptionsField::value_t v) {
field_frequency_min.set_step(v);
field_frequency_max.set_step(v);
steps = v;
};
steps_config.set_selected_index(0); // 1 Mhz step.
steps_config.set_selected_index(0); // 1 Mhz step.*/

scan_type.on_change = [this](size_t, OptionsField::value_t v) {
mode = v;
Expand Down Expand Up @@ -497,6 +537,27 @@ GlassView::GlassView(
receiver_model.set_baseband_bandwidth(looking_glass_bandwidth); // possible values: 1.75/2.5/3.5/5/5.5/6/7/8/9/10/12/14/15/20/24/28MHz
receiver_model.set_squelch_level(0);
receiver_model.enable();

button_beep_squelch.on_select = [this](ButtonWithEncoder& button) {
(void)button;
beep_enabled = 1 - beep_enabled;
manage_beep_audio();
update_display_beep();
};

button_beep_squelch.on_change = [this]() {
int new_beep_squelch = beep_squelch + button_beep_squelch.get_encoder_delta();
if (new_beep_squelch < -100)
new_beep_squelch = -100;
if (new_beep_squelch > 20)
new_beep_squelch = 20;
beep_squelch = new_beep_squelch;
button_beep_squelch.set_encoder_delta(0);
update_display_beep();
};

manage_beep_audio();
update_display_beep();
}

uint8_t GlassView::get_spec_iq_phase_calibration_value() { // define accessor functions inside AnalogAudioView to read & write real iq_phase_calibration_value
Expand Down
25 changes: 21 additions & 4 deletions firmware/application/apps/ui_looking_glass_app.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ class GlassView : public View {
uint8_t live_frequency_view = 0; // Spectrum
uint8_t live_frequency_integrate = 3; // Default (3 * old value + new_value) / 4
uint8_t iq_phase_calibration_value{15}; // initial default RX IQ phase calibration value , used for both max2837 & max2839
int32_t beep_squelch = 20; // range from -100 to +20, >=20 disabled
bool beep_enabled = false; // activate on bip button click
app_settings::SettingsManager settings_{
"rx_glass"sv,
app_settings::Mode::RX,
Expand All @@ -98,6 +100,8 @@ class GlassView : public View {
{"freq_view"sv, &live_frequency_view},
{"freq_integrate"sv, &live_frequency_integrate},
{"iq_phase_calibration"sv, &iq_phase_calibration_value}, // we are saving and restoring that CAL from Settings.
{"beep_squelch"sv, &beep_squelch},
{"beep_enabled"sv, &beep_enabled},
}};

struct preset_entry {
Expand All @@ -106,7 +110,10 @@ class GlassView : public View {
std::string label{};
};

int32_t map(int32_t value, int32_t fromLow, int32_t fromHigh, int32_t toLow, int32_t toHigh);
std::vector<preset_entry> presets_db{};
void manage_beep_audio();
void update_display_beep();
void update_min(int32_t v);
void update_max(int32_t v);
void update_range_field();
Expand Down Expand Up @@ -153,6 +160,8 @@ class GlassView : public View {
int32_t steps = 1;
bool locked_range = false;

uint8_t range_max_power = 0;
uint8_t range_max_power_counter = 0;
uint8_t max_power = 0;
rf::Frequency max_freq_hold = 0;
rf::Frequency last_max_freq = 0;
Expand All @@ -166,7 +175,8 @@ class GlassView : public View {
{{0, 1 * 16}, "RANGE: FILTER: AMP:", Color::light_grey()},
{{0, 2 * 16}, "PRESET:", Color::light_grey()},
{{0, 3 * 16}, "MARKER: MHz RXIQCAL", Color::light_grey()},
{{0, 4 * 16}, "RES: STEP:", Color::light_grey()}};
//{{0, 4 * 16}, "RES: STEPS:", Color::light_grey()}};
{{0, 4 * 16}, "RES: VOL:", Color::light_grey()}};

NumberField field_frequency_min{
{4 * 8, 0 * 16},
Expand Down Expand Up @@ -206,9 +216,13 @@ class GlassView : public View {

OptionsField range_presets{
{7 * 8, 2 * 16},
20,
10,
{}};

ButtonWithEncoder button_beep_squelch{
{18 * 8, 2 * 16 + 4, 12 * 8, 1 * 8},
""};

TextField field_marker{
{7 * 8, 3 * 16, 9 * 8, 16},
""};
Expand All @@ -228,7 +242,10 @@ class GlassView : public View {
2,
' '};

OptionsField steps_config{
AudioVolumeField field_volume{
{13 * 8, 4 * 16}};

/*OptionsField steps_config{
{13 * 8, 4 * 16},
3,
{
Expand All @@ -238,7 +255,7 @@ class GlassView : public View {
{"100", 100},
{"250", 250},
{"500", 500},
}};
}};*/

OptionsField scan_type{
{17 * 8, 4 * 16},
Expand Down
24 changes: 23 additions & 1 deletion firmware/baseband/proc_wideband_spectrum.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,30 @@ void WidebandSpectrum::execute(const buffer_c8_t& buffer) {
}
}

void WidebandSpectrum::on_signal_message(const RequestSignalMessage& message) {
if (message.signal == RequestSignalMessage::Signal::BeepStopRequest) {
audio::dma::beep_stop();
}
}

void WidebandSpectrum::on_beep_message(const AudioBeepMessage& message) {
audio::dma::beep_start(message.freq, message.sample_rate, message.duration_ms);
}

void WidebandSpectrum::on_message(const Message* const msg) {
switch (msg->id) {
case Message::ID::RequestSignal:
on_signal_message(*reinterpret_cast<const RequestSignalMessage*>(msg));
return;

case Message::ID::AudioBeep:
on_beep_message(*reinterpret_cast<const AudioBeepMessage*>(msg));
return;

default:
break;
}

const WidebandSpectrumConfigMessage message = *reinterpret_cast<const WidebandSpectrumConfigMessage*>(msg);

switch (msg->id) {
Expand All @@ -84,7 +107,6 @@ void WidebandSpectrum::on_message(const Message* const msg) {

int main() {
audio::dma::init_audio_out(); // for AudioRX app (enables audio output while this baseband image is running)

EventDispatcher event_dispatcher{std::make_unique<WidebandSpectrum>()};
event_dispatcher.run();
return 0;
Expand Down
3 changes: 3 additions & 0 deletions firmware/baseband/proc_wideband_spectrum.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ class WidebandSpectrum : public BasebandProcessor {
bool configured = false;
size_t baseband_fs = 20000000;

void on_beep_message(const AudioBeepMessage& message);
void on_signal_message(const RequestSignalMessage& message);

SpectrumCollector channel_spectrum{};

std::array<complex16_t, 256> spectrum{};
Expand Down

4 comments on commit c078bac

@ImDroided
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This takes up a bunch of the preset display and now you have no way of knowing what you are on for some things. Any chance at making this smaller? or even adding it under RES: VOL: on a new line?

@gullradriel
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello.
You're lucky I saw your comment in the bot reports, I would not have seen it else.
Adding it on a new line is definitely possible, at the cost of reducing the waterfall size.

@gullradriel
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add an enhancement issue so we can keep track :-)

@ImDroided
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add an enhancement issue so we can keep track :-)

I created a issue but I cant add tags to it.

Please sign in to comment.