* added myself to about.cc
authorHans Baier <hansfbaier@googlemail.com>
Thu, 11 Dec 2008 08:06:27 +0000 (08:06 +0000)
committerHans Baier <hansfbaier@googlemail.com>
Thu, 11 Dec 2008 08:06:27 +0000 (08:06 +0000)
* created ArdourCanvas::CanvasFlag as a base class for flags
* removed obsolete cruft from midi_model
* made MidiTimeAxisView and MidiRegionView work together to display program changes as
  names by means of MidiPatchManager

git-svn-id: svn://localhost/ardour2/branches/3.0@4307 d708f5d6-7413-0410-9779-e7cbd77b26cf

12 files changed:
gtk2_ardour/SConscript
gtk2_ardour/about.cc
gtk2_ardour/canvas-flag.cc [new file with mode: 0644]
gtk2_ardour/canvas-flag.h [new file with mode: 0644]
gtk2_ardour/canvas-program-change.cc
gtk2_ardour/canvas-program-change.h
gtk2_ardour/midi_region_view.cc
gtk2_ardour/midi_region_view.h
gtk2_ardour/midi_time_axis.cc
gtk2_ardour/midi_time_axis.h
libs/ardour/midi_model.cc
libs/midi++2/midi++/midnam_patch.h

index 89a5040400480c4095ef1d5dc26a527e28cb8cc0..f8089d099e138cd21b65c61196f9eba107517627 100644 (file)
@@ -131,6 +131,7 @@ axis_view.cc
 bundle_manager.cc
 canvas-note-event.cc
 canvas-note.cc
+canvas-flag.cc
 canvas-program-change.cc
 canvas-simpleline.c
 canvas-simplerect.c
index ae8c7f503b3061e228ac79d0439f32e4801ee627..7d41847e14d0ca96d7aecd9002c34a84ce2c1842 100644 (file)
@@ -148,6 +148,7 @@ static const char* authors[] = {
        N_("Christopher George"),
        N_("Robert Jordens"),
        N_("Dave Robillard"),
+       N_("Hans Baier"),
        N_("Hans Fugal"),
        N_("Brian Ahr"),
        N_("Nimal Ratnayake"),
diff --git a/gtk2_ardour/canvas-flag.cc b/gtk2_ardour/canvas-flag.cc
new file mode 100644 (file)
index 0000000..2692639
--- /dev/null
@@ -0,0 +1,41 @@
+#include "canvas-flag.h"
+#include <iostream>
+#include "ardour_ui.h"
+
+using namespace Gnome::Canvas;
+using namespace std;
+
+               
+void 
+CanvasFlag::set_text(string a_text)
+{
+       if (_text) {
+               delete _text;
+       }
+       
+       _text = new Text(*this, 0.0, 0.0, a_text);
+       _text->property_justification() = Gtk::JUSTIFY_CENTER;
+       _text->property_fill_color_rgba() = _outline_color_rgba;
+       double flagwidth  = _text->property_text_width()  + 10.0;
+       double flagheight = _text->property_text_height() + 3.0;
+       _text->property_x() = flagwidth / 2.0;
+       _text->property_y() = flagheight / 2.0;
+       _text->show();
+       _line = new SimpleLine(*this, 0.0, 0.0, 0.0, _height);
+       _line->property_color_rgba() = _outline_color_rgba;
+       _rect = new SimpleRect(*this, 0.0, 0.0, flagwidth, flagheight);
+       _rect->property_outline_color_rgba() = _outline_color_rgba;
+       _rect->property_fill_color_rgba() = _fill_color_rgba;
+       _text->lower_to_bottom();
+       _text->raise(2);        
+}
+
+CanvasFlag::~CanvasFlag()
+{
+       delete _line;
+       delete _rect;
+       if(_text) {
+               delete _text;
+       }
+}
+
diff --git a/gtk2_ardour/canvas-flag.h b/gtk2_ardour/canvas-flag.h
new file mode 100644 (file)
index 0000000..ec150f6
--- /dev/null
@@ -0,0 +1,58 @@
+#ifndef CANVASFLAG_H_
+#define CANVASFLAG_H_
+
+#include <libgnomecanvasmm/group.h>
+#include <libgnomecanvasmm/text.h>
+#include <libgnomecanvasmm/widget.h>
+
+#include <ardour/midi_model.h>
+
+#include "simplerect.h"
+#include "simpleline.h"
+
+class MidiRegionView;
+
+namespace Gnome {
+namespace Canvas {
+
+class CanvasFlag : public Group
+{
+public:
+       CanvasFlag(
+               MidiRegionView&                       region,
+               Group&                                parent,
+               double                                height,
+               guint                                 outline_color_rgba = 0xc0c0c0ff,
+               guint                                 fill_color_rgba = 0x07070707,
+               double                                x = 0.0,
+               double                                y = 0.0
+       )       : Group(parent, x, y)
+       , _text(0)
+       , _height(height)
+       , _outline_color_rgba(outline_color_rgba)
+       , _fill_color_rgba(fill_color_rgba)
+       , _region(region)
+       , _line(0)
+       , _rect(0)
+       {}
+       
+       virtual ~CanvasFlag();
+       
+       void set_text(string a_text);
+
+protected:
+       Text*                             _text;
+       double                            _height;
+       guint                             _outline_color_rgba;
+       guint                             _fill_color_rgba;
+       
+private:
+       MidiRegionView&                   _region;
+       SimpleLine*                       _line;
+       SimpleRect*                       _rect;
+};
+
+} // namespace Canvas
+} // namespace Gnome
+
+#endif /*CANVASFLAG_H_*/
index bd9c0e89dbcfb9c085b00690d8e659a6a6457846..f48d2e6be90193af19f85ab3d3761a568c440cd1 100644 (file)
@@ -8,40 +8,24 @@ using namespace std;
 CanvasProgramChange::CanvasProgramChange(
                MidiRegionView&                       region,
                Group&                                parent,
-               boost::shared_ptr<Evoral::Event>      event,
+               string                                text,
                double                                height,
                double                                x,
                double                                y)
-       : Group(parent, x, y)
-       , _region(region)
-       , _event(event)
-       , _text(0)
-       , _line(0)
-       , _rect(0)
+       : CanvasFlag(
+                       region, 
+                       parent, 
+                       height, 
+                       ARDOUR_UI::config()->canvasvar_MidiProgramChangeOutline.get(), 
+                       ARDOUR_UI::config()->canvasvar_MidiProgramChangeFill.get(),
+                       x,
+                       y
+               )
 {
-       char pgm_str[4];
-       snprintf(pgm_str, 4, "%d", (int)(((Evoral::MIDIEvent*)event.get())->pgm_number()));
-       _text = new Text(*this, 0.0, 0.0, pgm_str);
-       _text->property_justification() = Gtk::JUSTIFY_CENTER;
-       _text->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_MidiProgramChangeOutline.get();
-       double flagwidth  = _text->property_text_width()  + 10.0;
-       double flagheight = _text->property_text_height() + 3.0;
-       _text->property_x() = flagwidth / 2.0;
-       _text->property_y() = flagheight / 2.0;
-       _text->show();
-       _line = new SimpleLine(*this, 0.0, 0.0, 0.0, height);
-       _line->property_color_rgba() = ARDOUR_UI::config()->canvasvar_MidiProgramChangeOutline.get();
-       _rect = new SimpleRect(*this, 0.0, 0.0, flagwidth, flagheight);
-       _rect->property_outline_color_rgba() = ARDOUR_UI::config()->canvasvar_MidiProgramChangeOutline.get();
-       _rect->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_MidiProgramChangeFill.get();
-       _text->lower_to_bottom();
-       _text->raise(2);
+       set_text(text);
 }
 
 CanvasProgramChange::~CanvasProgramChange()
 {
-       delete _line;
-       delete _rect;
-       delete _text;
 }
 
index f2a912d5061730fa958a2ff2625628ba70f35960..18f7d9a9d7c40f3ce390b01ced1e424738133c04 100644 (file)
@@ -1,25 +1,20 @@
 #ifndef CANVASPROGRAMCHANGE_H_
 #define CANVASPROGRAMCHANGE_H_
 
-#include <libgnomecanvasmm/group.h>
-#include "simplerect.h"
-#include "simpleline.h"
-#include <libgnomecanvasmm/text.h>
-#include <libgnomecanvasmm/widget.h>
-#include <ardour/midi_model.h>
+#include "canvas-flag.h"
 
 class MidiRegionView;
 
 namespace Gnome {
 namespace Canvas {
 
-class CanvasProgramChange : public Group
+class CanvasProgramChange : public CanvasFlag
 {
 public:
        CanvasProgramChange(
                MidiRegionView&                       region,
                Group&                                parent,
-               boost::shared_ptr<Evoral::Event>      event,
+               string                                text,
                double                                height,
                double                                x = 0.0,
                double                                y = 0.0
@@ -28,11 +23,6 @@ public:
        virtual ~CanvasProgramChange();
        
 private:
-       MidiRegionView&                   _region;
-       boost::shared_ptr<Evoral::Event>  _event;
-       Text*                             _text;
-       SimpleLine*                       _line;
-       SimpleRect*                       _rect;
 };
 
 } // namespace Canvas
index 8fe67afdd3767839f3f63acc6260a95456cf0d70..a0e01c754679977e816d1879cab3f1c854bf76ea 100644 (file)
 #include <ardour/midi_source.h>
 #include <ardour/midi_diskstream.h>
 #include <ardour/midi_model.h>
+#include <ardour/midi_patch_manager.h>
+
+#include <evoral/Parameter.hpp>
+#include <evoral/Control.hpp>
 
 #include "streamview.h"
 #include "midi_region_view.h"
@@ -67,6 +71,8 @@ MidiRegionView::MidiRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView &
        , _default_note_length(0.0)
        , _current_range_min(0)
        , _current_range_max(0)
+       , _model_name(string())
+       , _custom_device_mode(string())
        , _active_notes(0)
        , _note_group(new ArdourCanvas::Group(*parent))
        , _delta_command(NULL)
@@ -81,6 +87,8 @@ MidiRegionView::MidiRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView &
        , _force_channel(-1)
        , _last_channel_selection(0xFFFF)
        , _default_note_length(0.0)
+       , _model_name(string())
+       , _custom_device_mode(string())
        , _active_notes(0)
        , _note_group(new ArdourCanvas::Group(*parent))
        , _delta_command(NULL)
@@ -97,6 +105,8 @@ MidiRegionView::MidiRegionView (const MidiRegionView& other)
        , _force_channel(-1)
        , _last_channel_selection(0xFFFF)
        , _default_note_length(0.0)
+       , _model_name(string())
+       , _custom_device_mode(string())
        , _active_notes(0)
        , _note_group(new ArdourCanvas::Group(*get_canvas_group()))
        , _delta_command(NULL)
@@ -117,6 +127,8 @@ MidiRegionView::MidiRegionView (const MidiRegionView& other, boost::shared_ptr<M
        , _force_channel(-1)
        , _last_channel_selection(0xFFFF)
        , _default_note_length(0.0)
+       , _model_name(string())
+       , _custom_device_mode(string())
        , _active_notes(0)
        , _note_group(new ArdourCanvas::Group(*get_canvas_group()))
        , _delta_command(NULL)
@@ -175,6 +187,9 @@ MidiRegionView::init (Gdk::Color& basic_color, bool wfd)
 
        midi_view()->signal_channel_mode_changed().connect(
                        mem_fun(this, &MidiRegionView::midi_channel_mode_changed));
+       
+       midi_view()->signal_midi_patch_settings_changed().connect(
+                       mem_fun(this, &MidiRegionView::midi_patch_settings_changed));
 }
 
 bool
@@ -546,7 +561,9 @@ MidiRegionView::redisplay_model()
                clear_events();
                _model->read_lock();
                
-               /*MidiModel::Notes notes = _model->notes();
+               
+               MidiModel::Notes notes = _model->notes();
+               /*
                cerr << endl << _model->midi_source()->name() << " : redisplaying " << notes.size() << " notes:" << endl;
                for (MidiModel::Notes::iterator i = notes.begin(); i != notes.end(); ++i) {
                        cerr << "NOTE  time: " << (*i)->time()
@@ -555,27 +572,14 @@ MidiRegionView::redisplay_model()
                             << "  end-time: " << (*i)->end_time() 
                             << "  velocity: " << int((*i)->velocity()) 
                             << endl;
-               }*/
+               }
+               */
                
-               for (size_t i = 0; i < _model->n_notes(); ++i)
+               for (size_t i = 0; i < _model->n_notes(); ++i) {
                        add_note(_model->note_at(i));
-
-               // Draw program change 'flags'
-               for (Automatable::Controls::iterator control = _model->controls().begin();
-                               control != _model->controls().end(); ++control) {
-                       if (control->first.type() == MidiPgmChangeAutomation) {
-                               Glib::Mutex::Lock list_lock (control->second->list()->lock());
-                               
-                               for (AutomationList::const_iterator event = control->second->list()->begin();
-                                               event != control->second->list()->end(); ++event) {
-                                       Evoral::ControlIterator iter(control->second->list(), (*event)->when, (*event)->value);
-                                       boost::shared_ptr<Evoral::Event> event(new Evoral::Event());
-                                       _model->control_to_midi_event(event, iter);
-                                       add_pgm_change(event);
-                               }
-                               break;
-                       }
                }
+               
+               find_and_insert_program_chage_flags();
 
                // Is this necessary?
                /*for (Automatable::Controls::const_iterator i = _model->controls().begin();
@@ -606,7 +610,6 @@ MidiRegionView::redisplay_model()
 
                        _automation_children.insert(std::make_pair(i->second->parameter(), arv));
                }*/
-
                _model->read_unlock();
 
        } else {
@@ -614,6 +617,74 @@ MidiRegionView::redisplay_model()
        }
 }
 
+void
+MidiRegionView::find_and_insert_program_change_flags()
+{
+       // Draw program change 'flags'
+       for (Automatable::Controls::iterator control = _model->controls().begin();
+                       control != _model->controls().end(); ++control) {
+               if (control->first.type() == MidiPgmChangeAutomation) {
+                       Glib::Mutex::Lock list_lock (control->second->list()->lock());
+
+                       uint8_t channel       = control->first.channel();
+                       
+                       for (AutomationList::const_iterator event = control->second->list()->begin();
+                                       event != control->second->list()->end(); ++event) {
+                               double event_time     = (*event)->when;
+                               double program_number = (*event)->value;
+
+                               //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
+                               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<Evoral::Control>  lsb_control = _model->control(bank_select_lsb);
+                               boost::shared_ptr<Evoral::Control>  msb_control = _model->control(bank_select_msb);
+                                                                       
+                               boost::shared_ptr<MIDI::Name::MasterDeviceNames> master_device 
+                                       = MIDI::Name::MidiPatchManager::instance().master_device_by_model(_model_name);
+                               
+                               MIDI::Name::Patch 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) << endl;
+                                       
+                                       patch = master_device->find_patch(
+                                                       _custom_device_mode, 
+                                                       channel, 
+                                                       msb,
+                                                       lsb,
+                                                       uint8_t(program_number)
+                                       );
+
+                                       //cerr << " got patch with name " << patch.name() << " number " << patch.number() << endl;
+                               }
+                               if (patch.name() != "") {
+                                       add_pgm_change(event_time, patch.name());
+                               } else {
+                                       char buf[4];
+                                       snprintf(buf, 4, "%d", int(program_number));
+                                       add_pgm_change(event_time, buf);
+                               }
+                       }
+                       break;
+               } else if (control->first.type() == MidiCCAutomation) {
+                       //cerr << " found CC Automation of channel " << int(control->first.channel()) << " and id " << control->first.id() << endl;
+               }
+       }       
+}
+
 
 MidiRegionView::~MidiRegionView ()
 {
@@ -925,21 +996,21 @@ MidiRegionView::add_note(const boost::shared_ptr<Evoral::Note> note)
 }
 
 void
-MidiRegionView::add_pgm_change(boost::shared_ptr<Evoral::Event> event)
+MidiRegionView::add_pgm_change(nframes_t time, string displaytext)
 {
-       assert(event->time() >= 0);
+       assert(time >= 0);
        
        // dont display notes beyond the region bounds
-       if (event->time() - _region->start() >= _region->length() || event->time() <  _region->start()) 
+       if (time - _region->start() >= _region->length() || time <  _region->start()) 
                return;
        
        ArdourCanvas::Group* const group = (ArdourCanvas::Group*)get_canvas_group();
-       const double x = trackview.editor.frame_to_pixel((nframes64_t)event->time() - _region->start());
+       const double x = trackview.editor.frame_to_pixel((nframes64_t)time - _region->start());
        
        double height = midi_stream_view()->contents_height();
        _pgm_changes.push_back(
                boost::shared_ptr<CanvasProgramChange>(
-                       new CanvasProgramChange(*this, *group, event, height, x, 1.0)));
+                       new CanvasProgramChange(*this, *group, displaytext, height, x, 1.0)));
 }
 
 void
@@ -1438,3 +1509,11 @@ MidiRegionView::midi_channel_mode_changed(ChannelMode mode, uint16_t mask)
        _last_channel_selection = mask;
 }
 
+void 
+MidiRegionView::midi_patch_settings_changed(std::string model, std::string custom_device_mode)
+{
+       _model_name         = model;
+       _custom_device_mode = custom_device_mode;
+       redisplay_model();
+}
+
index 6010e2253f698b1d1d4dfb35918c1dee2ab2f9c2..c76775f9f52c972632b2280352d475ad8e25d74b 100644 (file)
@@ -86,7 +86,8 @@ class MidiRegionView : public RegionView
        void add_note(const boost::shared_ptr<Evoral::Note> note);
        void resolve_note(uint8_t note_num, double end_time);
        
-       void add_pgm_change(boost::shared_ptr<Evoral::Event> event);
+       void add_pgm_change(nframes_t time, string displaytext);
+       void find_and_insert_program_change_flags();
 
        void begin_write();
        void end_write();
@@ -219,6 +220,7 @@ class MidiRegionView : public RegionView
        bool note_canvas_event(GdkEvent* ev);
        
        void midi_channel_mode_changed(ARDOUR::ChannelMode mode, uint16_t mask);
+       void midi_patch_settings_changed(std::string model, std::string custom_device_mode);
 
        void clear_selection_except(ArdourCanvas::CanvasNoteEvent* ev);
        void clear_selection() { clear_selection_except(NULL); }
@@ -229,6 +231,9 @@ class MidiRegionView : public RegionView
        double   _default_note_length;
        uint8_t  _current_range_min;
        uint8_t  _current_range_max;
+       
+       string   _model_name;
+       string   _custom_device_mode;   
 
        typedef std::vector<ArdourCanvas::CanvasNoteEvent*> Events;
        typedef std::vector< boost::shared_ptr<ArdourCanvas::CanvasProgramChange> > PgmChanges;
index ab0f0279f1ea5e64927cb3c5e0e34a9c6ba910ca..a8f6e3a6f43d77e078aa948cc2ec7a00db8af168 100644 (file)
@@ -141,36 +141,28 @@ MidiTimeAxisView::MidiTimeAxisView (PublicEditor& ed, Session& sess, boost::shar
        }
                
        HBox* midi_controls_hbox = manage(new HBox());
-       
-       // Instrument patch selector
-       ComboBoxText*       model_selector              = manage(new ComboBoxText());
-       ComboBoxText*       custom_device_mode_selector = manage(new ComboBoxText());
-       
+               
        MIDI::Name::MidiPatchManager& patch_manager = MIDI::Name::MidiPatchManager::instance();
 
        for (MIDI::Name::MasterDeviceNames::Models::const_iterator model = patch_manager.all_models().begin();
             model != patch_manager.all_models().end();
             ++model) {
-               model_selector->append_text(model->c_str());
+               _model_selector.append_text(model->c_str());
        }
        
-       // TODO: persist the choice
-       model_selector->set_active(0);
+       _model_selector.signal_changed().connect(mem_fun(*this, &MidiTimeAxisView::model_changed));
        
-       std::list<std::string> device_modes = patch_manager.custom_device_mode_names_by_model(model_selector->get_active_text());
+       _custom_device_mode_selector.signal_changed().connect(
+                       mem_fun(*this, &MidiTimeAxisView::custom_device_mode_changed));
        
-       for (std::list<std::string>::const_iterator i = device_modes.begin(); i != device_modes.end(); ++i) {
-               cerr << "found custom device mode " << *i << endl;
-               custom_device_mode_selector->append_text(*i);
-       }
-
        // TODO: persist the choice
-       custom_device_mode_selector->set_active(0);
-       
+       // this initializes the comboboxes and sends out the signal
+       _model_selector.set_active(0);
+
        midi_controls_hbox->pack_start(_channel_selector, true, false);
        if (!patch_manager.all_models().empty()) {
-               _midi_controls_box.pack_start(*model_selector, true, false);
-               _midi_controls_box.pack_start(*custom_device_mode_selector, true, false);
+               _midi_controls_box.pack_start(_model_selector, true, false);
+               _midi_controls_box.pack_start(_custom_device_mode_selector, true, false);
        }
        
        _midi_controls_box.pack_start(*midi_controls_hbox, true, true);
@@ -195,6 +187,26 @@ MidiTimeAxisView::~MidiTimeAxisView ()
        _range_scroomer = 0;
 }
 
+void MidiTimeAxisView::model_changed()
+{
+       std::list<std::string> device_modes = MIDI::Name::MidiPatchManager::instance()
+               .custom_device_mode_names_by_model(_model_selector.get_active_text());
+       
+       _custom_device_mode_selector.clear_items();
+       
+       for (std::list<std::string>::const_iterator i = device_modes.begin(); i != device_modes.end(); ++i) {
+               cerr << "found custom device mode " << *i << endl;
+               _custom_device_mode_selector.append_text(*i);
+       }
+
+       _custom_device_mode_selector.set_active(0);
+}
+
+void MidiTimeAxisView::custom_device_mode_changed()
+{
+       _midi_patch_settings_changed.emit(_model_selector.get_active_text(), _custom_device_mode_selector.get_active_text());   
+}
+
 MidiStreamView*
 MidiTimeAxisView::midi_view()
 {
index a09cb5e5f10d24885b6bfe84faf74963fa532f9a..8f95697e2d963b999a684149d7fb66e2c2960bc0 100644 (file)
@@ -77,10 +77,19 @@ class MidiTimeAxisView : public RouteTimeAxisView
 
        void update_range();
        
-       sigc::signal<void, ARDOUR::ChannelMode, uint16_t>& signal_channel_mode_changed() 
-               { return _channel_selector.mode_changed; }
+       sigc::signal<void, ARDOUR::ChannelMode, uint16_t>& signal_channel_mode_changed() { 
+               return _channel_selector.mode_changed; 
+       }
+       
+       sigc::signal<void, string, string>& signal_midi_patch_settings_changed() {
+               return _midi_patch_settings_changed;
+       }
        
   private:
+       sigc::signal<void, string, string>  _midi_patch_settings_changed;
+                       
+       void model_changed();
+       void custom_device_mode_changed();
        
        void append_extra_display_menu_items ();
        void build_automation_action_menu ();
@@ -102,6 +111,8 @@ class MidiTimeAxisView : public RouteTimeAxisView
        Gtk::RadioMenuItem*          _percussion_mode_item;
        Gtk::VBox                    _midi_controls_box;
        MidiMultipleChannelSelector  _channel_selector;
+       Gtk::ComboBoxText            _model_selector;
+       Gtk::ComboBoxText            _custom_device_mode_selector;
 };
 
 #endif /* __ardour_midi_time_axis_h__ */
index 539881e51c9147e776087c5d7692e39c38cce8dd..c1d53a25539d9247852e2de6d19f9bc79940e24c 100644 (file)
@@ -278,13 +278,6 @@ XMLNode& MidiModel::DeltaCommand::get_state()
        return *delta_command;
 }
 
-struct EventTimeComparator {
-       typedef const Evoral::Event* value_type;
-       inline bool operator()(const Evoral::Event& a, const Evoral::Event& b) const {
-               return a.time() >= b.time();
-       }
-};
-
 /** Write the model to a MidiSource (i.e. save the model).
  * This is different from manually using read to write to a source in that
  * note off events are written regardless of the track mode.  This is so the
index b025268c45273a9da362bd252473a19a8bde0f3c..74ab0f701d022001ea19fff63beacc62cf40cb9a 100644 (file)
@@ -147,6 +147,7 @@ public:
        
        Patch& find_patch(uint8_t msb, uint8_t lsb, uint8_t program_number) {
                PatchPrimaryKey key(msb, lsb, program_number);
+               assert(key.is_sane());
                return _patch_map[key];
        }