aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Linus Torvalds <torvalds@linux-foundation.org>2015-10-25 12:02:08 +0900
committerGravatar Dirk Hohndel <dirk@hohndel.org>2015-10-25 13:22:59 +0900
commit2b1017c986bf10a490592fba7e85b14df86cd58d (patch)
treed7130a28fca1fea9c944e21797bb757448e7869e
parentcd1884b29cff57b225e1ab58d0b1dcad25669034 (diff)
downloadsubsurface-2b1017c986bf10a490592fba7e85b14df86cd58d.tar.gz
Interpolate depth for samples that have no depth
When downloading from libdivecomputer, we used to initialize the depth of a sample to the previous depth. However, at least for the Suunto EON Steel, you can get sample times without any actual depth reading - the time might be associated with some ranbdom event rather than a new depth sample. Rather than initialize these samples to have the same depth as the previous one (and then perhaps getting a very sudden jump when the *real* depth event comes in a second later), initialize the depth samples to -1, and if that sample doesn't get a real depth, we'll create an interpolated depth. It is possible that we should just carry the sample around as not actually having a depth, and instead just interpolate in the plot_info generation, but at least right now we have a ton of code that "knows" that every sample has a depth. Not the least of which is our own save format. So generating an interpolated depth seems the path of least resistance, and at least makes the graph look correct - no odd staircase effect from other events that happen in between depth samples. Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
-rw-r--r--dive.c22
-rw-r--r--libdivecomputer.c11
2 files changed, 29 insertions, 4 deletions
diff --git a/dive.c b/dive.c
index dfd5b495c..2ae84ca1e 100644
--- a/dive.c
+++ b/dive.c
@@ -1243,6 +1243,23 @@ static void fixup_dc_events(struct divecomputer *dc)
}
}
+static int interpolate_depth(struct divecomputer *dc, int idx, int lastdepth, int lasttime, int now)
+{
+ int i;
+ int nextdepth = lastdepth;
+ int nexttime = now;
+
+ for (i = idx+1; i < dc->samples; i++) {
+ struct sample *sample = dc->sample + i;
+ if (sample->depth.mm < 0)
+ continue;
+ nextdepth = sample->depth.mm;
+ nexttime = sample->time.seconds;
+ break;
+ }
+ return interpolate(lastdepth, nextdepth, now-lasttime, nexttime-lasttime);
+}
+
static void fixup_dive_dc(struct dive *dive, struct divecomputer *dc)
{
int i, j;
@@ -1276,6 +1293,11 @@ static void fixup_dive_dc(struct dive *dive, struct divecomputer *dc)
int o2_pressure = sample->o2cylinderpressure.mbar;
int index;
+ if (depth < 0) {
+ depth = interpolate_depth(dc, i, lastdepth, lasttime, time);
+ sample->depth.mm = depth;
+ }
+
/* if we have an explicit first cylinder */
if (sample->sensor == 0 && first_cylinder != 0)
sample->sensor = first_cylinder;
diff --git a/libdivecomputer.c b/libdivecomputer.c
index a9d90d837..b5f90cb35 100644
--- a/libdivecomputer.c
+++ b/libdivecomputer.c
@@ -231,7 +231,6 @@ static void handle_event(struct divecomputer *dc, struct sample *sample, dc_samp
void
sample_cb(dc_sample_type_t type, dc_sample_value_t value, void *userdata)
{
- unsigned int mm;
static unsigned int nsensor = 0;
struct divecomputer *dc = userdata;
struct sample *sample;
@@ -252,7 +251,10 @@ sample_cb(dc_sample_type_t type, dc_sample_value_t value, void *userdata)
switch (type) {
case DC_SAMPLE_TIME:
nsensor = 0;
- mm = 0;
+
+ // The previous sample gets some sticky values
+ // that may have been around from before, even
+ // if there was no new data
if (sample) {
sample->in_deco = in_deco;
sample->ndl.seconds = ndl;
@@ -260,11 +262,12 @@ sample_cb(dc_sample_type_t type, dc_sample_value_t value, void *userdata)
sample->stopdepth.mm = stopdepth;
sample->setpoint.mbar = po2;
sample->cns = cns;
- mm = sample->depth.mm;
}
+ // Create a new sample.
+ // Mark depth as negative
sample = prepare_sample(dc);
sample->time.seconds = value.time;
- sample->depth.mm = mm;
+ sample->depth.mm = -1;
finish_sample(dc);
break;
case DC_SAMPLE_DEPTH: