diff --git a/src/demod/DemodulatorInstance.cpp b/src/demod/DemodulatorInstance.cpp index 8d4201f..ba58e7c 100644 --- a/src/demod/DemodulatorInstance.cpp +++ b/src/demod/DemodulatorInstance.cpp @@ -2,7 +2,7 @@ DemodulatorInstance::DemodulatorInstance() : t_Demod(NULL), t_PreDemod(NULL), t_Audio(NULL), threadQueueDemod(NULL), demodulatorThread(NULL), terminated(true), audioTerminated(true), demodTerminated( - true), preDemodTerminated(true), active(false), squelch(false), stereo(false), tracking(false), follow(false), currentAudioSampleRate(0), currentFrequency(0), currentBandwidth(0), currentOutputDevice(-1) { + true), preDemodTerminated(true), active(false), squelch(false), stereo(false), tracking(false), follow(false), currentAudioSampleRate(0), currentFrequency(0), currentBandwidth(0), currentOutputDevice(-1), currentAudioGain(1.0) { label = new std::string("Unnamed"); threadQueueDemod = new DemodulatorThreadInputQueue; @@ -244,25 +244,31 @@ void DemodulatorInstance::checkBandwidth() { } void DemodulatorInstance::setDemodulatorType(int demod_type_in) { - if (!active) { - currentDemodType = demod_type_in; - checkBandwidth(); - demodulatorPreThread->getParams().demodType = currentDemodType; - demodulatorThread->setDemodulatorType(currentDemodType); - } else if (demodulatorThread && threadQueueControl) { - DemodulatorThreadControlCommand command; - command.cmd = DemodulatorThreadControlCommand::DEMOD_THREAD_CMD_CTL_TYPE; - currentDemodType = demod_type_in; - command.demodType = demod_type_in; - checkBandwidth(); - threadQueueControl->push(command); - } + currentDemodType = demod_type_in; + if (currentDemodType == DEMOD_TYPE_RAW) { if (currentAudioSampleRate) { setBandwidth(currentAudioSampleRate); } else { setBandwidth(AudioThread::deviceSampleRate[getOutputDevice()]); } + } else if (currentDemodType == DEMOD_TYPE_USB || currentDemodType == DEMOD_TYPE_LSB || currentDemodType == DEMOD_TYPE_DSB || currentDemodType == DEMOD_TYPE_AM) { + demodulatorThread->setAGC(false); + } else { + demodulatorThread->setAGC(true); + } + setGain(getGain()); + + if (!active) { + checkBandwidth(); + demodulatorPreThread->getParams().demodType = currentDemodType; + demodulatorThread->setDemodulatorType(currentDemodType); + } else if (demodulatorThread && threadQueueControl) { + DemodulatorThreadControlCommand command; + command.cmd = DemodulatorThreadControlCommand::DEMOD_THREAD_CMD_CTL_TYPE; + command.demodType = demod_type_in; + checkBandwidth(); + threadQueueControl->push(command); } } @@ -348,11 +354,23 @@ int DemodulatorInstance::getAudioSampleRate() { void DemodulatorInstance::setGain(float gain_in) { - audioThread->setGain(gain_in); + currentAudioGain = gain_in; + + if (currentDemodType == DEMOD_TYPE_RAW) { + if (gain_in < 0.25) { + audioThread->setGain(1.0); + demodulatorThread->setAGC(false); + } else { + audioThread->setGain(gain_in); + demodulatorThread->setAGC(true); + } + } else { + audioThread->setGain(gain_in); + } } float DemodulatorInstance::getGain() { - return audioThread->getGain(); + return currentAudioGain; } bool DemodulatorInstance::isFollow() { diff --git a/src/demod/DemodulatorInstance.h b/src/demod/DemodulatorInstance.h index bbb4841..b0b8682 100644 --- a/src/demod/DemodulatorInstance.h +++ b/src/demod/DemodulatorInstance.h @@ -87,18 +87,19 @@ private: void checkBandwidth(); std::atomic label; // - bool terminated; // - bool demodTerminated; // - bool audioTerminated; // - bool preDemodTerminated; - std::atomic active; - std::atomic squelch; - std::atomic stereo; + std::atomic_bool terminated; // + std::atomic_bool demodTerminated; // + std::atomic_bool audioTerminated; // + std::atomic_bool preDemodTerminated; + std::atomic_bool active; + std::atomic_bool squelch; + std::atomic_bool stereo; - long long currentFrequency; - int currentBandwidth; - int currentDemodType; - int currentOutputDevice; - int currentAudioSampleRate; - bool follow, tracking; + std::atomic_llong currentFrequency; + std::atomic_int currentBandwidth; + std::atomic_int currentDemodType; + std::atomic_int currentOutputDevice; + std::atomic_int currentAudioSampleRate; + std::atomic currentAudioGain; + std::atomic_bool follow, tracking; }; diff --git a/src/demod/DemodulatorThread.cpp b/src/demod/DemodulatorThread.cpp index 7ffd6a9..00df8a7 100644 --- a/src/demod/DemodulatorThread.cpp +++ b/src/demod/DemodulatorThread.cpp @@ -14,7 +14,7 @@ DemodulatorThread::DemodulatorThread(DemodulatorThreadPostInputQueue* iqInputQueue, DemodulatorThreadControlCommandQueue *threadQueueControl, DemodulatorThreadCommandQueue* threadQueueNotify) : iqInputQueue(iqInputQueue), audioVisOutputQueue(NULL), audioOutputQueue(NULL), iqAutoGain(NULL), amOutputCeil(1), amOutputCeilMA(1), amOutputCeilMAA( - 1), stereo(false), terminated( + 1), stereo(false), agcEnabled(true), terminated( false), demodulatorType(DEMOD_TYPE_FM), threadQueueNotify(threadQueueNotify), threadQueueControl(threadQueueControl), squelchLevel(0), signalLevel( 0), squelchEnabled(false), audioSampleRate(0) { @@ -171,8 +171,16 @@ void DemodulatorThread::threadMain() { currentSignalLevel = agc_crcf_get_signal_level(iqAutoGain); } + std::vector *inputData; + + if (agcEnabled) { + inputData = &agcData; + } else { + inputData = &inp->data; + } + if (demodulatorType == DEMOD_TYPE_FM) { - freqdem_demodulate_block(demodFM, &agcData[0], bufSize, &demodOutputData[0]); + freqdem_demodulate_block(demodFM, &(*inputData)[0], bufSize, &demodOutputData[0]); } else if (demodulatorType == DEMOD_TYPE_RAW) { // do nothing here.. } else { @@ -180,20 +188,20 @@ void DemodulatorThread::threadMain() { switch (demodulatorType.load()) { case DEMOD_TYPE_LSB: for (int i = 0; i < bufSize; i++) { // Reject upper band - resamp2_cccf_filter_execute(ssbFilt,inp->data[i],&x,&y); + resamp2_cccf_filter_execute(ssbFilt,(*inputData)[i],&x,&y); ampmodem_demodulate(demodAM, x, &demodOutputData[i]); } break; case DEMOD_TYPE_USB: for (int i = 0; i < bufSize; i++) { // Reject lower band - resamp2_cccf_filter_execute(ssbFilt,inp->data[i],&x,&y); + resamp2_cccf_filter_execute(ssbFilt,(*inputData)[i],&x,&y); ampmodem_demodulate(demodAM, y, &demodOutputData[i]); } break; case DEMOD_TYPE_AM: case DEMOD_TYPE_DSB: for (int i = 0; i < bufSize; i++) { - ampmodem_demodulate(demodAM, inp->data[i], &demodOutputData[i]); + ampmodem_demodulate(demodAM, (*inputData)[i], &demodOutputData[i]); } break; } @@ -317,8 +325,8 @@ void DemodulatorThread::threadMain() { } ati->data.resize(numAudioWritten * 2); for (int i = 0; i < numAudioWritten; i++) { - ati->data[i * 2] = agcData[i].real; - ati->data[i * 2 + 1] = agcData[i].imag; + ati->data[i * 2] = (*inputData)[i].real; + ati->data[i * 2 + 1] = (*inputData)[i].imag; } } else if (stereo && inp->sampleRate >= 100000) { ati->channels = 2; @@ -351,8 +359,6 @@ void DemodulatorThread::threadMain() { ati->peak = p; } } - - audioOutputQueue->push(ati); } } @@ -372,8 +378,8 @@ void DemodulatorThread::threadMain() { if (demodulatorType == DEMOD_TYPE_RAW) { for (int i = 0; i < stereoSize / 2; i++) { - ati_vis->data[i] = ati->data[i * 2] * 0.75; - ati_vis->data[i + stereoSize / 2] = ati->data[i * 2 + 1] * 0.75; + ati_vis->data[i] = agcData[i].real * 0.75; + ati_vis->data[i + stereoSize / 2] = agcData[i].imag * 0.75; } } else { for (int i = 0; i < stereoSize / 2; i++) { @@ -403,6 +409,11 @@ void DemodulatorThread::threadMain() { ati_vis->busy_update.unlock(); } + + if (ati != NULL) { + audioOutputQueue->push(ati); + } + if (!threadQueueControl->empty()) { int newDemodType = DEMOD_TYPE_NULL; @@ -513,16 +524,25 @@ void DemodulatorThread::terminate() { } void DemodulatorThread::setStereo(bool state) { - stereo = state; + stereo.store(state); std::cout << "Stereo " << (state ? "Enabled" : "Disabled") << std::endl; } bool DemodulatorThread::isStereo() { - return stereo; + return stereo.load(); } +void DemodulatorThread::setAGC(bool state) { + agcEnabled.store(state); +} + +bool DemodulatorThread::getAGC() { + return agcEnabled.load(); +} + + float DemodulatorThread::getSignalLevel() { - return signalLevel; + return signalLevel.load(); } void DemodulatorThread::setSquelchLevel(float signal_level_in) { diff --git a/src/demod/DemodulatorThread.h b/src/demod/DemodulatorThread.h index f9d013b..be6cf69 100644 --- a/src/demod/DemodulatorThread.h +++ b/src/demod/DemodulatorThread.h @@ -31,6 +31,9 @@ public: void setStereo(bool state); bool isStereo(); + void setAGC(bool state); + bool getAGC(); + float getSignalLevel(); void setSquelchLevel(float signal_level_in); float getSquelchLevel(); @@ -72,9 +75,10 @@ protected: float amOutputCeilMA; float amOutputCeilMAA; - std::atomic stereo; - std::atomic terminated; - std::atomic demodulatorType; + std::atomic_bool stereo; + std::atomic_bool agcEnabled; + std::atomic_bool terminated; + std::atomic_int demodulatorType; int audioSampleRate; DemodulatorThreadCommandQueue* threadQueueNotify;