From e07e5f3e833b00f99fba017f94db37fce45f0e5c Mon Sep 17 00:00:00 2001 From: Vladislav P Date: Sat, 13 Apr 2024 16:52:31 +0300 Subject: [PATCH] squelch_recorder: get timestamps from IQ files --- src/applications/gqrx/receiver.cpp | 3 +++ src/applications/gqrx/receiver.h | 18 ++++++++++++++++++ src/interfaces/file_source.cpp | 3 --- src/interfaces/file_source.h | 2 +- src/interfaces/wav_sink.cpp | 5 +++-- src/interfaces/wav_sink.h | 13 ++++++++++++- src/receivers/receiver_base.h | 1 + 7 files changed, 38 insertions(+), 7 deletions(-) diff --git a/src/applications/gqrx/receiver.cpp b/src/applications/gqrx/receiver.cpp index 610ffa4a60..f1754b331f 100644 --- a/src/applications/gqrx/receiver.cpp +++ b/src/applications/gqrx/receiver.cpp @@ -214,6 +214,7 @@ void receiver::set_input_device(const std::string device) tb->disconnect_all(); iq_src.reset(); + d_iq_ts.set_file_source(nullptr); for (auto& rxc : rx) rxc->connected(false); @@ -284,6 +285,7 @@ void receiver::set_input_file(const std::string name, const int sample_rate, //set_demod(d_demod, fmt, true); input_file->set_save_progress_cb(d_save_progress); + d_iq_ts.set_file_source(input_file); reconnect_all(fmt, true); set_input_rate(sample_rate); @@ -2124,6 +2126,7 @@ void receiver::connect_rx(int n) if (rx[n]->connected()) return; std::cerr<<"connect_rx "<get_demod()<set_timestamp_source(&d_iq_ts); if (rx[n]->get_demod() != Modulations::MODE_OFF) { if (d_active == 0) diff --git a/src/applications/gqrx/receiver.h b/src/applications/gqrx/receiver.h index af6300cbac..62f8198f61 100644 --- a/src/applications/gqrx/receiver.h +++ b/src/applications/gqrx/receiver.h @@ -160,6 +160,23 @@ class receiver }; typedef std::shared_ptr fft_reader_sptr; + struct iqfile_timestamp_source:wavfile_sink_gqrx::timestamp_source + { + uint64_t get() override + { + if(iqfile) + return iqfile->get_timestamp_ms(); + else + return time(nullptr) * 1000llu; + } + void set_file_source(file_source::sptr value) + { + iqfile = value; + } + private: + file_source::sptr iqfile; + }; + receiver(const std::string input_device="", const std::string audio_device="", unsigned int decimation=1); @@ -431,6 +448,7 @@ class receiver bool d_mute; /*!< Enable audio mute. */ file_formats d_iq_fmt; file_formats d_last_format; + iqfile_timestamp_source d_iq_ts; std::string input_devstr; /*!< Current input device string. */ std::string output_devstr; /*!< Current output device string. */ diff --git a/src/interfaces/file_source.cpp b/src/interfaces/file_source.cpp index ddff6f79ff..ed135740bb 100644 --- a/src/interfaces/file_source.cpp +++ b/src/interfaces/file_source.cpp @@ -494,7 +494,6 @@ int file_source::work(int noutput_items, uint64_t file_source::tell() { - std::unique_lock guard(d_mutex); return d_length_items - d_items_remaining; } @@ -507,13 +506,11 @@ int file_source::get_buffer_usage() uint64_t file_source::get_timestamp_ms() { - std::unique_lock guard(d_mutex); return d_time_ms + (d_length_items - d_items_remaining) * 1000 / d_sample_rate; } uint64_t file_source::get_items_remaining() { - std::unique_lock guard(d_mutex); return d_items_remaining; } diff --git a/src/interfaces/file_source.h b/src/interfaces/file_source.h index 9e034a686d..0d1eb2972c 100644 --- a/src/interfaces/file_source.h +++ b/src/interfaces/file_source.h @@ -55,7 +55,7 @@ class BLOCKS_API file_source : public gr::sync_block size_t d_itemsize; uint64_t d_start_offset_items; uint64_t d_length_items; - uint64_t d_items_remaining; + std::atomic d_items_remaining; FILE* d_fp; FILE* d_new_fp; bool d_repeat; diff --git a/src/interfaces/wav_sink.cpp b/src/interfaces/wav_sink.cpp index e8e4f3e160..709de6d678 100644 --- a/src/interfaces/wav_sink.cpp +++ b/src/interfaces/wav_sink.cpp @@ -262,8 +262,9 @@ int wavfile_sink_gqrx::open_new() int wavfile_sink_gqrx::open_new_unlocked() { // FIXME: option to use local time + QDateTime ts = d_ts_src ? QDateTime::fromMSecsSinceEpoch(d_ts_src->get()) : QDateTime::currentDateTime().toUTC(); // use toUTC() function compatible with older versions of Qt. - QString file_name = QDateTime::currentDateTime().toUTC().toString("gqrx_yyyyMMdd_hhmmss"); + QString file_name = ts.toString("gqrx_yyyyMMdd_hhmmss"); QString filename = QString("%1/%2_%3.wav").arg(QString(d_rec_dir.data())).arg(file_name).arg(qint64(d_center_freq + d_offset)); if (open_unlocked(filename.toStdString().data())) { @@ -476,7 +477,7 @@ void wavfile_sink_gqrx::set_sample_rate(unsigned int sample_rate) std::unique_lock guard(d_mutex); d_h.sample_rate = sample_rate; d_min_time_samp = d_min_time_ms * d_h.sample_rate / 1000; - d_min_time_samp = d_min_time_ms * d_h.sample_rate / 1000; + d_max_gap_samp = d_max_gap_ms * d_h.sample_rate / 1000; set_history(1 + sample_rate * (SQL_REC_MIN_TIME + SQL_REC_MAX_GAP)); } diff --git a/src/interfaces/wav_sink.h b/src/interfaces/wav_sink.h index a9b5d5151d..dd468d9e8a 100644 --- a/src/interfaces/wav_sink.h +++ b/src/interfaces/wav_sink.h @@ -57,7 +57,13 @@ class wavfile_sink_gqrx : virtual public gr::sync_block FORMAT_DOUBLE, FORMAT_VORBIS = 0x0060, }; - + struct timestamp_source + { + virtual uint64_t get() + { + return time(nullptr) * 1000llu; + } + }; private: //! WAV file header information. struct wav_header_info { @@ -114,6 +120,7 @@ class wavfile_sink_gqrx : virtual public gr::sync_block int d_max_gap_samp; sql_action d_prev_action; int d_prev_roffset; + timestamp_source * d_ts_src{nullptr}; /*! * \brief If any file changes have occurred, update now. This is called @@ -184,6 +191,10 @@ class wavfile_sink_gqrx : virtual public gr::sync_block int get_min_time(); int get_max_gap(); bool is_active() { return !! d_fp; } + void set_timestamp_source(timestamp_source * value) + { + d_ts_src = value; + } private: bool open_unlocked(const char* filename); int open_new_unlocked(); diff --git a/src/receivers/receiver_base.h b/src/receivers/receiver_base.h index b2c20d1b2f..2595018675 100644 --- a/src/receivers/receiver_base.h +++ b/src/receivers/receiver_base.h @@ -95,6 +95,7 @@ class receiver_base_cf : public gr::hier_block2, public vfo_s void set_audio_rec_sql_triggered(bool enabled) override; void set_audio_rec_min_time(const int time_ms) override; void set_audio_rec_max_gap(const int time_ms) override; + void set_timestamp_source(wavfile_sink_gqrx::timestamp_source * value){ wav_sink->set_timestamp_source(value); } /* UDP streaming */ bool set_udp_host(const std::string &host) override;