No UI support yet. Most likely we'll only have UI support in Futatabi.
#include <unistd.h>
#include <algorithm>
#include <functional>
+#include <map>
#include <thread>
#include "defs.h"
void MIDIMapper::update_lights_lock_held()
{
- set<unsigned> active_lights; // Desired state.
+ map<unsigned, uint8_t> active_lights; // Desired state.
if (current_controller_bank == 0) {
activate_mapped_light(*mapping_proto, MIDIMappingProto::kBank1IsSelectedFieldNumber, &active_lights);
}
return;
}
- set<unsigned> active_lights; // Desired state.
+ map<unsigned, uint8_t> active_lights; // Desired state.
if (current_controller_bank == 0) {
activate_lights_all_buses(MIDIMappingBusProto::kBank1IsSelectedFieldNumber, &active_lights);
}
midi_device.update_lights(active_lights);
}
-void MIDIMapper::activate_lights_all_buses(int field_number, set<unsigned> *active_lights)
+void MIDIMapper::activate_lights_all_buses(int field_number, map<unsigned, uint8_t> *active_lights)
{
for (size_t bus_idx = 0; bus_idx < size_t(mapping_proto->bus_mapping_size()); ++bus_idx) {
const MIDIMappingBusProto &bus_mapping = mapping_proto->bus_mapping(bus_idx);
#include <map>
#include <memory>
#include <mutex>
-#include <set>
#include <string>
#include <thread>
void update_highlights();
void update_lights_lock_held();
- void activate_lights_all_buses(int field_number, std::set<unsigned> *active_lights);
+ void activate_lights_all_buses(int field_number, std::map<unsigned, uint8_t> *active_lights);
std::atomic<bool> should_quit{false};
int should_quit_fd;
}
// The current status of the device is unknown, so refresh it.
- set<unsigned> active_lights;
- for (const auto &it : current_light_status) {
- if (it.second) {
- active_lights.insert(it.first);
- }
- }
+ map<unsigned, uint8_t> active_lights = move(current_light_status);
current_light_status.clear();
update_lights_lock_held(active_lights);
}
-void MIDIDevice::update_lights_lock_held(const set<unsigned> &active_lights)
+void MIDIDevice::update_lights_lock_held(const map<unsigned, uint8_t> &active_lights)
{
if (alsa_seq == nullptr) {
return;
unsigned num_events = 0;
for (unsigned note_num = 1; note_num <= 127; ++note_num) { // Note: Pitch bend is ignored.
- bool active = active_lights.count(note_num);
+ const auto it = active_lights.find(note_num);
+ uint8_t velocity = (it == active_lights.end()) ? 0 : it->second;
if (current_light_status.count(note_num) &&
- current_light_status[note_num] == active) {
+ current_light_status[note_num] == velocity) {
// Already known to be in the desired state.
continue;
}
// For some reason, not all devices respond to note off.
// Use note-on with velocity of 0 (which is equivalent) instead.
- snd_seq_ev_set_noteon(&ev, /*channel=*/0, note_num, active ? 1 : 0);
+ snd_seq_ev_set_noteon(&ev, /*channel=*/0, note_num, velocity);
WARN_ON_ERROR("snd_seq_event_output", snd_seq_event_output(alsa_seq, &ev));
- current_light_status[note_num] = active;
+ current_light_status[note_num] = velocity;
}
WARN_ON_ERROR("snd_seq_drain_output", snd_seq_drain_output(alsa_seq));
}
#include <atomic>
#include <map>
#include <mutex>
-#include <set>
#include <thread>
typedef struct snd_seq_addr snd_seq_addr_t;
~MIDIDevice();
void start_thread();
- void update_lights(const std::set<unsigned> &active_lights)
+ void update_lights(const std::map<unsigned, uint8_t> &active_lights)
{
std::lock_guard<std::mutex> lock(mu);
update_lights_lock_held(active_lights);
void thread_func();
void handle_event(snd_seq_t *seq, snd_seq_event_t *event);
void subscribe_to_port_lock_held(snd_seq_t *seq, const snd_seq_addr_t &addr);
- void update_lights_lock_held(const std::set<unsigned> &active_lights);
+ void update_lights_lock_held(const std::map<unsigned, uint8_t> &active_lights);
std::atomic<bool> should_quit{false};
int should_quit_fd;
MIDIReceiver *receiver; // Under <mu>.
std::thread midi_thread;
- std::map<unsigned, bool> current_light_status; // Keyed by note number. Under <mu>.
+ std::map<unsigned, uint8_t> current_light_status; // Keyed by note number. Under <mu>.
snd_seq_t *alsa_seq{nullptr}; // Under <mu>.
int alsa_queue_id{-1}; // Under <mu>.
std::atomic<int> num_subscribed_ports{0};
// Find what MIDI note the given light (as given by field_number) is mapped to, and enable it.
template <class Proto>
-void activate_mapped_light(const Proto &msg, int field_number, std::set<unsigned> *active_lights)
+void activate_mapped_light(const Proto &msg, int field_number, std::map<unsigned, uint8_t> *active_lights)
{
using namespace google::protobuf;
const FieldDescriptor *descriptor = msg.GetDescriptor()->FindFieldByNumber(field_number);
}
const MIDILightProto &light_proto =
static_cast<const MIDILightProto &>(reflection->GetMessage(msg, descriptor));
- active_lights->insert(light_proto.note_number());
+ active_lights->emplace(light_proto.note_number(), light_proto.velocity());
}
inline double map_controller_to_float(int controller, int val)
message MIDILightProto {
required int32 note_number = 1;
+ optional int32 velocity = 2 [default=1];
}