mirror of
https://github.com/f4exb/sdrangel.git
synced 2024-12-23 01:55:48 -05:00
M17 demod: various adjustments
This commit is contained in:
parent
278a94f29e
commit
f326860f64
@ -274,6 +274,7 @@ struct M17FrameDecoder
|
||||
std::array<int8_t, 272> tmp;
|
||||
std::copy(buffer.begin() + 96, buffer.end(), tmp.begin());
|
||||
|
||||
depuncture(tmp, depuncture_buffer.stream, P2);
|
||||
viterbi_cost = viterbi_.decode(depuncture_buffer.stream, decode_buffer.stream);
|
||||
to_byte_array(decode_buffer.stream, output_buffer.stream);
|
||||
|
||||
|
@ -14,6 +14,19 @@
|
||||
namespace mobilinkd
|
||||
{
|
||||
|
||||
inline constexpr std::array<int8_t, 61> make_p1() {
|
||||
std::array<int8_t, 61> result{};
|
||||
for (size_t i = 0, j = 2; i != 61; ++i) {
|
||||
if (i == j) {
|
||||
result[i] = 0;
|
||||
j += 4;
|
||||
} else {
|
||||
result[i] = 1;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
/// Puncture matrix for LSF
|
||||
constexpr auto P1 = std::array<int8_t, 61>{
|
||||
1,
|
||||
@ -42,8 +55,7 @@ constexpr auto P2 = std::array<int8_t, 12>{
|
||||
|
||||
/// Puncture matrix for packet frames (7/8).
|
||||
constexpr auto P3 = std::array<int8_t, 8>{
|
||||
1, 1, 1, 1,
|
||||
1, 1, 1, 0};
|
||||
1, 1, 1, 1, 1, 1, 1, 0};
|
||||
|
||||
/**
|
||||
* Convert an integer value to an array of bits, with the
|
||||
|
@ -57,7 +57,7 @@ constexpr std::array<std::array<uint8_t, (1 << Trellis_::k)>, (1 << Trellis_::K)
|
||||
for (size_t j = 0; j != (1 << Trellis_::k); ++j)
|
||||
{
|
||||
size_t l = update_memory<Trellis_::K, Trellis_::k>(i, j) & (NumStates - 1);
|
||||
result[l][k] = i;
|
||||
result[l][k] = i;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
@ -156,7 +156,7 @@ struct Viterbi
|
||||
|
||||
/**
|
||||
* Viterbi soft decoder using LLR inputs where 0 == erasure.
|
||||
*
|
||||
*
|
||||
* @return path metric for estimating BER.
|
||||
*/
|
||||
template <size_t IN, size_t OUT>
|
||||
@ -198,7 +198,7 @@ struct Viterbi
|
||||
cost1[j] += std::abs(cost_[j][1] + s1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (size_t j = 0; j != BUTTERFLY_SIZE; ++j)
|
||||
{
|
||||
calculate_path_metric(cost0, cost1, history_[hindex], j);
|
||||
|
@ -148,7 +148,9 @@ public:
|
||||
const QString& getSrcCall() const { return m_basebandSink->getSrcCall(); }
|
||||
const QString& getDestcCall() const { return m_basebandSink->getDestcCall(); }
|
||||
const QString& getTypeInfo() const { return m_basebandSink->getTypeInfo(); }
|
||||
bool getStreamElsePacket() const { return m_basebandSink->getStreamElsePacket(); }
|
||||
uint16_t getCRC() const { return m_basebandSink->getCRC(); }
|
||||
int getStdPacketProtocol() const { return m_basebandSink->getStdPacketProtocol(); }
|
||||
|
||||
static const char* const m_channelIdURI;
|
||||
static const char* const m_channelId;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -94,7 +94,9 @@ public:
|
||||
const QString& getSrcCall() const { return m_sink.getSrcCall(); }
|
||||
const QString& getDestcCall() const { return m_sink.getDestcCall(); }
|
||||
const QString& getTypeInfo() const { return m_sink.getTypeInfo(); }
|
||||
bool getStreamElsePacket() const { return m_sink.getStreamElsePacket(); }
|
||||
uint16_t getCRC() const { return m_sink.getCRC(); }
|
||||
int getStdPacketProtocol() const { return m_sink.getStdPacketProtocol(); }
|
||||
|
||||
private:
|
||||
SampleSinkFifo m_sampleFifo;
|
||||
|
@ -157,8 +157,8 @@ void M17DemodGUI::on_fmDeviation_valueChanged(int value)
|
||||
|
||||
void M17DemodGUI::on_volume_valueChanged(int value)
|
||||
{
|
||||
m_settings.m_volume= value / 10.0;
|
||||
ui->volumeText->setText(QString("%1").arg(value / 10.0, 0, 'f', 1));
|
||||
m_settings.m_volume= value / 100.0;
|
||||
ui->volumeText->setText(QString("%1").arg(value / 100.0, 0, 'f', 2));
|
||||
applySettings();
|
||||
}
|
||||
|
||||
@ -419,8 +419,8 @@ void M17DemodGUI::displaySettings()
|
||||
ui->squelchGate->setValue(m_settings.m_squelchGate);
|
||||
ui->squelchGateText->setText(QString("%1").arg(ui->squelchGate->value() * 10.0, 0, 'f', 0));
|
||||
|
||||
ui->volume->setValue(m_settings.m_volume * 10.0);
|
||||
ui->volumeText->setText(QString("%1").arg(ui->volume->value() / 10.0, 0, 'f', 1));
|
||||
ui->volume->setValue(m_settings.m_volume * 100.0);
|
||||
ui->volumeText->setText(QString("%1").arg(ui->volume->value() / 100.0, 0, 'f', 2));
|
||||
|
||||
ui->syncOrConstellation->setChecked(m_settings.m_syncOrConstellation);
|
||||
ui->audioMute->setChecked(m_settings.m_audioMute);
|
||||
@ -561,10 +561,10 @@ void M17DemodGUI::tick()
|
||||
ui->lockLabel->setStyleSheet("QLabel { background-color : green; }");
|
||||
}
|
||||
|
||||
ui->syncText->setText(getStatus(status));
|
||||
ui->syncText->setText(getStatus(status, m_m17Demod->getStreamElsePacket(), m_m17Demod->getStdPacketProtocol()));
|
||||
ui->evmText->setText(tr("%1").arg(evm*100.0f, 3, 'f', 1));
|
||||
ui->deviationText->setText(tr("%1").arg(deviation, 2, 'f', 1));
|
||||
ui->offsetText->setText(tr("%1").arg(offset, 3, 'f', 2));
|
||||
ui->deviationText->setText(tr("%1").arg(deviation/1.5f, 3, 'f', 2));
|
||||
ui->offsetText->setText(tr("%1").arg(offset/1.5f, 3, 'f', 2));
|
||||
ui->viterbiText->setText(tr("%1").arg(viterbiCost));
|
||||
ui->clockText->setText(tr("%1").arg(clock, 2, 'f', 1));
|
||||
ui->sampleText->setText(tr("%1, %2, %3").arg(sampleIndex).arg(syncIndex).arg(clockIndex));
|
||||
@ -575,27 +575,47 @@ void M17DemodGUI::tick()
|
||||
ui->destText->setText(m_m17Demod->getDestcCall());
|
||||
ui->typeText->setText(m_m17Demod->getTypeInfo());
|
||||
ui->crcText->setText(tr("%1").arg(m_m17Demod->getCRC(), 4, 16, QChar('0')));
|
||||
|
||||
if (ui->activateStatusLog->isChecked() && (m_m17Demod->getLSFCount() != 0))
|
||||
{
|
||||
QString s = tr("Src: %1 Dst: %2 Typ: %3 CRC: %4")
|
||||
.arg(m_m17Demod->getSrcCall())
|
||||
.arg(m_m17Demod->getDestcCall())
|
||||
.arg(m_m17Demod->getTypeInfo())
|
||||
.arg(m_m17Demod->getCRC(), 4, 16, QChar('0'));
|
||||
m_m17StatusTextDialog.addLine(s);
|
||||
}
|
||||
|
||||
m_lsfCount = m_m17Demod->getLSFCount();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
m_tickCount++;
|
||||
}
|
||||
|
||||
QString M17DemodGUI::getStatus(int status)
|
||||
QString M17DemodGUI::getStatus(int status, bool streamElsePacket, int packetProtocol)
|
||||
{
|
||||
if (status == 0) {
|
||||
return "Unlocked";
|
||||
} else if (status == 1) {
|
||||
return "LSF";
|
||||
} else if (status == 2) {
|
||||
return "Stream";
|
||||
} else if (status == 3) {
|
||||
return "Packet";
|
||||
} else if (status == 4) {
|
||||
return "BERT";
|
||||
} else if (status == 5) {
|
||||
return "Frame";
|
||||
} else if (streamElsePacket) {
|
||||
return "Stream";
|
||||
} else if (packetProtocol == 0) {
|
||||
return "Raw";
|
||||
} else if (packetProtocol == 1) {
|
||||
return "AX.25";
|
||||
} else if (packetProtocol == 2) {
|
||||
return "APRS";
|
||||
} else if (packetProtocol == 3) {
|
||||
return "6LoWPAN";
|
||||
} else if (packetProtocol == 4) {
|
||||
return "IPv4";
|
||||
} else if (packetProtocol == 5) {
|
||||
return "SMS";
|
||||
} else if (packetProtocol == 6) {
|
||||
return "Winlink";
|
||||
} else {
|
||||
return "Unknown";
|
||||
}
|
||||
|
@ -110,7 +110,7 @@ private:
|
||||
bool handleMessage(const Message& message);
|
||||
void makeUIConnections();
|
||||
void updateAbsoluteCenterFrequency();
|
||||
QString getStatus(int status);
|
||||
QString getStatus(int status, bool streamElsePacket, int packetProtocol);
|
||||
|
||||
void leaveEvent(QEvent*);
|
||||
void enterEvent(QEvent*);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -40,7 +40,7 @@ M17DemodProcessor::M17DemodProcessor() :
|
||||
{
|
||||
m_this = this;
|
||||
m_codec2 = ::codec2_create(CODEC2_MODE_3200);
|
||||
m_audioBuffer.resize(48000);
|
||||
m_audioBuffer.resize(12000);
|
||||
m_audioBufferFill = 0;
|
||||
m_srcCall = "";
|
||||
m_destCall = "";
|
||||
@ -212,14 +212,16 @@ bool M17DemodProcessor::decode_lsf(mobilinkd::M17FrameDecoder::lsf_buffer_t cons
|
||||
}
|
||||
}
|
||||
|
||||
qDebug() << "M17DemodProcessor::decode_lsf: " << oss.str().c_str();
|
||||
m_lsfCount++;
|
||||
qDebug() << "M17DemodProcessor::decode_lsf: " << m_lsfCount << ":" << oss.str().c_str();
|
||||
return true;
|
||||
}
|
||||
|
||||
void M17DemodProcessor::decode_type(uint16_t type)
|
||||
{
|
||||
if (type & 1) // bit 0
|
||||
m_streamElsePacket = type & 1; // bit 0
|
||||
|
||||
if (m_streamElsePacket)
|
||||
{
|
||||
m_typeInfo = "STR:"; // Stream mode
|
||||
|
||||
@ -268,6 +270,7 @@ void M17DemodProcessor::resetInfo()
|
||||
m_srcCall = "";
|
||||
m_destCall = "";
|
||||
m_typeInfo = "";
|
||||
m_streamElsePacket = true;
|
||||
m_metadata.fill(0);
|
||||
m_crc = 0;
|
||||
m_lsfCount = 0;
|
||||
@ -301,33 +304,58 @@ bool M17DemodProcessor::decode_packet(mobilinkd::M17FrameDecoder::packet_buffer_
|
||||
if (packet_segment[25] & 0x80) // last frame of packet.
|
||||
{
|
||||
size_t packet_size = (packet_segment[25] & 0x7F) >> 2;
|
||||
packet_size = std::min(packet_size, size_t(25));
|
||||
packet_size = std::min(packet_size, size_t(25)); // on last frame this is the remainder byte count
|
||||
m_packetFrameCounter = 0;
|
||||
|
||||
for (size_t i = 0; i != packet_size; ++i) {
|
||||
m_currentPacket.push_back(packet_segment[i]);
|
||||
}
|
||||
|
||||
if (m_currentPacket.size() < 3) {
|
||||
qDebug() << "M17DemodProcessor::decode_packet: too small:" << m_currentPacket.size();
|
||||
return false;
|
||||
}
|
||||
|
||||
boost::crc_optimal<16, 0x1021, 0xFFFF, 0xFFFF, true, true> crc;
|
||||
crc.process_bytes(&m_currentPacket.front(), m_currentPacket.size());
|
||||
uint16_t checksum = crc.checksum();
|
||||
uint16_t calcChecksum = crc.checksum();
|
||||
uint16_t xmitChecksum = m_currentPacket.back() + (1<<8) * m_currentPacket.end()[-2];
|
||||
|
||||
if (checksum == 0x0f47)
|
||||
if (calcChecksum == xmitChecksum) // (checksum == 0x0f47)
|
||||
{
|
||||
std::string ax25;
|
||||
ax25.reserve(m_currentPacket.size());
|
||||
uint8_t protocol = m_currentPacket.front();
|
||||
m_stdPacketProtocol = protocol < (int) StdPacketUnknown ? (StdPacketProtocol) protocol : StdPacketUnknown;
|
||||
qDebug() << "M17DemodProcessor::decode_packet: protocol: " << m_stdPacketProtocol;
|
||||
|
||||
for (auto c : m_currentPacket) {
|
||||
ax25.push_back(char(c));
|
||||
if (m_stdPacketProtocol == StdPacketAX25)
|
||||
{
|
||||
std::string ax25;
|
||||
ax25.reserve(m_currentPacket.size());
|
||||
|
||||
for (auto c : m_currentPacket) {
|
||||
ax25.push_back(char(c));
|
||||
}
|
||||
|
||||
mobilinkd::ax25_frame frame(ax25);
|
||||
std::ostringstream oss;
|
||||
mobilinkd::write(oss, frame); // TODO: get details
|
||||
qDebug() << "M17DemodProcessor::decode_packet: AX25:" << oss.str().c_str();
|
||||
}
|
||||
else if (m_stdPacketProtocol == StdPacketSMS)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
|
||||
for (std::vector<uint8_t>::const_iterator it = m_currentPacket.begin()+1; it < m_currentPacket.end()-2; ++it) {
|
||||
oss << *it;
|
||||
}
|
||||
|
||||
qDebug() << "M17DemodProcessor::decode_packet: SMS:" << oss.str().c_str();
|
||||
}
|
||||
|
||||
mobilinkd::ax25_frame frame(ax25);
|
||||
std::ostringstream oss;
|
||||
mobilinkd::write(oss, frame); // TODO: get details
|
||||
qDebug() << "M17DemodProcessor::decode_packet: " << oss.str().c_str();
|
||||
return true;
|
||||
}
|
||||
|
||||
qWarning() << "M17DemodProcessor::decode_packet: Packet checksum error: " << std::hex << checksum << std::dec;
|
||||
qWarning() << "M17DemodProcessor::decode_packet: Packet checksum error: " << std::hex << calcChecksum << "vs" << xmitChecksum << std::dec;
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -450,8 +478,8 @@ void M17DemodProcessor::upsample(int upsampling, const int16_t *in, int nbSample
|
||||
for (int j = 1; j <= upsampling; j++)
|
||||
{
|
||||
upsample = (qint16) m_upsamplingFilter.runLP(cur*m_upsamplingFactors[j] + prev*m_upsamplingFactors[upsampling-j]);
|
||||
m_audioBuffer[m_audioBufferFill].l = upsample; //m_compressor.compress(upsample);
|
||||
m_audioBuffer[m_audioBufferFill].r = upsample; //m_compressor.compress(upsample);
|
||||
m_audioBuffer[m_audioBufferFill].l = m_compressor.compress(upsample);
|
||||
m_audioBuffer[m_audioBufferFill].r = m_compressor.compress(upsample);
|
||||
|
||||
if (m_audioBufferFill < m_audioBuffer.size() - 1) {
|
||||
++m_audioBufferFill;
|
||||
@ -492,3 +520,12 @@ void M17DemodProcessor::setVolumeFactors()
|
||||
m_upsamplingFactors[i] = (i*m_volume) / (float) m_upsampling;
|
||||
}
|
||||
}
|
||||
|
||||
M17DemodProcessor::StdPacketProtocol M17DemodProcessor::getStdPacketProtocol() const
|
||||
{
|
||||
if (m_streamElsePacket) {
|
||||
return StdPacketUnknown;
|
||||
} else {
|
||||
return m_stdPacketProtocol;
|
||||
}
|
||||
}
|
||||
|
@ -30,6 +30,18 @@ class M17DemodProcessor : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum StdPacketProtocol
|
||||
{
|
||||
StdPacketRaw,
|
||||
StdPacketAX25,
|
||||
StdPacketAPRS,
|
||||
StdPacket6LoWPAN,
|
||||
StdPacketIPv4,
|
||||
StdPacketSMS,
|
||||
StdPacketWinlink,
|
||||
StdPacketUnknown
|
||||
};
|
||||
|
||||
M17DemodProcessor();
|
||||
~M17DemodProcessor();
|
||||
|
||||
@ -47,7 +59,9 @@ public:
|
||||
const QString& getSrcCall() const { return m_srcCall; }
|
||||
const QString& getDestcCall() const { return m_destCall; }
|
||||
const QString& getTypeInfo() const { return m_typeInfo; }
|
||||
bool getStreamElsePacket() const { return m_streamElsePacket; }
|
||||
uint16_t getCRC() const { return m_crc; }
|
||||
StdPacketProtocol getStdPacketProtocol() const;
|
||||
|
||||
void getDiagnostics(
|
||||
bool& dcd,
|
||||
@ -110,9 +124,11 @@ private:
|
||||
QString m_srcCall;
|
||||
QString m_destCall;
|
||||
QString m_typeInfo;
|
||||
bool m_streamElsePacket;
|
||||
std::array<uint8_t, 14> m_metadata;
|
||||
uint16_t m_crc;
|
||||
uint32_t m_lsfCount; // Incremented each time a new LSF is decoded. Reset when lock is lost.
|
||||
StdPacketProtocol m_stdPacketProtocol;
|
||||
|
||||
static bool handle_frame(mobilinkd::M17FrameDecoder::output_buffer_t const& frame, int viterbi_cost);
|
||||
static void diagnostic_callback(
|
||||
|
@ -96,7 +96,9 @@ public:
|
||||
const QString& getSrcCall() const { return m_m17DemodProcessor.getSrcCall(); }
|
||||
const QString& getDestcCall() const { return m_m17DemodProcessor.getDestcCall(); }
|
||||
const QString& getTypeInfo() const { return m_m17DemodProcessor.getTypeInfo(); }
|
||||
bool getStreamElsePacket() const { return m_m17DemodProcessor.getStreamElsePacket(); }
|
||||
uint16_t getCRC() const { return m_m17DemodProcessor.getCRC(); }
|
||||
int getStdPacketProtocol() const { return (int) m_m17DemodProcessor.getStdPacketProtocol(); }
|
||||
|
||||
private:
|
||||
struct MagSqLevelsStore
|
||||
|
@ -39,17 +39,17 @@ M17StatusTextDialog::~M17StatusTextDialog()
|
||||
|
||||
void M17StatusTextDialog::addLine(const QString& line)
|
||||
{
|
||||
if ((line.size() > 0) && (line != m_lastLine))
|
||||
if (line.size() > 0)
|
||||
{
|
||||
QDateTime dt = QDateTime::currentDateTime();
|
||||
QString dateStr = dt.toString("HH:mm:ss");
|
||||
QTextCursor cursor = ui->logEdit->textCursor();
|
||||
cursor.movePosition(QTextCursor::End, QTextCursor::MoveAnchor);
|
||||
cursor.insertText(tr("%1 %2\n").arg(dateStr).arg(line));
|
||||
|
||||
if (ui->pinToLastLine->isChecked()) {
|
||||
ui->logEdit->verticalScrollBar()->setValue(ui->logEdit->verticalScrollBar()->maximum());
|
||||
}
|
||||
m_lastLine = line;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -36,7 +36,6 @@ public:
|
||||
|
||||
private:
|
||||
Ui::M17StatusTextDialog* ui;
|
||||
QString m_lastLine;
|
||||
|
||||
private slots:
|
||||
void on_clear_clicked();
|
||||
|
@ -109,6 +109,7 @@
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>Liberation Mono</family>
|
||||
<pointsize>9</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
@ -148,32 +149,32 @@
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>DSDStatusTextDialog</receiver>
|
||||
<receiver>M17StatusTextDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>257</x>
|
||||
<y>194</y>
|
||||
<x>369</x>
|
||||
<y>357</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>203</y>
|
||||
<x>369</x>
|
||||
<y>189</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>DSDStatusTextDialog</receiver>
|
||||
<receiver>M17StatusTextDialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>314</x>
|
||||
<y>194</y>
|
||||
<x>369</x>
|
||||
<y>357</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>203</y>
|
||||
<x>369</x>
|
||||
<y>189</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
|
Loading…
Reference in New Issue
Block a user