X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=midi_mapper.cpp;h=139746d673701b55a1efed5f5094fac2c123112c;hb=d87cd97d2353be6cfacf738447bfe6faf048e6f3;hp=dc5eab0342477668049263a44d50b579962a8267;hpb=6379b0adf2cee84b46d5a0d8e2ee5e6a7d1615cf;p=nageru diff --git a/midi_mapper.cpp b/midi_mapper.cpp index dc5eab0..139746d 100644 --- a/midi_mapper.cpp +++ b/midi_mapper.cpp @@ -64,8 +64,29 @@ bool load_midi_mapping_from_file(const string &filename, MIDIMappingProto *new_m return true; } +bool save_midi_mapping_to_file(const MIDIMappingProto &mapping_proto, const string &filename) +{ + // Save to disk. We use the text format because it's friendlier + // for a user to look at and edit. + int fd = open(filename.c_str(), O_WRONLY | O_TRUNC | O_CREAT, 0666); + if (fd == -1) { + perror(filename.c_str()); + return false; + } + io::FileOutputStream output(fd); // Takes ownership of fd. + if (!TextFormat::Print(mapping_proto, &output)) { + // TODO: Don't overwrite the old file (if any) on error. + output.Close(); + return false; + } + + output.Close(); + return true; +} + void MIDIMapper::set_midi_mapping(const MIDIMappingProto &new_mapping) { + lock_guard lock(mapping_mu); if (mapping_proto) { mapping_proto->CopyFrom(new_mapping); } else { @@ -81,6 +102,19 @@ void MIDIMapper::start_thread() midi_thread = thread(&MIDIMapper::thread_func, this); } +const MIDIMappingProto &MIDIMapper::get_current_mapping() const +{ + lock_guard lock(mapping_mu); + return *mapping_proto; +} + +ControllerReceiver *MIDIMapper::set_receiver(ControllerReceiver *new_receiver) +{ + lock_guard lock(mapping_mu); + swap(receiver, new_receiver); + return new_receiver; // Now old receiver. +} + #define RETURN_ON_ERROR(msg, expr) do { \ int err = (expr); \ if (err < 0) { \ @@ -171,6 +205,7 @@ void MIDIMapper::thread_func() void MIDIMapper::handle_event(snd_seq_t *seq, snd_seq_event_t *event) { + lock_guard lock(mapping_mu); switch (event->type) { case SND_SEQ_EVENT_CONTROLLER: { printf("Controller %d changed to %d\n", event->data.control.param, event->data.control.value); @@ -178,6 +213,8 @@ void MIDIMapper::handle_event(snd_seq_t *seq, snd_seq_event_t *event) const int controller = event->data.control.param; const float value = map_controller_to_float(event->data.control.value); + receiver->controller_changed(controller); + // Global controllers. match_controller(controller, MIDIMappingBusProto::kLocutFieldNumber, MIDIMappingProto::kLocutBankFieldNumber, value, bind(&ControllerReceiver::set_locut, receiver, _2)); @@ -204,6 +241,8 @@ void MIDIMapper::handle_event(snd_seq_t *seq, snd_seq_event_t *event) case SND_SEQ_EVENT_NOTEON: { const int note = event->data.note.note; + receiver->note_on(note); + printf("Note: %d\n", note); // Bank change commands. TODO: Highlight the bank change in the UI.