Skip to content

Commit

Permalink
New rx_agc implementation (3/4)
Browse files Browse the repository at this point in the history
Remove obsolete audio_gain# blocks as their function is now integrated into rx_agc.
Connect uiDockAudio gain control to the rx_agc manual gain input.
Update uiDockAudio gain control with rx_acg current gain values in auto
modes.
UI and connection logic fixes to make everything work.
  • Loading branch information
vladisslav2011 committed Aug 21, 2022
1 parent 2f7efd9 commit 96ee907
Show file tree
Hide file tree
Showing 17 changed files with 150 additions and 82 deletions.
32 changes: 29 additions & 3 deletions src/applications/gqrx/mainwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,7 @@ MainWindow::MainWindow(const QString& cfgfile, bool edit_conf, QWidget *parent)
connect(uiDockRxOpt, SIGNAL(sqlLevelChanged(double)), this, SLOT(setSqlLevel(double)));
connect(uiDockRxOpt, SIGNAL(sqlAutoClicked()), this, SLOT(setSqlLevelAuto()));
connect(uiDockAudio, SIGNAL(audioGainChanged(float)), this, SLOT(setAudioGain(float)));
connect(uiDockAudio, SIGNAL(audioMuteChanged(bool)), this, SLOT(setAudioMute(bool)));
connect(uiDockAudio, SIGNAL(audioStreamingStarted(QString,int,bool)), this, SLOT(startAudioStream(QString,int,bool)));
connect(uiDockAudio, SIGNAL(audioStreamingStopped()), this, SLOT(stopAudioStreaming()));
connect(uiDockAudio, SIGNAL(audioRecStarted(QString)), this, SLOT(startAudioRec(QString)));
Expand Down Expand Up @@ -1190,9 +1191,10 @@ void MainWindow::selectDemod(int mode_idx)
rx->set_cw_offset(cwofs);
rx->set_sql_level(uiDockRxOpt->currentSquelchLevel());

rx->set_agc_on(uiDockRxOpt->getAgcOn());
//Call wrapper to update enable/disabled state
setAgcOn(uiDockRxOpt->getAgcOn());
rx->set_agc_target_level(uiDockRxOpt->getAgcTargetLevel());
rx->set_agc_manual_gain(uiDockRxOpt->getAgcManualGain());
rx->set_agc_manual_gain(uiDockAudio->audioGain());
rx->set_agc_max_gain(uiDockRxOpt->getAgcMaxGain());
rx->set_agc_attack(uiDockRxOpt->getAgcAttack());
rx->set_agc_decay(uiDockRxOpt->getAgcDecay());
Expand Down Expand Up @@ -1274,13 +1276,35 @@ void MainWindow::setAmSyncPllBw(float pll_bw)
*/
void MainWindow::setAudioGain(float value)
{
rx->set_af_gain(value);
rx->set_agc_manual_gain(value);
}

/**
* @brief Audio mute changed.
* @param mute New state.
*/
void MainWindow::setAudioMute(bool mute)
{
if(mute)
{
rx->set_agc_target_level(-80);
rx->set_agc_manual_gain(-80);
if(!uiDockRxOpt->getAgcOn())
uiDockAudio->setGainEnabled(false);
}else{
rx->set_agc_target_level(uiDockRxOpt->getAgcTargetLevel());
rx->set_agc_manual_gain(uiDockAudio->audioGain() / 10.0);
if(!uiDockRxOpt->getAgcOn())
uiDockAudio->setGainEnabled(true);
}

}

/** Set AGC ON/OFF. */
void MainWindow::setAgcOn(bool agc_on)
{
rx->set_agc_on(agc_on);
uiDockAudio->setGainEnabled(!agc_on);
}

/** AGC hang ON/OFF. */
Expand Down Expand Up @@ -1366,6 +1390,8 @@ void MainWindow::meterTimeout()
level = rx->get_signal_pwr();
ui->sMeter->setLevel(level);
remote->setSignalLevel(level);
if(uiDockRxOpt->getAgcOn())
uiDockAudio->setAudioGain(rx->get_agc_gain() * 10.0);
}

#define LOG2_10 3.321928094887362
Expand Down
1 change: 1 addition & 0 deletions src/applications/gqrx/mainwindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ private slots:
void setSqlLevel(double level_db);
double setSqlLevelAuto();
void setAudioGain(float gain);
void setAudioMute(bool mute);
void setPassband(int bandwidth);

/* audio recording and playback */
Expand Down
100 changes: 55 additions & 45 deletions src/applications/gqrx/receiver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@
#include <gnuradio/audio/sink.h>
#endif

#define DEFAULT_AUDIO_GAIN -6.0
#define TARGET_QUAD_RATE 1e6

/**
Expand Down Expand Up @@ -118,9 +117,6 @@ receiver::receiver(const std::string input_device,
iq_fft = make_rx_fft_c(8192u, d_decim_rate, gr::fft::window::WIN_HANN);

audio_fft = make_rx_fft_f(8192u, d_audio_rate, gr::fft::window::WIN_HANN);
audio_gain0 = gr::blocks::multiply_const_ff::make(0);
audio_gain1 = gr::blocks::multiply_const_ff::make(0);
set_af_gain(DEFAULT_AUDIO_GAIN);

audio_udp_sink = make_udp_sink_f();

Expand Down Expand Up @@ -270,8 +266,13 @@ void receiver::set_output_device(const std::string device)

if (d_demod != RX_DEMOD_OFF)
{
tb->disconnect(audio_gain0, 0, audio_snk, 0);
tb->disconnect(audio_gain1, 0, audio_snk, 1);
try
{
tb->disconnect(audio_snk);
}
catch(std::exception &x)
{
}
}
audio_snk.reset();

Expand All @@ -286,8 +287,8 @@ void receiver::set_output_device(const std::string device)

if (d_demod != RX_DEMOD_OFF)
{
tb->connect(audio_gain0, 0, audio_snk, 0);
tb->connect(audio_gain1, 0, audio_snk, 1);
tb->connect(rx, 0, audio_snk, 0);
tb->connect(rx, 1, audio_snk, 1);
}

tb->unlock();
Expand Down Expand Up @@ -825,7 +826,7 @@ receiver::status receiver::set_agc_target_level(int target_level)
}

/** Set fixed gain used when AGC is OFF. */
receiver::status receiver::set_agc_manual_gain(int gain)
receiver::status receiver::set_agc_manual_gain(float gain)
{
if (rx->has_agc())
rx->set_agc_manual_gain(gain);
Expand Down Expand Up @@ -860,6 +861,15 @@ receiver::status receiver::set_agc_decay(int decay_ms)
return STATUS_OK; // FIXME
}

/** Get AGC current gain. */
float receiver::get_agc_gain()
{
if (rx->has_agc())
return rx->get_agc_gain();
else
return 0;
}

receiver::status receiver::set_demod(rx_demod demod, bool force)
{
status ret = STATUS_OK;
Expand Down Expand Up @@ -979,20 +989,6 @@ receiver::status receiver::set_amsync_pll_bw(float pll_bw)
return STATUS_OK;
}

receiver::status receiver::set_af_gain(float gain_db)
{
float k;

/* convert dB to factor */
k = pow(10.0, gain_db / 20.0);
//std::cout << "G:" << gain_db << "dB / K:" << k << std::endl;
audio_gain0->set_k(k);
audio_gain1->set_k(k);

return STATUS_OK;
}


/**
* @brief Start WAV file recorder.
* @param filename The filename where to record.
Expand Down Expand Up @@ -1125,15 +1121,15 @@ receiver::status receiver::start_audio_playback(const std::string filename)

stop();
/* route demodulator output to null sink */
tb->disconnect(rx, 0, audio_gain0, 0);
tb->disconnect(rx, 1, audio_gain1, 0);
tb->disconnect(rx, 0, audio_snk, 0);
tb->disconnect(rx, 1, audio_snk, 1);
tb->disconnect(rx, 0, audio_fft, 0);
tb->disconnect(rx, 0, audio_udp_sink, 0);
tb->disconnect(rx, 1, audio_udp_sink, 1);
tb->connect(rx, 0, audio_null_sink0, 0); /** FIXME: other channel? */
tb->connect(rx, 1, audio_null_sink1, 0); /** FIXME: other channel? */
tb->connect(wav_src, 0, audio_gain0, 0);
tb->connect(wav_src, 1, audio_gain1, 0);
tb->connect(wav_src, 0, audio_snk, 0);
tb->connect(wav_src, 1, audio_snk, 1);
tb->connect(wav_src, 0, audio_fft, 0);
tb->connect(wav_src, 0, audio_udp_sink, 0);
tb->connect(wav_src, 1, audio_udp_sink, 1);
Expand All @@ -1149,15 +1145,15 @@ receiver::status receiver::stop_audio_playback()
{
/* disconnect wav source and reconnect receiver */
stop();
tb->disconnect(wav_src, 0, audio_gain0, 0);
tb->disconnect(wav_src, 1, audio_gain1, 0);
tb->disconnect(wav_src, 0, audio_snk, 0);
tb->disconnect(wav_src, 1, audio_snk, 1);
tb->disconnect(wav_src, 0, audio_fft, 0);
tb->disconnect(wav_src, 0, audio_udp_sink, 0);
tb->disconnect(wav_src, 1, audio_udp_sink, 1);
tb->disconnect(rx, 0, audio_null_sink0, 0);
tb->disconnect(rx, 1, audio_null_sink1, 0);
tb->connect(rx, 0, audio_gain0, 0);
tb->connect(rx, 1, audio_gain1, 0);
tb->connect(rx, 0, audio_snk, 0);
tb->connect(rx, 1, audio_snk, 1);
tb->connect(rx, 0, audio_fft, 0); /** FIXME: other channel? */
tb->connect(rx, 0, audio_udp_sink, 0);
tb->connect(rx, 1, audio_udp_sink, 1);
Expand Down Expand Up @@ -1385,23 +1381,37 @@ void receiver::connect_all(rx_chain type)
tb->connect(rx, 0, audio_fft, 0);
tb->connect(rx, 0, audio_udp_sink, 0);
tb->connect(rx, 1, audio_udp_sink, 1);
tb->connect(rx, 0, audio_gain0, 0);
tb->connect(rx, 1, audio_gain1, 0);
tb->connect(audio_gain0, 0, audio_snk, 0);
tb->connect(audio_gain1, 0, audio_snk, 1);
}
tb->connect(rx, 0, audio_snk, 0);
tb->connect(rx, 1, audio_snk, 1);
// Recorders and sniffers
if (d_recording_wav)
{
tb->connect(rx, 0, wav_sink, 0);
tb->connect(rx, 1, wav_sink, 1);
}

// Recorders and sniffers
if (d_recording_wav)
{
tb->connect(rx, 0, wav_sink, 0);
tb->connect(rx, 1, wav_sink, 1);
if (d_sniffer_active)
{
tb->connect(rx, 0, sniffer_rr, 0);
tb->connect(sniffer_rr, 0, sniffer, 0);
}
}

if (d_sniffer_active)
else
{
tb->connect(rx, 0, sniffer_rr, 0);
tb->connect(sniffer_rr, 0, sniffer, 0);
if (d_recording_wav)
{
wav_sink->close();
wav_sink.reset();
d_recording_wav = false;
}

if (d_sniffer_active)
{
d_sniffer_active = false;

/* delete resampler */
sniffer_rr.reset();
}
}
}

Expand Down
8 changes: 2 additions & 6 deletions src/applications/gqrx/receiver.h
Original file line number Diff line number Diff line change
Expand Up @@ -181,11 +181,12 @@ class receiver
/* AGC */
status set_agc_on(bool agc_on);
status set_agc_target_level(int target_level);
status set_agc_manual_gain(int gain);
status set_agc_manual_gain(float gain);
status set_agc_max_gain(int gain);
status set_agc_attack(int attack_ms);
status set_agc_decay(int decay_ms);
status set_agc_hang(int hang_ms);
float get_agc_gain();

status set_demod(rx_demod demod, bool force=false);

Expand All @@ -201,7 +202,6 @@ class receiver
status set_amsync_pll_bw(float pll_bw);

/* Audio parameters */
status set_af_gain(float gain_db);
status start_audio_recording(const std::string filename);
status stop_audio_recording();
status start_audio_playback(const std::string filename);
Expand Down Expand Up @@ -273,11 +273,7 @@ class receiver

downconverter_cc_sptr ddc; /*!< Digital down-converter for demod chain. */

gr::blocks::multiply_const_ff::sptr audio_gain0; /*!< Audio gain block. */
gr::blocks::multiply_const_ff::sptr audio_gain1; /*!< Audio gain block. */

gr::blocks::file_sink::sptr iq_sink; /*!< I/Q file sink. */

gr::blocks::wavfile_sink::sptr wav_sink; /*!< WAV file sink for recording. */
gr::blocks::wavfile_source::sptr wav_src; /*!< WAV file source for playback. */
gr::blocks::null_sink::sptr audio_null_sink0; /*!< Audio null sink used during playback. */
Expand Down
2 changes: 1 addition & 1 deletion src/dsp/agc_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ CAgc::~CAgc()
}

void CAgc::SetParameters(double sample_rate, bool agc_on, int target_level,
int manual_gain, int max_gain, int attack, int decay,
float manual_gain, int max_gain, int attack, int decay,
int hang, bool force)
{
bool samp_rate_changed = false;
Expand Down
4 changes: 2 additions & 2 deletions src/dsp/agc_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class CAgc
CAgc();
virtual ~CAgc();
void SetParameters(double sample_rate, bool agc_on, int target_level,
int manual_gain, int max_gain, int attack, int decay,
float manual_gain, int max_gain, int attack, int decay,
int hang, bool force = false);
void ProcessData(float * pOutData0,float * pOutData1, const float * pInData0, const float * pInData1, int Length);
float CurrentGainDb();
Expand All @@ -36,7 +36,7 @@ class CAgc
float d_sample_rate;
bool d_agc_on;
int d_target_level;
int d_manual_gain;
float d_manual_gain;
int d_max_gain;
int d_attack;
int d_decay;
Expand Down
13 changes: 10 additions & 3 deletions src/dsp/rx_agc_xx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,15 +138,15 @@ void rx_agc_2f::set_target_level(int target_level)

/**
* \brief Set new manual gain.
* \param gain The new manual gain between 0 and 100dB.
* \param gain The new manual gain between -160 and 160dB.
*
* The manual gain is used when AGC is switched off.
*
* \sa set_agc_on()
*/
void rx_agc_2f::set_manual_gain(int gain)
void rx_agc_2f::set_manual_gain(float gain)
{
if ((gain != d_manual_gain) && (gain >= -160) && (gain <= 160)) {
if ((gain != d_manual_gain) && (gain >= -160.0) && (gain <= 160.0)) {
std::lock_guard<std::mutex> lock(d_mutex);
d_manual_gain = gain;
reconfigure();
Expand Down Expand Up @@ -211,3 +211,10 @@ void rx_agc_2f::set_hang(int hang)
reconfigure();
}
}

float rx_agc_2f::get_current_gain()
{
std::lock_guard<std::mutex> lock(d_mutex);
return d_agc->CurrentGainDb();
}

5 changes: 3 additions & 2 deletions src/dsp/rx_agc_xx.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,11 +88,12 @@ class rx_agc_2f : public gr::sync_block
void set_agc_on(bool agc_on);
void set_sample_rate(double sample_rate);
void set_target_level(int target_level);
void set_manual_gain(int gain);
void set_manual_gain(float gain);
void set_max_gain(int gain);
void set_attack(int attack);
void set_decay(int decay);
void set_hang(int hang);
float get_current_gain();

private:
void reconfigure();
Expand All @@ -103,7 +104,7 @@ class rx_agc_2f : public gr::sync_block
bool d_agc_on; /*! Current AGC status (true/false). */
double d_sample_rate; /*! Current sample rate. */
int d_target_level; /*! SGC target level (-160...0 dB). */
int d_manual_gain; /*! Current gain when AGC is OFF. */
float d_manual_gain; /*! Current gain when AGC is OFF. */
int d_max_gain; /*! Maximum gain when AGC is ON. */
int d_attack; /*! Current AGC attack (20...5000 ms). */
int d_decay; /*! Current AGC decay (20...5000 ms). */
Expand Down
Loading

0 comments on commit 96ee907

Please sign in to comment.