From 7d484181cc0bd3df56ab82e41846c2ac2c2951ae Mon Sep 17 00:00:00 2001 From: f4exb Date: Sun, 8 Oct 2017 17:37:12 +0200 Subject: [PATCH] NFM demod: GUI and demod separation phase1 --- .../channelrx/demodnfm/nfmdemodsettings.cpp | 159 ++++++++++++++++++ plugins/channelrx/demodnfm/nfmdemodsettings.h | 63 +++++++ 2 files changed, 222 insertions(+) create mode 100644 plugins/channelrx/demodnfm/nfmdemodsettings.cpp create mode 100644 plugins/channelrx/demodnfm/nfmdemodsettings.h diff --git a/plugins/channelrx/demodnfm/nfmdemodsettings.cpp b/plugins/channelrx/demodnfm/nfmdemodsettings.cpp new file mode 100644 index 000000000..7538a004e --- /dev/null +++ b/plugins/channelrx/demodnfm/nfmdemodsettings.cpp @@ -0,0 +1,159 @@ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2017 Edouard Griffiths, F4EXB // +// // +// 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 as version 3 of the License, or // +// // +// 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 V3 for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with this program. If not, see . // +/////////////////////////////////////////////////////////////////////////////////// + +#include + +#include "dsp/dspengine.h" +#include "util/simpleserializer.h" +#include "settings/serializable.h" + +#include "nfmdemodsettings.h" + +const int NFMDemodSettings::m_rfBW[] = { + 5000, 6250, 8330, 10000, 12500, 15000, 20000, 25000, 40000 +}; +const int NFMDemodSettings::m_fmDev[] = { // corresponding FM deviations + 1000, 1500, 2000, 2000, 2000, 2500, 3000, 3500, 5000 +}; +const int NFMDemodSettings::m_nbRfBW = 9; + +NFMDemodSettings::NFMDemodSettings() : + m_channelMarker(0) +{ + resetToDefaults(); +} + +void NFMDemodSettings::resetToDefaults() +{ + m_inputSampleRate = 96000; + m_inputFrequencyOffset = 0; + m_rfBandwidth = 12500; + m_afBandwidth = 3000; + m_fmDeviation = 2000; + m_squelchGate = 5; // 10s of ms at 48000 Hz sample rate. Corresponds to 2400 for AGC attack + m_deltaSquelch = false; + m_squelch = -300.0; + m_volume = 1.0; + m_ctcssOn = false; + m_audioMute = false; + m_ctcssIndex = 0; + m_audioSampleRate = DSPEngine::instance()->getAudioSampleRate(); + m_rgbColor = QColor(255, 0, 0).rgb(); +} + +QByteArray NFMDemodSettings::serialize() const +{ + SimpleSerializer s(1); + s.writeS32(1, m_inputFrequencyOffset); + s.writeS32(2, getRFBWIndex(m_rfBandwidth)); + s.writeS32(3, m_afBandwidth/1000.0); + s.writeS32(4, m_volume*10.0); + s.writeS32(5, (int) m_squelch); + s.writeU32(7, m_rgbColor); + s.writeS32(8, m_ctcssIndex); + s.writeBool(9, m_ctcssOn); + s.writeBool(10, m_audioMute); + s.writeS32(11, m_squelchGate); + s.writeBool(12, m_deltaSquelch); + + if (m_channelMarker) { + s.writeBlob(13, m_channelMarker->serialize()); + } + return s.final(); +} + +bool NFMDemodSettings::deserialize(const QByteArray& data) +{ + SimpleDeserializer d(data); + + if (!d.isValid()) + { + resetToDefaults(); + return false; + } + + if (d.getVersion() == 1) + { + QByteArray bytetmp; + qint32 tmp; + + if (m_channelMarker) + { + d.readBlob(13, &bytetmp); + m_channelMarker->deserialize(bytetmp); + } + + d.readS32(1, &tmp, 0); + m_inputFrequencyOffset = tmp; + d.readS32(2, &tmp, 4); + m_rfBandwidth = getRFBW(tmp); + m_fmDeviation = getFMDev(tmp); + d.readS32(3, &tmp, 3); + m_afBandwidth = tmp * 1000.0; + d.readS32(4, &tmp, 20); + m_volume = tmp / 10.0; + d.readS32(5, &tmp, -300); + m_squelch = tmp * 1.0; + d.readU32(7, &m_rgbColor, QColor(255, 0, 0).rgb()); + d.readS32(8, &m_ctcssIndex, 0); + d.readBool(9, &m_ctcssOn, false); + d.readBool(10, &m_audioMute, false); + d.readS32(11, &m_squelchGate, 5); + d.readBool(12, &m_deltaSquelch, false); + + return true; + } + else + { + resetToDefaults(); + return false; + } +} + +int NFMDemodSettings::getRFBW(int index) +{ + if (index < 0) { + return m_rfBW[0]; + } else if (index < m_nbRfBW) { + return m_rfBW[index]; + } else { + return m_rfBW[m_nbRfBW-1]; + } +} + +int NFMDemodSettings::getFMDev(int index) +{ + if (index < 0) { + return m_fmDev[0]; + } else if (index < m_nbRfBW) { + return m_fmDev[index]; + } else { + return m_fmDev[m_nbRfBW-1]; + } +} + +int NFMDemodSettings::getRFBWIndex(int rfbw) +{ + for (int i = 0; i < m_nbRfBW; i++) + { + if (rfbw <= m_rfBW[i]) + { + return i; + } + } + + return m_nbRfBW-1; +} diff --git a/plugins/channelrx/demodnfm/nfmdemodsettings.h b/plugins/channelrx/demodnfm/nfmdemodsettings.h new file mode 100644 index 000000000..d686babd1 --- /dev/null +++ b/plugins/channelrx/demodnfm/nfmdemodsettings.h @@ -0,0 +1,63 @@ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2017 Edouard Griffiths, F4EXB // +// // +// 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 as version 3 of the License, or // +// // +// 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 V3 for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with this program. If not, see . // +/////////////////////////////////////////////////////////////////////////////////// + +#ifndef PLUGINS_CHANNELRX_DEMODNFM_NFMDEMODSETTINGS_H_ +#define PLUGINS_CHANNELRX_DEMODNFM_NFMDEMODSETTINGS_H_ + +#include + +class Serializable; + +struct NFMDemodSettings +{ + static const int m_nbRfBW; + static const int m_rfBW[]; + static const int m_fmDev[]; + + int m_inputSampleRate; + int64_t m_inputFrequencyOffset; + Real m_rfBandwidth; + Real m_afBandwidth; + int m_fmDeviation; + int m_squelchGate; + bool m_deltaSquelch; + Real m_squelch; //!< centi-Bels + Real m_volume; + bool m_ctcssOn; + bool m_audioMute; + int m_ctcssIndex; + uint32_t m_audioSampleRate; + bool m_copyAudioToUDP; + QString m_udpAddress; + uint16_t m_udpPort; + quint32 m_rgbColor; + + Serializable *m_channelMarker; + + NFMDemodSettings(); + void resetToDefaults(); + void setChannelMarker(Serializable *channelMarker) { m_channelMarker = channelMarker; } + QByteArray serialize() const; + bool deserialize(const QByteArray& data); + + static int getRFBW(int index); + static int getFMDev(int index); + static int getRFBWIndex(int rfbw); +}; + + + +#endif /* PLUGINS_CHANNELRX_DEMODNFM_NFMDEMODSETTINGS_H_ */