mirror of
https://github.com/eried/portapack-mayhem.git
synced 2025-01-11 23:39:29 -05:00
Spectrum streaming control, spectrum attributes back in each frame.
TODO: This feels kinda complex, and there's some repeated Processor code that needs to be refactored into a base class.
This commit is contained in:
parent
0647f26707
commit
d821afc60d
@ -24,6 +24,7 @@
|
|||||||
#include "spectrum_color_lut.hpp"
|
#include "spectrum_color_lut.hpp"
|
||||||
|
|
||||||
#include "portapack.hpp"
|
#include "portapack.hpp"
|
||||||
|
#include "portapack_shared_memory.hpp"
|
||||||
using namespace portapack;
|
using namespace portapack;
|
||||||
|
|
||||||
#include "string_format.hpp"
|
#include "string_format.hpp"
|
||||||
@ -237,11 +238,6 @@ void WaterfallWidget::on_show() {
|
|||||||
context().message_map().register_handler(Message::ID::ChannelSpectrumConfig,
|
context().message_map().register_handler(Message::ID::ChannelSpectrumConfig,
|
||||||
[this](const Message* const p) {
|
[this](const Message* const p) {
|
||||||
const auto message = *reinterpret_cast<const ChannelSpectrumConfigMessage*>(p);
|
const auto message = *reinterpret_cast<const ChannelSpectrumConfigMessage*>(p);
|
||||||
frequency_scale.set_spectrum_sampling_rate(message.sampling_rate);
|
|
||||||
frequency_scale.set_channel_filter(
|
|
||||||
message.channel_filter_pass_frequency,
|
|
||||||
message.channel_filter_stop_frequency
|
|
||||||
);
|
|
||||||
this->fifo = message.fifo;
|
this->fifo = message.fifo;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@ -255,9 +251,21 @@ void WaterfallWidget::on_show() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
shared_memory.baseband_queue.push_and_wait(
|
||||||
|
SpectrumStreamingConfigMessage {
|
||||||
|
SpectrumStreamingConfigMessage::Mode::Running
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WaterfallWidget::on_hide() {
|
void WaterfallWidget::on_hide() {
|
||||||
|
shared_memory.baseband_queue.push_and_wait(
|
||||||
|
SpectrumStreamingConfigMessage {
|
||||||
|
SpectrumStreamingConfigMessage::Mode::Stopped
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
context().message_map().unregister_handler(Message::ID::DisplayFrameSync);
|
context().message_map().unregister_handler(Message::ID::DisplayFrameSync);
|
||||||
context().message_map().unregister_handler(Message::ID::ChannelSpectrumConfig);
|
context().message_map().unregister_handler(Message::ID::ChannelSpectrumConfig);
|
||||||
}
|
}
|
||||||
@ -281,6 +289,11 @@ void WaterfallWidget::paint(Painter& painter) {
|
|||||||
|
|
||||||
void WaterfallWidget::on_channel_spectrum(const ChannelSpectrum& spectrum) {
|
void WaterfallWidget::on_channel_spectrum(const ChannelSpectrum& spectrum) {
|
||||||
waterfall_view.on_channel_spectrum(spectrum);
|
waterfall_view.on_channel_spectrum(spectrum);
|
||||||
|
frequency_scale.set_spectrum_sampling_rate(spectrum.sampling_rate);
|
||||||
|
frequency_scale.set_channel_filter(
|
||||||
|
spectrum.channel_filter_pass_frequency,
|
||||||
|
spectrum.channel_filter_stop_frequency
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
} /* namespace spectrum */
|
} /* namespace spectrum */
|
||||||
|
@ -53,6 +53,10 @@ void NarrowbandAMAudio::on_message(const Message* const message) {
|
|||||||
configure(*reinterpret_cast<const AMConfigureMessage*>(message));
|
configure(*reinterpret_cast<const AMConfigureMessage*>(message));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case Message::ID::SpectrumStreamingConfig:
|
||||||
|
streaming_config(*reinterpret_cast<const SpectrumStreamingConfigMessage*>(message));
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -82,3 +86,11 @@ void NarrowbandAMAudio::configure(const AMConfigureMessage& message) {
|
|||||||
|
|
||||||
configured = true;
|
configured = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NarrowbandAMAudio::streaming_config(const SpectrumStreamingConfigMessage& message) {
|
||||||
|
if( message.mode == SpectrumStreamingConfigMessage::Mode::Running ) {
|
||||||
|
channel_spectrum.start();
|
||||||
|
} else {
|
||||||
|
channel_spectrum.stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -64,6 +64,8 @@ private:
|
|||||||
|
|
||||||
bool configured { false };
|
bool configured { false };
|
||||||
void configure(const AMConfigureMessage& message);
|
void configure(const AMConfigureMessage& message);
|
||||||
|
|
||||||
|
void streaming_config(const SpectrumStreamingConfigMessage& message);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif/*__PROC_AM_AUDIO_H__*/
|
#endif/*__PROC_AM_AUDIO_H__*/
|
||||||
|
@ -66,6 +66,10 @@ void NarrowbandFMAudio::on_message(const Message* const message) {
|
|||||||
configure(*reinterpret_cast<const NBFMConfigureMessage*>(message));
|
configure(*reinterpret_cast<const NBFMConfigureMessage*>(message));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case Message::ID::SpectrumStreamingConfig:
|
||||||
|
streaming_config(*reinterpret_cast<const SpectrumStreamingConfigMessage*>(message));
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -99,3 +103,11 @@ void NarrowbandFMAudio::configure(const NBFMConfigureMessage& message) {
|
|||||||
|
|
||||||
configured = true;
|
configured = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NarrowbandFMAudio::streaming_config(const SpectrumStreamingConfigMessage& message) {
|
||||||
|
if( message.mode == SpectrumStreamingConfigMessage::Mode::Running ) {
|
||||||
|
channel_spectrum.start();
|
||||||
|
} else {
|
||||||
|
channel_spectrum.stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -66,6 +66,8 @@ private:
|
|||||||
|
|
||||||
bool configured { false };
|
bool configured { false };
|
||||||
void configure(const NBFMConfigureMessage& message);
|
void configure(const NBFMConfigureMessage& message);
|
||||||
|
|
||||||
|
void streaming_config(const SpectrumStreamingConfigMessage& message);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif/*__PROC_NFM_AUDIO_H__*/
|
#endif/*__PROC_NFM_AUDIO_H__*/
|
||||||
|
@ -84,6 +84,10 @@ void WidebandFMAudio::on_message(const Message* const message) {
|
|||||||
configure(*reinterpret_cast<const WFMConfigureMessage*>(message));
|
configure(*reinterpret_cast<const WFMConfigureMessage*>(message));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case Message::ID::SpectrumStreamingConfig:
|
||||||
|
streaming_config(*reinterpret_cast<const SpectrumStreamingConfigMessage*>(message));
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -117,3 +121,11 @@ void WidebandFMAudio::configure(const WFMConfigureMessage& message) {
|
|||||||
|
|
||||||
configured = true;
|
configured = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WidebandFMAudio::streaming_config(const SpectrumStreamingConfigMessage& message) {
|
||||||
|
if( message.mode == SpectrumStreamingConfigMessage::Mode::Running ) {
|
||||||
|
channel_spectrum.start();
|
||||||
|
} else {
|
||||||
|
channel_spectrum.stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -67,6 +67,8 @@ private:
|
|||||||
|
|
||||||
bool configured { false };
|
bool configured { false };
|
||||||
void configure(const WFMConfigureMessage& message);
|
void configure(const WFMConfigureMessage& message);
|
||||||
|
|
||||||
|
void streaming_config(const SpectrumStreamingConfigMessage& message);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif/*__PROC_WFM_AUDIO_H__*/
|
#endif/*__PROC_WFM_AUDIO_H__*/
|
||||||
|
@ -29,6 +29,16 @@
|
|||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
|
void SpectrumCollector::start() {
|
||||||
|
streaming = true;
|
||||||
|
ChannelSpectrumConfigMessage message { &fifo };
|
||||||
|
shared_memory.application_queue.push(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpectrumCollector::stop() {
|
||||||
|
streaming = false;
|
||||||
|
}
|
||||||
|
|
||||||
void SpectrumCollector::set_decimation_factor(
|
void SpectrumCollector::set_decimation_factor(
|
||||||
const size_t decimation_factor
|
const size_t decimation_factor
|
||||||
) {
|
) {
|
||||||
@ -48,7 +58,7 @@ void SpectrumCollector::feed(
|
|||||||
// Called from baseband processing thread.
|
// Called from baseband processing thread.
|
||||||
channel_filter_pass_frequency = filter_pass_frequency;
|
channel_filter_pass_frequency = filter_pass_frequency;
|
||||||
channel_filter_stop_frequency = filter_stop_frequency;
|
channel_filter_stop_frequency = filter_stop_frequency;
|
||||||
post_configuration_message();
|
|
||||||
channel_spectrum_decimator.feed(
|
channel_spectrum_decimator.feed(
|
||||||
channel,
|
channel,
|
||||||
[this](const buffer_c16_t& data) {
|
[this](const buffer_c16_t& data) {
|
||||||
@ -59,7 +69,7 @@ void SpectrumCollector::feed(
|
|||||||
|
|
||||||
void SpectrumCollector::post_message(const buffer_c16_t& data) {
|
void SpectrumCollector::post_message(const buffer_c16_t& data) {
|
||||||
// Called from baseband processing thread.
|
// Called from baseband processing thread.
|
||||||
if( !channel_spectrum_request_update ) {
|
if( streaming && !channel_spectrum_request_update ) {
|
||||||
fft_swap(data, channel_spectrum);
|
fft_swap(data, channel_spectrum);
|
||||||
channel_spectrum_sampling_rate = data.sampling_rate;
|
channel_spectrum_sampling_rate = data.sampling_rate;
|
||||||
channel_spectrum_request_update = true;
|
channel_spectrum_request_update = true;
|
||||||
@ -67,24 +77,17 @@ void SpectrumCollector::post_message(const buffer_c16_t& data) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpectrumCollector::post_configuration_message() {
|
|
||||||
ChannelSpectrumConfigMessage message {
|
|
||||||
channel_spectrum_sampling_rate,
|
|
||||||
channel_filter_pass_frequency,
|
|
||||||
channel_filter_stop_frequency,
|
|
||||||
&fifo
|
|
||||||
};
|
|
||||||
shared_memory.application_queue.push(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SpectrumCollector::update() {
|
void SpectrumCollector::update() {
|
||||||
// Called from idle thread (after EVT_MASK_SPECTRUM is flagged)
|
// Called from idle thread (after EVT_MASK_SPECTRUM is flagged)
|
||||||
if( channel_spectrum_request_update ) {
|
if( streaming && channel_spectrum_request_update ) {
|
||||||
/* Decimated buffer is full. Compute spectrum. */
|
/* Decimated buffer is full. Compute spectrum. */
|
||||||
channel_spectrum_request_update = false;
|
channel_spectrum_request_update = false;
|
||||||
fft_c_preswapped(channel_spectrum);
|
fft_c_preswapped(channel_spectrum);
|
||||||
|
|
||||||
ChannelSpectrum spectrum;
|
ChannelSpectrum spectrum;
|
||||||
|
spectrum.sampling_rate = channel_spectrum_sampling_rate;
|
||||||
|
spectrum.channel_filter_pass_frequency = channel_filter_pass_frequency;
|
||||||
|
spectrum.channel_filter_stop_frequency = channel_filter_stop_frequency;
|
||||||
for(size_t i=0; i<spectrum.db.size(); i++) {
|
for(size_t i=0; i<spectrum.db.size(); i++) {
|
||||||
// Three point Hamming window.
|
// Three point Hamming window.
|
||||||
const auto corrected_sample = channel_spectrum[i] * 0.54f
|
const auto corrected_sample = channel_spectrum[i] * 0.54f
|
||||||
@ -95,7 +98,6 @@ void SpectrumCollector::update() {
|
|||||||
const unsigned int v = (db * mag_scale) + 255.0f;
|
const unsigned int v = (db * mag_scale) + 255.0f;
|
||||||
spectrum.db[i] = std::max(0U, std::min(255U, v));
|
spectrum.db[i] = std::max(0U, std::min(255U, v));
|
||||||
}
|
}
|
||||||
|
|
||||||
fifo.in(spectrum);
|
fifo.in(spectrum);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -39,6 +39,9 @@ public:
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void start();
|
||||||
|
void stop();
|
||||||
|
|
||||||
void set_decimation_factor(const size_t decimation_factor);
|
void set_decimation_factor(const size_t decimation_factor);
|
||||||
|
|
||||||
void feed(
|
void feed(
|
||||||
@ -54,13 +57,13 @@ private:
|
|||||||
ChannelSpectrumFIFO fifo;
|
ChannelSpectrumFIFO fifo;
|
||||||
|
|
||||||
volatile bool channel_spectrum_request_update { false };
|
volatile bool channel_spectrum_request_update { false };
|
||||||
|
bool streaming { false };
|
||||||
std::array<std::complex<float>, 256> channel_spectrum;
|
std::array<std::complex<float>, 256> channel_spectrum;
|
||||||
uint32_t channel_spectrum_sampling_rate { 0 };
|
uint32_t channel_spectrum_sampling_rate { 0 };
|
||||||
uint32_t channel_filter_pass_frequency { 0 };
|
uint32_t channel_filter_pass_frequency { 0 };
|
||||||
uint32_t channel_filter_stop_frequency { 0 };
|
uint32_t channel_filter_stop_frequency { 0 };
|
||||||
|
|
||||||
void post_message(const buffer_c16_t& data);
|
void post_message(const buffer_c16_t& data);
|
||||||
void post_configuration_message();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif/*__SPECTRUM_COLLECTOR_H__*/
|
#endif/*__SPECTRUM_COLLECTOR_H__*/
|
||||||
|
@ -57,6 +57,7 @@ public:
|
|||||||
WFMConfigure = 12,
|
WFMConfigure = 12,
|
||||||
AMConfigure = 13,
|
AMConfigure = 13,
|
||||||
ChannelSpectrumConfig = 14,
|
ChannelSpectrumConfig = 14,
|
||||||
|
SpectrumStreamingConfig = 15,
|
||||||
MAX
|
MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -209,8 +210,28 @@ public:
|
|||||||
BasebandConfiguration configuration;
|
BasebandConfiguration configuration;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class SpectrumStreamingConfigMessage : public Message {
|
||||||
|
public:
|
||||||
|
enum class Mode : uint32_t {
|
||||||
|
Stopped = 0,
|
||||||
|
Running = 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr SpectrumStreamingConfigMessage(
|
||||||
|
Mode mode
|
||||||
|
) : Message { ID::SpectrumStreamingConfig },
|
||||||
|
mode { mode }
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Mode mode { Mode::Stopped };
|
||||||
|
};
|
||||||
|
|
||||||
struct ChannelSpectrum {
|
struct ChannelSpectrum {
|
||||||
std::array<uint8_t, 256> db { { 0 } };
|
std::array<uint8_t, 256> db { { 0 } };
|
||||||
|
uint32_t sampling_rate { 0 };
|
||||||
|
uint32_t channel_filter_pass_frequency { 0 };
|
||||||
|
uint32_t channel_filter_stop_frequency { 0 };
|
||||||
};
|
};
|
||||||
|
|
||||||
using ChannelSpectrumFIFO = FIFO<ChannelSpectrum, 2>;
|
using ChannelSpectrumFIFO = FIFO<ChannelSpectrum, 2>;
|
||||||
@ -218,21 +239,12 @@ using ChannelSpectrumFIFO = FIFO<ChannelSpectrum, 2>;
|
|||||||
class ChannelSpectrumConfigMessage : public Message {
|
class ChannelSpectrumConfigMessage : public Message {
|
||||||
public:
|
public:
|
||||||
constexpr ChannelSpectrumConfigMessage(
|
constexpr ChannelSpectrumConfigMessage(
|
||||||
uint32_t sampling_rate,
|
|
||||||
uint32_t channel_filter_pass_frequency,
|
|
||||||
uint32_t channel_filter_stop_frequency,
|
|
||||||
ChannelSpectrumFIFO* fifo
|
ChannelSpectrumFIFO* fifo
|
||||||
) : Message { ID::ChannelSpectrumConfig },
|
) : Message { ID::ChannelSpectrumConfig },
|
||||||
sampling_rate { sampling_rate },
|
|
||||||
channel_filter_pass_frequency { channel_filter_pass_frequency },
|
|
||||||
channel_filter_stop_frequency { channel_filter_stop_frequency },
|
|
||||||
fifo { fifo }
|
fifo { fifo }
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t sampling_rate { 0 };
|
|
||||||
uint32_t channel_filter_pass_frequency { 0 };
|
|
||||||
uint32_t channel_filter_stop_frequency { 0 };
|
|
||||||
ChannelSpectrumFIFO* fifo { nullptr };
|
ChannelSpectrumFIFO* fifo { nullptr };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user