Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement audio sample rate selection #1034

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 18 additions & 9 deletions src/applications/gqrx/mainwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -529,6 +529,13 @@ bool MainWindow::loadConfig(const QString& cfgfile, bool check_crash,
restoreState(m_settings->value("gui/state", saveState()).toByteArray());
}

int_val = m_settings->value("output/sample_rate", 48000).toInt(&conv_ok);
if (conv_ok && (int_val > 0))
{
rx->set_audio_rate(int_val);
uiDockAudio->setFftSampleRate(int_val);
}

QString indev = m_settings->value("input/device", "").toString();
if (!indev.isEmpty())
{
Expand Down Expand Up @@ -655,6 +662,7 @@ bool MainWindow::loadConfig(const QString& cfgfile, bool check_crash,
uiDockFft->readSettings(m_settings);
uiDockAudio->readSettings(m_settings);
dxc_options->readSettings(m_settings);
rx->commit_audio_rate();

{
int64_val = m_settings->value("input/frequency", 14236000).toLongLong(&conv_ok);
Expand Down Expand Up @@ -1153,6 +1161,7 @@ void MainWindow::selectDemod(int mode_idx)
int filter_preset = uiDockRxOpt->currentFilter();
int flo=0, fhi=0, click_res=100;
bool rds_enabled;
int audio_rate = rx->get_audio_rate();

// validate mode_idx
if (mode_idx < DockRxOpt::MODE_OFF || mode_idx >= DockRxOpt::MODE_LAST)
Expand Down Expand Up @@ -1191,15 +1200,15 @@ void MainWindow::selectDemod(int mode_idx)
/* Raw I/Q; max 96 ksps*/
rx->set_demod(receiver::RX_DEMOD_NONE);
ui->plotter->setDemodRanges(-40000, -200, 200, 40000, true);
uiDockAudio->setFftRange(0,24000);
uiDockAudio->setFftRange(-std::min(24000, audio_rate / 2), std::min(24000, audio_rate / 2));
click_res = 100;
break;

case DockRxOpt::MODE_AM:
rx->set_demod(receiver::RX_DEMOD_AM);
rx->set_am_dcr(uiDockRxOpt->currentAmDcr());
ui->plotter->setDemodRanges(-40000, -200, 200, 40000, true);
uiDockAudio->setFftRange(0,6000);
uiDockAudio->setFftRange(0, std::min(6000, audio_rate / 2));
click_res = 100;
break;

Expand All @@ -1208,13 +1217,13 @@ void MainWindow::selectDemod(int mode_idx)
rx->set_amsync_dcr(uiDockRxOpt->currentAmsyncDcr());
rx->set_amsync_pll_bw(uiDockRxOpt->currentAmsyncPll());
ui->plotter->setDemodRanges(-40000, -200, 200, 40000, true);
uiDockAudio->setFftRange(0,6000);
uiDockAudio->setFftRange(0, std::min(6000, audio_rate / 2));
click_res = 100;
break;

case DockRxOpt::MODE_NFM:
ui->plotter->setDemodRanges(-40000, -1000, 1000, 40000, true);
uiDockAudio->setFftRange(0, 5000);
uiDockAudio->setFftRange(0, std::min(5000, audio_rate / 2));
rx->set_demod(receiver::RX_DEMOD_NFM);
rx->set_fm_maxdev(uiDockRxOpt->currentMaxdev());
rx->set_fm_deemph(uiDockRxOpt->currentEmph());
Expand All @@ -1226,7 +1235,7 @@ void MainWindow::selectDemod(int mode_idx)
case DockRxOpt::MODE_WFM_STEREO_OIRT:
/* Broadcast FM */
ui->plotter->setDemodRanges(-120e3, -10000, 10000, 120e3, true);
uiDockAudio->setFftRange(0,24000); /** FIXME: get audio rate from rx **/
uiDockAudio->setFftRange(0, std::min(24000, audio_rate / 2));
click_res = 1000;
if (mode_idx == DockRxOpt::MODE_WFM_MONO)
rx->set_demod(receiver::RX_DEMOD_WFM_M);
Expand All @@ -1244,15 +1253,15 @@ void MainWindow::selectDemod(int mode_idx)
/* LSB */
rx->set_demod(receiver::RX_DEMOD_SSB);
ui->plotter->setDemodRanges(-40000, -100, -5000, 0, false);
uiDockAudio->setFftRange(0,3000);
uiDockAudio->setFftRange(0, std::min(3000, audio_rate / 2));
click_res = 100;
break;

case DockRxOpt::MODE_USB:
/* USB */
rx->set_demod(receiver::RX_DEMOD_SSB);
ui->plotter->setDemodRanges(0, 5000, 100, 40000, false);
uiDockAudio->setFftRange(0,3000);
uiDockAudio->setFftRange(0, std::min(3000, audio_rate / 2));
click_res = 100;
break;

Expand All @@ -1261,7 +1270,7 @@ void MainWindow::selectDemod(int mode_idx)
rx->set_demod(receiver::RX_DEMOD_SSB);
cwofs = -uiDockRxOpt->getCwOffset();
ui->plotter->setDemodRanges(-5000, -100, 100, 5000, true);
uiDockAudio->setFftRange(0,1500);
uiDockAudio->setFftRange(0, std::min(1500, audio_rate / 2));
click_res = 10;
break;

Expand All @@ -1270,7 +1279,7 @@ void MainWindow::selectDemod(int mode_idx)
rx->set_demod(receiver::RX_DEMOD_SSB);
cwofs = uiDockRxOpt->getCwOffset();
ui->plotter->setDemodRanges(-5000, -100, 100, 5000, true);
uiDockAudio->setFftRange(0,1500);
uiDockAudio->setFftRange(0, std::min(1500, audio_rate / 2));
click_res = 10;
break;

Expand Down
50 changes: 35 additions & 15 deletions src/applications/gqrx/receiver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -125,14 +125,7 @@ receiver::receiver(const std::string input_device,

audio_udp_sink = make_udp_sink_f();

#ifdef WITH_PULSEAUDIO
audio_snk = make_pa_sink(audio_device, d_audio_rate, "GQRX", "Audio output");
#elif WITH_PORTAUDIO
audio_snk = make_portaudio_sink(audio_device, d_audio_rate, "GQRX", "Audio output");
#else
audio_snk = gr::audio::sink::make(d_audio_rate, audio_device, true);
#endif

create_audio_device(audio_device);
output_devstr = audio_device;

/* wav sink and source is created when rec/play is started */
Expand Down Expand Up @@ -277,13 +270,7 @@ void receiver::set_output_device(const std::string device)
audio_snk.reset();

try {
#ifdef WITH_PULSEAUDIO
audio_snk = make_pa_sink(device, d_audio_rate, "GQRX", "Audio output");
#elif WITH_PORTAUDIO
audio_snk = make_portaudio_sink(device, d_audio_rate, "GQRX", "Audio output");
#else
audio_snk = gr::audio::sink::make(d_audio_rate, device, true);
#endif
create_audio_device(device);

if (d_demod != RX_DEMOD_OFF)
{
Expand Down Expand Up @@ -981,6 +968,27 @@ receiver::status receiver::set_amsync_pll_bw(float pll_bw)
return STATUS_OK;
}

receiver::status receiver::set_audio_rate(int rate)
{
if(d_audio_rate != rate)
{
d_audio_rate = rate;
audio_fft->set_quad_rate(rate);
}
return STATUS_OK;
}

receiver::status receiver::commit_audio_rate()
{
rx->set_audio_rate(d_audio_rate);
return STATUS_OK;
}

int receiver::get_audio_rate()
{
return d_audio_rate;
}

receiver::status receiver::set_af_gain(float gain_db)
{
float k;
Expand Down Expand Up @@ -1470,3 +1478,15 @@ std::string receiver::escape_filename(std::string filename)
ss2 << std::quoted(ss1.str(), '\'', '\\');
return ss2.str();
}

void receiver::create_audio_device(const std::string device)
{
#ifdef WITH_PULSEAUDIO
audio_snk = make_pa_sink(device, d_audio_rate, "GQRX", "Audio output");
#elif WITH_PORTAUDIO
audio_snk = make_portaudio_sink(device, d_audio_rate, "GQRX", "Audio output");
#else
audio_snk = gr::audio::sink::make(d_audio_rate, device, true);
#endif

}
4 changes: 4 additions & 0 deletions src/applications/gqrx/receiver.h
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,9 @@ class receiver
status set_amsync_pll_bw(float pll_bw);

/* Audio parameters */
status set_audio_rate(int rate);
status commit_audio_rate();
int get_audio_rate();
status set_af_gain(float gain_db);
status start_audio_recording(const std::string filename);
status stop_audio_recording();
Expand Down Expand Up @@ -295,6 +298,7 @@ class receiver

//! Get a path to a file containing random bytes
static std::string get_zero_file(void);
void create_audio_device(const std::string device);
};

#endif // RECEIVER_H
16 changes: 13 additions & 3 deletions src/dsp/fm_deemph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,13 @@ fm_deemph::fm_deemph(float quad_rate, double tau)
: gr::hier_block2 ("fm_deemph",
gr::io_signature::make (MIN_IN, MAX_IN, sizeof (float)),
gr::io_signature::make (MIN_OUT, MAX_OUT, sizeof (float))),
d_quad_rate(quad_rate)
d_quad_rate(quad_rate),
d_tau(tau)
{
/* de-emphasis */
d_fftaps.resize(2);
d_fbtaps.resize(2);
calculate_iir_taps(tau);
calculate_iir_taps(d_tau);
d_deemph = gr::filter::iir_filter_ffd::make(d_fftaps, d_fbtaps, false);

connect(self(), 0, d_deemph, 0);
Expand All @@ -63,10 +64,19 @@ fm_deemph::~fm_deemph ()
*/
void fm_deemph::set_tau(double tau)
{
calculate_iir_taps(tau);
d_tau = tau;
calculate_iir_taps(d_tau);
d_deemph->set_taps(d_fftaps, d_fbtaps);
}

void fm_deemph::set_rate(float rate)
{
d_quad_rate = rate;
calculate_iir_taps(d_tau);
d_deemph->set_taps(d_fftaps, d_fbtaps);
}


/*! \brief Calculate taps for FM de-emph IIR filter. */
void fm_deemph::calculate_iir_taps(double tau)
{
Expand Down
2 changes: 2 additions & 0 deletions src/dsp/fm_deemph.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,15 @@ class fm_deemph : public gr::hier_block2
~fm_deemph();

void set_tau(double tau);
void set_rate(float rate);

private:
/* GR blocks */
gr::filter::iir_filter_ffd::sptr d_deemph; /*! De-emphasis IIR filter. */

/* other parameters */
float d_quad_rate; /*! Quadrature rate. */
double d_tau;

/* De-emph IIR filter taps */
std::vector<double> d_fftaps; /*! Feed forward taps. */
Expand Down
10 changes: 8 additions & 2 deletions src/dsp/rx_fft.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -380,19 +380,25 @@ void rx_fft_f::set_fft_size(unsigned int fftsize)
if (fftsize != d_fftsize)
{
d_fftsize = fftsize;

/* reset FFT object (also reset FFTW plan) */
delete d_fft;
#if GNURADIO_VERSION < 0x030900
d_fft = new gr::fft::fft_complex(d_fftsize, true);
#else
d_fft = new gr::fft::fft_complex_fwd(d_fftsize);
#endif

update_window();
}
}

/*! \brief Set new quadrature rate. */
void rx_fft_f::set_quad_rate(double quad_rate)
{
if (quad_rate != d_audiorate) {
d_audiorate = quad_rate;
}
}

/*! \brief Set new window type. */
void rx_fft_f::set_window_type(int wintype, bool normalize_energy)
{
Expand Down
1 change: 1 addition & 0 deletions src/dsp/rx_fft.h
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ class rx_fft_f : public gr::sync_block

void set_fft_size(unsigned int fftsize);
unsigned int fft_size() const {return d_fftsize;}
void set_quad_rate(double quad_rate);

private:
unsigned int d_fftsize; /*! Current FFT size. */
Expand Down
16 changes: 16 additions & 0 deletions src/dsp/stereo_demod.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -151,3 +151,19 @@ stereo_demod::~stereo_demod()
{

}

void stereo_demod::set_audio_rate(float audio_rate)
{
if (std::abs(d_audio_rate-audio_rate) > 0.5f)
{
d_audio_rate = audio_rate;
audio_rr0->set_rate(d_audio_rate/d_input_rate);
deemph0->set_rate(d_audio_rate);
if(d_stereo)
{
audio_rr1->set_rate(d_audio_rate/d_input_rate);
deemph1->set_rate(d_audio_rate);
}
}
}

1 change: 1 addition & 0 deletions src/dsp/stereo_demod.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ class stereo_demod : public gr::hier_block2

public:
~stereo_demod();
void set_audio_rate(float audio_rate);

private:
/* GR blocks */
Expand Down
5 changes: 5 additions & 0 deletions src/qtgui/dockaudio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,11 @@ void DockAudio::setFftRange(quint64 minf, quint64 maxf)
}
}

void DockAudio::setFftSampleRate(quint64 rate)
{
ui->audioSpectrum->setSampleRate(rate);
}

void DockAudio::setNewFftData(float *fftData, int size)
{
ui->audioSpectrum->setNewFftData(fftData, size);
Expand Down
1 change: 1 addition & 0 deletions src/qtgui/dockaudio.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ class DockAudio : public QDockWidget
~DockAudio();

void setFftRange(quint64 minf, quint64 maxf);
void setFftSampleRate(quint64 rate);
void setNewFftData(float *fftData, int size);
void setInvertScrolling(bool enabled);
int fftRate() const { return 10; }
Expand Down
20 changes: 20 additions & 0 deletions src/qtgui/ioconfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,20 @@ CIoConfig::CIoConfig(QSettings * settings,
connect(ui->inSrCombo, SIGNAL(editTextChanged(QString)), this, SLOT(inputRateChanged(QString)));
connect(ui->decimCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(decimationChanged(int)));
connect(m_scanButton, SIGNAL(clicked(bool)), this, SLOT(onScanButtonClicked()));
ui->outSrCombo->addItem("96 kHz", 96000);
ui->outSrCombo->addItem("88.2 kHz", 88200);
ui->outSrCombo->addItem("48 kHz", 48000);
ui->outSrCombo->addItem("44.1 kHz", 44100);
ui->outSrCombo->addItem("24 kHz", 24000);
ui->outSrCombo->addItem("22.05 kHz", 22050);
ui->outSrCombo->addItem("12 kHz", 12000);
ui->outSrCombo->addItem("11.025 kHz", 11025);
ui->outSrCombo->addItem("8 kHz", 8000);
int found = ui->outSrCombo->findData(settings->value("output/sample_rate", 48000));
if (found == -1)
ui->outSrCombo->setCurrentIndex(0);
else
ui->outSrCombo->setCurrentIndex(found);
}

CIoConfig::~CIoConfig()
Expand Down Expand Up @@ -211,6 +225,12 @@ void CIoConfig::saveConfig()
else
m_settings->remove("input/sample_rate");

int_val = ui->outSrCombo->currentData().toInt(&conv_ok);
if (conv_ok)
m_settings->setValue("output/sample_rate", int_val);
else
m_settings->remove("output/sample_rate");

idx = ui->decimCombo->currentIndex();
int_val = idx2decim(idx);
if (int_val < 2)
Expand Down
5 changes: 0 additions & 5 deletions src/qtgui/ioconfig.ui
Original file line number Diff line number Diff line change
Expand Up @@ -316,11 +316,6 @@ Leave it at default unless you know what you are doing.</string>
<property name="toolTip">
<string>Select the audio sample rate</string>
</property>
<item>
<property name="text">
<string>48 kHz</string>
</property>
</item>
</widget>
</item>
</layout>
Expand Down
Loading