aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMatthias P. Braendli <matthias.braendli@mpb.li>2022-10-14 20:00:26 +0200
committerMatthias P. Braendli <matthias.braendli@mpb.li>2022-10-14 20:00:26 +0200
commita2be0c3ab77dab50ded4850f38d2b796b322d0c4 (patch)
treedbbfe88cd7515f08ff552628c1483697eb5f8cf9 /src
parent7441d427947aaa79b88e1eae157981c95d7ca5fa (diff)
downloaddabmod-a2be0c3ab77dab50ded4850f38d2b796b322d0c4.tar.gz
dabmod-a2be0c3ab77dab50ded4850f38d2b796b322d0c4.tar.bz2
dabmod-a2be0c3ab77dab50ded4850f38d2b796b322d0c4.zip
Add timestamp refresh logic
Diffstat (limited to 'src')
-rw-r--r--src/DabMod.cpp4
-rw-r--r--src/output/Dexter.cpp67
-rw-r--r--src/output/Dexter.h8
-rw-r--r--src/output/SDR.cpp1
4 files changed, 61 insertions, 19 deletions
diff --git a/src/DabMod.cpp b/src/DabMod.cpp
index 278f8ce..5a4da9a 100644
--- a/src/DabMod.cpp
+++ b/src/DabMod.cpp
@@ -662,7 +662,9 @@ static run_modulator_state_t run_modulator(const mod_settings_t& mod_settings, m
else {
etiLog.level(warn) << "Skipping frame " << fct << " FCT " <<
(fct_good ? "good" : "bad") << " TS " <<
- (ts_good ? "good" : "bad");
+ (ts_good ? "good, " : "bad, ") <<
+ (ts.timestamp_valid ? (ts.offset_to_system_time() > 0 ? "in the future" : "in the past") : "invalid");
+
if (m.ediInput) {
m.ediInput->ediReader.clearFrame();
}
diff --git a/src/output/Dexter.cpp b/src/output/Dexter.cpp
index b389b31..9437ae6 100644
--- a/src/output/Dexter.cpp
+++ b/src/output/Dexter.cpp
@@ -347,9 +347,13 @@ void Dexter::transmit_frame(const struct FrameData& frame)
throw std::runtime_error("Dexter: invalid buffer size");
}
- const bool has_time_spec = (m_conf.enableSync and frame.ts.timestamp_valid);
+ const bool require_timestamped_tx = (m_conf.enableSync and frame.ts.timestamp_valid);
- if (has_time_spec) {
+ if (not require_timestamped_tx) {
+ etiLog.level(debug) << "TIMESTAMP_STATE STREAMING 1";
+ timestamp_state = timestamp_state_t::STREAMING;
+ }
+ else if (require_timestamped_tx and timestamp_state == timestamp_state_t::REQUIRES_SET) {
/*
uint64_t timeS = frame.ts.timestamp_sec;
etiLog.level(debug) << "Dexter: TS S " << timeS << " - " << m_utc_seconds_at_startup << " = " <<
@@ -393,31 +397,58 @@ void Dexter::transmit_frame(const struct FrameData& frame)
num_late++;
return;
}
+ timestamp_state = timestamp_state_t::STREAMING;
+ etiLog.level(debug) << "TIMESTAMP_STATE STREAMING 2";
+ }
+
+ if (frame.ts.timestamp_refresh) {
+ etiLog.level(debug) << "TIMESTAMP_STATE WAIT_FOR_UNDERRUN";
+ timestamp_state = timestamp_state_t::WAIT_FOR_UNDERRUN;
+ long long attr_value = 0;
+ int r = 0;
+
+ if ((r = iio_device_attr_read_longlong(m_dexter_dsp_tx, "buffer_underflows0", &attr_value)) == 0) {
+ underflows = attr_value;
+ etiLog.level(debug) << "UNDERFLOWS CAPTURE " << underflows;
+ }
}
// DabMod::launch_modulator ensures we get int16_t IQ here
//const size_t num_samples = frame.buf.size() / (2*sizeof(int16_t));
//const int16_t *buf = reinterpret_cast<const int16_t*>(frame.buf.data());
- for (size_t i = 0; i < IIO_BUFFERS; i++) {
- constexpr size_t buflen = TRANSMISSION_FRAME_LEN / IIO_BUFFERS;
-
- memcpy(iio_buffer_start(m_buffer), frame.buf.data() + (i * buflen), buflen);
- ssize_t pushed = iio_buffer_push(m_buffer);
- if (pushed < 0) {
- etiLog.level(error) << "Dexter: failed to push buffer " << get_iio_error(pushed);
+ if (timestamp_state == timestamp_state_t::STREAMING) {
+ for (size_t i = 0; i < IIO_BUFFERS; i++) {
+ constexpr size_t buflen = TRANSMISSION_FRAME_LEN / IIO_BUFFERS;
+
+ memcpy(iio_buffer_start(m_buffer), frame.buf.data() + (i * buflen), buflen);
+ ssize_t pushed = iio_buffer_push(m_buffer);
+ if (pushed < 0) {
+ etiLog.level(error) << "Dexter: failed to push buffer " << get_iio_error(pushed);
+ etiLog.level(debug) << "TIMESTAMP_STATE REQUIRES_SET";
+ timestamp_state = timestamp_state_t::REQUIRES_SET;
+ }
}
+ num_frames_modulated++;
}
- num_frames_modulated++;
-
- long long attr_value = 0;
- int r = 0;
-
- if ((r = iio_device_attr_read_longlong(m_dexter_dsp_tx, "buffer_underflows0", &attr_value)) == 0) {
- if ((size_t)attr_value != underflows and underflows != 0) {
- etiLog.level(warn) << "Dexter: underflow! " << underflows << " -> " << attr_value;
- underflows = attr_value;
+#warning "We should update underflows all the time"
+ if (timestamp_state == timestamp_state_t::WAIT_FOR_UNDERRUN) {
+ long long attr_value = 0;
+ int r = 0;
+
+ if ((r = iio_device_attr_read_longlong(m_dexter_dsp_tx, "buffer_underflows0", &attr_value)) == 0) {
+ size_t underflows_new = attr_value;
+ etiLog.level(debug) << "UNDERFLOWS COMPARE " << underflows_new;
+
+ if (underflows_new != underflows and attr_value != 0) {
+ etiLog.level(warn) << "Dexter: underflow! " << underflows << " -> " << underflows_new;
+ underflows = underflows_new;
+ if (timestamp_state == timestamp_state_t::WAIT_FOR_UNDERRUN) {
+ etiLog.level(debug) << "TIMESTAMP_STATE REQUIRES_SET";
+ timestamp_state = timestamp_state_t::REQUIRES_SET;
+ }
+ }
}
}
}
diff --git a/src/output/Dexter.h b/src/output/Dexter.h
index 5418b73..3e9c34f 100644
--- a/src/output/Dexter.h
+++ b/src/output/Dexter.h
@@ -97,6 +97,14 @@ class Dexter : public Output::SDRDevice
uint64_t m_utc_seconds_at_startup;
uint64_t m_clock_count_at_startup = 0;
uint64_t m_clock_count_frame = 0;
+
+ enum class timestamp_state_t {
+ REQUIRES_SET,
+ STREAMING,
+ WAIT_FOR_UNDERRUN,
+ };
+
+ timestamp_state_t timestamp_state = timestamp_state_t::REQUIRES_SET;
};
} // namespace Output
diff --git a/src/output/SDR.cpp b/src/output/SDR.cpp
index bd02cab..53f68c2 100644
--- a/src/output/SDR.cpp
+++ b/src/output/SDR.cpp
@@ -331,6 +331,7 @@ void SDR::handle_frame(struct FrameData& frame)
"(" << tx_pps << ")";
frame.ts.timestamp_refresh = true;
+#error "wrong, as the frame could be discarded"
}
}