#include <atomic>
#include <functional>
#include <memory>
+#include <mutex>
#include <string>
#include <thread>
class MIDIMappingProto;
+typedef struct snd_seq_addr snd_seq_addr_t;
+typedef struct snd_seq_event snd_seq_event_t;
+typedef struct _snd_seq snd_seq_t;
// Interface for receiving interpreted controller messages.
class ControllerReceiver {
virtual void toggle_auto_gain_staging(unsigned bus_idx) = 0;
virtual void toggle_compressor(unsigned bus_idx) = 0;
virtual void clear_peak(unsigned bus_idx) = 0;
+
+ // Raw events; used for the editor dialog only.
+ virtual void controller_changed(unsigned controller) = 0;
+ virtual void note_on(unsigned note) = 0;
};
class MIDIMapper {
virtual ~MIDIMapper();
void set_midi_mapping(const MIDIMappingProto &new_mapping);
void start_thread();
- const MIDIMappingProto &get_current_mapping() const { return *mapping_proto; }
+ const MIDIMappingProto &get_current_mapping() const;
+
+ // Overwrites and returns the previous value.
+ ControllerReceiver *set_receiver(ControllerReceiver *new_receiver);
private:
void thread_func();
+ void handle_event(snd_seq_t *seq, snd_seq_event_t *event);
+ void subscribe_to_port(snd_seq_t *seq, const snd_seq_addr_t &addr);
void match_controller(int controller, int field_number, int bank_field_number, float value, std::function<void(unsigned, float)> func);
void match_button(int note, int field_number, int bank_field_number, std::function<void(unsigned)> func);
bool bank_mismatch(int bank_field_number);
- ControllerReceiver *receiver;
std::atomic<bool> should_quit{false};
int should_quit_fd;
- std::unique_ptr<MIDIMappingProto> mapping_proto;
- int num_controller_banks;
- int current_controller_bank = 0;
+ mutable std::mutex mapping_mu;
+ ControllerReceiver *receiver; // Under <mapping_mu>.
+ std::unique_ptr<MIDIMappingProto> mapping_proto; // Under <mapping_mu>.
+ int num_controller_banks; // Under <mapping_mu>.
+ std::atomic<int> current_controller_bank{0};
std::thread midi_thread;
};
bool load_midi_mapping_from_file(const std::string &filename, MIDIMappingProto *new_mapping);
+bool save_midi_mapping_to_file(const MIDIMappingProto &mapping_proto, const std::string &filename);
#endif // !defined(_MIDI_MAPPER_H)