[gnome-settings-daemon] power: Ambient light moving average now time-aware
- From: Benjamin Berg <bberg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-settings-daemon] power: Ambient light moving average now time-aware
- Date: Tue, 14 Jul 2020 21:28:47 +0000 (UTC)
commit bbdef3f87c6a16588cc05dfd798e610b327ebfbd
Author: Kyle Hofmann <kyle hofmann gmail com>
Date: Sat Jul 11 12:22:32 2020 -0700
power: Ambient light moving average now time-aware
The readings from the ambient light sensor were being filtered using an
exponential moving average (equivalently, a first-order low pass
filter), but the average did not account for the time since the previous
reading. Now the power manager records the time of the last reading,
making the brightness adjustments more even.
plugins/power/gsd-power-manager.c | 30 +++++++++++++++++++++++-------
1 file changed, 23 insertions(+), 7 deletions(-)
---
diff --git a/plugins/power/gsd-power-manager.c b/plugins/power/gsd-power-manager.c
index 36c89aaa..c18f7ec2 100644
--- a/plugins/power/gsd-power-manager.c
+++ b/plugins/power/gsd-power-manager.c
@@ -79,10 +79,13 @@
/* And the time before we stop the warning sound */
#define GSD_STOP_SOUND_DELAY GSD_ACTION_DELAY - 2
-/* the amount of smoothing done to the the ambient light readings; a lower
- * number means the backlight changes slower in response to changing ambient
- * conditions, a hugher number may lead to noticable jitteryness */
-#define GSD_AMBIENT_SMOOTH 0.3f
+/* The bandwidth of the low-pass filter used to smooth ambient light readings,
+ * measured in Hz. Smaller numbers result in smoother backlight changes.
+ * Larger numbers are more responsive to abrupt changes in ambient light. */
+#define GSD_AMBIENT_BANDWIDTH_HZ 0.1f
+
+/* Convert bandwidth to time constant. Units of constant are microseconds. */
+#define GSD_AMBIENT_TIME_CONSTANT (G_USEC_PER_SEC * 1.0f / (2.0f * G_PI * GSD_AMBIENT_BANDWIDTH_HZ))
static const gchar introspection_xml[] =
"<node>"
@@ -179,6 +182,7 @@ struct _GsdPowerManager
gdouble ambient_norm_value;
gdouble ambient_percentage_old;
gdouble ambient_last_absolute;
+ gint64 ambient_last_time;
/* Sound */
guint32 critical_alert_timeout_id;
@@ -2572,6 +2576,8 @@ iio_proxy_changed (GsdPowerManager *manager)
GVariant *val_has = NULL;
GVariant *val_als = NULL;
gdouble brightness;
+ gdouble alpha;
+ gint64 current_time;
gint pc;
/* no display hardware */
@@ -2600,12 +2606,21 @@ iio_proxy_changed (GsdPowerManager *manager)
ch_backlight_renormalize (manager);
}
- /* calculate exponential moving average */
+ /* time-weighted constant for moving average */
+ current_time = g_get_monotonic_time();
+ if (manager->ambient_last_time)
+ alpha = 1.0f / (1.0f + (GSD_AMBIENT_TIME_CONSTANT / (current_time -
manager->ambient_last_time)));
+ else
+ alpha = 0.0f;
+ manager->ambient_last_time = current_time;
+
+ /* calculate exponential weighted moving average */
brightness = manager->ambient_last_absolute * 100.f / manager->ambient_norm_value;
brightness = MIN (brightness, 100.f);
brightness = MAX (brightness, 0.f);
- manager->ambient_accumulator = (GSD_AMBIENT_SMOOTH * brightness) +
- (1.0 - GSD_AMBIENT_SMOOTH) * manager->ambient_accumulator;
+
+ manager->ambient_accumulator = (alpha * brightness) +
+ (1.0 - alpha) * manager->ambient_accumulator;
/* no valid readings yet */
if (manager->ambient_accumulator < 0.f)
@@ -2712,6 +2727,7 @@ gsd_power_manager_start (GsdPowerManager *manager,
manager->ambient_norm_value = -1.f;
manager->ambient_percentage_old = -1.f;
manager->ambient_last_absolute = -1.f;
+ manager->ambient_last_time = 0;
gnome_settings_profile_end (NULL);
return TRUE;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]