mirror of
https://github.com/eried/portapack-mayhem.git
synced 2024-12-24 23:09:26 -05:00
Use IFIR decimation for broadcast FM receiver.
This commit is contained in:
parent
a02bfe55d0
commit
e720bfb054
@ -618,6 +618,12 @@ buffer_c16_t DecimateBy2CIC3::execute(
|
||||
return { dst.p, src.count / 2, src.sampling_rate / 2 };
|
||||
}
|
||||
|
||||
void FIR64AndDecimateBy2Real::configure(
|
||||
const std::array<int16_t, taps_count>& new_taps
|
||||
) {
|
||||
std::copy(new_taps.cbegin(), new_taps.cend(), taps.begin());
|
||||
}
|
||||
|
||||
buffer_s16_t FIR64AndDecimateBy2Real::execute(
|
||||
buffer_s16_t src,
|
||||
buffer_s16_t dst
|
||||
|
@ -76,11 +76,9 @@ class FIR64AndDecimateBy2Real {
|
||||
public:
|
||||
static constexpr size_t taps_count = 64;
|
||||
|
||||
FIR64AndDecimateBy2Real(
|
||||
void configure(
|
||||
const std::array<int16_t, taps_count>& taps
|
||||
) : taps(taps)
|
||||
{
|
||||
}
|
||||
);
|
||||
|
||||
buffer_s16_t execute(
|
||||
buffer_s16_t src,
|
||||
@ -89,7 +87,7 @@ public:
|
||||
|
||||
private:
|
||||
std::array<int16_t, taps_count + 2> z;
|
||||
const std::array<int16_t, taps_count>& taps;
|
||||
std::array<int16_t, taps_count> taps;
|
||||
};
|
||||
|
||||
class FIRC8xR16x24FS4Decim4 {
|
||||
|
@ -182,6 +182,27 @@ constexpr fir_taps_real<32> taps_6k0_channel {
|
||||
} },
|
||||
};
|
||||
|
||||
// WFM 200KF8E emission type //////////////////////////////////////////////
|
||||
|
||||
constexpr fir_taps_real<24> taps_200k_wfm_decim_0 = {
|
||||
.pass_frequency_normalized = 100000.0f / 3072000.0f,
|
||||
.stop_frequency_normalized = 484000.0f / 3072000.0f,
|
||||
.taps = { {
|
||||
48, -18, -151, -364, -557, -548, -139, 789,
|
||||
2187, 3800, 5230, 6071, 6071, 5230, 3800, 2187,
|
||||
789, -139, -548, -557, -364, -151, -18, 48,
|
||||
} },
|
||||
};
|
||||
|
||||
constexpr fir_taps_real<16> taps_200k_wfm_decim_1 = {
|
||||
.pass_frequency_normalized = 100000.0f / 768000.0f,
|
||||
.stop_frequency_normalized = 284000.0f / 768000.0f,
|
||||
.taps = { {
|
||||
-67, -123, 388, 622, -1342, -2185, 4599, 14486,
|
||||
14486, 4599, -2185, -1342, 622, 388, -123, -67,
|
||||
} },
|
||||
};
|
||||
|
||||
/* Wideband audio filter */
|
||||
/* 96kHz int16_t input
|
||||
* -> FIR filter, <15kHz (0.156fs) pass, >19kHz (0.198fs) stop
|
||||
|
@ -23,8 +23,34 @@
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
WidebandFMAudio::WidebandFMAudio() {
|
||||
constexpr size_t baseband_fs = 3072000;
|
||||
|
||||
constexpr size_t decim_0_input_fs = baseband_fs;
|
||||
constexpr size_t decim_0_decimation_factor = 4;
|
||||
constexpr size_t decim_0_output_fs = decim_0_input_fs / decim_0_decimation_factor;
|
||||
|
||||
constexpr size_t decim_1_input_fs = decim_0_output_fs;
|
||||
constexpr size_t decim_1_decimation_factor = 2;
|
||||
constexpr size_t decim_1_output_fs = decim_1_input_fs / decim_1_decimation_factor;
|
||||
|
||||
constexpr size_t demod_input_fs = decim_1_output_fs;
|
||||
|
||||
decim_0.configure(taps_200k_wfm_decim_0.taps, 33554432);
|
||||
decim_1.configure(taps_200k_wfm_decim_1.taps, 131072);
|
||||
demod.configure(demod_input_fs, 75000);
|
||||
audio_filter.configure(taps_64_lp_156_198.taps);
|
||||
}
|
||||
|
||||
void WidebandFMAudio::execute(const buffer_c8_t& buffer) {
|
||||
auto decimator_out = decimator.execute(buffer);
|
||||
const buffer_c16_t dst_buffer {
|
||||
dst.data(),
|
||||
dst.size()
|
||||
};
|
||||
|
||||
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 decimator_out = decim_1_out;
|
||||
|
||||
const buffer_s16_t work_audio_buffer {
|
||||
(int16_t*)decimator_out.p,
|
||||
@ -37,29 +63,24 @@ void WidebandFMAudio::execute(const buffer_c8_t& buffer) {
|
||||
feed_channel_stats(channel);
|
||||
//feed_channel_spectrum(channel);
|
||||
|
||||
/* 768kHz complex<int16_t>[512]
|
||||
/* 384kHz complex<int16_t>[256]
|
||||
* -> FM demodulation
|
||||
* -> 768kHz int16_t[512] */
|
||||
* -> 384kHz int16_t[256] */
|
||||
/* TODO: To improve adjacent channel rejection, implement complex channel filter:
|
||||
* pass < +/- 100kHz, stop > +/- 200kHz
|
||||
*/
|
||||
|
||||
auto audio_oversampled = demod.execute(decimator_out, work_audio_buffer);
|
||||
|
||||
/* 768kHz int16_t[512]
|
||||
* -> 4th order CIC decimation by 2, gain of 1
|
||||
* -> 384kHz int16_t[256] */
|
||||
auto audio_8fs = 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_2.execute(audio_8fs, work_audio_buffer);
|
||||
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_3.execute(audio_4fs, work_audio_buffer);
|
||||
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
|
||||
|
@ -33,21 +33,19 @@
|
||||
|
||||
class WidebandFMAudio : public BasebandProcessor {
|
||||
public:
|
||||
WidebandFMAudio() {
|
||||
decimator.set_decimation_factor(ChannelDecimator::DecimationFactor::By4);
|
||||
}
|
||||
WidebandFMAudio();
|
||||
|
||||
void execute(const buffer_c8_t& buffer) override;
|
||||
|
||||
private:
|
||||
ChannelDecimator decimator;
|
||||
std::array<complex16_t, 512> dst;
|
||||
dsp::decimate::FIRC8xR16x24FS4Decim4 decim_0;
|
||||
dsp::decimate::FIRC16xR16x16Decim2 decim_1;
|
||||
|
||||
dsp::demodulate::FM demod { 768000, 75000 };
|
||||
dsp::demodulate::FM demod;
|
||||
dsp::decimate::DecimateBy2CIC4Real audio_dec_1;
|
||||
dsp::decimate::DecimateBy2CIC4Real audio_dec_2;
|
||||
dsp::decimate::DecimateBy2CIC4Real audio_dec_3;
|
||||
const fir_taps_real<64>& audio_filter_taps = taps_64_lp_156_198;
|
||||
dsp::decimate::FIR64AndDecimateBy2Real audio_filter { audio_filter_taps.taps };
|
||||
dsp::decimate::FIR64AndDecimateBy2Real audio_filter;
|
||||
|
||||
IIRBiquadFilter audio_hpf { audio_hpf_30hz_config };
|
||||
IIRBiquadFilter audio_deemph { audio_deemph_2122_6_config };
|
||||
|
Loading…
Reference in New Issue
Block a user