From: Hans Baier Date: Thu, 11 Dec 2008 08:06:27 +0000 (+0000) Subject: * added myself to about.cc X-Git-Tag: 3.0-alpha5~3948 X-Git-Url: https://main.carlh.net/gitweb/?a=commitdiff_plain;h=e009016b03ea5c5c690d7d4939b264313600fd4b;p=ardour.git * added myself to about.cc * 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 --- diff --git a/gtk2_ardour/SConscript b/gtk2_ardour/SConscript index 89a5040400..f8089d099e 100644 --- a/gtk2_ardour/SConscript +++ b/gtk2_ardour/SConscript @@ -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 diff --git a/gtk2_ardour/about.cc b/gtk2_ardour/about.cc index ae8c7f503b..7d41847e14 100644 --- a/gtk2_ardour/about.cc +++ b/gtk2_ardour/about.cc @@ -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 index 0000000000..2692639da4 --- /dev/null +++ b/gtk2_ardour/canvas-flag.cc @@ -0,0 +1,41 @@ +#include "canvas-flag.h" +#include +#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 index 0000000000..ec150f685a --- /dev/null +++ b/gtk2_ardour/canvas-flag.h @@ -0,0 +1,58 @@ +#ifndef CANVASFLAG_H_ +#define CANVASFLAG_H_ + +#include +#include +#include + +#include + +#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_*/ diff --git a/gtk2_ardour/canvas-program-change.cc b/gtk2_ardour/canvas-program-change.cc index bd9c0e89db..f48d2e6be9 100644 --- a/gtk2_ardour/canvas-program-change.cc +++ b/gtk2_ardour/canvas-program-change.cc @@ -8,40 +8,24 @@ using namespace std; CanvasProgramChange::CanvasProgramChange( MidiRegionView& region, Group& parent, - boost::shared_ptr 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; } diff --git a/gtk2_ardour/canvas-program-change.h b/gtk2_ardour/canvas-program-change.h index f2a912d506..18f7d9a9d7 100644 --- a/gtk2_ardour/canvas-program-change.h +++ b/gtk2_ardour/canvas-program-change.h @@ -1,25 +1,20 @@ #ifndef CANVASPROGRAMCHANGE_H_ #define CANVASPROGRAMCHANGE_H_ -#include -#include "simplerect.h" -#include "simpleline.h" -#include -#include -#include +#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 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 _event; - Text* _text; - SimpleLine* _line; - SimpleRect* _rect; }; } // namespace Canvas diff --git a/gtk2_ardour/midi_region_view.cc b/gtk2_ardour/midi_region_view.cc index 8fe67afdd3..a0e01c7546 100644 --- a/gtk2_ardour/midi_region_view.cc +++ b/gtk2_ardour/midi_region_view.cc @@ -33,6 +33,10 @@ #include #include #include +#include + +#include +#include #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_ptrsignal_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 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 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); + + 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 note) } void -MidiRegionView::add_pgm_change(boost::shared_ptr 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( - 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(); +} + diff --git a/gtk2_ardour/midi_region_view.h b/gtk2_ardour/midi_region_view.h index 6010e2253f..c76775f9f5 100644 --- a/gtk2_ardour/midi_region_view.h +++ b/gtk2_ardour/midi_region_view.h @@ -86,7 +86,8 @@ 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(boost::shared_ptr 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 Events; typedef std::vector< boost::shared_ptr > PgmChanges; diff --git a/gtk2_ardour/midi_time_axis.cc b/gtk2_ardour/midi_time_axis.cc index ab0f0279f1..a8f6e3a6f4 100644 --- a/gtk2_ardour/midi_time_axis.cc +++ b/gtk2_ardour/midi_time_axis.cc @@ -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 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::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 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::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() { diff --git a/gtk2_ardour/midi_time_axis.h b/gtk2_ardour/midi_time_axis.h index a09cb5e5f1..8f95697e2d 100644 --- a/gtk2_ardour/midi_time_axis.h +++ b/gtk2_ardour/midi_time_axis.h @@ -77,10 +77,19 @@ class MidiTimeAxisView : public RouteTimeAxisView void update_range(); - sigc::signal& signal_channel_mode_changed() - { return _channel_selector.mode_changed; } + sigc::signal& signal_channel_mode_changed() { + return _channel_selector.mode_changed; + } + + sigc::signal& signal_midi_patch_settings_changed() { + return _midi_patch_settings_changed; + } private: + sigc::signal _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__ */ diff --git a/libs/ardour/midi_model.cc b/libs/ardour/midi_model.cc index 539881e51c..c1d53a2553 100644 --- a/libs/ardour/midi_model.cc +++ b/libs/ardour/midi_model.cc @@ -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 diff --git a/libs/midi++2/midi++/midnam_patch.h b/libs/midi++2/midi++/midnam_patch.h index b025268c45..74ab0f701d 100644 --- a/libs/midi++2/midi++/midnam_patch.h +++ b/libs/midi++2/midi++/midnam_patch.h @@ -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]; }