From a66afffd9ed9078dbb1ea0e556916d90998b8218 Mon Sep 17 00:00:00 2001 From: f4exb Date: Mon, 25 Feb 2019 02:29:59 +0100 Subject: [PATCH] FreeDV demod: initialize FreeDV stuff --- plugins/channelrx/demodfreedv/CMakeLists.txt | 3 + plugins/channelrx/demodfreedv/freedvdemod.cpp | 98 +++++++++++++++++++ plugins/channelrx/demodfreedv/freedvdemod.h | 13 +++ 3 files changed, 114 insertions(+) diff --git a/plugins/channelrx/demodfreedv/CMakeLists.txt b/plugins/channelrx/demodfreedv/CMakeLists.txt index 4b41d26ce..059071e2d 100644 --- a/plugins/channelrx/demodfreedv/CMakeLists.txt +++ b/plugins/channelrx/demodfreedv/CMakeLists.txt @@ -24,6 +24,7 @@ include_directories( . ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_SOURCE_DIR}/swagger/sdrangel/code/qt5/client + ${CODEC2_INCLUDE_DIR} ) add_definitions(${QT_DEFINITIONS}) @@ -42,6 +43,8 @@ target_link_libraries(demodfreedv ${QT_LIBRARIES} sdrbase sdrgui + swagger + ${CODEC2_LIBRARIES} ) target_link_libraries(demodfreedv Qt5::Core Qt5::Widgets) diff --git a/plugins/channelrx/demodfreedv/freedvdemod.cpp b/plugins/channelrx/demodfreedv/freedvdemod.cpp index 1eaf7fc81..75235b394 100644 --- a/plugins/channelrx/demodfreedv/freedvdemod.cpp +++ b/plugins/channelrx/demodfreedv/freedvdemod.cpp @@ -22,6 +22,8 @@ #include #include +#include "codec2/freedv_api.h" + #include "SWGChannelSettings.h" #include "SWGFreeDVDemodSettings.h" #include "SWGChannelReport.h" @@ -59,6 +61,14 @@ FreeDVDemod::FreeDVDemod(DeviceSourceAPI *deviceAPI) : m_sampleSink(0), m_audioFifo(24000), m_modemSampleRate(48000), + m_freeDV(0), + m_nSpeechSamples(0), + m_nMaxModemSamples(0), + m_iSpeech(0), + m_iModem(0), + m_speechOut(0), + m_modIn(0), + m_scaleFactor(SDR_RX_SCALEF), m_settingsMutex(QMutex::Recursive) { setObjectName(m_channelId); @@ -413,6 +423,94 @@ void FreeDVDemod::applyFreeDVMode(FreeDVDemodSettings::FreeDVMode mode) } } + // FreeDV object + + if (m_freeDV) { + freedv_close(m_freeDV); + } + + int fdv_mode = -1; + + switch(mode) + { + case FreeDVDemodSettings::FreeDVMode700D: + fdv_mode = FREEDV_MODE_700D; + m_scaleFactor = SDR_RX_SCALEF / 3.2f; + break; + case FreeDVDemodSettings::FreeDVMode800XA: + fdv_mode = FREEDV_MODE_800XA; + m_scaleFactor = SDR_RX_SCALEF / 8.2f; + break; + case FreeDVDemodSettings::FreeDVMode1600: + fdv_mode = FREEDV_MODE_1600; + m_scaleFactor = SDR_RX_SCALEF / 3.2f; + break; + case FreeDVDemodSettings::FreeDVMode2400A: + default: + fdv_mode = FREEDV_MODE_2400A; + m_scaleFactor = SDR_RX_SCALEF / 8.2f; + break; + } + + if (fdv_mode == FREEDV_MODE_700D) + { + struct freedv_advanced adv; + adv.interleave_frames = 1; + m_freeDV = freedv_open_advanced(fdv_mode, &adv); + } + else + { + m_freeDV = freedv_open(fdv_mode); + } + + if (m_freeDV) + { + freedv_set_test_frames(m_freeDV, 0); + freedv_set_snr_squelch_thresh(m_freeDV, -100.0); + freedv_set_squelch_en(m_freeDV, 0); + freedv_set_clip(m_freeDV, 0); + freedv_set_tx_bpf(m_freeDV, 1); + freedv_set_ext_vco(m_freeDV, 0); + + int nSpeechSamples = freedv_get_n_speech_samples(m_freeDV); + int nNomModemSamples = freedv_get_n_max_modem_samples(m_freeDV); + int Fs = freedv_get_modem_sample_rate(m_freeDV); + int Rs = freedv_get_modem_symbol_rate(m_freeDV); + + if (nSpeechSamples != m_nSpeechSamples) + { + if (m_speechOut) { + delete[] m_speechOut; + } + + m_speechOut = new int16_t[m_nSpeechSamples]; + m_nSpeechSamples = nSpeechSamples; + } + + if (nNomModemSamples != m_nMaxModemSamples) + { + if (m_modIn) { + delete[] m_modIn; + } + + m_modIn = new int16_t[m_nMaxModemSamples]; + m_nMaxModemSamples = nNomModemSamples; + } + + m_iSpeech = 0; + m_iModem = 0; + m_nin = freedv_nin(m_freeDV); + + qDebug() << "FreeDVMod::applyFreeDVMode:" + << " fdv_mode: " << fdv_mode + << " m_modemSampleRate: " << m_modemSampleRate + << " Fs: " << Fs + << " Rs: " << Rs + << " m_nSpeechSamples: " << m_nSpeechSamples + << " m_nMaxModemSamples: " << m_nMaxModemSamples + << " m_nin: " << m_nin; + } + m_settingsMutex.unlock(); } diff --git a/plugins/channelrx/demodfreedv/freedvdemod.h b/plugins/channelrx/demodfreedv/freedvdemod.h index 594193421..73bb980e4 100644 --- a/plugins/channelrx/demodfreedv/freedvdemod.h +++ b/plugins/channelrx/demodfreedv/freedvdemod.h @@ -29,6 +29,7 @@ #include "dsp/fftfilt.h" #include "dsp/agc.h" #include "audio/audiofifo.h" +#include "audio/audioresampler.h" #include "util/message.h" #include "util/doublebufferfifo.h" @@ -42,6 +43,7 @@ class QNetworkReply; class DeviceSourceAPI; class ThreadedBasebandSampleSink; class DownChannelizer; +struct freedv; class FreeDVDemod : public BasebandSampleSink, public ChannelSinkAPI { Q_OBJECT @@ -314,6 +316,17 @@ private: QNetworkAccessManager *m_networkManager; QNetworkRequest m_networkRequest; + struct freedv *m_freeDV; + int m_nSpeechSamples; + int m_nMaxModemSamples; + int m_nin; + int m_iSpeech; + int m_iModem; + int16_t *m_speechOut; + int16_t *m_modIn; + float m_scaleFactor; //!< divide by this amount to scale from int16 to float in [-1.0, 1.0] interval + AudioResampler m_audioResampler; + QMutex m_settingsMutex; void applyChannelSettings(int inputSampleRate, int inputFrequencyOffset, bool force = false);