+ insert->plugin()->BankPatchChange.connect (
+ midi_connections, invalidator (*this),
+ boost::bind (&GenericPluginUI::midi_bank_patch_change, this, _1),
+ gui_context());
+
+ insert->plugin()->UpdatedMidnam.connect (
+ midi_connections, invalidator (*this),
+ boost::bind (&GenericPluginUI::midi_refill_patches, this),
+ gui_context());
+}
+
+void
+GenericPluginUI::midi_refill_patches ()
+{
+ assert (midi_pgmsel.size() == 16);
+
+ pgm_names.clear ();
+
+ const std::string model = insert->plugin ()->midnam_model ();
+ std::string mode;
+ const std::list<std::string> device_modes = MIDI::Name::MidiPatchManager::instance().custom_device_mode_names_by_model (model);
+ if (device_modes.size() > 0) {
+ mode = device_modes.front();
+ }
+
+ for (uint8_t chn = 0; chn < 16; ++chn) {
+ midi_pgmsel[chn]->clear_items ();
+ boost::shared_ptr<MIDI::Name::ChannelNameSet> cns =
+ MIDI::Name::MidiPatchManager::instance().find_channel_name_set (model, mode, chn);
+
+ if (cns) {
+ using namespace Menu_Helpers;
+ using namespace Gtkmm2ext;
+
+ for (MIDI::Name::ChannelNameSet::PatchBanks::const_iterator i = cns->patch_banks().begin(); i != cns->patch_banks().end(); ++i) {
+ const MIDI::Name::PatchNameList& patches = (*i)->patch_name_list ();
+ for (MIDI::Name::PatchNameList::const_iterator j = patches.begin(); j != patches.end(); ++j) {
+ const std::string pgm = (*j)->name ();
+ MIDI::Name::PatchPrimaryKey const& key = (*j)->patch_primary_key ();
+ assert ((*i)->number () == key.bank());
+ const uint32_t bp = (key.bank() << 7) | key.program();
+ midi_pgmsel[chn]->AddMenuElem (MenuElemNoMnemonic (pgm, sigc::bind (sigc::mem_fun (*this, &GenericPluginUI::midi_bank_patch_select), chn, bp)));
+ pgm_names[bp] = pgm;
+ }
+ }
+ }
+
+ midi_bank_patch_change (chn);
+ }
+}
+
+void
+GenericPluginUI::midi_bank_patch_change (uint8_t chn)
+{
+ assert (chn < 16 && midi_pgmsel.size() == 16);
+ uint32_t bankpgm = insert->plugin()->bank_patch (chn);
+ if (bankpgm == UINT32_MAX) {
+ midi_pgmsel[chn]->set_text (_("--Unset--"));
+ } else {
+ int bank = bankpgm >> 7;
+ int pgm = bankpgm & 127;
+ if (pgm_names.find (bankpgm) != pgm_names.end ()) {
+ midi_pgmsel[chn]->set_text (pgm_names[bankpgm]);
+ } else {
+ midi_pgmsel[chn]->set_text (string_compose ("Bank %1,%2 Pgm %3",
+ (bank >> 7) + 1, (bank & 127) + 1, pgm +1));
+ }
+ }
+}
+
+void
+GenericPluginUI::midi_bank_patch_select (uint8_t chn, uint32_t bankpgm)
+{
+ int bank = bankpgm >> 7;
+ int pgm = bankpgm & 127;
+ MidiTrack* mt = dynamic_cast<MidiTrack*> (insert->owner());
+ if (mt) {
+ /* send to track */
+ boost::shared_ptr<AutomationControl> bank_msb = mt->automation_control(Evoral::Parameter (MidiCCAutomation, chn, MIDI_CTL_MSB_BANK), true);
+ boost::shared_ptr<AutomationControl> bank_lsb = mt->automation_control(Evoral::Parameter (MidiCCAutomation, chn, MIDI_CTL_LSB_BANK), true);
+ boost::shared_ptr<AutomationControl> program = mt->automation_control(Evoral::Parameter (MidiPgmChangeAutomation, chn), true);
+
+ bank_msb->set_value (bank >> 7, PBD::Controllable::NoGroup);
+ bank_lsb->set_value (bank & 127, PBD::Controllable::NoGroup);
+ program->set_value (pgm, PBD::Controllable::NoGroup);
+ } else {
+ uint8_t event[3];
+ event[0] = (MIDI_CMD_CONTROL | chn);
+ event[1] = 0x00;
+ event[2] = bank >> 7;
+ insert->write_immediate_event (3, event);
+
+ event[1] = 0x20;
+ event[2] = bank & 127;
+ insert->write_immediate_event (3, event);
+
+ event[0] = (MIDI_CMD_PGM_CHANGE | chn);
+ event[1] = pgm;
+ insert->write_immediate_event (2, event);
+ }