mirror of
https://github.com/portapack-mayhem/mayhem-firmware.git
synced 2025-08-14 05:17:39 +00:00
Use matched filter for AIS GMSK demodulation demo.
Less than optimal for plain FSK, but flexible enough to also support GFSK/GMSK. Not at all optimized for SIMD instructions, so may not perform adequately at Bluetooth/GSM rates.
This commit is contained in:
@@ -43,7 +43,7 @@ FSKProcessor::~FSKProcessor() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void FSKProcessor::configure(const FSKConfiguration new_configuration) {
|
void FSKProcessor::configure(const FSKConfiguration new_configuration) {
|
||||||
demod.configure(sampling_rate, 2 * new_configuration.symbol_rate);
|
// TODO: Matched filter characteristics are hard-coded for the moment. YUCK!
|
||||||
clock_recovery.configure(sampling_rate / 4, new_configuration.symbol_rate);
|
clock_recovery.configure(sampling_rate / 4, new_configuration.symbol_rate);
|
||||||
access_code_correlator.configure(
|
access_code_correlator.configure(
|
||||||
new_configuration.access_code,
|
new_configuration.access_code,
|
||||||
@@ -84,16 +84,18 @@ void FSKProcessor::execute(buffer_c8_t buffer) {
|
|||||||
|
|
||||||
// 76.8k
|
// 76.8k
|
||||||
|
|
||||||
const buffer_s16_t work_demod_buffer {
|
|
||||||
(int16_t*)decimator_out.p,
|
|
||||||
decimator_out.count * sizeof(*decimator_out.p) / sizeof(int16_t)
|
|
||||||
};
|
|
||||||
|
|
||||||
auto demodulated = demod.execute(channel, work_demod_buffer);
|
|
||||||
|
|
||||||
// TODO: Factor out this hidden decimation magic.
|
// TODO: Factor out this hidden decimation magic.
|
||||||
for(size_t i=0; i<demodulated.count; i+=4) {
|
for(size_t i=0; i<channel.count; i+=4) {
|
||||||
clock_recovery(demodulated.p[i] / 32768.0f);
|
std::complex<float> sample { channel.p[i].real(), channel.p[i].imag() };
|
||||||
|
mf_0.execute_once(sample);
|
||||||
|
if( mf_1.execute_once(sample) ) {
|
||||||
|
const auto value_0 = mf_0.get_output();
|
||||||
|
const float mag_0 = std::sqrt(value_0.real() * value_0.real() + value_0.imag() * value_0.imag());
|
||||||
|
const auto value_1 = mf_1.get_output();
|
||||||
|
const float mag_1 = std::sqrt(value_1.real() * value_1.real() + value_1.imag() * value_1.imag());
|
||||||
|
const float diff = mag_1 - mag_0;
|
||||||
|
clock_recovery(diff);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
i2s::i2s0::tx_mute();
|
i2s::i2s0::tx_mute();
|
||||||
|
@@ -26,7 +26,7 @@
|
|||||||
|
|
||||||
#include "channel_decimator.hpp"
|
#include "channel_decimator.hpp"
|
||||||
#include "dsp_decimate.hpp"
|
#include "dsp_decimate.hpp"
|
||||||
#include "dsp_demodulate.hpp"
|
#include "matched_filter.hpp"
|
||||||
#include "dsp_fir_taps.hpp"
|
#include "dsp_fir_taps.hpp"
|
||||||
|
|
||||||
#include "clock_recovery.hpp"
|
#include "clock_recovery.hpp"
|
||||||
@@ -40,6 +40,20 @@
|
|||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <bitset>
|
#include <bitset>
|
||||||
|
|
||||||
|
constexpr std::array<std::complex<float>, 8> ais_taps_n { {
|
||||||
|
{ 0.00533687f, 0.00000000f }, { -0.00667109f, -0.00667109f },
|
||||||
|
{ -0.00000000f, -0.01334218f }, { -0.05145006f, 0.05145006f },
|
||||||
|
{ -0.14292666f, 0.00000000f }, { -0.05145006f, -0.05145006f },
|
||||||
|
{ 0.00000000f, 0.01334218f }, { -0.00667109f, 0.00667109f },
|
||||||
|
} };
|
||||||
|
|
||||||
|
constexpr std::array<std::complex<float>, 8> ais_taps_p { {
|
||||||
|
{ 0.00533687f, 0.00000000f }, { -0.00667109f, 0.00667109f },
|
||||||
|
{ -0.00000000f, 0.01334218f }, { -0.05145006f, -0.05145006f },
|
||||||
|
{ -0.14292666f, -0.00000000f }, { -0.05145006f, 0.05145006f },
|
||||||
|
{ 0.00000000f, -0.01334218f }, { -0.00667109f, -0.00667109f },
|
||||||
|
} };
|
||||||
|
|
||||||
class FSKProcessor : public BasebandProcessor {
|
class FSKProcessor : public BasebandProcessor {
|
||||||
public:
|
public:
|
||||||
FSKProcessor(MessageHandlerMap& message_handlers);
|
FSKProcessor(MessageHandlerMap& message_handlers);
|
||||||
@@ -55,7 +69,15 @@ private:
|
|||||||
ChannelDecimator decimator { ChannelDecimator::DecimationFactor::By16 };
|
ChannelDecimator decimator { ChannelDecimator::DecimationFactor::By16 };
|
||||||
const fir_taps_real<64>& channel_filter_taps = taps_64_lp_031_070_tfilter;
|
const fir_taps_real<64>& channel_filter_taps = taps_64_lp_031_070_tfilter;
|
||||||
dsp::decimate::FIRAndDecimateBy2Complex<64> channel_filter { channel_filter_taps.taps };
|
dsp::decimate::FIRAndDecimateBy2Complex<64> channel_filter { channel_filter_taps.taps };
|
||||||
dsp::demodulate::FM demod { sampling_rate, 9600 * 2 };
|
|
||||||
|
dsp::matched_filter::MatchedFilter mf_0 {
|
||||||
|
ais_taps_n,
|
||||||
|
1
|
||||||
|
};
|
||||||
|
dsp::matched_filter::MatchedFilter mf_1 {
|
||||||
|
ais_taps_p,
|
||||||
|
1
|
||||||
|
};
|
||||||
|
|
||||||
clock_recovery::ClockRecovery clock_recovery {
|
clock_recovery::ClockRecovery clock_recovery {
|
||||||
sampling_rate / 4,
|
sampling_rate / 4,
|
||||||
|
Reference in New Issue
Block a user