-
Notifications
You must be signed in to change notification settings - Fork 78
Description
I ran into an issue when using flush for a period to ignore data while not allowing the data to accumulate in the queue, then when I resumed using pull_chunk the timestamps were incorrect because the postprocessing was trying to smooth them with the pre-flush timestamps.
I think it would be good if using flush reset the internal postprocessing state.
More generally, there should be a mechanism to reset the post-processing state. This should be done automatically when flush is called, also when set_postprocessing is called, and we can expose it via the inlet interface.
Inside the post-processor, the state is reset whenever smoothing_initialized_ is false (a private variable, false on init):
liblsl/src/time_postprocessor.cpp
Line 51 in c8cb4df
| if (!smoothing_initialized_) { |
So if we can somehow set smoothing_initialized_ to false then this should reset the state and fix my problem. We could write a function or a setter to expose this. But first I want to see if there are any existing ways to do this. smoothing_initialize_ will be set to false if the query_reset_ callback returns true:
liblsl/src/time_postprocessor.cpp
Lines 33 to 39 in c8cb4df
| if (query_reset_()) { | |
| // reset state to unitialized | |
| last_offset_ = query_correction_(); | |
| last_value_ = -std::numeric_limits<double>::infinity(); | |
| samples_seen_ = 0; | |
| smoothing_initialized_ = false; | |
| } |
Here is where the inlet initializes the post-processor and passes the callbacks, the 3rd is the query_reset_ callback.
liblsl/src/stream_inlet_impl.h
Lines 45 to 47 in c8cb4df
| postprocessor_([this]() { return time_receiver_.time_correction(5); }, | |
| [this]() { return conn_.current_srate(); }, | |
| [this]() { return time_receiver_.was_reset(); }) { |
time_receiver_.was_reset() is not too helpful other than telling it to look for was_reset_, another private variable:
Lines 68 to 73 in c8cb4df
| bool time_receiver::was_reset() { | |
| std::unique_lock<std::mutex> lock(timeoffset_mut_); | |
| bool result = was_reset_; | |
| was_reset_ = false; | |
| return result; | |
| } |
One way the was_reset_ variable gets changed is when reset_timeoffset_on_recovery
Lines 201 to 208 in c8cb4df
| void time_receiver::reset_timeoffset_on_recovery() { | |
| std::lock_guard<std::mutex> lock(timeoffset_mut_); | |
| if (timeoffset_ != NOT_ASSIGNED) | |
| // this will only be set to true if the reset may have caused a possible interruption in the | |
| // obtained time offsets | |
| was_reset_ = true; | |
| timeoffset_ = NOT_ASSIGNED; | |
| } |
This is a bit of a dead end; I don't want to "trick" the inlet into thinking we're recovering from a disconnect. But, we can expose another way to change
was_reset_ and that could be helpful.
Proposed changes:
time_postprocessor::set_optionsshould also dosmoothing_initialized_ = false;
liblsl/src/time_postprocessor.h
Line 33 in 1eaaf08
void set_options(uint32_t options = proc_ALL) { options_ = options; } - Add public
time_receiver::void force_reset() {was_reset_ = true;} - new inlet method called
reset_postprocess(or other name suggestions?) which callstime_receiver_.force_reset(); - inlet flush should also call
time_receiver_.force_reset();liblsl/src/stream_inlet_impl.h
Line 309 in c8cb4df
uint32_t flush() { return data_receiver_.flush(); }