2 #define _MIDI_DEVICE_H 1
4 // MIDIDevice is a class that pools incoming MIDI messages from
5 // all MIDI devices in the system, decodes them and sends them on.
13 typedef struct snd_seq_addr snd_seq_addr_t;
14 typedef struct snd_seq_event snd_seq_event_t;
15 typedef struct _snd_seq snd_seq_t;
19 // Pitch bend events are received as a virtual controller with
20 // range -8192..8191 instead of 0..127 (but see the comment
21 // in map_controller_to_float() in midi_mapper.cpp).
22 static constexpr int PITCH_BEND_CONTROLLER = 128;
24 virtual ~MIDIReceiver() {}
25 virtual void controller_received(int controller, int value) = 0;
26 virtual void note_on_received(int note) = 0;
27 virtual void update_num_subscribers(unsigned num_subscribers) = 0;
32 MIDIDevice(MIDIReceiver *receiver);
36 void update_lights(const std::set<unsigned> &active_lights)
38 std::lock_guard<std::mutex> lock(mu);
39 update_lights_lock_held(active_lights);
44 void handle_event(snd_seq_t *seq, snd_seq_event_t *event);
45 void subscribe_to_port_lock_held(snd_seq_t *seq, const snd_seq_addr_t &addr);
46 void update_lights_lock_held(const std::set<unsigned> &active_lights);
48 std::atomic<bool> should_quit{false};
51 mutable std::mutex mu;
52 MIDIReceiver *receiver; // Under <mu>.
54 std::thread midi_thread;
55 std::map<unsigned, bool> current_light_status; // Keyed by note number. Under <mu>.
56 snd_seq_t *alsa_seq{nullptr}; // Under <mu>.
57 int alsa_queue_id{-1}; // Under <mu>.
58 std::atomic<int> num_subscribed_ports{0};
61 #endif // !defined(_MIDI_DEVICE_H)