Skip to content

Commit 3841597

Browse files
IQ Tool: implement buffered file reader
And add IQ player repeat option...
1 parent 9cae09f commit 3841597

File tree

10 files changed

+920
-286
lines changed

10 files changed

+920
-286
lines changed

src/applications/gqrx/mainwindow.cpp

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,8 @@ MainWindow::MainWindow(const QString& cfgfile, bool edit_conf, QWidget *parent)
281281
// I/Q playback
282282
connect(iq_tool, SIGNAL(startRecording(QString, enum receiver::file_formats, int)), this, SLOT(startIqRecording(QString, enum receiver::file_formats, int)));
283283
connect(iq_tool, SIGNAL(stopRecording()), this, SLOT(stopIqRecording()));
284-
connect(iq_tool, SIGNAL(startPlayback(QString, float, qint64, enum receiver::file_formats, bool)), this, SLOT(startIqPlayback(QString, float, qint64, enum receiver::file_formats, bool)));
284+
connect(iq_tool, SIGNAL(startPlayback(QString, float, qint64, enum receiver::file_formats, int, bool)),
285+
this, SLOT(startIqPlayback(QString, float, qint64, enum receiver::file_formats, int, bool)));
285286
connect(iq_tool, SIGNAL(stopPlayback()), this, SLOT(stopIqPlayback()));
286287
connect(iq_tool, SIGNAL(seek(qint64)), this,SLOT(seekIqFile(qint64)));
287288

@@ -1377,26 +1378,30 @@ double MainWindow::setSqlLevelAuto()
13771378
void MainWindow::meterTimeout()
13781379
{
13791380
float level;
1380-
struct receiver::iq_recorder_stats iq_stats;
1381+
struct receiver::iq_tool_stats iq_stats;
13811382

13821383
level = rx->get_signal_pwr();
13831384
ui->sMeter->setLevel(level);
13841385
remote->setSignalLevel(level);
13851386
// As it looks like this timer is always active (when the DSP is running),
13861387
// check iq recorder state here too
1387-
rx->get_iq_recorder_stats(iq_stats);
1388-
if(iq_stats.active)
1388+
rx->get_iq_tool_stats(iq_stats);
1389+
if(iq_stats.recording)
13891390
{
13901391
if(iq_stats.failed)
13911392
{
13921393
//stop the recorder
1393-
iq_tool->updateStats(iq_stats.failed, iq_stats.buffers_used, iq_stats.file_size);
1394+
iq_tool->updateStats(iq_stats.failed, iq_stats.buffer_usage, iq_stats.file_pos);
13941395
iq_tool->cancelRecording();
13951396
}else{
13961397
//update status
1397-
iq_tool->updateStats(iq_stats.failed, iq_stats.buffers_used, iq_stats.file_size);
1398+
iq_tool->updateStats(iq_stats.failed, iq_stats.buffer_usage, iq_stats.file_pos);
13981399
}
13991400
}
1401+
if(iq_stats.playing)
1402+
{
1403+
iq_tool->updateStats(iq_stats.failed, iq_stats.buffer_usage, iq_stats.file_pos);
1404+
}
14001405
}
14011406

14021407
#define LOG2_10 3.321928094887362
@@ -1661,7 +1666,8 @@ void MainWindow::stopIqRecording()
16611666

16621667
void MainWindow::startIqPlayback(const QString& filename, float samprate,
16631668
qint64 center_freq,
1664-
enum receiver::file_formats fmt, bool repeat)
1669+
enum receiver::file_formats fmt,
1670+
int buffers_max, bool repeat)
16651671
{
16661672
if (ui->actionDSP->isChecked())
16671673
{
@@ -1682,7 +1688,7 @@ void MainWindow::startIqPlayback(const QString& filename, float samprate,
16821688

16831689
rx->set_input_device(devstr.toStdString());
16841690
updateHWFrequencyRange(false);
1685-
rx->set_input_file(filename.toStdString(), samprate, fmt, repeat);
1691+
rx->set_input_file(filename.toStdString(), samprate, fmt, buffers_max, repeat);
16861692

16871693
// sample rate
16881694
auto actual_rate = rx->set_input_rate(samprate);

src/applications/gqrx/mainwindow.h

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

182182
/* I/Q playback and recording*/
183-
void startIqRecording(const QString& recdir, enum receiver::file_formats fmt, int buffers_max);
183+
void startIqRecording(const QString& recdir,
184+
enum receiver::file_formats fmt, int buffers_max);
184185
void stopIqRecording();
185-
void startIqPlayback(const QString& filename, float samprate, qint64 center_freq,
186-
enum receiver::file_formats fmt, bool repeat);
186+
void startIqPlayback(const QString& filename, float samprate,
187+
qint64 center_freq, enum receiver::file_formats fmt,
188+
int buffers_max, bool repeat);
187189
void stopIqPlayback();
188190
void seekIqFile(qint64 seek_pos);
189191

src/applications/gqrx/receiver.cpp

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

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

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

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

273275
if (d_running)
274276
{
@@ -1485,14 +1487,19 @@ receiver::status receiver::seek_iq_file(long pos)
14851487
return status;
14861488
}
14871489

1488-
void receiver::get_iq_recorder_stats(struct iq_recorder_stats &stats)
1490+
void receiver::get_iq_tool_stats(struct iq_tool_stats &stats)
14891491
{
1490-
stats.active = d_recording_iq;
1492+
stats.recording = d_recording_iq;
1493+
stats.playing = (d_last_format != FILE_FORMAT_NONE);
14911494
if(d_recording_iq && iq_sink)
14921495
{
14931496
stats.failed = iq_sink->get_failed();
1494-
stats.buffers_used = iq_sink->get_buffer_usage();
1495-
stats.file_size = iq_sink->get_written();
1497+
stats.buffer_usage = iq_sink->get_buffer_usage();
1498+
stats.file_pos = iq_sink->get_written();
1499+
}else{
1500+
stats.failed = input_file->get_failed();
1501+
stats.buffer_usage = input_file->get_buffer_usage();
1502+
stats.file_pos = input_file->tell();
14961503
}
14971504
}
14981505

src/applications/gqrx/receiver.h

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@
2929
#include <gnuradio/blocks/multiply_const.h>
3030
#endif
3131

32-
#include <gnuradio/blocks/file_sink.h>
33-
#include <gnuradio/blocks/file_source.h>
32+
//#include <gnuradio/blocks/file_sink.h>
33+
//#include <gnuradio/blocks/file_source.h>
3434
#include <gnuradio/blocks/null_sink.h>
3535
#include <gnuradio/blocks/wavfile_sink.h>
3636
#include <gnuradio/blocks/wavfile_source.h>
@@ -54,6 +54,7 @@
5454
#include "dsp/format_converter.h"
5555
#include "interfaces/udp_sink_f.h"
5656
#include "interfaces/file_sink.h"
57+
#include "interfaces/file_source.h"
5758
#include "receivers/receiver_base.h"
5859

5960
#ifdef WITH_PULSEAUDIO
@@ -126,12 +127,13 @@ class receiver
126127
FILE_FORMAT_CS32LU,
127128
};
128129

129-
struct iq_recorder_stats
130+
struct iq_tool_stats
130131
{
131-
bool active;
132+
bool recording;
133+
bool playing;
132134
bool failed;
133-
int buffers_used;
134-
size_t file_size;
135+
int buffer_usage;
136+
size_t file_pos;
135137
};
136138

137139
receiver(const std::string input_device="",
@@ -144,7 +146,8 @@ class receiver
144146
void set_input_device(const std::string device);
145147
void set_output_device(const std::string device);
146148
void set_input_file(const std::string name, const int sample_rate,
147-
const enum file_formats fmt, bool repeat);
149+
const enum file_formats fmt, int buffers_max,
150+
bool repeat);
148151

149152
std::vector<std::string> get_antennas(void) const;
150153
void set_antenna(const std::string &antenna);
@@ -241,8 +244,8 @@ class receiver
241244
status start_iq_recording(const std::string filename, const enum file_formats fmt, int buffers_max);
242245
status stop_iq_recording();
243246
status seek_iq_file(long pos);
244-
void get_iq_recorder_stats(struct iq_recorder_stats &stats);
245-
bool is_playing_iq() const { return !(d_iq_fmt == FILE_FORMAT_NONE); }
247+
void get_iq_tool_stats(struct iq_tool_stats &stats);
248+
bool is_playing_iq() { return d_iq_fmt != FILE_FORMAT_NONE; }
246249

247250
/* sample sniffer */
248251
status start_sniffer(unsigned int samplrate, int buffsize);
@@ -329,7 +332,7 @@ class receiver
329332
any_to_any<std::complex<uint8_t>, gr_complex>::sptr from_s8uc;
330333

331334
gr::blocks::throttle::sptr input_throttle;
332-
gr::blocks::file_source::sptr input_file;
335+
file_source::sptr input_file;
333336

334337
gr::blocks::wavfile_sink::sptr wav_sink; /*!< WAV file sink for recording. */
335338
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)