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

Don't run FFTs until enough samples have arrived #1288

Merged
merged 2 commits into from
Sep 30, 2023
Merged
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
1 change: 1 addition & 0 deletions resources/news.txt
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
IMPROVED: Reduced CPU utilization of demodulators.
IMPROVED: Properly handle smooth scrolling.
IMPROVED: Shorten band names to fit in narrow spaces.
IMPROVED: Delay plot & waterfall drawing until samples arrive from hardware.
CHANGED: Frequency zoom slider zooms around center of display.
CHANGED: Disallow scrolling beyond the FFT frequency limits.
CHANGED: Default narrow FM deviation increased to 5 kHz.
Expand Down
10 changes: 4 additions & 6 deletions src/applications/gqrx/mainwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1499,9 +1499,8 @@ void MainWindow::iqFftTimeout()
}
d_last_fft_ms = now_ms;

rx->get_iq_fft_data(d_iqFftData.data());

ui->plotter->setNewFftData(d_iqFftData.data(), fftsize);
if (rx->get_iq_fft_data(d_iqFftData.data()) >= 0)
ui->plotter->setNewFftData(d_iqFftData.data(), fftsize);
}

/** Audio FFT plot timeout. */
Expand All @@ -1519,9 +1518,8 @@ void MainWindow::audioFftTimeout()
if (!d_have_audio || !uiDockAudio->isVisible())
return;

rx->get_audio_fft_data(d_audioFftData.data());

uiDockAudio->setNewFftData(d_audioFftData.data(), fftsize);
if (rx->get_audio_fft_data(d_audioFftData.data()) >= 0)
uiDockAudio->setNewFftData(d_audioFftData.data(), fftsize);
}

/** RDS message display timeout. */
Expand Down
8 changes: 4 additions & 4 deletions src/applications/gqrx/receiver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -751,9 +751,9 @@ void receiver::set_iq_fft_window(int window_type, bool normalize_energy)
}

/** Get latest baseband FFT data. */
void receiver::get_iq_fft_data(float* fftPoints)
int receiver::get_iq_fft_data(float* fftPoints)
{
iq_fft->get_fft_data(fftPoints);
return iq_fft->get_fft_data(fftPoints);
}

unsigned int receiver::audio_fft_size() const
Expand All @@ -762,9 +762,9 @@ unsigned int receiver::audio_fft_size() const
}

/** Get latest audio FFT data. */
void receiver::get_audio_fft_data(float* fftPoints)
int receiver::get_audio_fft_data(float* fftPoints)
{
audio_fft->get_fft_data(fftPoints);
return audio_fft->get_fft_data(fftPoints);
}

receiver::status receiver::set_nb_on(int nbid, bool on)
Expand Down
4 changes: 2 additions & 2 deletions src/applications/gqrx/receiver.h
Original file line number Diff line number Diff line change
Expand Up @@ -163,8 +163,8 @@ class receiver
void set_iq_fft_size(int newsize);
unsigned int iq_fft_size(void) const;
void set_iq_fft_window(int window_type, bool normalize_energy);
void get_iq_fft_data(float* fftPoints);
void get_audio_fft_data(float* fftPoints);
int get_iq_fft_data(float* fftPoints);
int get_audio_fft_data(float* fftPoints);
unsigned int audio_fft_size(void) const;

/* Noise blanker */
Expand Down
26 changes: 23 additions & 3 deletions src/dsp/rx_fft.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ rx_fft_c::rx_fft_c(unsigned int fftsize, double quad_rate, int wintype, bool nor
gr::io_signature::make(1, 1, sizeof(gr_complex)),
gr::io_signature::make(0, 0, 0)),
d_fftsize(fftsize),
d_startup_samples(0),
d_quadrate(quad_rate),
d_wintype(-1),
d_normalize_energy(false)
Expand Down Expand Up @@ -110,6 +111,9 @@ int rx_fft_c::work(int noutput_items,
d_reader->update_read_pointer(items_to_copy - d_writer->space_available());
memcpy(d_writer->write_pointer(), in, sizeof(gr_complex) * items_to_copy);
d_writer->update_write_pointer(items_to_copy);

if (d_startup_samples < d_writer->bufsize())
d_startup_samples += items_to_copy;
}

return noutput_items;
Expand All @@ -119,7 +123,7 @@ int rx_fft_c::work(int noutput_items,
* \param fftPoints Buffer to copy FFT data
* \param fftSize Current FFT size (output).
*/
void rx_fft_c::get_fft_data(float* fftPoints)
int rx_fft_c::get_fft_data(float* fftPoints)
{
std::chrono::time_point<std::chrono::steady_clock> now = std::chrono::steady_clock::now();
std::chrono::duration<double> diff = now - d_lasttime;
Expand All @@ -130,6 +134,10 @@ void rx_fft_c::get_fft_data(float* fftPoints)
std::lock_guard<std::mutex> lock(d_in_mutex);

d_reader->update_read_pointer(std::min((int)(diff.count() * d_quadrate * 1.001), d_reader->items_available() - MAX_FFT_SIZE));

if (d_startup_samples < d_reader->items_available() - (MAX_FFT_SIZE - d_fftsize))
return -1;

apply_window(d_fftsize);
}

Expand All @@ -143,6 +151,8 @@ void rx_fft_c::get_fft_data(float* fftPoints)
fftPoints[i] = static_cast<float>(std::norm(fftOut[i + d_fftsize/2]));
for (unsigned int i = d_fftsize/2; i < d_fftsize; ++i)
fftPoints[i] = static_cast<float>(std::norm(fftOut[i - d_fftsize/2]));

return 0;
}

/*! \brief Compute FFT on the available input data.
Expand Down Expand Up @@ -249,6 +259,7 @@ rx_fft_f::rx_fft_f(unsigned int fftsize, double audio_rate,
gr::io_signature::make(1, 1, sizeof(float)),
gr::io_signature::make(0, 0, 0)),
d_fftsize(fftsize),
d_startup_samples(0),
d_audiorate(audio_rate),
d_wintype(-1),
d_normalize_energy(false)
Expand Down Expand Up @@ -311,6 +322,9 @@ int rx_fft_f::work(int noutput_items,
d_reader->update_read_pointer(items_to_copy - d_writer->space_available());
memcpy(d_writer->write_pointer(), in, sizeof(float) * items_to_copy);
d_writer->update_write_pointer(items_to_copy);

if (d_startup_samples < d_writer->bufsize())
d_startup_samples += items_to_copy;
}

return noutput_items;
Expand All @@ -320,7 +334,7 @@ int rx_fft_f::work(int noutput_items,
* \param fftPoints Buffer to copy FFT data
* \param fftSize Current FFT size (output).
*/
void rx_fft_f::get_fft_data(float* fftPoints)
int rx_fft_f::get_fft_data(float* fftPoints)
{
std::chrono::time_point<std::chrono::steady_clock> now = std::chrono::steady_clock::now();
std::chrono::duration<double> diff = now - d_lasttime;
Expand All @@ -333,6 +347,10 @@ void rx_fft_f::get_fft_data(float* fftPoints)
std::lock_guard<std::mutex> lock(d_in_mutex);

d_reader->update_read_pointer(std::min((unsigned int)(diff.count() * d_audiorate * 1.001), d_reader->items_available() - d_fftsize));

if ((int)d_startup_samples < d_reader->items_available())
return -1;

apply_window(d_fftsize);
}

Expand All @@ -347,6 +365,8 @@ void rx_fft_f::get_fft_data(float* fftPoints)
for (unsigned int i = d_fftsize/2; i < d_fftsize; ++i)
fftPoints[i] = static_cast<float>(std::norm(fftOut[i - d_fftsize/2]));
}

return 0;
}

/*! \brief Compute FFT on the available input data.
Expand Down Expand Up @@ -425,4 +445,4 @@ void rx_fft_f::update_window()
if (d_normalize_energy)
factor = std::sqrt(factor);
volk_32f_s32f_normalize(d_window.data(), factor, d_fftsize);
}
}
6 changes: 4 additions & 2 deletions src/dsp/rx_fft.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ class rx_fft_c : public gr::sync_block
gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items);

void get_fft_data(float* fftPoints);
int get_fft_data(float* fftPoints);

void set_window_type(int wintype, bool normalize_energy);
int get_window_type() const { return d_wintype; }
Expand All @@ -105,6 +105,7 @@ class rx_fft_c : public gr::sync_block

private:
unsigned int d_fftsize; /*! Current FFT size. */
unsigned int d_startup_samples;
double d_quadrate;
int d_wintype; /*! Current window type. */
bool d_normalize_energy;
Expand Down Expand Up @@ -172,7 +173,7 @@ class rx_fft_f : public gr::sync_block
gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items);

void get_fft_data(float* fftPoints);
int get_fft_data(float* fftPoints);

void set_window_type(int wintype, bool normalize_energy);
int get_window_type() const { return d_wintype; }
Expand All @@ -182,6 +183,7 @@ class rx_fft_f : public gr::sync_block

private:
unsigned int d_fftsize; /*! Current FFT size. */
unsigned int d_startup_samples;
double d_audiorate;
int d_wintype; /*! Current window type. */
bool d_normalize_energy;
Expand Down