Added support for multiple sample rates in IQ record

Support for any sample rate <= 500k in IQ replay
Fixed bias-t power not activating in TX
Removed RSSI pitch output option (awful code)
Udated binary
This commit is contained in:
furrtek 2018-02-22 07:04:19 +00:00
parent 57c759627d
commit 7fd987a2b4
23 changed files with 193 additions and 84 deletions

View File

@ -35,6 +35,7 @@ CaptureAppView::CaptureAppView(NavigationView& nav) {
baseband::run_image(portapack::spi_flash::image_tag_capture); baseband::run_image(portapack::spi_flash::image_tag_capture);
add_children({ add_children({
&labels,
&rssi, &rssi,
&channel, &channel,
&field_frequency, &field_frequency,
@ -42,6 +43,7 @@ CaptureAppView::CaptureAppView(NavigationView& nav) {
&field_rf_amp, &field_rf_amp,
&field_lna, &field_lna,
&field_vga, &field_vga,
&option_bandwidth,
&record_view, &record_view,
&waterfall, &waterfall,
}); });
@ -66,6 +68,16 @@ CaptureAppView::CaptureAppView(NavigationView& nav) {
this->field_frequency.set_step(v); this->field_frequency.set_step(v);
}; };
option_bandwidth.on_change = [this](size_t, uint32_t divider) {
sampling_rate = 4000000 / divider;
waterfall.on_hide();
set_target_frequency(target_frequency());
record_view.set_sampling_rate(sampling_rate);
radio::set_baseband_rate(sampling_rate);
waterfall.on_show();
};
radio::enable({ radio::enable({
tuning_frequency(), tuning_frequency(),
sampling_rate, sampling_rate,
@ -76,7 +88,8 @@ CaptureAppView::CaptureAppView(NavigationView& nav) {
static_cast<int8_t>(receiver_model.vga()), static_cast<int8_t>(receiver_model.vga()),
}); });
record_view.set_sampling_rate(sampling_rate / 8); option_bandwidth.set_selected_index(4); // 500k
record_view.on_error = [&nav](std::string message) { record_view.on_error = [&nav](std::string message) {
nav.display_modal("Error", message); nav.display_modal("Error", message);
}; };

View File

@ -47,9 +47,9 @@ public:
std::string title() const override { return "Capture"; }; std::string title() const override { return "Capture"; };
private: private:
static constexpr ui::Dim header_height = 2 * 16; static constexpr ui::Dim header_height = 3 * 16;
static constexpr uint32_t sampling_rate = 4000000; uint32_t sampling_rate = 0;
static constexpr uint32_t baseband_bandwidth = 2500000; static constexpr uint32_t baseband_bandwidth = 2500000;
void on_target_frequency_changed(rf::Frequency f); void on_target_frequency_changed(rf::Frequency f);
@ -59,6 +59,10 @@ private:
rf::Frequency tuning_frequency() const; rf::Frequency tuning_frequency() const;
Labels labels {
{ { 0 * 8, 1 * 16 }, "Rate:", Color::light_grey() },
};
RSSI rssi { RSSI rssi {
{ 24 * 8, 0, 6 * 8, 4 }, { 24 * 8, 0, 6 * 8, 4 },
}; };
@ -87,8 +91,20 @@ private:
{ 21 * 8, 0 * 16 } { 21 * 8, 0 * 16 }
}; };
OptionsField option_bandwidth {
{ 5 * 8, 1 * 16 },
4,
{
{ " 25k", 20 },
{ " 50k", 10 },
{ "100k", 5 },
{ "250k", 2 },
{ "500k", 1 }
}
};
RecordView record_view { RecordView record_view {
{ 0 * 8, 1 * 16, 30 * 8, 1 * 16 }, { 0 * 8, 2 * 16, 30 * 8, 1 * 16 },
u"BBD_????", RecordView::FileType::RawS16, 16384, 3 u"BBD_????", RecordView::FileType::RawS16, 16384, 3
}; };

View File

@ -51,30 +51,40 @@ void ReplayAppView::on_file_changed(std::filesystem::path new_file_path) {
file_path = new_file_path; file_path = new_file_path;
auto file_size = data_file.size();
auto duration = (file_size * 1000) / (2 * 2 * sampling_rate / 8);
progressbar.set_max(file_size);
text_filename.set(file_path.filename().string().substr(0, 19));
text_duration.set(to_string_time_ms(duration));
// Get original record frequency if available // Get original record frequency if available
std::filesystem::path info_file_path = file_path; std::filesystem::path info_file_path = file_path;
info_file_path.replace_extension(u".TXT"); info_file_path.replace_extension(u".TXT");
sample_rate = 500000;
auto info_open_error = info_file.open("/" + info_file_path.string()); auto info_open_error = info_file.open("/" + info_file_path.string());
if (!info_open_error.is_valid()) { if (!info_open_error.is_valid()) {
memset(file_data, 0, 257); memset(file_data, 0, 257);
auto read_size = info_file.read(file_data, 256); auto read_size = info_file.read(file_data, 256);
if (!read_size.is_error()) { if (!read_size.is_error()) {
auto pos = strstr(file_data, "center_frequency="); auto pos1 = strstr(file_data, "center_frequency=");
if (pos) { if (pos1) {
pos += 17; pos1 += 17;
field_frequency.set_value(strtoll(pos, nullptr, 10)); field_frequency.set_value(strtoll(pos1, nullptr, 10));
}
auto pos2 = strstr(file_data, "sample_rate=");
if (pos2) {
pos2 += 12;
sample_rate = strtoll(pos2, nullptr, 10);
} }
} }
} }
text_sample_rate.set(unit_auto_scale(sample_rate, 3, 0) + "Hz");
auto file_size = data_file.size();
auto duration = (file_size * 1000) / (2 * 2 * sample_rate);
progressbar.set_max(file_size);
text_filename.set(file_path.filename().string().substr(0, 12));
text_duration.set(to_string_time_ms(duration));
button_play.focus(); button_play.focus();
} }
@ -117,6 +127,8 @@ void ReplayAppView::start() {
if( reader ) { if( reader ) {
button_play.set_bitmap(&bitmap_stop); button_play.set_bitmap(&bitmap_stop);
baseband::set_sample_rate(sample_rate * 8);
replay_thread = std::make_unique<ReplayThread>( replay_thread = std::make_unique<ReplayThread>(
std::move(reader), std::move(reader),
read_size, buffer_count, read_size, buffer_count,
@ -130,7 +142,7 @@ void ReplayAppView::start() {
radio::enable({ radio::enable({
receiver_model.tuning_frequency(), receiver_model.tuning_frequency(),
sampling_rate, sample_rate * 8 ,
baseband_bandwidth, baseband_bandwidth,
rf::Direction::Transmit, rf::Direction::Transmit,
receiver_model.rf_amp(), receiver_model.rf_amp(),
@ -172,6 +184,7 @@ ReplayAppView::ReplayAppView(
&labels, &labels,
&button_open, &button_open,
&text_filename, &text_filename,
&text_sample_rate,
&text_duration, &text_duration,
&progressbar, &progressbar,
&field_frequency, &field_frequency,

View File

@ -50,7 +50,7 @@ private:
static constexpr ui::Dim header_height = 3 * 16; static constexpr ui::Dim header_height = 3 * 16;
static constexpr uint32_t sampling_rate = 4000000; uint32_t sample_rate = 0;
static constexpr uint32_t baseband_bandwidth = 2500000; static constexpr uint32_t baseband_bandwidth = 2500000;
const size_t read_size { 16384 }; const size_t read_size { 16384 };
const size_t buffer_count { 3 }; const size_t buffer_count { 3 };
@ -76,7 +76,6 @@ private:
Labels labels { Labels labels {
{ { 10 * 8, 2 * 16 }, "LNA: A:", Color::light_grey() } { { 10 * 8, 2 * 16 }, "LNA: A:", Color::light_grey() }
//{ { 10 * 8, 2 * 16 }, "500ksps", Color::light_grey() }
}; };
Button button_open { Button button_open {
@ -85,9 +84,14 @@ private:
}; };
Text text_filename { Text text_filename {
{ 11 * 8, 0 * 16, 19 * 8, 16 }, { 11 * 8, 0 * 16, 12 * 8, 16 },
"-" "-"
}; };
Text text_sample_rate {
{ 24 * 8, 0 * 16, 6 * 8, 16 },
"-"
};
Text text_duration { Text text_duration {
{ 11 * 8, 1 * 16, 6 * 8, 16 }, { 11 * 8, 1 * 16, 6 * 8, 16 },
"-" "-"

View File

@ -97,7 +97,7 @@ private:
{ 1 * 8, " Windyoona Channels", 0 }, { 1 * 8, " Windyoona Channels", 0 },
{ 1 * 8, " F4GEV Pyr3x", 0 }, { 1 * 8, " F4GEV Pyr3x", 0 },
{ 1 * 8, " HB3YOE", 24 }, { 1 * 8, " HB3YOE", 24 },
{ 12 * 8, "MMXVII", -1 } { 11 * 8, "MMXVIII", -1 }
}; };
CreditsWidget credits_display { CreditsWidget credits_display {

View File

@ -135,9 +135,9 @@ SetRadioView::SetRadioView(
form_init(model); form_init(model);
check_bias.set_value(receiver_model.antenna_bias()); check_bias.set_value(portapack::get_antenna_bias());
check_bias.on_select = [this](Checkbox&, bool v) { check_bias.on_select = [this](Checkbox&, bool v) {
receiver_model.set_antenna_bias(v); portapack::set_antenna_bias(v);
StatusRefreshMessage message { }; StatusRefreshMessage message { };
EventDispatcher::send_message(message); EventDispatcher::send_message(message);
}; };

View File

@ -296,6 +296,11 @@ void spectrum_streaming_stop() {
send_message(&message); send_message(&message);
} }
void set_sample_rate(const uint32_t sample_rate) {
SamplerateConfigMessage message { sample_rate };
send_message(&message);
}
void capture_start(CaptureConfig* const config) { void capture_start(CaptureConfig* const config) {
CaptureConfigMessage message { config }; CaptureConfigMessage message { config };
send_message(&message); send_message(&message);

View File

@ -87,6 +87,7 @@ void shutdown();
void spectrum_streaming_start(); void spectrum_streaming_start();
void spectrum_streaming_stop(); void spectrum_streaming_stop();
void set_sample_rate(const uint32_t sample_rate);
void capture_start(CaptureConfig* const config); void capture_start(CaptureConfig* const config);
void capture_stop(); void capture_stop();
void replay_start(ReplayConfig* const config); void replay_start(ReplayConfig* const config);

View File

@ -77,12 +77,20 @@ WM8731 audio_codec_wm8731 { i2c0, 0x1a };
AK4951 audio_codec_ak4951 { i2c0, 0x12 }; AK4951 audio_codec_ak4951 { i2c0, 0x12 };
ReceiverModel receiver_model; ReceiverModel receiver_model;
TransmitterModel transmitter_model;
TemperatureLogger temperature_logger; TemperatureLogger temperature_logger;
TransmitterModel transmitter_model; bool antenna_bias { false };
uint8_t bl_tick_counter { 0 };
uint8_t bl_tick_counter = 0; void set_antenna_bias(const bool v) {
antenna_bias = v;
}
bool get_antenna_bias() {
return antenna_bias;
}
class Power { class Power {
public: public:

View File

@ -52,9 +52,13 @@ extern ReceiverModel receiver_model;
extern TransmitterModel transmitter_model; extern TransmitterModel transmitter_model;
extern uint8_t bl_tick_counter; extern uint8_t bl_tick_counter;
extern bool antenna_bias;
extern TemperatureLogger temperature_logger; extern TemperatureLogger temperature_logger;
void set_antenna_bias(const bool v);
bool get_antenna_bias();
bool init(); bool init();
void shutdown(); void shutdown();

View File

@ -25,6 +25,7 @@
#include "portapack_persistent_memory.hpp" #include "portapack_persistent_memory.hpp"
#include "hackrf_gpio.hpp" #include "hackrf_gpio.hpp"
#include "portapack.hpp"
using namespace hackrf::one; using namespace hackrf::one;
using namespace portapack; using namespace portapack;
@ -72,12 +73,7 @@ void ReceiverModel::set_frequency_step(rf::Frequency f) {
frequency_step_ = f; frequency_step_ = f;
} }
bool ReceiverModel::antenna_bias() const { void ReceiverModel::set_antenna_bias() {
return antenna_bias_;
}
void ReceiverModel::set_antenna_bias(bool enabled) {
antenna_bias_ = enabled;
update_antenna_bias(); update_antenna_bias();
} }
@ -180,7 +176,7 @@ void ReceiverModel::enable() {
void ReceiverModel::disable() { void ReceiverModel::disable() {
enabled_ = false; enabled_ = false;
update_antenna_bias(); radio::set_antenna_bias(false);
// TODO: Responsibility for enabling/disabling the radio is muddy. // TODO: Responsibility for enabling/disabling the radio is muddy.
// Some happens in ReceiverModel, some inside radio namespace. // Some happens in ReceiverModel, some inside radio namespace.
@ -201,7 +197,8 @@ void ReceiverModel::update_tuning_frequency() {
} }
void ReceiverModel::update_antenna_bias() { void ReceiverModel::update_antenna_bias() {
radio::set_antenna_bias(antenna_bias_ && enabled_); if (enabled_)
radio::set_antenna_bias(portapack::get_antenna_bias());
} }
void ReceiverModel::update_rf_amp() { void ReceiverModel::update_rf_amp() {

View File

@ -45,8 +45,7 @@ public:
rf::Frequency frequency_step() const; rf::Frequency frequency_step() const;
void set_frequency_step(rf::Frequency f); void set_frequency_step(rf::Frequency f);
bool antenna_bias() const; void set_antenna_bias();
void set_antenna_bias(bool enabled);
bool rf_amp() const; bool rf_amp() const;
void set_rf_amp(bool enabled); void set_rf_amp(bool enabled);
@ -91,7 +90,6 @@ private:
rf::Frequency frequency_step_ { 25000 }; rf::Frequency frequency_step_ { 25000 };
bool enabled_ { false }; bool enabled_ { false };
bool rf_amp_ { false }; bool rf_amp_ { false };
bool antenna_bias_ { false };
int32_t lna_gain_db_ { 32 }; int32_t lna_gain_db_ { 32 };
uint32_t baseband_bandwidth_ { max2837::filter::bandwidth_minimum }; uint32_t baseband_bandwidth_ { max2837::filter::bandwidth_minimum };
int32_t vga_gain_db_ { 32 }; int32_t vga_gain_db_ { 32 };

View File

@ -26,6 +26,7 @@
#include "portapack_persistent_memory.hpp" #include "portapack_persistent_memory.hpp"
#include "hackrf_gpio.hpp" #include "hackrf_gpio.hpp"
#include "portapack.hpp"
using namespace hackrf::one; using namespace hackrf::one;
using namespace portapack; using namespace portapack;
@ -43,6 +44,10 @@ void TransmitterModel::set_tuning_frequency(rf::Frequency f) {
update_tuning_frequency(); update_tuning_frequency();
} }
void TransmitterModel::set_antenna_bias() {
update_antenna_bias();
}
bool TransmitterModel::rf_amp() const { bool TransmitterModel::rf_amp() const {
return rf_amp_; return rf_amp_;
} }
@ -114,6 +119,7 @@ void TransmitterModel::enable() {
enabled_ = true; enabled_ = true;
radio::set_direction(rf::Direction::Transmit); radio::set_direction(rf::Direction::Transmit);
update_tuning_frequency(); update_tuning_frequency();
update_antenna_bias();
update_rf_amp(); update_rf_amp();
update_lna(); update_lna();
update_vga(); update_vga();
@ -132,6 +138,7 @@ void TransmitterModel::enable() {
void TransmitterModel::disable() { void TransmitterModel::disable() {
enabled_ = false; enabled_ = false;
radio::set_antenna_bias(false);
// TODO: Responsibility for enabling/disabling the radio is muddy. // TODO: Responsibility for enabling/disabling the radio is muddy.
// Some happens in ReceiverModel, some inside radio namespace. // Some happens in ReceiverModel, some inside radio namespace.
@ -145,6 +152,11 @@ void TransmitterModel::update_tuning_frequency() {
radio::set_tuning_frequency(persistent_memory::tuned_frequency()); radio::set_tuning_frequency(persistent_memory::tuned_frequency());
} }
void TransmitterModel::update_antenna_bias() {
if (enabled_)
radio::set_antenna_bias(portapack::get_antenna_bias());
}
void TransmitterModel::update_rf_amp() { void TransmitterModel::update_rf_amp() {
radio::set_rf_amp(rf_amp_); radio::set_rf_amp(rf_amp_);
} }

View File

@ -38,6 +38,8 @@ public:
rf::Frequency tuning_frequency() const; rf::Frequency tuning_frequency() const;
void set_tuning_frequency(rf::Frequency f); void set_tuning_frequency(rf::Frequency f);
void set_antenna_bias();
bool rf_amp() const; bool rf_amp() const;
void set_rf_amp(bool enabled); void set_rf_amp(bool enabled);
@ -74,6 +76,7 @@ private:
SignalToken signal_token_tick_second { }; SignalToken signal_token_tick_second { };
void update_tuning_frequency(); void update_tuning_frequency();
void update_antenna_bias();
void update_rf_amp(); void update_rf_amp();
void update_lna(); void update_lna();
void update_baseband_bandwidth(); void update_baseband_bandwidth();

View File

@ -77,6 +77,7 @@
#include "png_writer.hpp" #include "png_writer.hpp"
using portapack::receiver_model; using portapack::receiver_model;
using portapack::transmitter_model;
namespace ui { namespace ui {
@ -145,7 +146,7 @@ SystemStatusView::SystemStatusView(
} }
void SystemStatusView::refresh() { void SystemStatusView::refresh() {
if (receiver_model.antenna_bias()) { if (portapack::get_antenna_bias()) {
button_bias_tee.set_bitmap(&bitmap_icon_biast_on); button_bias_tee.set_bitmap(&bitmap_icon_biast_on);
button_bias_tee.set_foreground(ui::Color::yellow()); button_bias_tee.set_foreground(ui::Color::yellow());
} else { } else {
@ -172,27 +173,25 @@ void SystemStatusView::on_stealth() {
portapack::persistent_memory::set_stealth_mode(mode); portapack::persistent_memory::set_stealth_mode(mode);
if (mode) button_stealth.set_foreground(mode ? ui::Color::green() : ui::Color::light_grey());
button_stealth.set_foreground(ui::Color::green());
else
button_stealth.set_foreground(ui::Color::light_grey());
button_stealth.set_dirty(); button_stealth.set_dirty();
} }
void SystemStatusView::on_bias_tee() { void SystemStatusView::on_bias_tee() {
bool antenna_bias = receiver_model.antenna_bias(); if (!portapack::antenna_bias) {
if (!antenna_bias) {
nav_.display_modal("Bias voltage", "Enable DC voltage on\nantenna connector ?", YESNO, [this](bool v) { nav_.display_modal("Bias voltage", "Enable DC voltage on\nantenna connector ?", YESNO, [this](bool v) {
if (v) { if (v) {
receiver_model.set_antenna_bias(true); portapack::set_antenna_bias(true);
receiver_model.set_antenna_bias();
transmitter_model.set_antenna_bias();
refresh(); refresh();
} }
}); });
} else { } else {
receiver_model.set_antenna_bias(false); portapack::set_antenna_bias(false);
receiver_model.set_antenna_bias();
transmitter_model.set_antenna_bias();
refresh(); refresh();
} }
} }

View File

@ -27,8 +27,8 @@ using namespace portapack;
#include "io_file.hpp" #include "io_file.hpp"
#include "io_wave.hpp" #include "io_wave.hpp"
#include "baseband_api.hpp"
#include "rtc_time.hpp" #include "rtc_time.hpp"
#include "string_format.hpp" #include "string_format.hpp"
#include "utility.hpp" #include "utility.hpp"
@ -36,7 +36,7 @@ using namespace portapack;
namespace ui { namespace ui {
void RecordView::toggle_pitch_rssi() { /*void RecordView::toggle_pitch_rssi() {
pitch_rssi_enabled = !pitch_rssi_enabled; pitch_rssi_enabled = !pitch_rssi_enabled;
// Send to RSSI widget // Send to RSSI widget
@ -51,7 +51,7 @@ void RecordView::toggle_pitch_rssi() {
} else { } else {
button_pitch_rssi.set_foreground(Color::green()); button_pitch_rssi.set_foreground(Color::green());
} }
} }*/
RecordView::RecordView( RecordView::RecordView(
const Rect parent_rect, const Rect parent_rect,
@ -67,7 +67,7 @@ RecordView::RecordView(
{ {
add_children({ add_children({
&rect_background, &rect_background,
&button_pitch_rssi, //&button_pitch_rssi,
&button_record, &button_record,
&text_record_filename, &text_record_filename,
&text_record_dropped, &text_record_dropped,
@ -76,9 +76,9 @@ RecordView::RecordView(
rect_background.set_parent_rect({ { 0, 0 }, size() }); rect_background.set_parent_rect({ { 0, 0 }, size() });
button_pitch_rssi.on_select = [this](ImageButton&) { /*button_pitch_rssi.on_select = [this](ImageButton&) {
this->toggle_pitch_rssi(); this->toggle_pitch_rssi();
}; };*/
button_record.on_select = [this](ImageButton&) { button_record.on_select = [this](ImageButton&) {
this->toggle(); this->toggle();
@ -100,7 +100,9 @@ void RecordView::focus() {
void RecordView::set_sampling_rate(const size_t new_sampling_rate) { void RecordView::set_sampling_rate(const size_t new_sampling_rate) {
if( new_sampling_rate != sampling_rate ) { if( new_sampling_rate != sampling_rate ) {
stop(); stop();
sampling_rate = new_sampling_rate; sampling_rate = new_sampling_rate;
baseband::set_sample_rate(sampling_rate);
button_record.hidden(sampling_rate == 0); button_record.hidden(sampling_rate == 0);
text_record_filename.hidden(sampling_rate == 0); text_record_filename.hidden(sampling_rate == 0);
@ -214,7 +216,7 @@ Optional<File::Error> RecordView::write_metadata_file(const std::filesystem::pat
if( create_error.is_valid() ) { if( create_error.is_valid() ) {
return create_error; return create_error;
} else { } else {
const auto error_line1 = file.write_line("sample_rate=" + to_string_dec_uint(sampling_rate)); const auto error_line1 = file.write_line("sample_rate=" + to_string_dec_uint(sampling_rate / 8));
if( error_line1.is_valid() ) { if( error_line1.is_valid() ) {
return error_line1; return error_line1;
} }
@ -237,13 +239,13 @@ void RecordView::update_status_display() {
text_record_dropped.set(s); text_record_dropped.set(s);
} }
if (pitch_rssi_enabled) { /*if (pitch_rssi_enabled) {
button_pitch_rssi.invert_colors(); button_pitch_rssi.invert_colors();
} }*/
if( sampling_rate ) { if( sampling_rate ) {
const auto space_info = std::filesystem::space(u""); const auto space_info = std::filesystem::space(u"");
const uint32_t bytes_per_second = file_type == FileType::WAV ? (sampling_rate * 2) : (sampling_rate * 4); const uint32_t bytes_per_second = file_type == FileType::WAV ? (sampling_rate * 2) : (sampling_rate / 8 * 4);
const uint32_t available_seconds = space_info.free / bytes_per_second; const uint32_t available_seconds = space_info.free / bytes_per_second;
const uint32_t seconds = available_seconds % 60; const uint32_t seconds = available_seconds % 60;
const uint32_t available_minutes = available_seconds / 60; const uint32_t available_minutes = available_seconds / 60;

View File

@ -64,7 +64,7 @@ public:
private: private:
void toggle(); void toggle();
void toggle_pitch_rssi(); //void toggle_pitch_rssi();
Optional<File::Error> write_metadata_file(const std::filesystem::path& filename); Optional<File::Error> write_metadata_file(const std::filesystem::path& filename);
void on_tick_second(); void on_tick_second();
@ -73,7 +73,7 @@ private:
void handle_capture_thread_done(const File::Error error); void handle_capture_thread_done(const File::Error error);
void handle_error(const File::Error error); void handle_error(const File::Error error);
bool pitch_rssi_enabled = false; //bool pitch_rssi_enabled = false;
const std::filesystem::path filename_stem_pattern; const std::filesystem::path filename_stem_pattern;
const FileType file_type; const FileType file_type;
const size_t write_size; const size_t write_size;
@ -85,15 +85,16 @@ private:
Color::black() Color::black()
}; };
ImageButton button_pitch_rssi { /*ImageButton button_pitch_rssi {
{ 2, 0 * 16, 3 * 8, 1 * 16 }, { 2, 0 * 16, 3 * 8, 1 * 16 },
&bitmap_rssipwm, &bitmap_rssipwm,
Color::orange(), Color::orange(),
Color::black() Color::black()
}; };*/
ImageButton button_record { ImageButton button_record {
{ 4 * 8, 0 * 16, 2 * 8, 1 * 16 }, //{ 4 * 8, 0 * 16, 2 * 8, 1 * 16 },
{ 0 * 8, 0 * 16, 2 * 8, 1 * 16 },
&bitmap_record, &bitmap_record,
Color::red(), Color::red(),
Color::black() Color::black()

View File

@ -1,5 +1,6 @@
/* /*
* Copyright (C) 2016 Jared Boone, ShareBrained Technology, Inc. * Copyright (C) 2016 Jared Boone, ShareBrained Technology, Inc.
* Copyright (C) 2018 Furrtek
* *
* This file is part of PortaPack. * This file is part of PortaPack.
* *
@ -28,22 +29,8 @@
#include "utility.hpp" #include "utility.hpp"
CaptureProcessor::CaptureProcessor() { CaptureProcessor::CaptureProcessor() {
const auto& decim_0_filter = taps_200k_decim_0; decim_0.configure(taps_200k_decim_0.taps, 33554432);
constexpr size_t decim_0_input_fs = baseband_fs; decim_1.configure(taps_200k_decim_1.taps, 131072);
constexpr size_t decim_0_output_fs = decim_0_input_fs / decim_0.decimation_factor;
const auto& decim_1_filter = taps_200k_decim_1;
constexpr size_t decim_1_input_fs = decim_0_output_fs;
constexpr size_t decim_1_output_fs = decim_1_input_fs / decim_1.decimation_factor;
decim_0.configure(decim_0_filter.taps, 33554432);
decim_1.configure(decim_1_filter.taps, 131072);
channel_filter_pass_f = decim_1_filter.pass_frequency_normalized * decim_1_input_fs; // 162760.416666667
channel_filter_stop_f = decim_1_filter.stop_frequency_normalized * decim_1_input_fs; // 337239.583333333
spectrum_interval_samples = decim_1_output_fs / spectrum_rate_hz;
spectrum_samples = 0;
channel_spectrum.set_decimation_factor(1); channel_spectrum.set_decimation_factor(1);
} }
@ -76,6 +63,10 @@ void CaptureProcessor::on_message(const Message* const message) {
channel_spectrum.on_message(message); channel_spectrum.on_message(message);
break; break;
case Message::ID::SamplerateConfig:
samplerate_config(*reinterpret_cast<const SamplerateConfigMessage*>(message));
break;
case Message::ID::CaptureConfig: case Message::ID::CaptureConfig:
capture_config(*reinterpret_cast<const CaptureConfigMessage*>(message)); capture_config(*reinterpret_cast<const CaptureConfigMessage*>(message));
break; break;
@ -85,6 +76,22 @@ void CaptureProcessor::on_message(const Message* const message) {
} }
} }
void CaptureProcessor::samplerate_config(const SamplerateConfigMessage& message) {
baseband_fs = message.sample_rate;
baseband_thread.set_sampling_rate(baseband_fs);
size_t decim_0_output_fs = baseband_fs / decim_0.decimation_factor;
size_t decim_1_input_fs = decim_0_output_fs;
size_t decim_1_output_fs = decim_1_input_fs / decim_1.decimation_factor;
channel_filter_pass_f = taps_200k_decim_1.pass_frequency_normalized * decim_1_input_fs; // 162760.416666667
channel_filter_stop_f = taps_200k_decim_1.stop_frequency_normalized * decim_1_input_fs; // 337239.583333333
spectrum_interval_samples = decim_1_output_fs / spectrum_rate_hz;
spectrum_samples = 0;
}
void CaptureProcessor::capture_config(const CaptureConfigMessage& message) { void CaptureProcessor::capture_config(const CaptureConfigMessage& message) {
if( message.config ) { if( message.config ) {
stream = std::make_unique<StreamInput>(message.config); stream = std::make_unique<StreamInput>(message.config);

View File

@ -1,5 +1,6 @@
/* /*
* Copyright (C) 2016 Jared Boone, ShareBrained Technology, Inc. * Copyright (C) 2016 Jared Boone, ShareBrained Technology, Inc.
* Copyright (C) 2018 Furrtek
* *
* This file is part of PortaPack. * This file is part of PortaPack.
* *
@ -45,7 +46,7 @@ public:
private: private:
// TODO: Repeated value needs to be transmitted from application side. // TODO: Repeated value needs to be transmitted from application side.
static constexpr size_t baseband_fs = 4000000; size_t baseband_fs = 0;
static constexpr auto spectrum_rate_hz = 50.0f; static constexpr auto spectrum_rate_hz = 50.0f;
BasebandThread baseband_thread { baseband_fs, this, NORMALPRIO + 20, baseband::Direction::Receive }; BasebandThread baseband_thread { baseband_fs, this, NORMALPRIO + 20, baseband::Direction::Receive };
@ -68,6 +69,7 @@ private:
size_t spectrum_interval_samples = 0; size_t spectrum_interval_samples = 0;
size_t spectrum_samples = 0; size_t spectrum_samples = 0;
void samplerate_config(const SamplerateConfigMessage& message);
void capture_config(const CaptureConfigMessage& message); void capture_config(const CaptureConfigMessage& message);
}; };

View File

@ -32,7 +32,6 @@ ReplayProcessor::ReplayProcessor() {
channel_filter_pass_f = taps_200k_decim_1.pass_frequency_normalized * 1000000; // 162760.416666667 channel_filter_pass_f = taps_200k_decim_1.pass_frequency_normalized * 1000000; // 162760.416666667
channel_filter_stop_f = taps_200k_decim_1.stop_frequency_normalized * 1000000; // 337239.583333333 channel_filter_stop_f = taps_200k_decim_1.stop_frequency_normalized * 1000000; // 337239.583333333
spectrum_interval_samples = baseband_fs / spectrum_rate_hz;
spectrum_samples = 0; spectrum_samples = 0;
channel_spectrum.set_decimation_factor(1); channel_spectrum.set_decimation_factor(1);
@ -86,6 +85,10 @@ void ReplayProcessor::on_message(const Message* const message) {
channel_spectrum.on_message(message); channel_spectrum.on_message(message);
break; break;
case Message::ID::SamplerateConfig:
samplerate_config(*reinterpret_cast<const SamplerateConfigMessage*>(message));
break;
case Message::ID::ReplayConfig: case Message::ID::ReplayConfig:
configured = false; configured = false;
bytes_read = 0; bytes_read = 0;
@ -102,8 +105,15 @@ void ReplayProcessor::on_message(const Message* const message) {
} }
} }
void ReplayProcessor::samplerate_config(const SamplerateConfigMessage& message) {
baseband_fs = message.sample_rate;
baseband_thread.set_sampling_rate(baseband_fs);
spectrum_interval_samples = baseband_fs / spectrum_rate_hz;
}
void ReplayProcessor::replay_config(const ReplayConfigMessage& message) { void ReplayProcessor::replay_config(const ReplayConfigMessage& message) {
if( message.config ) { if( message.config ) {
stream = std::make_unique<StreamOutput>(message.config); stream = std::make_unique<StreamOutput>(message.config);
// Tell application that the buffers and FIFO pointers are ready, prefill // Tell application that the buffers and FIFO pointers are ready, prefill

View File

@ -42,7 +42,7 @@ public:
void on_message(const Message* const message) override; void on_message(const Message* const message) override;
private: private:
static constexpr size_t baseband_fs = 4000000; size_t baseband_fs = 0;
static constexpr auto spectrum_rate_hz = 50.0f; static constexpr auto spectrum_rate_hz = 50.0f;
BasebandThread baseband_thread { baseband_fs, this, NORMALPRIO + 20, baseband::Direction::Transmit }; BasebandThread baseband_thread { baseband_fs, this, NORMALPRIO + 20, baseband::Direction::Transmit };
@ -66,6 +66,7 @@ private:
bool configured { false }; bool configured { false };
uint32_t bytes_read { 0 }; uint32_t bytes_read { 0 };
void samplerate_config(const SamplerateConfigMessage& message);
void replay_config(const ReplayConfigMessage& message); void replay_config(const ReplayConfigMessage& message);
TXProgressMessage txprogress_message { }; TXProgressMessage txprogress_message { };

View File

@ -75,6 +75,7 @@ public:
ReplayThreadDone = 21, ReplayThreadDone = 21,
AFSKRxConfigure = 22, AFSKRxConfigure = 22,
StatusRefresh = 23, StatusRefresh = 23,
SamplerateConfig = 24,
TXProgress = 30, TXProgress = 30,
Retune = 31, Retune = 31,
@ -751,6 +752,18 @@ public:
uint32_t range = 0; uint32_t range = 0;
}; };
class SamplerateConfigMessage : public Message {
public:
constexpr SamplerateConfigMessage(
const uint32_t sample_rate
) : Message { ID::SamplerateConfig },
sample_rate(sample_rate)
{
}
const uint32_t sample_rate = 0;
};
class AudioLevelReportMessage : public Message { class AudioLevelReportMessage : public Message {
public: public:
constexpr AudioLevelReportMessage( constexpr AudioLevelReportMessage(

Binary file not shown.