diff options
author | Matthias P. Braendli <matthias.braendli@mpb.li> | 2022-10-14 20:00:26 +0200 |
---|---|---|
committer | Matthias P. Braendli <matthias.braendli@mpb.li> | 2022-10-14 20:00:26 +0200 |
commit | a2be0c3ab77dab50ded4850f38d2b796b322d0c4 (patch) | |
tree | dbbfe88cd7515f08ff552628c1483697eb5f8cf9 | |
parent | 7441d427947aaa79b88e1eae157981c95d7ca5fa (diff) | |
download | dabmod-a2be0c3ab77dab50ded4850f38d2b796b322d0c4.tar.gz dabmod-a2be0c3ab77dab50ded4850f38d2b796b322d0c4.tar.bz2 dabmod-a2be0c3ab77dab50ded4850f38d2b796b322d0c4.zip |
Add timestamp refresh logic
-rw-r--r-- | src/DabMod.cpp | 4 | ||||
-rw-r--r-- | src/output/Dexter.cpp | 67 | ||||
-rw-r--r-- | src/output/Dexter.h | 8 | ||||
-rw-r--r-- | src/output/SDR.cpp | 1 |
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" } } |