1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#![allow(non_snake_case, non_upper_case_globals)]
use crate::ColorRGB;
pub trait PowerEstimator {
#[allow(non_snake_case, non_upper_case_globals)]
const R_mW: u32;
#[allow(non_snake_case, non_upper_case_globals)]
const G_mW: u32;
#[allow(non_snake_case, non_upper_case_globals)]
const B_mW: u32;
#[allow(non_snake_case, non_upper_case_globals)]
const IDLE_mW: u32;
#[inline(always)]
fn estimate(rgb: ColorRGB) -> u32 {
Self::IDLE_mW + Self::estimate_no_idle(rgb)
}
#[inline]
fn estimate_no_idle(rgb: ColorRGB) -> u32 {
u32::from(rgb.r) * Self::R_mW
+ u32::from(rgb.g) * Self::G_mW
+ u32::from(rgb.b) * Self::B_mW
}
fn estimate_strand(strand: &[ColorRGB]) -> u32 {
let mut sums = strand
.iter()
.map(|p| (u32::from(p.r), u32::from(p.g), u32::from(p.b)))
.fold((0, 0, 0), |acc, x| {
(acc.0 + x.0, acc.1 + acc.1, acc.2 + x.2)
});
sums.0 *= Self::R_mW;
sums.1 *= Self::G_mW;
sums.2 *= Self::B_mW;
sums.0 + sums.1 + sums.2 + (strand.len() as u32 * Self::IDLE_mW)
}
fn estimate_max_brightness(
strand: &[ColorRGB],
target_brightness: u8,
max_power_mW: u32,
) -> u8 {
let max_estimated_mW: u32 = Self::estimate_strand(strand);
let current_estimated_mW: u32 = (max_estimated_mW * u32::from(target_brightness)) / 256;
if current_estimated_mW > max_power_mW {
((u32::from(target_brightness) as u32 * max_power_mW) / current_estimated_mW) as u8
} else {
target_brightness
}
}
#[inline]
fn estimate_max_brightness_av(
strand: &[ColorRGB],
target_brightness: u8,
max_power_mA: u32,
max_power_mV: u32,
) -> u8 {
Self::estimate_max_brightness(strand, target_brightness, max_power_mA * max_power_mV)
}
}
pub struct DefaultPowerEstimator;
impl PowerEstimator for DefaultPowerEstimator {
const R_mW: u32 = 16 * 5;
const G_mW: u32 = 11 * 6;
const B_mW: u32 = 15 * 5;
const IDLE_mW: u32 = 5;
}