X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=shared%2Fmidi_device.h;h=ec6bf9b5a160b5ededf14600744435a96ef0e951;hb=69ca346ecb6d52febde969af332142131a501d33;hp=3c1e6b2f4e63bf1cd4390329c037630d4748dc9f;hpb=d1e616378bda406c96acf7c2dc975b7ab2e8165e;p=nageru diff --git a/shared/midi_device.h b/shared/midi_device.h index 3c1e6b2..ec6bf9b 100644 --- a/shared/midi_device.h +++ b/shared/midi_device.h @@ -7,7 +7,6 @@ #include #include #include -#include #include typedef struct snd_seq_addr snd_seq_addr_t; @@ -16,6 +15,11 @@ typedef struct _snd_seq snd_seq_t; class MIDIReceiver { public: + // Pitch bend events are received as a virtual controller with + // range -8192..8191 instead of 0..127 (but see the comment + // in map_controller_to_float() in midi_mapper.cpp). + static constexpr int PITCH_BEND_CONTROLLER = 128; + virtual ~MIDIReceiver() {} virtual void controller_received(int controller, int value) = 0; virtual void note_on_received(int note) = 0; @@ -24,13 +28,26 @@ public: class MIDIDevice { public: + struct LightKey { + enum { NOTE, CONTROLLER } type; + unsigned number; + + bool operator< (const LightKey& other) const + { + if (type != other.type) { + return type < other.type; + } + return number < other.number; + } + }; + MIDIDevice(MIDIReceiver *receiver); ~MIDIDevice(); void start_thread(); - void update_lights(const std::set &active_lights) + void update_lights(const std::map &active_lights) { - std::lock_guard lock(mu); + std::lock_guard lock(mu); update_lights_lock_held(active_lights); } @@ -38,16 +55,16 @@ private: 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 &active_lights); + void update_lights_lock_held(const std::map &active_lights); std::atomic should_quit{false}; int should_quit_fd; - mutable std::mutex mu; + mutable std::recursive_mutex mu; // Recursive because the MIDI receiver may update_lights() back while we are sending it stuff. MIDIReceiver *receiver; // Under . std::thread midi_thread; - std::map current_light_status; // Keyed by note number. Under . + std::map current_light_status; // Keyed by note number. Under . snd_seq_t *alsa_seq{nullptr}; // Under . int alsa_queue_id{-1}; // Under . std::atomic num_subscribed_ports{0};