mirror of
https://github.com/cjcliffe/CubicSDR.git
synced 2025-08-06 07:32:26 -04:00
Disable I/Q AGC when gain < 0.25
This commit is contained in:
parent
927de58e4e
commit
6beeb70549
@ -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() {
|
||||||
|
@ -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;
|
||||||
};
|
};
|
||||||
|
@ -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) {
|
||||||
|
@ -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;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user