Rebased code from new eried repo commits. Changed to to reflect strijar implementation. Fixed previous issue with old ssb-am-tx ui_mictx code.

This commit is contained in:
DESKTOP-R56EVJP\Alex
2021-03-21 20:11:40 -05:00
parent 603b7fb1ab
commit f65852ff05
20 changed files with 1545 additions and 16 deletions

View File

@@ -113,6 +113,8 @@ set(CPPSRC
baseband_stats_collector.cpp
dsp_decimate.cpp
dsp_demodulate.cpp
dsp_hilbert.cpp
dsp_modulate.cpp
dsp_goertzel.cpp
matched_filter.cpp
spectrum_collector.cpp
@@ -125,6 +127,7 @@ set(CPPSRC
${COMMON}/dsp_fft.cpp
${COMMON}/dsp_fir_taps.cpp
${COMMON}/dsp_iir.cpp
${COMMON}/dsp_sos.cpp
fxpt_atan2.cpp
rssi.cpp
rssi_dma.cpp

View File

@@ -0,0 +1,57 @@
/*
* Copyright (C) 2020 Belousov Oleg
*
* This file is part of PortaPack.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#include "dsp_hilbert.hpp"
#include "dsp_sos_config.hpp"
namespace dsp {
HilbertTransform::HilbertTransform() {
n = 0;
sos_i.configure(half_band_lpf_config);
sos_q.configure(half_band_lpf_config);
}
void HilbertTransform::execute(float in, float &out_i, float &out_q) {
float a = 0, b = 0;
switch (n) {
case 0: a = in; b = 0; break;
case 1: a = 0; b = -in; break;
case 2: a = -in; b = 0; break;
case 3: a = 0; b = in; break;
}
float i = sos_i.execute(a) * 2.0f;
float q = sos_q.execute(b) * 2.0f;
switch (n) {
case 0: out_i = i; out_q = q; break;
case 1: out_i = -q; out_q = i; break;
case 2: out_i = -i; out_q = -q; break;
case 3: out_i = q; out_q = -i; break;
}
n = (n + 1) % 4;
}
} /* namespace dsp */

View File

@@ -0,0 +1,44 @@
/*
* Copyright (C) 2020 Belousov Oleg
*
* This file is part of PortaPack.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#ifndef __DSP_HILBERT_H__
#define __DSP_HILBERT_H__
#include "dsp_sos.hpp"
#include "dsp_types.hpp"
namespace dsp {
class HilbertTransform {
public:
HilbertTransform();
void execute(float in, float &out_i, float &out_q);
private:
uint8_t n = 0;
SOSFilter<5> sos_i;
SOSFilter<5> sos_q;
};
} /* namespace dsp */
#endif/*__DSP_HILBERT_H__*/

View File

@@ -0,0 +1,137 @@
/*
* Copyright (C) 2020 Belousov Oleg
*
* This file is part of PortaPack.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#include "dsp_modulate.hpp"
#include "sine_table_int8.hpp"
namespace dsp {
namespace modulate {
Modulator::~Modulator() {
}
Mode Modulator::get_mode() {
return mode;
}
void Modulator::set_mode(Mode new_mode) {
mode = new_mode;
}
void Modulator::set_over(uint32_t new_over) {
over = new_over;
}
///
SSB::SSB() : hilbert() {
mode = Mode::LSB;
}
void SSB::execute(const buffer_s16_t& audio, const buffer_c8_t& buffer) {
int32_t sample = 0;
int8_t re = 0, im = 0;
for (size_t counter = 0; counter < buffer.count; counter++) {
if (counter % 128 == 0) {
float i = 0.0, q = 0.0;
sample = audio.p[counter / over] >> 2;
//switch (mode) {
//case Mode::LSB:
hilbert.execute(sample / 32768.0f, i, q);
//case Mode::USB: hilbert.execute(sample / 32768.0f, q, i);
//default: break;
//}
i *= 64.0f;
q *= 64.0f;
switch (mode) {
case Mode::LSB: re = q; im = i; break;
case Mode::USB: re = i; im = q; break;
default: re = 0; im = 0; break;
}
//re = q;
//im = i;
//break;
}
buffer.p[counter] = { re, im };
}
}
///
FM::FM() {
mode = Mode::FM;
}
void FM::set_fm_delta(uint32_t new_delta) {
fm_delta = new_delta;
}
void FM::execute(const buffer_s16_t& audio, const buffer_c8_t& buffer) {
int32_t sample = 0;
int8_t re, im;
for (size_t counter = 0; counter < buffer.count; counter++) {
if (counter % over == 0) {
sample = audio.p[counter / over] >> 8;
delta = sample * fm_delta;
}
phase += delta;
sphase = phase >> 24;
re = (sine_table_i8[(sphase + 64) & 255]);
im = (sine_table_i8[sphase]);
buffer.p[counter] = { re, im };
}
}
AM::AM() {
mode = Mode::AM;
}
void AM::execute(const buffer_s16_t& audio, const buffer_c8_t& buffer) {
int32_t sample = 0;
int8_t re, im;
float q = 0.0;
for (size_t counter = 0; counter < buffer.count; counter++) {
if (counter % 128 == 0) {
sample = audio.p[counter / over] >> 2;
}
q = sample / 32768.0f;
q *= 64.0f;
switch (mode) {
case Mode::AM: re = q + 20; im = q + 20;
case Mode::DSB: re = q; im = q;
default: break;
}
buffer.p[counter] = { re, im };
}
}
}
}

View File

@@ -0,0 +1,96 @@
/*
* Copyright (C) 2020 Belousov Oleg
*
* This file is part of PortaPack.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#ifndef __DSP_MODULATE_H__
#define __DSP_MODULATE_H__
#include "dsp_types.hpp"
#include "dsp_hilbert.hpp"
namespace dsp {
namespace modulate {
enum class Mode {
None,
AM,
DSB,
LSB,
USB,
FM
};
///
class Modulator {
public:
virtual void execute(const buffer_s16_t& audio, const buffer_c8_t& buffer) = 0;
virtual ~Modulator();
Mode get_mode();
void set_mode(Mode new_mode);
void set_over(uint32_t new_over);
protected:
uint32_t over = 1;
Mode mode = Mode::None;
};
///
class SSB : public Modulator {
public:
SSB();
virtual void execute(const buffer_s16_t& audio, const buffer_c8_t& buffer);
private:
dsp::HilbertTransform hilbert;
};
///
class FM : public Modulator {
public:
FM();
virtual void execute(const buffer_s16_t& audio, const buffer_c8_t& buffer);
void set_fm_delta(uint32_t new_delta);
///
private:
uint32_t fm_delta { 0 };
uint32_t phase { 0 }, sphase { 0 };
int32_t sample { 0 }, delta { };
};
class AM : public Modulator {
public:
AM();
virtual void execute(const buffer_s16_t& audio, const buffer_c8_t& buffer);
};
} /* namespace modulate */
} /* namespace dsp */
#endif/*__DSP_MODULATE_H__*/

View File

@@ -35,6 +35,7 @@ void MicTXProcessor::execute(const buffer_c8_t& buffer){
if (!configured) return;
audio_input.read_audio_buffer(audio_buffer);
modulator->execute(audio_buffer, buffer);
for (size_t i = 0; i < buffer.count; i++) {
@@ -70,6 +71,7 @@ void MicTXProcessor::execute(const buffer_c8_t& buffer){
sample = beep_gen.process(0);
}
/*
sample = tone_gen.process(sample);
// FM
@@ -87,6 +89,7 @@ void MicTXProcessor::execute(const buffer_c8_t& buffer){
}
buffer.p[i] = { re, im };
*/
}
}
@@ -96,7 +99,40 @@ void MicTXProcessor::on_message(const Message* const msg) {
switch(msg->id) {
case Message::ID::AudioTXConfig:
fm_delta = config_message.deviation_hz * (0xFFFFFFUL / baseband_fs);
if (fm_enabled) {
dsp::modulate::FM *fm = new dsp::modulate::FM();
fm->set_fm_delta(config_message.deviation_hz * (0xFFFFFFUL / baseband_fs));
modulator = fm;
}
if (usb_enabled) {
modulator = new dsp::modulate::SSB();
modulator->set_mode(dsp::modulate::Mode::USB);
}
if (lsb_enabled) {
modulator = new dsp::modulate::SSB();
modulator->set_mode(dsp::modulate::Mode::LSB);
}
if (am_enabled) {
modulator = new dsp::modulate::AM();
modulator->set_mode(dsp::modulate::Mode::AM);
}
if (dsb_enabled) {
modulator = new dsp::modulate::AM();
modulator->set_mode(dsp::modulate::Mode::DSB);
}
modulator->set_over(baseband_fs / 24000);
am_enabled = config_message.am_enabled;
usb_enabled = config_message.usb_enabled;
lsb_enabled = config_message.lsb_enabled;
dsb_enabled = config_message.dsb_enabled;
if (!am_enabled || !usb_enabled || !lsb_enabled || !dsb_enabled) {
fm_enabled = true;
}
audio_gain = config_message.audio_gain;
divider = config_message.divider;

View File

@@ -27,6 +27,7 @@
#include "baseband_thread.hpp"
#include "audio_input.hpp"
#include "tone_gen.hpp"
#include "dsp_modulate.hpp"
class MicTXProcessor : public BasebandProcessor {
public:
@@ -50,7 +51,14 @@ private:
AudioInput audio_input { };
ToneGen tone_gen { };
ToneGen beep_gen { };
dsp::modulate::Modulator *modulator;
bool am_enabled { false };
bool fm_enabled { true };
bool usb_enabled { false };
bool lsb_enabled { false };
bool dsb_enabled { false };
uint32_t divider { };
float audio_gain { };
uint64_t power_acc { 0 };