Copy missing sample values from the previous sample.

The Uwatec Smart stores a sample value only when it's diffent from the
previous value. While this compressed format does save some space on the
device, it is less practical for use in an application. The original
uncompressed data can easily be obtained by copying missing sample
values from the previous sample.

The implementation uses a two pass approach. In the first pass, all
sample values that are explicitly stored in the profile date are
collected. Any sample value that is not present, will automatically
retain the value from the previous sample. In the second pass, all
sample values are passed back to the application. The presence of an
absolute value is used to decide which sample types are present in the
data.
This commit is contained in:
Jef Driesen 2010-07-20 17:18:38 +02:00
parent 10377f969a
commit 0f5b6028ef

View File

@ -381,7 +381,7 @@ uwatec_smart_parser_samples_foreach (parser_t *abstract, sample_callback_t callb
return PARSER_STATUS_ERROR; return PARSER_STATUS_ERROR;
} }
int complete = 1; int complete = 0;
int calibrated = 0; int calibrated = 0;
unsigned int time = 0; unsigned int time = 0;
@ -391,7 +391,11 @@ uwatec_smart_parser_samples_foreach (parser_t *abstract, sample_callback_t callb
double temperature = 0; double temperature = 0;
double pressure = 0; double pressure = 0;
unsigned int heartrate = 0; unsigned int heartrate = 0;
unsigned char alarms = 0; unsigned int bearing = 0;
unsigned char alarms[3] = {0, 0, 0};
int have_depth = 0, have_temperature = 0, have_pressure = 0, have_rbt = 0,
have_heartrate = 0, have_alarms = 0, have_bearing = 0;
unsigned int offset = header; unsigned int offset = header;
while (offset < size) { while (offset < size) {
@ -439,53 +443,37 @@ uwatec_smart_parser_samples_foreach (parser_t *abstract, sample_callback_t callb
// Fix the sign bit. // Fix the sign bit.
signed int svalue = uwatec_smart_fixsignbit (value, nbits); signed int svalue = uwatec_smart_fixsignbit (value, nbits);
if (complete && table[id].type != TIME) {
complete = 0;
sample.time = time;
if (callback) callback (SAMPLE_TYPE_TIME, sample, userdata);
}
// Parse the value. // Parse the value.
switch (table[id].type) { switch (table[id].type) {
case PRESSURE_DEPTH: case PRESSURE_DEPTH:
pressure += ((signed char) ((svalue >> NBITS) & 0xFF)) / 4.0; pressure += ((signed char) ((svalue >> NBITS) & 0xFF)) / 4.0;
depth += ((signed char) (svalue & 0xFF)) / 50.0; depth += ((signed char) (svalue & 0xFF)) / 50.0;
sample.pressure.tank = tank;
sample.pressure.value = pressure;
if (callback) callback (SAMPLE_TYPE_PRESSURE, sample, userdata);
sample.depth = depth - depth_calibration;
if (callback) callback (SAMPLE_TYPE_DEPTH, sample, userdata);
complete = 1; complete = 1;
time += 4;
break; break;
case RBT: case RBT:
if (table[id].absolute) { if (table[id].absolute) {
rbt = value; rbt = value;
have_rbt = 1;
} else { } else {
rbt += svalue; rbt += svalue;
} }
sample.rbt = rbt;
if (callback) callback (SAMPLE_TYPE_RBT, sample, userdata);
break; break;
case TEMPERATURE: case TEMPERATURE:
if (table[id].absolute) { if (table[id].absolute) {
temperature = value / 2.5; temperature = value / 2.5;
have_temperature = 1;
} else { } else {
temperature += svalue / 2.5; temperature += svalue / 2.5;
} }
sample.temperature = temperature;
if (callback) callback (SAMPLE_TYPE_TEMPERATURE, sample, userdata);
break; break;
case PRESSURE: case PRESSURE:
if (table[id].absolute) { if (table[id].absolute) {
tank = table[id].index; tank = table[id].index;
pressure = value / 4.0; pressure = value / 4.0;
have_pressure = 1;
} else { } else {
pressure += svalue / 4.0; pressure += svalue / 4.0;
} }
sample.pressure.tank = tank;
sample.pressure.value = pressure;
if (callback) callback (SAMPLE_TYPE_PRESSURE, sample, userdata);
break; break;
case DEPTH: case DEPTH:
if (table[id].absolute) { if (table[id].absolute) {
@ -494,42 +482,84 @@ uwatec_smart_parser_samples_foreach (parser_t *abstract, sample_callback_t callb
calibrated = 1; calibrated = 1;
depth_calibration = depth; depth_calibration = depth;
} }
have_depth = 1;
} else { } else {
depth += svalue / 50.0; depth += svalue / 50.0;
} }
sample.depth = depth - depth_calibration;
if (callback) callback (SAMPLE_TYPE_DEPTH, sample, userdata);
complete = 1; complete = 1;
time += 4;
break; break;
case HEARTRATE: case HEARTRATE:
if (table[id].absolute) { if (table[id].absolute) {
heartrate = value; heartrate = value;
have_heartrate = 1;
} else { } else {
heartrate += svalue; heartrate += svalue;
} }
sample.heartbeat = heartrate;
if (callback) callback (SAMPLE_TYPE_HEARTBEAT, sample, userdata);
break; break;
case BEARING: case BEARING:
sample.bearing = value; bearing = value;
if (callback) callback (SAMPLE_TYPE_BEARING, sample, userdata); have_bearing = 1;
break; break;
case ALARMS: case ALARMS:
alarms = value; alarms[table[id].index] = value;
sample.vendor.type = SAMPLE_VENDOR_UWATEC_SMART; have_alarms = 1;
sample.vendor.size = sizeof (alarms);
sample.vendor.data = &alarms;
if (callback) callback (SAMPLE_TYPE_VENDOR, sample, userdata);
break; break;
case TIME: case TIME:
complete = 1; complete = value;
time += value * 4;
break; break;
default: default:
WARNING ("Unknown sample type."); WARNING ("Unknown sample type.");
break; break;
} }
while (complete) {
sample.time = time;
if (callback) callback (SAMPLE_TYPE_TIME, sample, userdata);
if (have_temperature) {
sample.temperature = temperature;
if (callback) callback (SAMPLE_TYPE_TEMPERATURE, sample, userdata);
}
if (have_alarms) {
sample.vendor.type = SAMPLE_VENDOR_UWATEC_SMART;
sample.vendor.size = sizeof (alarms);
sample.vendor.data = alarms;
if (callback) callback (SAMPLE_TYPE_VENDOR, sample, userdata);
memset (alarms, 0, sizeof (alarms));
have_alarms = 0;
}
if (have_rbt || have_pressure) {
sample.rbt = rbt;
if (callback) callback (SAMPLE_TYPE_RBT, sample, userdata);
}
if (have_pressure) {
sample.pressure.tank = tank;
sample.pressure.value = pressure;
if (callback) callback (SAMPLE_TYPE_PRESSURE, sample, userdata);
}
if (have_heartrate) {
sample.heartbeat = heartrate;
if (callback) callback (SAMPLE_TYPE_HEARTBEAT, sample, userdata);
}
if (have_bearing) {
sample.bearing = bearing;
if (callback) callback (SAMPLE_TYPE_BEARING, sample, userdata);
have_bearing = 0;
}
if (have_depth) {
sample.depth = depth - depth_calibration;
if (callback) callback (SAMPLE_TYPE_DEPTH, sample, userdata);
}
time += 4;
complete--;
}
} }
assert (offset == size); assert (offset == size);