/** * @file cusdr_receiver.cpp * @brief cuSDR receiver class * @author Hermann von Hasseln, DL3HVH * @version 0.1 * @date 2010-11-12 */ /* Copyright (C) * * 2010 - Hermann von Hasseln, DL3HVH * * 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 * of the License, 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; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ #define LOG_RECEIVER // use: RECEIVER_DEBUG #include "cusdr_receiver.h" Receiver::Receiver(int rx) : QObject() , set(Settings::instance()) , m_filterMode(set->getCurrentFilterMode()) , m_stopped(false) , m_receiver(rx) , m_samplerate(set->getSampleRate()) , m_audioMode(1) //, m_calOffset(63.0) //, m_calOffset(33.0) { setReceiverData(set->getReceiverDataList().at(m_receiver)); InitCPX(inBuf, BUFFER_SIZE, 0.0f); InitCPX(outBuf, BUFFER_SIZE, 0.0f); newSpectrum.resize(BUFFER_SIZE*4); qtdsp = 0; setupConnections(); highResTimer = new HResTimer(); m_displayTime = (int)(1000000.0/set->getFramesPerSecond(m_receiver)); m_smeterTime.start(); } Receiver::~Receiver() { inBuf.clear(); outBuf.clear(); if (qtdsp) { delete qtdsp; qtdsp = 0; } if (highResTimer) { delete highResTimer; } m_stopped = false; } void Receiver::setupConnections() { CHECKED_CONNECT( set, SIGNAL(systemStateChanged( QObject *, QSDR::_Error, QSDR::_HWInterfaceMode, QSDR::_ServerMode, QSDR::_DataEngineState)), this, SLOT(setSystemState( QObject *, QSDR::_Error, QSDR::_HWInterfaceMode, QSDR::_ServerMode, QSDR::_DataEngineState))); CHECKED_CONNECT( set, SIGNAL(mainVolumeChanged(QObject *, int, float)), this, SLOT(setAudioVolume(QObject *, int, float))); CHECKED_CONNECT( set, SIGNAL(sampleRateChanged(QObject *, int)), this, SLOT(setSampleRate(QObject *, int))); CHECKED_CONNECT( set, SIGNAL(dspModeChanged(QObject *, int, DSPMode)), this, SLOT(setDspMode(QObject *, int, DSPMode))); CHECKED_CONNECT( set, SIGNAL(hamBandChanged(QObject *, int, bool, HamBand)), this, SLOT(setHamBand(QObject *, int, bool, HamBand))); CHECKED_CONNECT( set, SIGNAL(agcModeChanged(QObject *, int, AGCMode, bool)), this, SLOT(setAGCMode(QObject *, int, AGCMode, bool))); CHECKED_CONNECT( set, SIGNAL(agcGainChanged(QObject *, int, int)), this, SLOT(setAGCGain(QObject *, int, int))); // CHECKED_CONNECT( // set, // SIGNAL(agcMaximumGain_dBmChanged(QObject *, int, int)), // this, // SLOT(setAGCMaximumGain_dBm(QObject *, int, int))); CHECKED_CONNECT( set, SIGNAL(agcMaximumGainChanged_dB(QObject *, int, qreal)), this, SLOT(setAGCMaximumGain_dB(QObject *, int, qreal))); CHECKED_CONNECT( set, SIGNAL(agcFixedGainChanged_dB(QObject *, int, qreal)), this, SLOT(setAGCFixedGain_dB(QObject *, int, qreal))); CHECKED_CONNECT( set, SIGNAL(agcThresholdChanged_dB(QObject *, int, qreal)), this, SLOT(setAGCThreshold_dB(QObject *, int, qreal))); CHECKED_CONNECT( set, SIGNAL(agcHangThresholdChanged(QObject *, int, int)), this, SLOT(setAGCHangThreshold(QObject *, int, int))); CHECKED_CONNECT( set, SIGNAL(agcHangLevelChanged_dB(QObject *, int, qreal)), this, SLOT(setAGCHangLevel_dB(QObject *, int, qreal))); CHECKED_CONNECT( set, SIGNAL(agcVariableGainChanged_dB(QObject *, int, qreal)), this, SLOT(setAGCVariableGain_dB(QObject *, int, qreal))); CHECKED_CONNECT( set, SIGNAL(agcAttackTimeChanged(QObject *, int, qreal)), this, SLOT(setAGCAttackTime(QObject *, int, qreal))); CHECKED_CONNECT( set, SIGNAL(agcDecayTimeChanged(QObject *, int, qreal)), this, SLOT(setAGCDecayTime(QObject *, int, qreal))); CHECKED_CONNECT( set, SIGNAL(agcHangTimeChanged(QObject *, int, qreal)), this, SLOT(setAGCHangTime(QObject *, int, qreal))); CHECKED_CONNECT( set, SIGNAL(filterFrequenciesChanged(QObject *, int, qreal, qreal)), this, SLOT(setFilterFrequencies(QObject *, int, qreal, qreal))); CHECKED_CONNECT( set, SIGNAL(framesPerSecondChanged(QObject*, int, int)), this, SLOT(setFramesPerSecond(QObject*, int, int))); /*CHECKED_CONNECT( set, SIGNAL(receiverDataReady()), this, SLOT(dspProcessing()));*/ } void Receiver::setReceiverData(TReceiver data) { m_receiverData = data; //m_serverMode = m_receiverData.serverMode; m_dspCore = m_receiverData.dspCore; m_sampleRate = m_receiverData.sampleRate; m_hamBand = m_receiverData.hamBand; m_dspMode = m_receiverData.dspMode; m_dspModeList = m_receiverData.dspModeList; m_agcMode = m_receiverData.agcMode; m_agcGain = m_receiverData.acgGain; m_agcFixedGain_dB = m_receiverData.agcFixedGain_dB; m_agcMaximumGain_dB = m_receiverData.agcMaximumGain_dB; m_agcHangThreshold = m_receiverData.agcHangThreshold; m_agcVariableGain = m_receiverData.agcVariableGain; m_audioVolume = m_receiverData.audioVolume; m_filterLo = m_receiverData.filterLo; m_filterHi = m_receiverData.filterHi; m_lastCtrFrequencyList = m_receiverData.lastCenterFrequencyList; m_lastVfoFrequencyList = m_receiverData.lastVfoFrequencyList; m_mercuryAttenuators = m_receiverData.mercuryAttenuators; } bool Receiver::initDSPInterface() { if (m_dspCore == QSDR::QtDSP) { if (!initQtDSPInterface()) return false; } return true; } bool Receiver::initQtDSPInterface() { qtdsp = new QDSPEngine(this, m_receiver, BUFFER_SIZE); if (qtdsp) qtdsp->setQtDSPStatus(true); else { RECEIVER_DEBUG << "could not start QtDSP for receiver: " << m_receiver; qtdsp = 0; return false; } qtdsp->setVolume(m_audioVolume); DSPMode mode = m_dspModeList.at(m_hamBand); RECEIVER_DEBUG << "set DSP mode to: " << set->getDSPModeString(mode); qtdsp->setDSPMode(mode); qtdsp->filter->setFilter( getFilterFromDSPMode(set->getDefaultFilterList(), mode).filterLo, getFilterFromDSPMode(set->getDefaultFilterList(), mode).filterHi); qtdsp->wpagc->setMode(m_agcMode); qtdsp->wpagc->setAGCFixedGainDb(m_agcFixedGain_dB); qtdsp->wpagc->setMaximumGainDb(m_agcMaximumGain_dB); // if (m_agcMode == (AGCMode) agcOFF) // set->setAGCFixedGain_dB(this, m_receiver, m_agcFixedGain_dB); // else // set->setAGCMaximumGain_dB(this, m_receiver, m_agcMaximumGain_dB); RECEIVER_DEBUG << "QtDSP for receiver: " << m_receiver << " started."; return true; } void Receiver::deleteDSPInterface() { if (m_dspCore == QSDR::QtDSP) deleteQtDSP(); } void Receiver::deleteQtDSP() { if (qtdsp) { delete qtdsp; qtdsp = 0; } } void Receiver::enqueueData() { inQueue.enqueue(inBuf); if (inQueue.isFull()) { RECEIVER_DEBUG << "inQueue full!"; } } void Receiver::stop() { m_mutex.lock(); m_stopped = true; m_mutex.unlock(); } void Receiver::dspProcessing() { //RECEIVER_DEBUG << "dspProcessing: " << this->thread(); //io.mutex.lock(); qtdsp->processDSP(inBuf, outBuf, BUFFER_SIZE); //io.mutex.unlock(); // spectrum qtdsp->getSpectrum(newSpectrum, set->getFFTMultiplicator(m_receiver)); if (highResTimer->getElapsedTimeInMicroSec() >= getDisplayDelay()) { emit spectrumBufferChanged(m_receiver, newSpectrum); highResTimer->start(); } if (m_receiver == set->getCurrentReceiver()) { // S-Meter if (m_smeterTime.elapsed() > 20) { m_sMeterValue = qtdsp->getSMeterInstValue(); emit sMeterValueChanged(m_receiver, m_sMeterValue); m_smeterTime.restart(); } // process output data emit outputBufferSignal(m_receiver, outBuf); } } void Receiver::setSampleRate(QObject *sender, int value) { Q_UNUSED(sender) if (m_samplerate == value) return; switch (value) { case 48000: m_samplerate = value; break; case 96000: m_samplerate = value; break; case 192000: m_samplerate = value; break; case 384000: m_samplerate = value; break; default: RECEIVER_DEBUG << "invalid sample rate (possible values are: 48, 96, 192, or 384 kHz)!\n"; break; } if (qtdsp) qtdsp->setSampleRate(this, m_samplerate); else RECEIVER_DEBUG << "qtdsp down: cannot set sample rate!\n"; } void Receiver::setServerMode(QSDR::_ServerMode mode) { m_serverMode = mode; } QSDR::_ServerMode Receiver::getServerMode() const { return m_serverMode; } QSDR::_DSPCore Receiver::getDSPCoreMode() const { return m_dspCore; } //void Receiver::setSocketState(SocketState state) { // // m_socketState = state; //} //Receiver::SocketState Receiver::socketState() const { // // return m_socketState; //} void Receiver::setSystemState( QObject *sender, QSDR::_Error err, QSDR::_HWInterfaceMode hwmode, QSDR::_ServerMode mode, QSDR::_DataEngineState state) { Q_UNUSED (sender) Q_UNUSED (err) if (m_hwInterface != hwmode) m_hwInterface = hwmode; if (m_serverMode != mode) m_serverMode = mode; if (m_dataEngineState != state) m_dataEngineState = state; } void Receiver::setAudioMode(QObject* sender, int mode) { if (sender != this && m_audioMode == mode) return; m_audioMode = mode; } //void Receiver::setID(int value) { // // m_receiverID = value; // RECEIVER_DEBUG << "This is receiver " << m_receiverID; //} void Receiver::setReceiver(int value) { m_receiver = value; } void Receiver::setSampleRate(int value) { m_sampleRate = value; } void Receiver::setHamBand(QObject *sender, int rx, bool byBtn, HamBand band) { Q_UNUSED(sender) Q_UNUSED(byBtn) if (m_receiver == rx) { if (m_hamBand == band) return; m_hamBand = band; } } void Receiver::setDspMode(QObject *sender, int rx, DSPMode mode) { Q_UNUSED(sender) if (m_receiver != rx) return; if (m_dspMode == mode) return; m_dspMode = mode; if (qtdsp) { qtdsp->setDSPMode(mode); qtdsp->filter->setFilter( getFilterFromDSPMode(set->getDefaultFilterList(), mode).filterLo, getFilterFromDSPMode(set->getDefaultFilterList(), mode).filterHi); } //QString msg = "[receiver]: set mode for receiver %1 to %2"; //emit messageEvent(msg.arg(rx).arg(set->getDSPModeString(m_dspMode))); } void Receiver::setAGCMode(QObject *sender, int rx, AGCMode mode, bool hang) { Q_UNUSED(sender) Q_UNUSED(hang) if (m_receiver != rx) return; if (m_agcMode == mode) return; m_agcMode = mode; if (qtdsp) { qtdsp->wpagc->setMode(mode); } } void Receiver::setAGCGain(QObject *sender, int rx, int value) { Q_UNUSED(sender) if (m_receiver != rx) return; if (m_agcGain == value) return; m_agcGain = value; if (qtdsp) { //RECEIVER_DEBUG << "AGCThreshDB (plus offset) = " << m_agcGain - AGCOFFSET; //qtdsp->wpagc->setAGCThreshDb(m_filterLo, m_filterHi, BUFFER_SIZE, m_agcGain - AGCOFFSET); } } void Receiver::setAGCFixedGain_dB(QObject *sender, int rx, qreal value) { Q_UNUSED(sender) if (m_receiver != rx) return; if (m_agcFixedGain_dB == value) return; m_agcFixedGain_dB = value; if (qtdsp) { //RECEIVER_DEBUG << "m_agcFixedGain = " << m_agcFixedGain; qtdsp->wpagc->setAGCFixedGainDb(m_agcFixedGain_dB); } } void Receiver::setAGCMaximumGain_dB(QObject *sender, int rx, qreal value) { Q_UNUSED(sender) if (m_receiver != rx) return; if (m_agcMaximumGain_dB == value) return; m_agcMaximumGain_dB = value; if (qtdsp) { //RECEIVER_DEBUG << "setAGCMaximumGain_dB = " << m_agcMaximumGain_dB; qtdsp->wpagc->setMaximumGainDb(m_agcMaximumGain_dB); } } void Receiver::setAGCThreshold_dB(QObject *sender, int rx, qreal value) { Q_UNUSED(sender) if (m_receiver != rx) return; if (m_agcThreshold_dBm == value) return; m_agcThreshold_dBm = value; if (qtdsp) { //RECEIVER_DEBUG << "AGCThreshDB (minus offset) for Rx " << m_receiver << ": " << m_agcThreshold_dBm - AGCOFFSET; qtdsp->wpagc->setAGCThreshDb(m_filterLo, m_filterHi, 2*BUFFER_SIZE, m_agcThreshold_dBm - AGCOFFSET); } } void Receiver::setAGCHangThreshold(QObject *sender, int rx, int value) { Q_UNUSED(sender) if (m_receiver != rx) return; if (m_agcHangThreshold == value) return; m_agcHangThreshold = value; if (qtdsp) { RECEIVER_DEBUG << "m_agcHangThreshold =" << m_agcHangThreshold/100.0; qtdsp->wpagc->setHangThresh(m_agcHangThreshold/100.0); } } void Receiver::setAGCHangLevel_dB(QObject *sender, int rx, qreal value) { Q_UNUSED(sender) if (m_receiver != rx) return; if (m_agcHangLevel == value) return; m_agcHangLevel = value; if (qtdsp) { //RECEIVER_DEBUG << "m_agcHangLevel = " << m_agcHangLevel - AGCOFFSET; qtdsp->wpagc->setHangLevelDb(m_agcHangLevel - AGCOFFSET); } //set->setAGCHangLeveldB(this, m_receiverID, value); } void Receiver::setAGCVariableGain_dB(QObject *sender, int rx, qreal value) { Q_UNUSED(sender) if (m_receiver != rx) return; if (m_agcVariableGain == value) return; m_agcVariableGain = value; if (qtdsp) { RECEIVER_DEBUG << "m_agcVariableGain = " << m_agcVariableGain; qtdsp->wpagc->setVarGainDb(m_agcVariableGain); } } void Receiver::setAGCAttackTime(QObject *sender, int rx, qreal value) { Q_UNUSED(sender) if (m_receiver != rx) return; if (m_agcAttackTime == value) return; m_agcAttackTime = value; if (qtdsp) { RECEIVER_DEBUG << "m_agcAttackTime = " << m_agcAttackTime; qtdsp->wpagc->setTauAttack(m_agcAttackTime); } } void Receiver::setAGCDecayTime(QObject *sender, int rx, qreal value) { Q_UNUSED(sender) if (m_receiver != rx) return; if (m_agcDecayTime == value) return; m_agcDecayTime = value; if (qtdsp) { RECEIVER_DEBUG << "m_agcDecayTime = " << m_agcDecayTime; qtdsp->wpagc->setTauDecay(m_agcDecayTime); } } void Receiver::setAGCHangTime(QObject *sender, int rx, qreal value) { Q_UNUSED(sender) if (m_receiver != rx) return; if (m_agcHangTime == value) return; m_agcHangTime = value; if (qtdsp) { RECEIVER_DEBUG << "m_agcHangTime = " << m_agcHangTime; qtdsp->wpagc->setHangTime(m_agcHangTime); } } void Receiver::setAudioVolume(QObject *sender, int rx, float value) { Q_UNUSED(sender) if (m_receiver != rx) return; //if (m_audioVolume == value) return; m_audioVolume = value; if (qtdsp) { //RECEIVER_DEBUG << "setAudioVolume =" << m_audioVolume; qtdsp->setVolume(value); } } void Receiver::setFilterFrequencies(QObject *sender, int rx, double low, double high) { Q_UNUSED(sender) if (m_receiver == rx) { if (m_filterLo == low && m_filterHi == high) return; m_filterLo = low; m_filterHi = high; if (qtdsp) { qtdsp->filter->setFilter((float)low, (float)high); qtdsp->wpagc->filterChanged(); } } } void Receiver::setCtrFrequency(long frequency) { if (m_ctrFrequency == frequency) return; m_ctrFrequency = frequency; HamBand band = getBandFromFrequency(set->getBandFrequencyList(), frequency); m_lastCtrFrequencyList[(int) band] = m_ctrFrequency; } void Receiver::setVfoFrequency(long frequency) { if (m_vfoFrequency == frequency) return; m_vfoFrequency = frequency; HamBand band = getBandFromFrequency(set->getBandFrequencyList(), frequency); m_lastVfoFrequencyList[(int) band] = m_vfoFrequency; } void Receiver::setLastCtrFrequencyList(const QList &fList) { m_lastCtrFrequencyList = fList; } void Receiver::setLastVfoFrequencyList(const QList &fList) { m_lastVfoFrequencyList = fList; } void Receiver::setdBmPanScaleMin(qreal value) { if (m_dBmPanScaleMin == value) return; m_dBmPanScaleMin = value; } void Receiver::setdBmPanScaleMax(qreal value) { if (m_dBmPanScaleMax == value) return; m_dBmPanScaleMax = value; } void Receiver::setMercuryAttenuators(const QList &attenuators) { m_mercuryAttenuators = attenuators; } void Receiver::setFramesPerSecond(QObject *sender, int rx, int value) { Q_UNUSED(sender) if (m_receiver == rx) m_displayTime = (int)(1000000.0/value); } void Receiver::setPeerAddress(QHostAddress addr) { m_peerAddress = addr; } void Receiver::setSocketDescriptor(int value) { m_socketDescriptor = value; } void Receiver::setClient(int value) { m_client = value; } void Receiver::setIQPort(int value) { m_iqPort = value; } void Receiver::setBSPort(int value) { m_bsPort = value; } void Receiver::setConnectedStatus(bool value) { m_connected = value; }