- for (unsigned note_num = 1; note_num <= 127; ++note_num) {
- bool active = active_lights.count(note_num);
- if (current_light_status.count(note_num) &&
- current_light_status[note_num] == active) {
- // Already known to be in the desired state.
- continue;
- }
+ for (auto type : { LightKey::NOTE, LightKey::CONTROLLER }) {
+ for (unsigned num = 1; num <= 127; ++num) { // Note: Pitch bend is ignored.
+ LightKey key{type, num};
+ const auto it = active_lights.find(key);
+ uint8_t value; // Velocity for notes, controller value for controllers.
+
+ // Notes have a natural “off”, while controllers don't really.
+ // For some reason, not all devices respond to note off.
+ // Use note-on with value of 0 (which is equivalent) instead.
+ if (it == active_lights.end()) {
+ // Notes have a natural “off”, while controllers don't really,
+ // so just skip them if we have no set value.
+ if (type == LightKey::CONTROLLER) continue;
+
+ // For some reason, not all devices respond to note off.
+ // Use note-on with value of 0 (which is equivalent) instead.
+ value = 0;
+ } else {
+ value = it->second;
+ }
+ if (current_light_status.count(key) &&
+ current_light_status[key] == value) {
+ // Already known to be in the desired state.
+ continue;
+ }