From 06268c30c784051dfa5d651cb9195298094113b1 Mon Sep 17 00:00:00 2001 From: "Bram (morningbird)" Date: Wed, 1 Aug 2012 15:06:22 +0200 Subject: dabmod: offset calculation includes pipeline delay due to FIRFilter --- src/DabMod.cpp | 7 ++++++ src/FIRFilter.h | 6 ++--- src/OutputUHD.cpp | 9 ++++++-- src/TimestampDecoder.cpp | 60 ++++++++++++++++++++++++++++++++++++++++-------- src/TimestampDecoder.h | 19 ++++++++++++++- 5 files changed, 86 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/DabMod.cpp b/src/DabMod.cpp index 24dfe4f..6627ed1 100644 --- a/src/DabMod.cpp +++ b/src/DabMod.cpp @@ -35,6 +35,7 @@ #include "OutputUHD.h" #include "PcDebug.h" #include "TimestampDecoder.h" +#include "FIRFilter.h" #include #include @@ -170,6 +171,7 @@ int main(int argc, char* argv[]) struct modulator_offset_config modconf; modconf.use_offset_file = false; modconf.use_offset_fixed = false; + modconf.delay_calculation_pipeline_stages = 0; Flowgraph* flowgraph = NULL; DabModulator* modulator = NULL; @@ -276,6 +278,11 @@ int main(int argc, char* argv[]) modconf.offset_fixed = 0; } + // When using the FIRFilter, increase the modulator offset pipelining delay + // by the correct amount + modconf.delay_calculation_pipeline_stages += FIRFILTER_PIPELINE_DELAY; + + // Setting ETI input filename if (optind < argc) { inputName = argv[optind++]; diff --git a/src/FIRFilter.h b/src/FIRFilter.h index 397301d..7f34fd8 100644 --- a/src/FIRFilter.h +++ b/src/FIRFilter.h @@ -33,6 +33,7 @@ #include #include "ModCodec.h" +#include "PcDebug.h" #include #include @@ -40,8 +41,7 @@ #include #include -//#define MDEBUG(fmt, args...) fprintf (stderr, fmt , ## args) -#define MDEBUG(fmt, args...) +#define FIRFILTER_PIPELINE_DELAY 1 typedef std::complex complexf; @@ -108,7 +108,7 @@ class FIRFilterWorker { } ~FIRFilterWorker() { - MDEBUG("~FIRFilterWorker: Total elapsed thread time filtering: %zu\n", calculationTime); + PDEBUG("~FIRFilterWorker: Total elapsed thread time filtering: %zu\n", calculationTime); } void start(struct FIRFilterWorkerData *firworkerdata) { diff --git a/src/OutputUHD.cpp b/src/OutputUHD.cpp index 6fd3956..c8f4ea9 100644 --- a/src/OutputUHD.cpp +++ b/src/OutputUHD.cpp @@ -339,8 +339,8 @@ void UHDWorker::process(struct UHDWorkerData *uwd) } #endif - if (frame->fct % 50 < 4) { - fprintf(stderr, "UHDOut (%f): frame %d tx_second %zu; pps %.9f\n", + if (last_pps > pps_offset) { + fprintf(stderr, "UHDOut (usrp time: %f): frame %d; tx_second %zu; pps %.9f\n", usrp_time, frame->fct, tx_second, pps_offset); } @@ -461,6 +461,11 @@ void UHDWorker::process(struct UHDWorkerData *uwd) } +#else // ENABLE_UHD + fprintf(stderr, "UHDOut UHD DISABLED: Sample %d : valid timestamp %zu + %f\n", + frame->fct, + tx_second, + pps_offset); #endif last_pps = pps_offset; diff --git a/src/TimestampDecoder.cpp b/src/TimestampDecoder.cpp index 3dd64bf..d3bf578 100644 --- a/src/TimestampDecoder.cpp +++ b/src/TimestampDecoder.cpp @@ -22,14 +22,15 @@ along with CRC-DADMOD. If not, see . */ -#include "TimestampDecoder.h" -#include "Eti.h" -#include -#include "PcDebug.h" +#include #include #include #include #include +#include +#include "PcDebug.h" +#include "TimestampDecoder.h" +#include "Eti.h" //#define MDEBUG(fmt, args...) fprintf (LOG, fmt , ## args) #define MDEBUG(fmt, args...) PDEBUG(fmt, ## args) @@ -37,14 +38,55 @@ void TimestampDecoder::calculateTimestamp(struct frame_timestamp& ts) { - ts.timestamp_valid = full_timestamp_received_mnsc; - ts.timestamp_sec = time_secs; - ts.timestamp_pps_offset = time_pps; + struct frame_timestamp* ts_queued = new struct frame_timestamp; + + /* Push new timestamp into queue */ + ts_queued->timestamp_valid = full_timestamp_received_mnsc; + ts_queued->timestamp_sec = time_secs; + ts_queued->timestamp_pps_offset = time_pps; - ts.timestamp_refresh = offset_changed; + ts_queued->timestamp_refresh = offset_changed; offset_changed = false; - ts += timestamp_offset; + *ts_queued += timestamp_offset; + + queue_timestamps.push(ts_queued); + + if (queue_timestamps.size() < modconfig.delay_calculation_pipeline_stages) { + /* Return invalid timestamp */ + ts.timestamp_valid = false; + ts.timestamp_sec = 0; + ts.timestamp_pps_offset = 0; + ts.timestamp_refresh = false; + } + else { + /* Return timestamp from queue */ + ts_queued = queue_timestamps.front(); + queue_timestamps.pop(); + /*fprintf(stderr, "ts_queued v:%d, sec:%d, pps:%f, ref:%d\n", + ts_queued->timestamp_valid, + ts_queued->timestamp_sec, + ts_queued->timestamp_pps_offset, + ts_queued->timestamp_refresh);*/ + ts = *ts_queued; + /*fprintf(stderr, "ts v:%d, sec:%d, pps:%f, ref:%d\n\n", + ts.timestamp_valid, + ts.timestamp_sec, + ts.timestamp_pps_offset, + ts.timestamp_refresh);*/ + + delete ts_queued; + } + + PDEBUG("Timestamp queue size %zu, delay_calc %u\n", + queue_timestamps.size(), + modconfig.delay_calculation_pipeline_stages); + + if (queue_timestamps.size() > modconfig.delay_calculation_pipeline_stages) { + fprintf(stderr, "Error: Timestamp queue is too large : size %zu ! This should not happen !\n", + queue_timestamps.size()); + } + //ts.print("calc2 "); } diff --git a/src/TimestampDecoder.h b/src/TimestampDecoder.h index 3a1fb1b..68fe546 100644 --- a/src/TimestampDecoder.h +++ b/src/TimestampDecoder.h @@ -25,18 +25,27 @@ #ifndef TIMESTAMP_DECODER_H #define TIMESTAMP_DECODER_H -#include "Eti.h" +#include #include #include #include +#include "Eti.h" struct modulator_offset_config { bool use_offset_fixed; double offset_fixed; + /* These two fields are used when the modulator is run with a fixed offset */ bool use_offset_file; char* offset_filename; + /* These two fields are used when the modulator reads the offset from a file */ + + unsigned delay_calculation_pipeline_stages; + /* Specifies by how many stages the timestamp must be delayed. + * (e.g. The FIRFilter is pipelined, therefore we must increase + * delay_calculation_pipeline_stages by one if the filter is used + */ }; struct frame_timestamp @@ -149,6 +158,14 @@ class TimestampDecoder /* Disable timstamps until full time has been received in mnsc */ bool full_timestamp_received_mnsc; + + /* when pipelining, we must shift the calculated timestamps + * through this queue. Otherwise, it would not be possible to + * synchronise two modulators if only one uses (for instance) the + * FIRFilter (1 stage pipeline) + */ + std::queue queue_timestamps; + }; #endif -- cgit v1.2.3