Skip to content

Commit 631df78

Browse files
iq_tool: implement buffered file reader
And add IQ player repeat option...
1 parent 3ebbbde commit 631df78

File tree

9 files changed

+670
-44
lines changed

9 files changed

+670
-44
lines changed

src/applications/gqrx/mainwindow.cpp

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,8 @@ MainWindow::MainWindow(const QString& cfgfile, bool edit_conf, QWidget *parent)
313313
// I/Q playback
314314
connect(iq_tool, SIGNAL(startRecording(QString, enum receiver::file_formats, int)), this, SLOT(startIqRecording(QString, enum receiver::file_formats, int)));
315315
connect(iq_tool, SIGNAL(stopRecording()), this, SLOT(stopIqRecording()));
316-
connect(iq_tool, SIGNAL(startPlayback(QString, float, qint64, enum receiver::file_formats, bool)), this, SLOT(startIqPlayback(QString, float, qint64, enum receiver::file_formats, bool)));
316+
connect(iq_tool, SIGNAL(startPlayback(QString, float, qint64, enum receiver::file_formats, int, bool)),
317+
this, SLOT(startIqPlayback(QString, float, qint64, enum receiver::file_formats, int, bool)));
317318
connect(iq_tool, SIGNAL(stopPlayback()), this, SLOT(stopIqPlayback()));
318319
connect(iq_tool, SIGNAL(seek(qint64)), this,SLOT(seekIqFile(qint64)));
319320

@@ -1478,26 +1479,30 @@ double MainWindow::setSqlLevelAuto()
14781479
void MainWindow::meterTimeout()
14791480
{
14801481
float level;
1481-
struct receiver::iq_recorder_stats iq_stats;
1482+
struct receiver::iq_tool_stats iq_stats;
14821483

14831484
level = rx->get_signal_pwr();
14841485
ui->sMeter->setLevel(level);
14851486
remote->setSignalLevel(level);
14861487
// As it looks like this timer is always active (when the DSP is running),
14871488
// check iq recorder state here too
1488-
rx->get_iq_recorder_stats(iq_stats);
1489-
if(iq_stats.active)
1489+
rx->get_iq_tool_stats(iq_stats);
1490+
if(iq_stats.recording)
14901491
{
14911492
if(iq_stats.failed)
14921493
{
14931494
//stop the recorder
1494-
iq_tool->updateStats(iq_stats.failed, iq_stats.buffers_used, iq_stats.file_size);
1495+
iq_tool->updateStats(iq_stats.failed, iq_stats.buffer_usage, iq_stats.file_pos);
14951496
iq_tool->cancelRecording();
14961497
}else{
14971498
//update status
1498-
iq_tool->updateStats(iq_stats.failed, iq_stats.buffers_used, iq_stats.file_size);
1499+
iq_tool->updateStats(iq_stats.failed, iq_stats.buffer_usage, iq_stats.file_pos);
14991500
}
15001501
}
1502+
if(iq_stats.playing)
1503+
{
1504+
iq_tool->updateStats(iq_stats.failed, iq_stats.buffer_usage, iq_stats.file_pos);
1505+
}
15011506
}
15021507

15031508
/** Baseband FFT plot timeout. */
@@ -1738,7 +1743,8 @@ void MainWindow::stopIqRecording()
17381743

17391744
void MainWindow::startIqPlayback(const QString& filename, float samprate,
17401745
qint64 center_freq,
1741-
enum receiver::file_formats fmt, bool repeat)
1746+
enum receiver::file_formats fmt,
1747+
int buffers_max, bool repeat)
17421748
{
17431749
if (ui->actionDSP->isChecked())
17441750
{
@@ -1759,7 +1765,7 @@ void MainWindow::startIqPlayback(const QString& filename, float samprate,
17591765

17601766
rx->set_input_device(devstr.toStdString());
17611767
updateHWFrequencyRange(false);
1762-
rx->set_input_file(filename.toStdString(), samprate, fmt, repeat);
1768+
rx->set_input_file(filename.toStdString(), samprate, fmt, buffers_max, repeat);
17631769

17641770
// sample rate
17651771
auto actual_rate = rx->set_input_rate((double)samprate);

src/applications/gqrx/mainwindow.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -197,10 +197,12 @@ private slots:
197197
void stopAudioStreaming();
198198

199199
/* I/Q playback and recording*/
200-
void startIqRecording(const QString& recdir, enum receiver::file_formats fmt, int buffers_max);
200+
void startIqRecording(const QString& recdir,
201+
enum receiver::file_formats fmt, int buffers_max);
201202
void stopIqRecording();
202-
void startIqPlayback(const QString& filename, float samprate, qint64 center_freq,
203-
enum receiver::file_formats fmt, bool repeat);
203+
void startIqPlayback(const QString& filename, float samprate,
204+
qint64 center_freq, enum receiver::file_formats fmt,
205+
int buffers_max, bool repeat);
204206
void stopIqPlayback();
205207
void seekIqFile(qint64 seek_pos);
206208

src/applications/gqrx/receiver.cpp

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ receiver::receiver(const std::string input_device,
116116
ddc = make_downconverter_cc(d_ddc_decim, 0.0, d_decim_rate);
117117
rx = make_nbrx(d_quad_rate, d_audio_rate);
118118

119-
input_file = gr::blocks::file_source::make(sizeof(gr_complex),get_zero_file().c_str(),false);
119+
input_file = file_source::make(sizeof(gr_complex),get_zero_file().c_str(),0,0,1);
120120
input_throttle = gr::blocks::throttle::make(sizeof(gr_complex),192000.0);
121121

122122
to_s32lc = any_to_any<gr_complex,std::complex<int32_t>>::make();
@@ -264,12 +264,14 @@ void receiver::set_input_device(const std::string device)
264264
* @param fmt
265265
*/
266266
void receiver::set_input_file(const std::string name, const int sample_rate,
267-
const enum file_formats fmt, bool repeat)
267+
const enum file_formats fmt, int buffers_max,
268+
bool repeat)
268269
{
269270
std::string error = "";
270271
size_t sample_size = sample_size_from_format(fmt);
271272

272-
input_file = gr::blocks::file_source::make(sample_size, name.c_str(), repeat);
273+
input_file = file_source::make(sample_size, name.c_str(), 0, 0, sample_rate,
274+
repeat,buffers_max);
273275

274276
if (d_running)
275277
{
@@ -1505,14 +1507,19 @@ receiver::status receiver::seek_iq_file(long pos)
15051507
return status;
15061508
}
15071509

1508-
void receiver::get_iq_recorder_stats(struct iq_recorder_stats &stats)
1510+
void receiver::get_iq_tool_stats(struct iq_tool_stats &stats)
15091511
{
1510-
stats.active = d_recording_iq;
1512+
stats.recording = d_recording_iq;
1513+
stats.playing = (d_last_format != FILE_FORMAT_NONE);
15111514
if(d_recording_iq && iq_sink)
15121515
{
15131516
stats.failed = iq_sink->get_failed();
1514-
stats.buffers_used = iq_sink->get_buffer_usage();
1515-
stats.file_size = iq_sink->get_written();
1517+
stats.buffer_usage = iq_sink->get_buffer_usage();
1518+
stats.file_pos = iq_sink->get_written();
1519+
}else{
1520+
stats.failed = input_file->get_failed();
1521+
stats.buffer_usage = input_file->get_buffer_usage();
1522+
stats.file_pos = input_file->tell();
15161523
}
15171524
}
15181525

src/applications/gqrx/receiver.h

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,6 @@
2424
#define RECEIVER_H
2525

2626
#include <gnuradio/blocks/multiply_const.h>
27-
#include <gnuradio/blocks/file_sink.h>
28-
#include <gnuradio/blocks/file_source.h>
2927
#include <gnuradio/blocks/null_sink.h>
3028
#include <gnuradio/blocks/wavfile_sink.h>
3129
#include <gnuradio/blocks/wavfile_source.h>
@@ -49,6 +47,7 @@
4947
#include "dsp/format_converter.h"
5048
#include "interfaces/udp_sink_f.h"
5149
#include "interfaces/file_sink.h"
50+
#include "interfaces/file_source.h"
5251
#include "receivers/receiver_base.h"
5352

5453
#ifdef WITH_PULSEAUDIO
@@ -121,12 +120,13 @@ class receiver
121120
FILE_FORMAT_CS32LU,
122121
};
123122

124-
struct iq_recorder_stats
123+
struct iq_tool_stats
125124
{
126-
bool active;
125+
bool recording;
126+
bool playing;
127127
bool failed;
128-
int buffers_used;
129-
size_t file_size;
128+
int buffer_usage;
129+
size_t file_pos;
130130
};
131131

132132
static const unsigned int DEFAULT_FFT_SIZE = 8192;
@@ -141,7 +141,8 @@ class receiver
141141
void set_input_device(const std::string device);
142142
void set_output_device(const std::string device);
143143
void set_input_file(const std::string name, const int sample_rate,
144-
const enum file_formats fmt, bool repeat);
144+
const enum file_formats fmt, int buffers_max,
145+
bool repeat);
145146

146147
std::vector<std::string> get_antennas(void) const;
147148
void set_antenna(const std::string &antenna);
@@ -238,8 +239,8 @@ class receiver
238239
status start_iq_recording(const std::string filename, const enum file_formats fmt, int buffers_max);
239240
status stop_iq_recording();
240241
status seek_iq_file(long pos);
241-
void get_iq_recorder_stats(struct iq_recorder_stats &stats);
242-
bool is_playing_iq() const { return !(d_iq_fmt == FILE_FORMAT_NONE); }
242+
void get_iq_tool_stats(struct iq_tool_stats &stats);
243+
bool is_playing_iq() { return d_iq_fmt != FILE_FORMAT_NONE; }
243244

244245
/* sample sniffer */
245246
status start_sniffer(unsigned int samplrate, int buffsize);
@@ -328,7 +329,7 @@ class receiver
328329
any_to_any<std::complex<uint8_t>, gr_complex>::sptr from_s8uc;
329330

330331
gr::blocks::throttle::sptr input_throttle;
331-
gr::blocks::file_source::sptr input_file;
332+
file_source::sptr input_file;
332333

333334
gr::blocks::wavfile_sink::sptr wav_sink; /*!< WAV file sink for recording. */
334335
gr::blocks::wavfile_source::sptr wav_src; /*!< WAV file source for playback. */

src/interfaces/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,6 @@ add_source_files(SRCS_LIST
55
udp_sink_f.h
66
file_sink.cpp
77
file_sink.h
8+
file_source.cpp
9+
file_source.h
810
)

0 commit comments

Comments
 (0)