Merge pull request #422 from cjcliffe/squelch_improved

Squelch Improvements
This commit is contained in:
Charles J. Cliffe 2016-08-12 23:06:58 -04:00 committed by GitHub
commit 1fd23b6d33
6 changed files with 108 additions and 25 deletions

View File

@ -1402,7 +1402,11 @@ void AppFrame::OnIdle(wxIdleEvent& event) {
demodWaterfallCanvas->setBandwidth(demodBw); demodWaterfallCanvas->setBandwidth(demodBw);
demodSpectrumCanvas->setBandwidth(demodBw); demodSpectrumCanvas->setBandwidth(demodBw);
} }
demodSignalMeter->setLevel(demod->getSignalLevel()); demodSignalMeter->setLevel(demod->getSignalLevel());
demodSignalMeter->setMin(demod->getSignalFloor());
demodSignalMeter->setMax(demod->getSignalCeil());
demodGainMeter->setLevel(demod->getGain()); demodGainMeter->setLevel(demod->getGain());
if (demodSignalMeter->inputChanged()) { if (demodSignalMeter->inputChanged()) {
demod->setSquelchLevel(demodSignalMeter->getInputValue()); demod->setSquelchLevel(demodSignalMeter->getInputValue());

View File

@ -257,6 +257,14 @@ float DemodulatorInstance::getSignalLevel() {
return demodulatorThread->getSignalLevel(); return demodulatorThread->getSignalLevel();
} }
float DemodulatorInstance::getSignalFloor() {
return demodulatorThread->getSignalFloor();
}
float DemodulatorInstance::getSignalCeil() {
return demodulatorThread->getSignalCeil();
}
void DemodulatorInstance::setSquelchLevel(float signal_level_in) { void DemodulatorInstance::setSquelchLevel(float signal_level_in) {
demodulatorThread->setSquelchLevel(signal_level_in); demodulatorThread->setSquelchLevel(signal_level_in);
wxGetApp().getDemodMgr().setLastSquelchLevel(signal_level_in); wxGetApp().getDemodMgr().setLastSquelchLevel(signal_level_in);

View File

@ -63,6 +63,8 @@ public:
void setSquelchEnabled(bool state); void setSquelchEnabled(bool state);
float getSignalLevel(); float getSignalLevel();
float getSignalFloor();
float getSignalCeil();
void setSquelchLevel(float signal_level_in); void setSquelchLevel(float signal_level_in);
float getSquelchLevel(); float getSquelchLevel();

View File

@ -13,9 +13,12 @@
#include <pthread.h> #include <pthread.h>
#endif #endif
DemodulatorThread::DemodulatorThread(DemodulatorInstance *parent) std::atomic<DemodulatorInstance *> DemodulatorThread::squelchLock(nullptr);
std::mutex DemodulatorThread::squelchLockMutex;
DemodulatorThread::DemodulatorThread(DemodulatorInstance *parent)
: IOThread(), outputBuffers("DemodulatorThreadBuffers"), squelchLevel(-100), : IOThread(), outputBuffers("DemodulatorThreadBuffers"), squelchLevel(-100),
signalLevel(-100), squelchEnabled(false) { signalLevel(-100), signalFloor(-30), signalCeil(30), squelchEnabled(false) {
demodInstance = parent; demodInstance = parent;
muted.store(false); muted.store(false);
@ -23,6 +26,10 @@ DemodulatorThread::DemodulatorThread(DemodulatorInstance *parent)
} }
DemodulatorThread::~DemodulatorThread() { DemodulatorThread::~DemodulatorThread() {
std::lock_guard < std::mutex > lock(squelchLockMutex);
if (squelchLock.load() == demodInstance) {
squelchLock.store(nullptr);
}
} }
void DemodulatorThread::onBindOutput(std::string name, ThreadQueueBase *threadQueue) { void DemodulatorThread::onBindOutput(std::string name, ThreadQueueBase *threadQueue) {
@ -102,18 +109,6 @@ void DemodulatorThread::run() {
continue; continue;
} }
float currentSignalLevel = 0;
float accum = 0;
for (std::vector<liquid_float_complex>::iterator i = inp->data.begin(); i != inp->data.end(); i++) {
accum += abMagnitude(0.948059448969, 0.392699081699, i->real, i->imag);
}
currentSignalLevel = linearToDb(accum / float(inp->data.size()));
if (currentSignalLevel < DEMOD_SIGNAL_MIN+1) {
currentSignalLevel = DEMOD_SIGNAL_MIN+1;
}
std::vector<liquid_float_complex> *inputData; std::vector<liquid_float_complex> *inputData;
inputData = &inp->data; inputData = &inp->data;
@ -140,23 +135,83 @@ void DemodulatorThread::run() {
} }
cModem->demodulate(cModemKit, &modemData, ati); cModem->demodulate(cModemKit, &modemData, ati);
float currentSignalLevel = 0;
float sampleTime = float(inp->data.size()) / float(inp->sampleRate);
if (audioOutputQueue != nullptr && ati && ati->data.size()) {
float accum = 0;
for (auto i : ati->data) {
accum += abMagnitude(0.948059448969, 0.392699081699, i, 0.0);
}
float audioSignalLevel = linearToDb(accum / float(ati->data.size()));
accum = 0;
for (auto i : inp->data) {
accum += abMagnitude(0.948059448969, 0.392699081699, i.real, i.imag);
}
float iqSignalLevel = linearToDb(accum / float(inp->data.size()));
currentSignalLevel = iqSignalLevel>audioSignalLevel?iqSignalLevel:audioSignalLevel;
float sf = signalFloor.load(), sc = signalCeil.load(), sl = squelchLevel.load();
if (currentSignalLevel > sc) {
sc = currentSignalLevel;
}
if (currentSignalLevel < sf) {
sf = currentSignalLevel;
}
if (sl+1.0f > sc) {
sc = sl+1.0f;
}
if ((sf+2.0f) > sc) {
sc = sf+2.0f;
}
sc -= (sc - (currentSignalLevel + 2.0f)) * sampleTime * 0.05f;
sf += ((currentSignalLevel - 5.0f) - sf) * sampleTime * 0.15f;
signalFloor.store(sf);
signalCeil.store(sc);
}
if (currentSignalLevel > signalLevel) { if (currentSignalLevel > signalLevel) {
signalLevel = signalLevel + (currentSignalLevel - signalLevel) * 0.5; signalLevel = signalLevel + (currentSignalLevel - signalLevel) * 0.5;
} else { } else {
signalLevel = signalLevel + (currentSignalLevel - signalLevel) * 0.05; signalLevel = signalLevel + (currentSignalLevel - signalLevel) * 0.05 * sampleTime * 30.0;
} }
bool squelched = (squelchEnabled && (signalLevel < squelchLevel)); bool squelched = (muted.load() || (squelchEnabled && (signalLevel < squelchLevel)));
if (squelchEnabled) { if (squelchEnabled) {
if (!squelched && !squelchBreak) { if (!squelched && !squelchBreak) {
if (wxGetApp().getSoloMode() && !muted.load()) { if (wxGetApp().getSoloMode()) {
wxGetApp().getDemodMgr().setActiveDemodulator(demodInstance, false); std::lock_guard < std::mutex > lock(squelchLockMutex);
} if (squelchLock.load() == nullptr) {
squelchBreak = true; squelchLock.store(demodInstance);
demodInstance->getVisualCue()->triggerSquelchBreak(120); wxGetApp().getDemodMgr().setActiveDemodulator(nullptr);
wxGetApp().getDemodMgr().setActiveDemodulator(demodInstance, false);
squelchBreak = true;
demodInstance->getVisualCue()->triggerSquelchBreak(120);
}
} else {
squelchBreak = true;
demodInstance->getVisualCue()->triggerSquelchBreak(120);
}
} else if (squelched && squelchBreak) { } else if (squelched && squelchBreak) {
std::lock_guard < std::mutex > lock(squelchLockMutex);
if (squelchLock.load() == demodInstance) {
squelchLock.store(nullptr);
}
squelchBreak = false; squelchBreak = false;
} }
} }
@ -164,8 +219,8 @@ void DemodulatorThread::run() {
if (audioOutputQueue != nullptr && ati && ati->data.size() && !squelched) { if (audioOutputQueue != nullptr && ati && ati->data.size() && !squelched) {
std::vector<float>::iterator data_i; std::vector<float>::iterator data_i;
ati->peak = 0; ati->peak = 0;
for (data_i = ati->data.begin(); data_i != ati->data.end(); data_i++) { for (auto data_i : ati->data) {
float p = fabs(*data_i); float p = fabs(data_i);
if (p > ati->peak) { if (p > ati->peak) {
ati->peak = p; ati->peak = p;
} }
@ -330,6 +385,14 @@ float DemodulatorThread::getSignalLevel() {
return signalLevel.load(); return signalLevel.load();
} }
float DemodulatorThread::getSignalFloor() {
return signalFloor.load();
}
float DemodulatorThread::getSignalCeil() {
return signalCeil.load();
}
void DemodulatorThread::setSquelchLevel(float signal_level_in) { void DemodulatorThread::setSquelchLevel(float signal_level_in) {
if (!squelchEnabled) { if (!squelchEnabled) {
squelchEnabled = true; squelchEnabled = true;

View File

@ -30,6 +30,8 @@ public:
bool isMuted(); bool isMuted();
float getSignalLevel(); float getSignalLevel();
float getSignalCeil();
float getSignalFloor();
void setSquelchLevel(float signal_level_in); void setSquelchLevel(float signal_level_in);
float getSquelchLevel(); float getSquelchLevel();
@ -46,9 +48,13 @@ protected:
std::atomic_bool muted; std::atomic_bool muted;
std::atomic<float> squelchLevel; std::atomic<float> squelchLevel;
std::atomic<float> signalLevel; std::atomic<float> signalLevel, signalFloor, signalCeil;
bool squelchEnabled, squelchBreak; bool squelchEnabled, squelchBreak;
static std::atomic<DemodulatorInstance *> squelchLock;
static std::mutex squelchLockMutex;
Modem *cModem = nullptr; Modem *cModem = nullptr;
ModemKit *cModemKit = nullptr; ModemKit *cModemKit = nullptr;

View File

@ -313,7 +313,7 @@ void SpectrumVisualProcessor::process() {
} }
if (!resampler || resampleBw != lastBandwidth || lastInputBandwidth != iqData->sampleRate) { if (!resampler || resampleBw != lastBandwidth || lastInputBandwidth != iqData->sampleRate) {
float As = 60.0f; float As = 480.0;
if (resampler) { if (resampler) {
msresamp_crcf_destroy(resampler); msresamp_crcf_destroy(resampler);