diff --git a/gtk2_ardour/canvas-program-change.cc b/gtk2_ardour/canvas-program-change.cc index 61d043e184..2e6473ef66 100644 --- a/gtk2_ardour/canvas-program-change.cc +++ b/gtk2_ardour/canvas-program-change.cc @@ -36,10 +36,10 @@ CanvasProgramChange::on_event(GdkEvent* ev) switch (ev->type) { case GDK_SCROLL: if (ev->scroll.direction == GDK_SCROLL_UP) { - cerr << "increasing program" << endl; + previous_patch(); return true; } else if (ev->scroll.direction == GDK_SCROLL_DOWN) { - cerr << "decreasing program" << endl; + next_patch(); return true; } default: @@ -48,3 +48,15 @@ CanvasProgramChange::on_event(GdkEvent* ev) return false; } + +void +CanvasProgramChange::previous_patch() +{ + cerr << "decreasing program" << endl; +} + +void +CanvasProgramChange::next_patch() +{ + cerr << "increasing program" << endl; +} diff --git a/gtk2_ardour/canvas-program-change.h b/gtk2_ardour/canvas-program-change.h index cfe73052d0..929c302b7c 100644 --- a/gtk2_ardour/canvas-program-change.h +++ b/gtk2_ardour/canvas-program-change.h @@ -24,7 +24,23 @@ public: virtual bool on_event(GdkEvent* ev); + nframes_t event_time() const { return _event_time; } + void set_event_time(nframes_t new_time) { _event_time = new_time; }; + + uint8_t program() const { return _program; } + void set_program(uint8_t new_time) { _program = new_time; }; + + uint8_t channel() const { return _channel; } + void set_channel(uint8_t new_time) { _channel = new_time; }; + + private: + void previous_patch(); + void next_patch(); + + nframes_t _event_time; + uint8_t _program; + uint8_t _channel; }; } // namespace Canvas diff --git a/gtk2_ardour/midi_region_view.cc b/gtk2_ardour/midi_region_view.cc index 6063667210..ed4176bbfb 100644 --- a/gtk2_ardour/midi_region_view.cc +++ b/gtk2_ardour/midi_region_view.cc @@ -635,47 +635,42 @@ MidiRegionView::find_and_insert_program_change_flags() //cerr << " got program change on channel " << int(channel) << " time: " << event_time << " number: " << program_number << endl; - // find bank select msb and lsb for the program change + // find bank select msb and lsb for the program change Evoral::Parameter bank_select_msb(MidiCCAutomation, channel, MIDI_CTL_MSB_BANK); - Evoral::Parameter bank_select_lsb(MidiCCAutomation, channel, MIDI_CTL_LSB_BANK); - - boost::shared_ptr lsb_control = _model->control(bank_select_lsb); boost::shared_ptr msb_control = _model->control(bank_select_msb); - - boost::shared_ptr master_device - = MIDI::Name::MidiPatchManager::instance().master_device_by_model(_model_name); + uint8_t msb = 0; + if (msb_control != 0) { + msb = uint8_t(msb_control->get_float(true, event_time)); + } + + Evoral::Parameter bank_select_lsb(MidiCCAutomation, channel, MIDI_CTL_LSB_BANK); + boost::shared_ptr lsb_control = _model->control(bank_select_lsb); + uint8_t lsb = 0; + if (lsb_control != 0) { + lsb = uint8_t(lsb_control->get_float(true, event_time)); + } + + cerr << " got msb " << int(msb) << " and lsb " << int(lsb) << " thread_id: " << pthread_self() << endl; + + MIDI::Name::PatchPrimaryKey patch_key(msb, lsb, program_number); - boost::shared_ptr patch; - - if (master_device != 0 && _custom_device_mode != "") { - uint8_t msb = 0; - if (msb_control != 0) { - msb = uint8_t(msb_control->get_float(true, event_time)); - } - - uint8_t lsb = 0; - if (lsb_control != 0) { - lsb = uint8_t(lsb_control->get_float(true, event_time)); - } - - cerr << " got msb " << int(msb) << " and lsb " << int(lsb) << " thread_id: " << pthread_self() << endl; - - patch = master_device->find_patch( + boost::shared_ptr patch = + MIDI::Name::MidiPatchManager::instance().find_patch( + _model_name, _custom_device_mode, channel, - msb, - lsb, - uint8_t(program_number) + patch_key ); - - } + + ControlEvent program_change(nframes_t(event_time), uint8_t(program_number), channel); + if (patch != 0) { cerr << " got patch with name " << patch->name() << " number " << patch->number() << endl; - add_pgm_change(event_time, patch->name()); + add_pgm_change(program_change, patch->name()); } else { char buf[4]; snprintf(buf, 4, "%d", int(program_number)); - add_pgm_change(event_time, buf); + add_pgm_change(program_change, buf); } } break; @@ -996,21 +991,44 @@ MidiRegionView::add_note(const boost::shared_ptr note) } void -MidiRegionView::add_pgm_change(nframes_t time, string displaytext) +MidiRegionView::add_pgm_change(ControlEvent& program, string displaytext) { - assert(time >= 0); + assert(program.time >= 0); // dont display program changes beyond the region bounds - if (time - _region->start() >= _region->length() || time < _region->start()) + if (program.time - _region->start() >= _region->length() || program.time < _region->start()) return; ArdourCanvas::Group* const group = (ArdourCanvas::Group*)get_canvas_group(); - const double x = trackview.editor.frame_to_pixel((nframes64_t)time - _region->start()); + const double x = trackview.editor.frame_to_pixel((nframes64_t)program.time - _region->start()); double height = midi_stream_view()->contents_height(); - _pgm_changes.push_back( - boost::shared_ptr( - new CanvasProgramChange(*this, *group, displaytext, height, x, 1.0))); + + boost::shared_ptr pgm_change = boost::shared_ptr( + new CanvasProgramChange(*this, *group, displaytext, height, x, 1.0)); + pgm_change->set_event_time(program.time); + pgm_change->set_program(program.value); + pgm_change->set_channel(program.channel); + + _pgm_changes.push_back(pgm_change); +} + +void +MidiRegionView::alter_program_change(ControlEvent& old_program, ControlEvent& new_program) +{ + +} + +void +MidiRegionView::previous_program(boost::shared_ptr program) +{ + +} + +void +MidiRegionView::next_program(boost::shared_ptr program) +{ + } void diff --git a/gtk2_ardour/midi_region_view.h b/gtk2_ardour/midi_region_view.h index c76775f9f5..1789437d83 100644 --- a/gtk2_ardour/midi_region_view.h +++ b/gtk2_ardour/midi_region_view.h @@ -86,7 +86,20 @@ class MidiRegionView : public RegionView void add_note(const boost::shared_ptr note); void resolve_note(uint8_t note_num, double end_time); - void add_pgm_change(nframes_t time, string displaytext); + struct ControlEvent + { + nframes_t time; + uint8_t value; + uint8_t channel; + + ControlEvent(nframes_t a_time, uint8_t a_value, uint8_t a_channel) + : time(a_time), value(a_value), channel(a_channel) {} + }; + + void add_pgm_change(ControlEvent& program, string displaytext); + void alter_program_change(ControlEvent& old_program, ControlEvent& new_program); + void previous_program(boost::shared_ptr program); + void next_program(boost::shared_ptr program); void find_and_insert_program_change_flags(); void begin_write(); diff --git a/libs/ardour/ardour/midi_patch_manager.h b/libs/ardour/ardour/midi_patch_manager.h index 9a99571f79..1642b1a22b 100644 --- a/libs/ardour/ardour/midi_patch_manager.h +++ b/libs/ardour/ardour/midi_patch_manager.h @@ -63,6 +63,23 @@ public: boost::shared_ptr master_device_by_model(std::string model_name) { return _master_devices_by_model[model_name]; } + boost::shared_ptr find_patch( + string model, + string custom_device_mode, + uint8_t channel, + PatchPrimaryKey patch_key) { + + boost::shared_ptr master_device = master_device_by_model(model); + + if (master_device != 0 && custom_device_mode != "") { + return master_device-> + channel_name_set_by_device_mode_and_channel(custom_device_mode, channel)-> + find_patch(patch_key); + } else { + return boost::shared_ptr(); + } + } + std::list custom_device_mode_names_by_model(std::string model_name) { if (model_name != "") { return master_device_by_model(model_name)->custom_device_mode_names(); diff --git a/libs/midi++2/midi++/midnam_patch.h b/libs/midi++2/midi++/midnam_patch.h index 7570a9f84d..1fa73a56b6 100644 --- a/libs/midi++2/midi++/midnam_patch.h +++ b/libs/midi++2/midi++/midnam_patch.h @@ -151,11 +151,20 @@ public: return _available_for_channels.find(channel) != _available_for_channels.end(); } - boost::shared_ptr find_patch(uint8_t msb, uint8_t lsb, uint8_t program_number) { - PatchPrimaryKey key(msb, lsb, program_number); + boost::shared_ptr find_patch(PatchPrimaryKey& key) { assert(key.is_sane()); return _patch_map[key]; } + + boost::shared_ptr previous_patch(PatchPrimaryKey& key) { + assert(key.is_sane()); + return (*(--_patch_map.find(key))).second; + } + + boost::shared_ptr next_patch(PatchPrimaryKey& key) { + assert(key.is_sane()); + return (*(++_patch_map.find(key))).second; + } XMLNode& get_state (void); int set_state (const XMLNode& a_node); @@ -266,8 +275,8 @@ public: return _channel_name_sets[custom_device_mode_by_name(mode)->channel_name_set_name_by_channel(channel)]; } - boost::shared_ptr find_patch(string mode, uint8_t channel, uint8_t msb, uint8_t lsb, uint8_t program_number) { - return channel_name_set_by_device_mode_and_channel(mode, channel)->find_patch(msb, lsb, program_number); + boost::shared_ptr find_patch(string mode, uint8_t channel, PatchPrimaryKey& key) { + return channel_name_set_by_device_mode_and_channel(mode, channel)->find_patch(key); } XMLNode& get_state (void); diff --git a/libs/midi++2/midnam_patch.cc b/libs/midi++2/midnam_patch.cc index 7f17d8de3c..555e19fc63 100644 --- a/libs/midi++2/midnam_patch.cc +++ b/libs/midi++2/midnam_patch.cc @@ -78,6 +78,7 @@ Patch::set_state (const XMLNode& node) } } + //cerr << "deserialized Patch: name: " << _name << _id.msb << " lsb: " << _id.lsb << " program " << _id.program_number << endl; assert(_id.is_sane()); return 0;