mirror of
https://github.com/eried/portapack-mayhem.git
synced 2024-12-24 14:59:24 -05:00
Added PWM RSSI output for NBFM and WFM
This commit is contained in:
parent
1beac3bdbd
commit
1d697d2201
@ -100,6 +100,15 @@ void set_afsk_data(const char message_data[], const uint32_t afsk_samples_per_bi
|
||||
send_message(&message);
|
||||
}
|
||||
|
||||
void set_pwmrssi(int32_t avg, bool enabled) {
|
||||
const PWMRSSIConfigureMessage message {
|
||||
enabled,
|
||||
1000, // 1kHz
|
||||
avg
|
||||
};
|
||||
send_message(&message);
|
||||
}
|
||||
|
||||
static bool baseband_image_running = false;
|
||||
|
||||
void run_image(const portapack::spi_flash::image_tag_t image_tag) {
|
||||
|
@ -53,6 +53,7 @@ struct WFMConfig {
|
||||
};
|
||||
|
||||
void set_xylos_data(const char ccir_message[]);
|
||||
void set_pwmrssi(int32_t avg, bool enabled);
|
||||
void set_afsk_data(const char message_data[], const uint32_t afsk_samples_per_bit, const uint32_t afsk_phase_inc_mark,
|
||||
const uint32_t afsk_phase_inc_space, const uint8_t afsk_repeat, const uint32_t afsk_bw,
|
||||
const bool afsk_alt_format);
|
||||
|
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc.
|
||||
* Copyright (C) 2016 Furrtek
|
||||
*
|
||||
* This file is part of PortaPack.
|
||||
*
|
||||
@ -26,6 +27,48 @@
|
||||
|
||||
namespace ui {
|
||||
|
||||
/*
|
||||
00000000 00000000 00000000
|
||||
11110001 11100111 10111110
|
||||
10001010 00001000 00001000
|
||||
10001010 00001000 00001000
|
||||
11110001 11000111 00001000
|
||||
10010000 00100000 10001000
|
||||
10001000 00100000 10001000
|
||||
10001011 11001111 00111110
|
||||
00000000 00000000 00000000
|
||||
11111100 01111000 01111000
|
||||
10000100 01001000 01001000
|
||||
10000100 01001000 01001000
|
||||
10000100 01001000 01001000
|
||||
10000100 01001000 01001000
|
||||
10000100 01001000 01001000
|
||||
10000111 11001111 11001110
|
||||
*/
|
||||
|
||||
static constexpr uint8_t bitmap_rssipwm_data[] = {
|
||||
0x00, 0x00, 0x00,
|
||||
0x8F, 0xE7, 0x7D,
|
||||
0x51, 0x10, 0x10,
|
||||
0x51, 0x10, 0x10,
|
||||
0x8F, 0xE3, 0x10,
|
||||
0x09, 0x04, 0x11,
|
||||
0x11, 0x04, 0x11,
|
||||
0xD1, 0xF3, 0x7C,
|
||||
0x00, 0x00, 0x00,
|
||||
0x3F, 0x1E, 0x1E,
|
||||
0x21, 0x12, 0x12,
|
||||
0x21, 0x12, 0x12,
|
||||
0x21, 0x12, 0x12,
|
||||
0x21, 0x12, 0x12,
|
||||
0x21, 0x12, 0x12,
|
||||
0xE1, 0xF3, 0x73
|
||||
};
|
||||
|
||||
static constexpr Bitmap bitmap_rssipwm {
|
||||
{ 24, 16 }, bitmap_rssipwm_data
|
||||
};
|
||||
|
||||
static constexpr uint8_t bitmap_keyboard_data[] = {
|
||||
0x00, 0x00,
|
||||
0x00, 0x00,
|
||||
|
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Jared Boone, ShareBrained Technology, Inc.
|
||||
* Copyright (C) 2016 Furrtek
|
||||
*
|
||||
* This file is part of PortaPack.
|
||||
*
|
||||
|
@ -21,22 +21,12 @@
|
||||
*/
|
||||
|
||||
#include "ui_lcr.hpp"
|
||||
#include "ui_receiver.hpp"
|
||||
#include "ui_afsksetup.hpp"
|
||||
#include "ui_debug.hpp"
|
||||
|
||||
#include "ch.h"
|
||||
|
||||
#include "ff.h"
|
||||
#include "baseband_api.hpp"
|
||||
#include "hackrf_gpio.hpp"
|
||||
#include "portapack.hpp"
|
||||
#include "event_m0.hpp"
|
||||
|
||||
#include "string_format.hpp"
|
||||
|
||||
#include "hackrf_hal.hpp"
|
||||
#include "portapack_shared_memory.hpp"
|
||||
#include "portapack_persistent_memory.hpp"
|
||||
|
||||
#include <cstring>
|
||||
@ -231,6 +221,7 @@ void LCRView::on_txdone(int n) {
|
||||
char str[16];
|
||||
|
||||
if (n > 0) {
|
||||
// Repeating...
|
||||
repeat_index = n + 1;
|
||||
if (tx_mode == SCAN) {
|
||||
scan_progress++;
|
||||
@ -239,9 +230,11 @@ void LCRView::on_txdone(int n) {
|
||||
update_progress();
|
||||
}
|
||||
} else {
|
||||
// Done transmitting
|
||||
if ((tx_mode == SCAN) && (scan_index < (LCR_SCAN_COUNT - 1))) {
|
||||
transmitter_model.disable();
|
||||
if (abort_scan) {
|
||||
// Kill scan process
|
||||
strcpy(str, "Abort @");
|
||||
strcat(str, rgsb);
|
||||
text_status.set(str);
|
||||
@ -415,16 +408,17 @@ LCRView::LCRView(NavigationView& nav) {
|
||||
};
|
||||
|
||||
button_clear.on_select = [this, &nav](Button&) {
|
||||
uint8_t n;
|
||||
|
||||
if (tx_mode == IDLE) {
|
||||
memset(litteral, 0, 5 * 8);
|
||||
options_ec.set_selected_index(0);
|
||||
checkbox_am_a.set_value(true);
|
||||
checkbox_am_b.set_value(true);
|
||||
checkbox_am_c.set_value(true);
|
||||
checkbox_am_d.set_value(true);
|
||||
checkbox_am_e.set_value(true);
|
||||
options_ec.set_selected_index(0); // Auto
|
||||
for (n = 0; n < 5; n++)
|
||||
checkboxes[n].set_value(true);
|
||||
set_dirty();
|
||||
start_tx(false);
|
||||
} else if (tx_mode == SCAN) {
|
||||
abort_scan = true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -22,16 +22,8 @@
|
||||
|
||||
#include "ui.hpp"
|
||||
#include "ui_widget.hpp"
|
||||
#include "ui_painter.hpp"
|
||||
#include "ui_menu.hpp"
|
||||
#include "ui_navigation.hpp"
|
||||
#include "ui_textentry.hpp"
|
||||
#include "ui_font_fixed_8x16.hpp"
|
||||
#include "clock_manager.hpp"
|
||||
#include "message.hpp"
|
||||
#include "rf_path.hpp"
|
||||
#include "max2837.hpp"
|
||||
#include "volume.hpp"
|
||||
#include "transmitter_model.hpp"
|
||||
|
||||
namespace ui {
|
||||
@ -149,36 +141,6 @@ private:
|
||||
"TX setup"
|
||||
};
|
||||
|
||||
Checkbox checkbox_am_a {
|
||||
{ 16, 64 },
|
||||
0,
|
||||
""
|
||||
};
|
||||
|
||||
Checkbox checkbox_am_b {
|
||||
{ 16, 96 },
|
||||
0,
|
||||
""
|
||||
};
|
||||
|
||||
Checkbox checkbox_am_c {
|
||||
{ 16, 128 },
|
||||
0,
|
||||
""
|
||||
};
|
||||
|
||||
Checkbox checkbox_am_d {
|
||||
{ 16, 160 },
|
||||
0,
|
||||
""
|
||||
};
|
||||
|
||||
Checkbox checkbox_am_e {
|
||||
{ 16, 192 },
|
||||
0,
|
||||
""
|
||||
};
|
||||
|
||||
Button button_lcrdebug {
|
||||
{ 168, 216, 56, 24 },
|
||||
"DEBUG"
|
||||
|
@ -238,14 +238,15 @@ ReceiverMenuView::ReceiverMenuView(NavigationView& nav) {
|
||||
/* SystemMenuView ********************************************************/
|
||||
|
||||
SystemMenuView::SystemMenuView(NavigationView& nav) {
|
||||
add_items<12>({ {
|
||||
add_items<11>({ {
|
||||
{ "Play dead", ui::Color::red(), [&nav](){ nav.push<PlayDeadView>(false); } },
|
||||
{ "Receiver RX", ui::Color::cyan(), [&nav](){ nav.push<ReceiverMenuView>(); } },
|
||||
{ "Capture RX", ui::Color::orange(), [&nav](){ nav.push<CaptureAppView>(); } },
|
||||
{ "Close Call RX", ui::Color::cyan(), [&nav](){ nav.push<CloseCallView>(); } },
|
||||
{ "Pokemon GO Away TX", ui::Color::blue(), [&nav](){ nav.push<JammerView>(); } },
|
||||
//{ "Pokemon GO Away TX", ui::Color::blue(), [&nav](){ nav.push<JammerView>(); } },
|
||||
//{ "Soundboard TX", ui::Color::yellow(), [&nav](){ nav.push<LoadModuleView>(md5_baseband_tx, SoundBoard); } },
|
||||
//{ "Audio TX", ui::Color::yellow(), [&nav](){ nav.push<LoadModuleView>(md5_baseband_tx, AudioTX); } },
|
||||
{ "Frequency manager", ui::Color::white(), [&nav](){ nav.push<FreqManView>(); } },
|
||||
//{ "Frequency manager", ui::Color::white(), [&nav](){ nav.push<FreqManView>(); } },
|
||||
//{ "EPAR TX", ui::Color::green(), [&nav](){ nav.push<LoadModuleView>(md5_baseband_tx, EPAR); } },
|
||||
{ "Xylos TX", ui::Color::green(), [&nav](){ nav.push<XylosView>(); } },
|
||||
{ "TEDI/LCR TX", ui::Color::orange(), [&nav](){ nav.push<LCRView>(); } },
|
||||
|
@ -22,6 +22,8 @@
|
||||
#include "ui_record_view.hpp"
|
||||
|
||||
#include "portapack.hpp"
|
||||
#include "message.hpp"
|
||||
#include "portapack_shared_memory.hpp"
|
||||
using namespace portapack;
|
||||
|
||||
#include "file.hpp"
|
||||
@ -176,6 +178,7 @@ RecordView::RecordView(
|
||||
{
|
||||
add_children({ {
|
||||
&rect_background,
|
||||
&button_pwmrssi,
|
||||
&button_record,
|
||||
&text_record_filename,
|
||||
&text_record_dropped,
|
||||
@ -183,6 +186,10 @@ RecordView::RecordView(
|
||||
} });
|
||||
|
||||
rect_background.set_parent_rect({ { 0, 0 }, size() });
|
||||
|
||||
button_pwmrssi.on_select = [this](ImageButton&) {
|
||||
this->toggle_pwmrssi();
|
||||
};
|
||||
|
||||
button_record.on_select = [this](ImageButton&) {
|
||||
this->toggle();
|
||||
@ -228,6 +235,24 @@ void RecordView::toggle() {
|
||||
}
|
||||
}
|
||||
|
||||
void RecordView::toggle_pwmrssi() {
|
||||
pwmrssi_enabled = !pwmrssi_enabled;
|
||||
|
||||
// Send to RSSI widget
|
||||
const PWMRSSIConfigureMessage message {
|
||||
pwmrssi_enabled,
|
||||
1000,
|
||||
0
|
||||
};
|
||||
shared_memory.application_queue.push(message);
|
||||
|
||||
if( !pwmrssi_enabled ) {
|
||||
button_pwmrssi.set_foreground(Color::orange());
|
||||
} else {
|
||||
button_pwmrssi.set_foreground(Color::green());
|
||||
}
|
||||
}
|
||||
|
||||
void RecordView::start() {
|
||||
stop();
|
||||
|
||||
@ -342,6 +367,10 @@ void RecordView::update_status_display() {
|
||||
const auto s = to_string_dec_uint(dropped_percent, 2, ' ') + "\%";
|
||||
text_record_dropped.set(s);
|
||||
}
|
||||
|
||||
if (pwmrssi_enabled) {
|
||||
button_pwmrssi.invert_colors();
|
||||
}
|
||||
|
||||
if( sampling_rate ) {
|
||||
const auto space_info = std::filesystem::space("");
|
||||
|
@ -64,6 +64,7 @@ public:
|
||||
|
||||
private:
|
||||
void toggle();
|
||||
void toggle_pwmrssi();
|
||||
Optional<File::Error> write_metadata_file(const std::string& filename);
|
||||
|
||||
void on_tick_second();
|
||||
@ -72,6 +73,7 @@ private:
|
||||
void handle_capture_thread_done(const File::Error error);
|
||||
void handle_error(const File::Error error);
|
||||
|
||||
bool pwmrssi_enabled = false;
|
||||
const std::string filename_stem_pattern;
|
||||
const FileType file_type;
|
||||
const size_t write_size;
|
||||
@ -82,16 +84,23 @@ private:
|
||||
Rectangle rect_background {
|
||||
Color::black()
|
||||
};
|
||||
|
||||
ImageButton button_pwmrssi {
|
||||
{ 2, 0 * 16, 3 * 8, 1 * 16 },
|
||||
&bitmap_rssipwm,
|
||||
Color::orange(),
|
||||
Color::black()
|
||||
};
|
||||
|
||||
ImageButton button_record {
|
||||
{ 0 * 8, 0 * 16, 2 * 8, 1 * 16 },
|
||||
{ 4 * 8, 0 * 16, 2 * 8, 1 * 16 },
|
||||
&bitmap_record,
|
||||
Color::red(),
|
||||
Color::black()
|
||||
};
|
||||
|
||||
Text text_record_filename {
|
||||
{ 3 * 8, 0 * 16, 8 * 8, 16 },
|
||||
{ 7 * 8, 0 * 16, 8 * 8, 16 },
|
||||
"",
|
||||
};
|
||||
|
||||
|
@ -21,6 +21,7 @@
|
||||
|
||||
#include "ui_rssi.hpp"
|
||||
|
||||
#include "baseband_api.hpp"
|
||||
#include "utility.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
@ -88,6 +89,17 @@ void RSSI::paint(Painter& painter) {
|
||||
r4,
|
||||
Color::black()
|
||||
);
|
||||
|
||||
if (pwmrssi_enabled) {
|
||||
const range_t<int> pwmrssi_avg_range { 0, 96 };
|
||||
const auto pwmrssi_avg = pwmrssi_avg_range.clip((avg_ - raw_min) * 96 / raw_delta);
|
||||
baseband::set_pwmrssi(pwmrssi_avg, true);
|
||||
}
|
||||
}
|
||||
|
||||
void RSSI::set_pwmrssi(bool enabled) {
|
||||
pwmrssi_enabled = enabled;
|
||||
if (!enabled) baseband::set_pwmrssi(0, false);
|
||||
}
|
||||
|
||||
void RSSI::on_statistics_update(const RSSIStatistics& statistics) {
|
||||
|
@ -46,11 +46,13 @@ public:
|
||||
}
|
||||
|
||||
void paint(Painter& painter) override;
|
||||
|
||||
|
||||
private:
|
||||
int32_t min_;
|
||||
int32_t avg_;
|
||||
int32_t max_;
|
||||
|
||||
bool pwmrssi_enabled = false;
|
||||
|
||||
MessageHandlerRegistration message_handler_stats {
|
||||
Message::ID::RSSIStatistics,
|
||||
@ -58,8 +60,17 @@ private:
|
||||
this->on_statistics_update(static_cast<const RSSIStatisticsMessage*>(p)->statistics);
|
||||
}
|
||||
};
|
||||
|
||||
MessageHandlerRegistration message_handler_pwmrssi {
|
||||
Message::ID::PWMRSSIConfigure,
|
||||
[this](const Message* const p) {
|
||||
const auto message = *reinterpret_cast<const PWMRSSIConfigureMessage*>(p);
|
||||
this->set_pwmrssi(message.enabled);
|
||||
}
|
||||
};
|
||||
|
||||
void on_statistics_update(const RSSIStatistics& statistics);
|
||||
void set_pwmrssi(bool enabled);
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -21,20 +21,11 @@
|
||||
*/
|
||||
|
||||
#include "ui_xylos.hpp"
|
||||
|
||||
#include "ch.h"
|
||||
#include "hackrf_hal.hpp"
|
||||
|
||||
#include "event_m0.hpp"
|
||||
#include "audio.hpp"
|
||||
#include "ui_alphanum.hpp"
|
||||
#include "ff.h"
|
||||
#include "hackrf_gpio.hpp"
|
||||
|
||||
#include "portapack.hpp"
|
||||
#include "baseband_api.hpp"
|
||||
|
||||
#include "hackrf_hal.hpp"
|
||||
#include "portapack_shared_memory.hpp"
|
||||
//#include "audio.hpp"
|
||||
#include "portapack_persistent_memory.hpp"
|
||||
|
||||
#include <cstring>
|
||||
|
@ -22,9 +22,7 @@
|
||||
|
||||
#include "ui.hpp"
|
||||
#include "ui_widget.hpp"
|
||||
#include "ui_painter.hpp"
|
||||
#include "ui_navigation.hpp"
|
||||
#include "ui_menu.hpp"
|
||||
#include "ui_font_fixed_8x16.hpp"
|
||||
|
||||
#include "bulb_on_bmp.hpp"
|
||||
@ -32,8 +30,7 @@
|
||||
#include "bulb_ignore_bmp.hpp"
|
||||
|
||||
#include "message.hpp"
|
||||
#include "max2837.hpp"
|
||||
#include "volume.hpp"
|
||||
//#include "volume.hpp"
|
||||
#include "transmitter_model.hpp"
|
||||
//#include "receiver_model.hpp"
|
||||
#include "portapack.hpp"
|
||||
|
@ -32,7 +32,7 @@ void NarrowbandFMAudio::execute(const buffer_c8_t& buffer) {
|
||||
if( !configured ) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
const auto decim_0_out = decim_0.execute(buffer, dst_buffer);
|
||||
const auto decim_1_out = decim_1.execute(decim_0_out, dst_buffer);
|
||||
const auto channel_out = channel_filter.execute(decim_1_out, dst_buffer);
|
||||
@ -40,8 +40,23 @@ void NarrowbandFMAudio::execute(const buffer_c8_t& buffer) {
|
||||
feed_channel_stats(channel_out);
|
||||
channel_spectrum.feed(channel_out, channel_filter_pass_f, channel_filter_stop_f);
|
||||
|
||||
auto audio = demod.execute(channel_out, audio_buffer);
|
||||
audio_output.write(audio);
|
||||
if ( !pwmrssi_enabled ) {
|
||||
auto audio = demod.execute(channel_out, audio_buffer);
|
||||
audio_output.write(audio);
|
||||
} else {
|
||||
for (c = 0; c < 32; c++) {
|
||||
if (synth_acc < pwmrssi_avg)
|
||||
pwmrssi_audio_buffer.p[c] = 32767;
|
||||
else
|
||||
pwmrssi_audio_buffer.p[c] = -32768;
|
||||
if (synth_acc < 30) // 24kHz / 30 = 800Hz (TODO: use pwmrssi_freq !)
|
||||
synth_acc++;
|
||||
else
|
||||
synth_acc = 0;
|
||||
}
|
||||
|
||||
audio_output.write(pwmrssi_audio_buffer);
|
||||
}
|
||||
}
|
||||
|
||||
void NarrowbandFMAudio::on_message(const Message* const message) {
|
||||
@ -58,6 +73,10 @@ void NarrowbandFMAudio::on_message(const Message* const message) {
|
||||
case Message::ID::CaptureConfig:
|
||||
capture_config(*reinterpret_cast<const CaptureConfigMessage*>(message));
|
||||
break;
|
||||
|
||||
case Message::ID::PWMRSSIConfigure:
|
||||
pwmrssi_config(*reinterpret_cast<const PWMRSSIConfigureMessage*>(message));
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
@ -83,11 +102,19 @@ void NarrowbandFMAudio::configure(const NBFMConfigureMessage& message) {
|
||||
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_spectrum.set_decimation_factor(std::floor(channel_filter_output_fs / (channel_filter_pass_f + channel_filter_stop_f)));
|
||||
audio_output.configure(message.audio_hpf_config, message.audio_deemph_config, 0.8f);
|
||||
audio_output.configure(message.audio_hpf_config, message.audio_deemph_config); // , 0.8f
|
||||
|
||||
synth_acc = 0;
|
||||
|
||||
configured = true;
|
||||
}
|
||||
|
||||
void NarrowbandFMAudio::pwmrssi_config(const PWMRSSIConfigureMessage& message) {
|
||||
pwmrssi_enabled = message.enabled;
|
||||
pwmrssi_freq = message.freq;
|
||||
pwmrssi_avg = message.avg / 3;
|
||||
}
|
||||
|
||||
void NarrowbandFMAudio::capture_config(const CaptureConfigMessage& message) {
|
||||
if( message.config ) {
|
||||
audio_output.set_stream(std::make_unique<StreamInput>(message.config));
|
||||
|
@ -56,6 +56,12 @@ private:
|
||||
audio.data(),
|
||||
audio.size()
|
||||
};
|
||||
|
||||
std::array<int16_t, 32> pwm;
|
||||
const buffer_s16_t pwmrssi_audio_buffer {
|
||||
(int16_t*)pwm.data(),
|
||||
sizeof(pwm) / sizeof(int16_t)
|
||||
};
|
||||
|
||||
dsp::decimate::FIRC8xR16x24FS4Decim8 decim_0;
|
||||
dsp::decimate::FIRC16xR16x32Decim8 decim_1;
|
||||
@ -68,8 +74,14 @@ private:
|
||||
AudioOutput audio_output;
|
||||
|
||||
SpectrumCollector channel_spectrum;
|
||||
|
||||
unsigned int c, synth_acc = 0;
|
||||
bool pwmrssi_enabled = false;
|
||||
uint32_t pwmrssi_freq;
|
||||
uint32_t pwmrssi_avg;
|
||||
|
||||
bool configured { false };
|
||||
void pwmrssi_config(const PWMRSSIConfigureMessage& message);
|
||||
void configure(const NBFMConfigureMessage& message);
|
||||
void capture_config(const CaptureConfigMessage& message);
|
||||
};
|
||||
|
@ -31,7 +31,7 @@ void WidebandFMAudio::execute(const buffer_c8_t& buffer) {
|
||||
if( !configured ) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
const auto decim_0_out = decim_0.execute(buffer, dst_buffer);
|
||||
const auto channel = decim_1.execute(decim_0_out, dst_buffer);
|
||||
|
||||
@ -44,32 +44,49 @@ void WidebandFMAudio::execute(const buffer_c8_t& buffer) {
|
||||
channel_spectrum.feed(channel, channel_filter_pass_f, channel_filter_stop_f);
|
||||
}
|
||||
|
||||
/* 384kHz complex<int16_t>[256]
|
||||
* -> FM demodulation
|
||||
* -> 384kHz int16_t[256] */
|
||||
/* TODO: To improve adjacent channel rejection, implement complex channel filter:
|
||||
* pass < +/- 100kHz, stop > +/- 200kHz
|
||||
*/
|
||||
if ( !pwmrssi_enabled ) {
|
||||
/* 384kHz complex<int16_t>[256]
|
||||
* -> FM demodulation
|
||||
* -> 384kHz int16_t[256] */
|
||||
/* TODO: To improve adjacent channel rejection, implement complex channel filter:
|
||||
* pass < +/- 100kHz, stop > +/- 200kHz
|
||||
*/
|
||||
|
||||
auto audio_oversampled = demod.execute(channel, work_audio_buffer);
|
||||
auto audio_oversampled = demod.execute(channel, work_audio_buffer);
|
||||
|
||||
/* 384kHz int16_t[256]
|
||||
* -> 4th order CIC decimation by 2, gain of 1
|
||||
* -> 192kHz int16_t[128] */
|
||||
auto audio_4fs = audio_dec_1.execute(audio_oversampled, work_audio_buffer);
|
||||
/* 384kHz int16_t[256]
|
||||
* -> 4th order CIC decimation by 2, gain of 1
|
||||
* -> 192kHz int16_t[128] */
|
||||
auto audio_4fs = audio_dec_1.execute(audio_oversampled, work_audio_buffer);
|
||||
|
||||
/* 192kHz int16_t[128]
|
||||
* -> 4th order CIC decimation by 2, gain of 1
|
||||
* -> 96kHz int16_t[64] */
|
||||
auto audio_2fs = audio_dec_2.execute(audio_4fs, work_audio_buffer);
|
||||
/* 192kHz int16_t[128]
|
||||
* -> 4th order CIC decimation by 2, gain of 1
|
||||
* -> 96kHz int16_t[64] */
|
||||
auto audio_2fs = audio_dec_2.execute(audio_4fs, work_audio_buffer);
|
||||
|
||||
/* 96kHz int16_t[64]
|
||||
* -> FIR filter, <15kHz (0.156fs) pass, >19kHz (0.198fs) stop, gain of 1
|
||||
* -> 48kHz int16_t[32] */
|
||||
auto audio = audio_filter.execute(audio_2fs, work_audio_buffer);
|
||||
/* 96kHz int16_t[64]
|
||||
* -> FIR filter, <15kHz (0.156fs) pass, >19kHz (0.198fs) stop, gain of 1
|
||||
* -> 48kHz int16_t[32] */
|
||||
auto audio = audio_filter.execute(audio_2fs, work_audio_buffer);
|
||||
|
||||
/* -> 48kHz int16_t[32] */
|
||||
audio_output.write(audio);
|
||||
} else {
|
||||
for (c = 0; c < 32; c++) {
|
||||
if (synth_acc < pwmrssi_avg)
|
||||
pwmrssi_audio_buffer.p[c] = 32767;
|
||||
else
|
||||
pwmrssi_audio_buffer.p[c] = -32768;
|
||||
if (synth_acc < 96) // 48kHz / 96 = 500Hz (TODO: use pwmrssi_freq !)
|
||||
synth_acc++;
|
||||
else
|
||||
synth_acc = 0;
|
||||
}
|
||||
|
||||
/* -> 48kHz int16_t[32] */
|
||||
audio_output.write(audio);
|
||||
/* -> 48kHz int16_t[32] */
|
||||
audio_output.write(pwmrssi_audio_buffer);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void WidebandFMAudio::on_message(const Message* const message) {
|
||||
@ -86,6 +103,10 @@ void WidebandFMAudio::on_message(const Message* const message) {
|
||||
case Message::ID::CaptureConfig:
|
||||
capture_config(*reinterpret_cast<const CaptureConfigMessage*>(message));
|
||||
break;
|
||||
|
||||
case Message::ID::PWMRSSIConfigure:
|
||||
pwmrssi_config(*reinterpret_cast<const PWMRSSIConfigureMessage*>(message));
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
@ -114,9 +135,18 @@ void WidebandFMAudio::configure(const WFMConfigureMessage& message) {
|
||||
|
||||
channel_spectrum.set_decimation_factor(1);
|
||||
|
||||
pwmrssi_enabled = false;
|
||||
synth_acc = 0;
|
||||
|
||||
configured = true;
|
||||
}
|
||||
|
||||
void WidebandFMAudio::pwmrssi_config(const PWMRSSIConfigureMessage& message) {
|
||||
pwmrssi_enabled = message.enabled;
|
||||
pwmrssi_freq = message.freq;
|
||||
pwmrssi_avg = message.avg;
|
||||
}
|
||||
|
||||
void WidebandFMAudio::capture_config(const CaptureConfigMessage& message) {
|
||||
if( message.config ) {
|
||||
audio_output.set_stream(std::make_unique<StreamInput>(message.config));
|
||||
|
@ -54,6 +54,12 @@ private:
|
||||
(int16_t*)dst.data(),
|
||||
sizeof(dst) / sizeof(int16_t)
|
||||
};
|
||||
|
||||
std::array<int16_t, 32> pwm;
|
||||
const buffer_s16_t pwmrssi_audio_buffer {
|
||||
(int16_t*)pwm.data(),
|
||||
sizeof(pwm) / sizeof(int16_t)
|
||||
};
|
||||
|
||||
dsp::decimate::FIRC8xR16x24FS4Decim4 decim_0;
|
||||
dsp::decimate::FIRC16xR16x16Decim2 decim_1;
|
||||
@ -70,8 +76,14 @@ private:
|
||||
SpectrumCollector channel_spectrum;
|
||||
size_t spectrum_interval_samples = 0;
|
||||
size_t spectrum_samples = 0;
|
||||
|
||||
unsigned int c, synth_acc = 0;
|
||||
bool pwmrssi_enabled = false;
|
||||
uint32_t pwmrssi_freq;
|
||||
uint32_t pwmrssi_avg;
|
||||
|
||||
bool configured { false };
|
||||
void pwmrssi_config(const PWMRSSIConfigureMessage& message);
|
||||
void configure(const WFMConfigureMessage& message);
|
||||
void capture_config(const CaptureConfigMessage& message);
|
||||
};
|
||||
|
@ -21,10 +21,6 @@
|
||||
*/
|
||||
|
||||
#include "proc_xylos.hpp"
|
||||
|
||||
#include "dsp_iir_config.hpp"
|
||||
#include "audio_output.hpp"
|
||||
|
||||
#include "portapack_shared_memory.hpp"
|
||||
#include "sine_table_int8.hpp"
|
||||
#include "event_m4.hpp"
|
||||
|
@ -69,7 +69,7 @@ public:
|
||||
Retune = 21,
|
||||
XylosConfigure = 22,
|
||||
AFSKConfigure = 23,
|
||||
ModuleID = 24,
|
||||
PWMRSSIConfigure = 24,
|
||||
FIFOSignal = 25,
|
||||
FIFOData = 26,
|
||||
MAX
|
||||
@ -479,15 +479,24 @@ public:
|
||||
int n = 0;
|
||||
};
|
||||
|
||||
class ModuleIDMessage : public Message {
|
||||
|
||||
|
||||
class PWMRSSIConfigureMessage : public Message {
|
||||
public:
|
||||
ModuleIDMessage(
|
||||
) : Message { ID::ModuleID }
|
||||
PWMRSSIConfigureMessage(
|
||||
const bool enabled,
|
||||
const uint32_t freq,
|
||||
const int32_t avg
|
||||
) : Message { ID::PWMRSSIConfigure },
|
||||
enabled(enabled),
|
||||
freq(freq),
|
||||
avg(avg)
|
||||
{
|
||||
}
|
||||
|
||||
bool query;
|
||||
char md5_signature[16];
|
||||
const bool enabled;
|
||||
const uint32_t freq;
|
||||
const int32_t avg;
|
||||
};
|
||||
|
||||
class XylosConfigureMessage : public Message {
|
||||
|
@ -369,13 +369,13 @@ void BigFrequency::paint(Painter& painter) {
|
||||
digit_y = rect.pos.y;
|
||||
if (digit < 16) {
|
||||
digit_def = big_segment_font[(uint8_t)digit];
|
||||
if (digit_def & 0x01) painter.fill_rectangle({{digit_x + 4, digit_y}, {20, 4}}, segment_color);
|
||||
if (digit_def & 0x02) painter.fill_rectangle({{digit_x + 24, digit_y + 4}, {4, 20}}, segment_color);
|
||||
if (digit_def & 0x04) painter.fill_rectangle({{digit_x + 24, digit_y + 28}, {4, 20}}, segment_color);
|
||||
if (digit_def & 0x08) painter.fill_rectangle({{digit_x + 4, digit_y + 48}, {20, 4}}, segment_color);
|
||||
if (digit_def & 0x10) painter.fill_rectangle({{digit_x, digit_y + 28}, {4, 20}}, segment_color);
|
||||
if (digit_def & 0x20) painter.fill_rectangle({{digit_x, digit_y + 4}, {4, 20}}, segment_color);
|
||||
if (digit_def & 0x40) painter.fill_rectangle({{digit_x + 4, digit_y + 24}, {20, 4}}, segment_color);
|
||||
if (digit_def & 0x01) painter.fill_rectangle({{digit_x + 4, digit_y}, {20, 4}}, segment_color);
|
||||
if (digit_def & 0x02) painter.fill_rectangle({{digit_x + 24, digit_y + 4}, {4, 20}}, segment_color);
|
||||
if (digit_def & 0x04) painter.fill_rectangle({{digit_x + 24, digit_y + 28}, {4, 20}}, segment_color);
|
||||
if (digit_def & 0x08) painter.fill_rectangle({{digit_x + 4, digit_y + 48}, {20, 4}}, segment_color);
|
||||
if (digit_def & 0x10) painter.fill_rectangle({{digit_x, digit_y + 28}, {4, 20}}, segment_color);
|
||||
if (digit_def & 0x20) painter.fill_rectangle({{digit_x, digit_y + 4}, {4, 20}}, segment_color);
|
||||
if (digit_def & 0x40) painter.fill_rectangle({{digit_x + 4, digit_y + 24}, {20, 4}}, segment_color);
|
||||
}
|
||||
if (i == 3) {
|
||||
// Dot
|
||||
@ -665,6 +665,15 @@ void Image::set_background(const Color color) {
|
||||
set_dirty();
|
||||
}
|
||||
|
||||
void Image::invert_colors() {
|
||||
Color temp;
|
||||
|
||||
temp = background_;
|
||||
background_ = foreground_;
|
||||
foreground_ = temp;
|
||||
set_dirty();
|
||||
}
|
||||
|
||||
void Image::paint(Painter& painter) {
|
||||
if( bitmap_ ) {
|
||||
// Code also handles ImageButton behavior.
|
||||
|
@ -289,6 +289,7 @@ public:
|
||||
void set_bitmap(const Bitmap* bitmap);
|
||||
void set_foreground(const Color color);
|
||||
void set_background(const Color color);
|
||||
void invert_colors();
|
||||
|
||||
void paint(Painter& painter) override;
|
||||
|
||||
|
Binary file not shown.
Loading…
Reference in New Issue
Block a user