aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/example.ini1
-rw-r--r--src/DabMod.cpp2
-rw-r--r--src/EtiReader.cpp39
-rw-r--r--src/EtiReader.h16
-rw-r--r--src/Flowgraph.cpp53
-rw-r--r--src/TimestampDecoder.cpp12
-rw-r--r--src/TimestampDecoder.h17
7 files changed, 94 insertions, 46 deletions
diff --git a/doc/example.ini b/doc/example.ini
index a0cd110..3dd8505 100644
--- a/doc/example.ini
+++ b/doc/example.ini
@@ -60,6 +60,7 @@ loop=0
; before it timeouts
;edi_max_delay=240
; No support yet for multicast, should work with and without PFT
+; This EDI implementation does not support EDI Packet Resend
; When recieving data using ZeroMQ, the source is the URI to be used
;transport=zeromq
diff --git a/src/DabMod.cpp b/src/DabMod.cpp
index ac7842f..44951d7 100644
--- a/src/DabMod.cpp
+++ b/src/DabMod.cpp
@@ -699,7 +699,7 @@ int launch_modulator(int argc, char* argv[])
}
- EdiReader ediReader;
+ EdiReader ediReader(tist_offset_s, tist_delay_stages);
EdiDecoder::ETIDecoder ediInput(ediReader);
if (edi_max_delay_ms > 0.0f) {
// setMaxDelay wants number of AF packets, which correspond to 24ms ETI frames
diff --git a/src/EtiReader.cpp b/src/EtiReader.cpp
index a1053c6..f0a1793 100644
--- a/src/EtiReader.cpp
+++ b/src/EtiReader.cpp
@@ -304,6 +304,13 @@ uint32_t EtiReader::getPPSOffset()
return timestamp;
}
+EdiReader::EdiReader(
+ double& tist_offset_s,
+ unsigned tist_delay_stages) :
+ m_timestamp_decoder(tist_offset_s, tist_delay_stages)
+{
+ rcs.enrol(&m_timestamp_decoder);
+}
unsigned EdiReader::getMode()
{
@@ -339,6 +346,19 @@ const std::vector<std::shared_ptr<SubchannelSource> > EdiReader::getSubchannels(
return sources;
}
+bool EdiReader::sourceContainsTimestamp()
+{
+ if (not (m_frameReady and m_fc_valid)) {
+ throw std::runtime_error("Trying to get timestamp before it is ready");
+ }
+
+ return m_fc.tsta != 0xFFFFFF;
+}
+
+void EdiReader::calculateTimestamp(struct frame_timestamp& ts)
+{
+}
+
bool EdiReader::isFrameReady()
{
return m_frameReady;
@@ -493,13 +513,20 @@ void EdiReader::assemble()
// Accept zero subchannels, because of an edge-case that can happen
// during reconfiguration. See ETS 300 799 Clause 5.3.3
- // TODO check time validity
+ if (m_utco == 0 and m_seconds == 0) {
+ // We don't support relative-only timestamps
+ m_fc.tsta = 0xFFFFFF; // disable TSTA
+ }
+
+ /* According to Annex F
+ * EDI = UTC + UTCO
+ * We need UTC = EDI - UTCO
+ */
+ auto utc_ts = m_seconds - m_utco;
+
+ m_timestamp_decoder.updateTimestampEdi(
+ utc_ts, m_fc.tsta, m_fc.fct());
- /* TODO timestamp
- myTimestampDecoder.updateTimestampEti(
- eti_fc.FP & 0x3,
- eti_eoh.MNSC, getPPSOffset(), eti_fc.FCT);
- */
m_frameReady = true;
}
diff --git a/src/EtiReader.h b/src/EtiReader.h
index 1b75025..5231365 100644
--- a/src/EtiReader.h
+++ b/src/EtiReader.h
@@ -122,11 +122,14 @@ private:
class EdiReader : public EtiSource, public EdiDecoder::DataCollector
{
public:
+ EdiReader(
+ double& tist_offset_s,
+ unsigned tist_delay_stages);
+
virtual unsigned getMode();
virtual unsigned getFp();
- virtual bool sourceContainsTimestamp() { return false; }
- virtual void calculateTimestamp(struct frame_timestamp& ts)
- { /* TODO */ }
+ virtual bool sourceContainsTimestamp();
+ virtual void calculateTimestamp(struct frame_timestamp& ts);
virtual const std::vector<std::shared_ptr<SubchannelSource> > getSubchannels() const;
virtual bool isFrameReady(void);
@@ -181,10 +184,13 @@ private:
uint16_t m_rfu = 0xffff;
std::map<uint8_t, std::shared_ptr<SubchannelSource> > m_sources;
+
+ TimestampDecoder m_timestamp_decoder;
};
-/* The EDI input does not use the inputs defined in InputReader.h, as they were designed
- * for ETI. It uses the EdiUdpInput which in turn uses a threaded receiver.
+/* The EDI input does not use the inputs defined in InputReader.h, as they were
+ * designed for ETI. It uses the EdiUdpInput which in turn uses a threaded
+ * receiver.
*/
class EdiUdpInput {
diff --git a/src/Flowgraph.cpp b/src/Flowgraph.cpp
index 0eb1c60..ae75808 100644
--- a/src/Flowgraph.cpp
+++ b/src/Flowgraph.cpp
@@ -111,32 +111,6 @@ void Node::removeInputBuffer(Buffer::sptr& buffer)
}
}
-Edge::Edge(shared_ptr<Node>& srcNode, shared_ptr<Node>& dstNode) :
- mySrcNode(srcNode),
- myDstNode(dstNode)
-{
- PDEBUG("Edge::Edge(srcNode(%s): %p, dstNode(%s): %p) @ %p\n",
- srcNode->plugin()->name(), srcNode.get(),
- dstNode->plugin()->name(), dstNode.get(),
- this);
-
- myBuffer = make_shared<Buffer>();
- srcNode->addOutputBuffer(myBuffer);
- dstNode->addInputBuffer(myBuffer);
-}
-
-
-Edge::~Edge()
-{
- PDEBUG("Edge::~Edge() @ %p\n", this);
-
- if (myBuffer) {
- mySrcNode->removeOutputBuffer(myBuffer);
- myDstNode->removeInputBuffer(myBuffer);
- }
-}
-
-
int Node::process()
{
PDEBUG("Node::process()\n");
@@ -178,12 +152,37 @@ int Node::process()
return ret;
}
+Edge::Edge(shared_ptr<Node>& srcNode, shared_ptr<Node>& dstNode) :
+ mySrcNode(srcNode),
+ myDstNode(dstNode)
+{
+ PDEBUG("Edge::Edge(srcNode(%s): %p, dstNode(%s): %p) @ %p\n",
+ srcNode->plugin()->name(), srcNode.get(),
+ dstNode->plugin()->name(), dstNode.get(),
+ this);
+
+ myBuffer = make_shared<Buffer>();
+ srcNode->addOutputBuffer(myBuffer);
+ dstNode->addInputBuffer(myBuffer);
+}
+
+
+Edge::~Edge()
+{
+ PDEBUG("Edge::~Edge() @ %p\n", this);
+
+ if (myBuffer) {
+ mySrcNode->removeOutputBuffer(myBuffer);
+ myDstNode->removeInputBuffer(myBuffer);
+ }
+}
+
+
Flowgraph::Flowgraph() :
myProcessTime(0)
{
PDEBUG("Flowgraph::Flowgraph() @ %p\n", this);
-
}
diff --git a/src/TimestampDecoder.cpp b/src/TimestampDecoder.cpp
index 5f93407..42d53ab 100644
--- a/src/TimestampDecoder.cpp
+++ b/src/TimestampDecoder.cpp
@@ -2,7 +2,7 @@
Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Her Majesty the
Queen in Right of Canada (Communications Research Center Canada)
- Copyright (C) 2014, 2015
+ Copyright (C) 2017
Matthias P. Braendli, matthias.braendli@mpb.li
http://opendigitalradio.org
@@ -197,6 +197,16 @@ void TimestampDecoder::updateTimestampEti(
latestFCT = fct;
}
+void TimestampDecoder::updateTimestampEdi(
+ uint32_t seconds_utc,
+ uint32_t pps, // In units of 1/16384000 s
+ int32_t fct)
+{
+ updateTimestampPPS(pps);
+ time_secs = seconds_utc;
+ latestFCT = fct;
+}
+
void TimestampDecoder::set_parameter(
const std::string& parameter,
const std::string& value)
diff --git a/src/TimestampDecoder.h b/src/TimestampDecoder.h
index 29e12c2..a822ee5 100644
--- a/src/TimestampDecoder.h
+++ b/src/TimestampDecoder.h
@@ -2,7 +2,7 @@
Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Her Majesty the
Queen in Right of Canada (Communications Research Center Canada)
- Copyright (C) 2014, 2015
+ Copyright (C) 2017
Matthias P. Braendli, matthias.braendli@mpb.li
http://opendigitalradio.org
@@ -24,8 +24,7 @@
along with ODR-DabMod. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef TIMESTAMP_DECODER_H
-#define TIMESTAMP_DECODER_H
+#pragma once
#include <queue>
#include <memory>
@@ -97,7 +96,8 @@ struct frame_timestamp
}
};
-/* This module decodes MNSC time information */
+/* This module decodes MNSC time information from an ETI source and
+ * EDI time information*/
class TimestampDecoder : public RemoteControllable
{
public:
@@ -135,13 +135,19 @@ class TimestampDecoder : public RemoteControllable
/* Calculate the timestamp for the current frame. */
void calculateTimestamp(struct frame_timestamp& ts);
- /* Update timestamp data from data in ETI */
+ /* Update timestamp data from ETI */
void updateTimestampEti(
int framephase,
uint16_t mnsc,
uint32_t pps, // In units of 1/16384000 s
int32_t fct);
+ /* Update timestamp data from EDI */
+ void updateTimestampEdi(
+ uint32_t seconds_utc,
+ uint32_t pps, // In units of 1/16384000 s
+ int32_t fct);
+
/*********** REMOTE CONTROL ***************/
/* Base function to set parameters. */
@@ -199,5 +205,4 @@ class TimestampDecoder : public RemoteControllable
};
-#endif