Disable I/Q AGC when gain < 0.25

This commit is contained in:
Charles J. Cliffe 2015-07-19 15:34:06 -04:00
parent 927de58e4e
commit 6beeb70549
4 changed files with 89 additions and 46 deletions

View File

@ -2,7 +2,7 @@
DemodulatorInstance::DemodulatorInstance() : DemodulatorInstance::DemodulatorInstance() :
t_Demod(NULL), t_PreDemod(NULL), t_Audio(NULL), threadQueueDemod(NULL), demodulatorThread(NULL), terminated(true), audioTerminated(true), demodTerminated( 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"); label = new std::string("Unnamed");
threadQueueDemod = new DemodulatorThreadInputQueue; threadQueueDemod = new DemodulatorThreadInputQueue;
@ -244,25 +244,31 @@ void DemodulatorInstance::checkBandwidth() {
} }
void DemodulatorInstance::setDemodulatorType(int demod_type_in) { void DemodulatorInstance::setDemodulatorType(int demod_type_in) {
if (!active) {
currentDemodType = demod_type_in; 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);
}
if (currentDemodType == DEMOD_TYPE_RAW) { if (currentDemodType == DEMOD_TYPE_RAW) {
if (currentAudioSampleRate) { if (currentAudioSampleRate) {
setBandwidth(currentAudioSampleRate); setBandwidth(currentAudioSampleRate);
} else { } else {
setBandwidth(AudioThread::deviceSampleRate[getOutputDevice()]); 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) { void DemodulatorInstance::setGain(float 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); audioThread->setGain(gain_in);
demodulatorThread->setAGC(true);
}
} else {
audioThread->setGain(gain_in);
}
} }
float DemodulatorInstance::getGain() { float DemodulatorInstance::getGain() {
return audioThread->getGain(); return currentAudioGain;
} }
bool DemodulatorInstance::isFollow() { bool DemodulatorInstance::isFollow() {

View File

@ -87,18 +87,19 @@ private:
void checkBandwidth(); void checkBandwidth();
std::atomic<std::string *> label; // std::atomic<std::string *> label; //
bool terminated; // std::atomic_bool terminated; //
bool demodTerminated; // std::atomic_bool demodTerminated; //
bool audioTerminated; // std::atomic_bool audioTerminated; //
bool preDemodTerminated; std::atomic_bool preDemodTerminated;
std::atomic<bool> active; std::atomic_bool active;
std::atomic<bool> squelch; std::atomic_bool squelch;
std::atomic<bool> stereo; std::atomic_bool stereo;
long long currentFrequency; std::atomic_llong currentFrequency;
int currentBandwidth; std::atomic_int currentBandwidth;
int currentDemodType; std::atomic_int currentDemodType;
int currentOutputDevice; std::atomic_int currentOutputDevice;
int currentAudioSampleRate; std::atomic_int currentAudioSampleRate;
bool follow, tracking; std::atomic<float> currentAudioGain;
std::atomic_bool follow, tracking;
}; };

View File

@ -14,7 +14,7 @@
DemodulatorThread::DemodulatorThread(DemodulatorThreadPostInputQueue* iqInputQueue, DemodulatorThreadControlCommandQueue *threadQueueControl, DemodulatorThread::DemodulatorThread(DemodulatorThreadPostInputQueue* iqInputQueue, DemodulatorThreadControlCommandQueue *threadQueueControl,
DemodulatorThreadCommandQueue* threadQueueNotify) : DemodulatorThreadCommandQueue* threadQueueNotify) :
iqInputQueue(iqInputQueue), audioVisOutputQueue(NULL), audioOutputQueue(NULL), iqAutoGain(NULL), amOutputCeil(1), amOutputCeilMA(1), amOutputCeilMAA( 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( false), demodulatorType(DEMOD_TYPE_FM), threadQueueNotify(threadQueueNotify), threadQueueControl(threadQueueControl), squelchLevel(0), signalLevel(
0), squelchEnabled(false), audioSampleRate(0) { 0), squelchEnabled(false), audioSampleRate(0) {
@ -171,8 +171,16 @@ void DemodulatorThread::threadMain() {
currentSignalLevel = agc_crcf_get_signal_level(iqAutoGain); currentSignalLevel = agc_crcf_get_signal_level(iqAutoGain);
} }
std::vector<liquid_float_complex> *inputData;
if (agcEnabled) {
inputData = &agcData;
} else {
inputData = &inp->data;
}
if (demodulatorType == DEMOD_TYPE_FM) { 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) { } else if (demodulatorType == DEMOD_TYPE_RAW) {
// do nothing here.. // do nothing here..
} else { } else {
@ -180,20 +188,20 @@ void DemodulatorThread::threadMain() {
switch (demodulatorType.load()) { switch (demodulatorType.load()) {
case DEMOD_TYPE_LSB: case DEMOD_TYPE_LSB:
for (int i = 0; i < bufSize; i++) { // Reject upper band 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]); ampmodem_demodulate(demodAM, x, &demodOutputData[i]);
} }
break; break;
case DEMOD_TYPE_USB: case DEMOD_TYPE_USB:
for (int i = 0; i < bufSize; i++) { // Reject lower band 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]); ampmodem_demodulate(demodAM, y, &demodOutputData[i]);
} }
break; break;
case DEMOD_TYPE_AM: case DEMOD_TYPE_AM:
case DEMOD_TYPE_DSB: case DEMOD_TYPE_DSB:
for (int i = 0; i < bufSize; i++) { for (int i = 0; i < bufSize; i++) {
ampmodem_demodulate(demodAM, inp->data[i], &demodOutputData[i]); ampmodem_demodulate(demodAM, (*inputData)[i], &demodOutputData[i]);
} }
break; break;
} }
@ -317,8 +325,8 @@ void DemodulatorThread::threadMain() {
} }
ati->data.resize(numAudioWritten * 2); ati->data.resize(numAudioWritten * 2);
for (int i = 0; i < numAudioWritten; i++) { for (int i = 0; i < numAudioWritten; i++) {
ati->data[i * 2] = agcData[i].real; ati->data[i * 2] = (*inputData)[i].real;
ati->data[i * 2 + 1] = agcData[i].imag; ati->data[i * 2 + 1] = (*inputData)[i].imag;
} }
} else if (stereo && inp->sampleRate >= 100000) { } else if (stereo && inp->sampleRate >= 100000) {
ati->channels = 2; ati->channels = 2;
@ -351,8 +359,6 @@ void DemodulatorThread::threadMain() {
ati->peak = p; ati->peak = p;
} }
} }
audioOutputQueue->push(ati);
} }
} }
@ -372,8 +378,8 @@ void DemodulatorThread::threadMain() {
if (demodulatorType == DEMOD_TYPE_RAW) { if (demodulatorType == DEMOD_TYPE_RAW) {
for (int i = 0; i < stereoSize / 2; i++) { for (int i = 0; i < stereoSize / 2; i++) {
ati_vis->data[i] = ati->data[i * 2] * 0.75; ati_vis->data[i] = agcData[i].real * 0.75;
ati_vis->data[i + stereoSize / 2] = ati->data[i * 2 + 1] * 0.75; ati_vis->data[i + stereoSize / 2] = agcData[i].imag * 0.75;
} }
} else { } else {
for (int i = 0; i < stereoSize / 2; i++) { for (int i = 0; i < stereoSize / 2; i++) {
@ -403,6 +409,11 @@ void DemodulatorThread::threadMain() {
ati_vis->busy_update.unlock(); ati_vis->busy_update.unlock();
} }
if (ati != NULL) {
audioOutputQueue->push(ati);
}
if (!threadQueueControl->empty()) { if (!threadQueueControl->empty()) {
int newDemodType = DEMOD_TYPE_NULL; int newDemodType = DEMOD_TYPE_NULL;
@ -513,16 +524,25 @@ void DemodulatorThread::terminate() {
} }
void DemodulatorThread::setStereo(bool state) { void DemodulatorThread::setStereo(bool state) {
stereo = state; stereo.store(state);
std::cout << "Stereo " << (state ? "Enabled" : "Disabled") << std::endl; std::cout << "Stereo " << (state ? "Enabled" : "Disabled") << std::endl;
} }
bool DemodulatorThread::isStereo() { 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() { float DemodulatorThread::getSignalLevel() {
return signalLevel; return signalLevel.load();
} }
void DemodulatorThread::setSquelchLevel(float signal_level_in) { void DemodulatorThread::setSquelchLevel(float signal_level_in) {

View File

@ -31,6 +31,9 @@ public:
void setStereo(bool state); void setStereo(bool state);
bool isStereo(); bool isStereo();
void setAGC(bool state);
bool getAGC();
float getSignalLevel(); float getSignalLevel();
void setSquelchLevel(float signal_level_in); void setSquelchLevel(float signal_level_in);
float getSquelchLevel(); float getSquelchLevel();
@ -72,9 +75,10 @@ protected:
float amOutputCeilMA; float amOutputCeilMA;
float amOutputCeilMAA; float amOutputCeilMAA;
std::atomic<bool> stereo; std::atomic_bool stereo;
std::atomic<bool> terminated; std::atomic_bool agcEnabled;
std::atomic<int> demodulatorType; std::atomic_bool terminated;
std::atomic_int demodulatorType;
int audioSampleRate; int audioSampleRate;
DemodulatorThreadCommandQueue* threadQueueNotify; DemodulatorThreadCommandQueue* threadQueueNotify;