diff options
author | Paul Davis <paul@linuxaudiosystems.com> | 2009-09-25 19:00:34 +0000 |
---|---|---|
committer | Paul Davis <paul@linuxaudiosystems.com> | 2009-09-25 19:00:34 +0000 |
commit | 9867035f2981e60f00cc9ec19aef5840a5bd7fad (patch) | |
tree | afa78bb74bc4a3537893d920532d12c1391b4c14 | |
parent | 756fc1839442ae236083c918ba7c7af30e5f8100 (diff) |
make MIDI thru work even when not rolling; add GUI control over MIDI thru (midi track context menu); add "default channel" concept for MIDI tracks so that piano roll header events can send stuff on the right channel; add GUI control over this channel setting
git-svn-id: svn://localhost/ardour2/branches/3.0@5687 d708f5d6-7413-0410-9779-e7cbd77b26cf
-rw-r--r-- | gtk2_ardour/midi_time_axis.cc | 54 | ||||
-rw-r--r-- | gtk2_ardour/midi_time_axis.h | 5 | ||||
-rw-r--r-- | gtk2_ardour/piano_roll_header.cc | 4 | ||||
-rw-r--r-- | libs/ardour/ardour/midi_track.h | 9 | ||||
-rw-r--r-- | libs/ardour/midi_track.cc | 38 |
5 files changed, 102 insertions, 8 deletions
diff --git a/gtk2_ardour/midi_time_axis.cc b/gtk2_ardour/midi_time_axis.cc index 6103e02544..b189827782 100644 --- a/gtk2_ardour/midi_time_axis.cc +++ b/gtk2_ardour/midi_time_axis.cc @@ -108,6 +108,9 @@ MidiTimeAxisView::MidiTimeAxisView (PublicEditor& ed, Session& sess, , _meter_color_mode_item(0) , _channel_color_mode_item(0) , _track_color_mode_item(0) + , _step_edit_item (0) + , _midi_thru_item (0) + , default_channel_menu (0) { subplugin_menu.set_name ("ArdourContextMenu"); @@ -301,8 +304,57 @@ MidiTimeAxisView::append_extra_display_menu_items () MidiStreamView::ContentsRange))); items.push_back (MenuElem (_("Note range"), *range_menu)); - items.push_back (MenuElem (_("Note mode"), *build_note_mode_menu())); + items.push_back (MenuElem (_("Default Channel"), *build_def_channel_menu())); + + items.push_back (CheckMenuElem (_("MIDI Thru"), mem_fun(*this, &MidiTimeAxisView::toggle_midi_thru))); + _midi_thru_item = dynamic_cast<CheckMenuItem*>(&items.back()); +} + +Gtk::Menu* +MidiTimeAxisView::build_def_channel_menu () +{ + using namespace Menu_Helpers; + + if (default_channel_menu == 0) { + default_channel_menu = manage (new Menu ()); + } + + uint8_t defchn = midi_track()->default_channel(); + MenuList& def_channel_items = default_channel_menu->items(); + RadioMenuItem* item; + RadioMenuItem::Group dc_group; + + for (int i = 0; i < 16; ++i) { + char buf[4]; + snprintf (buf, sizeof (buf), "%d", i+1); + + def_channel_items.push_back (RadioMenuElem (dc_group, buf, + bind (mem_fun (*this, &MidiTimeAxisView::set_default_channel), i))); + item = dynamic_cast<RadioMenuItem*>(&def_channel_items.back()); + item->set_active ((i == defchn)); + } + + return default_channel_menu; +} + +void +MidiTimeAxisView::set_default_channel (int chn) +{ + midi_track()->set_default_channel (chn); +} + +void +MidiTimeAxisView::toggle_midi_thru () +{ + if (!_midi_thru_item) { + return; + } + + bool view_yn = _midi_thru_item->get_active(); + if (view_yn != midi_track()->midi_thru()) { + midi_track()->set_midi_thru (view_yn); + } } void diff --git a/gtk2_ardour/midi_time_axis.h b/gtk2_ardour/midi_time_axis.h index fd9db05a99..d71c156f48 100644 --- a/gtk2_ardour/midi_time_axis.h +++ b/gtk2_ardour/midi_time_axis.h @@ -129,12 +129,17 @@ class MidiTimeAxisView : public RouteTimeAxisView Gtk::ComboBoxText _custom_device_mode_selector; Gtk::CheckMenuItem* _step_edit_item; + Gtk::CheckMenuItem* _midi_thru_item; + Gtk::Menu* default_channel_menu; nframes64_t step_edit_insert_position; Evoral::MusicalTime step_edit_beat_pos; boost::shared_ptr<ARDOUR::Region> step_edit_region; MidiRegionView* step_edit_region_view; + Gtk::Menu* build_def_channel_menu(); + void set_default_channel (int); + void toggle_midi_thru (); }; #endif /* __ardour_midi_time_axis_h__ */ diff --git a/gtk2_ardour/piano_roll_header.cc b/gtk2_ardour/piano_roll_header.cc index 9a7b86396f..c6784bf853 100644 --- a/gtk2_ardour/piano_roll_header.cc +++ b/gtk2_ardour/piano_roll_header.cc @@ -651,7 +651,7 @@ PianoRollHeader::send_note_on(uint8_t note) //cerr << "note on: " << (int) note << endl; if (track) { - _event[0] = MIDI_CMD_NOTE_ON; + _event[0] = (MIDI_CMD_NOTE_ON | track->default_channel()); _event[1] = note; _event[2] = 100; @@ -665,7 +665,7 @@ PianoRollHeader::send_note_off(uint8_t note) boost::shared_ptr<ARDOUR::MidiTrack> track = _view.trackview().midi_track(); if (track) { - _event[0] = MIDI_CMD_NOTE_OFF; + _event[0] = (MIDI_CMD_NOTE_OFF | track->default_channel()); _event[1] = note; _event[2] = 100; diff --git a/libs/ardour/ardour/midi_track.h b/libs/ardour/ardour/midi_track.h index a1b0d2003e..f8bca2304c 100644 --- a/libs/ardour/ardour/midi_track.h +++ b/libs/ardour/ardour/midi_track.h @@ -84,6 +84,12 @@ public: bool step_editing() const { return _step_editing; } void set_step_editing (bool yn); MidiRingBuffer<nframes_t>& step_edit_ring_buffer() { return _step_edit_ring_buffer; } + + uint8_t default_channel() const { return _default_channel; } + void set_default_channel (uint8_t chn); + + bool midi_thru() const { return _midi_thru; } + void set_midi_thru (bool yn); protected: XMLNode& state (bool full); @@ -105,6 +111,9 @@ private: MidiRingBuffer<nframes_t> _step_edit_ring_buffer; NoteMode _note_mode; bool _step_editing; + uint8_t _default_channel; + bool _midi_thru; + int no_roll (nframes_t nframes, sframes_t start_frame, sframes_t end_frame, bool state_changing, bool can_record, bool rec_monitors_input); diff --git a/libs/ardour/midi_track.cc b/libs/ardour/midi_track.cc index 4f13682a89..bc6ea5fe58 100644 --- a/libs/ardour/midi_track.cc +++ b/libs/ardour/midi_track.cc @@ -55,6 +55,8 @@ MidiTrack::MidiTrack (Session& sess, string name, Route::Flag flag, TrackMode mo , _step_edit_ring_buffer(64) // FIXME: size? , _note_mode(Sustained) , _step_editing (false) + , _default_channel (0) + , _midi_thru (true) { use_new_diskstream (); @@ -70,6 +72,8 @@ MidiTrack::MidiTrack (Session& sess, const XMLNode& node) , _step_edit_ring_buffer(64) // FIXME: size? , _note_mode(Sustained) , _step_editing (false) + , _default_channel (0) + , _midi_thru (true) { _set_state(node, false); } @@ -175,6 +179,14 @@ MidiTrack::_set_state (const XMLNode& node, bool call_base) _note_mode = Sustained; } + if ((prop = node.property ("midi-thru")) != 0) { + set_midi_thru (prop->value() == "yes"); + } + + if ((prop = node.property ("default-channel")) != 0) { + set_default_channel ((uint8_t) atoi (prop->value())); + } + if ((prop = node.property ("diskstream-id")) == 0) { /* some old sessions use the diskstream name rather than the ID */ @@ -284,6 +296,9 @@ MidiTrack::state(bool full_state) root.add_property ("step-editing", (_step_editing ? "yes" : "no")); root.add_property ("note-mode", enum_2_string (_note_mode)); + root.add_property ("midi-thru", (_midi_thru ? "yes" : "no")); + snprintf (buf, sizeof (buf), "%d", (int) _default_channel); + root.add_property ("default-channel", buf); return root; } @@ -450,11 +465,6 @@ MidiTrack::roll (nframes_t nframes, sframes_t start_frame, sframes_t end_frame, write_out_of_band_data (bufs, start_frame, end_frame, nframes); - /* send incoming data "through" output */ - if (_input->n_ports().n_midi()) { - mbuf.merge_in_place (_input->midi(0)->get_midi_buffer(nframes)); - } - // Feed the data through the MidiStateTracker bool did_loop; @@ -535,8 +545,14 @@ MidiTrack::write_out_of_band_data (BufferSet& bufs, sframes_t /*start*/, sframes MidiBuffer& buf (bufs.get_midi (0)); _immediate_events.read (buf, 0, 0, nframes - 1); // all stamps = 0 + + /* MIDI thru: send incoming data "through" output */ + if (_midi_thru && _input->n_ports().n_midi()) { + buf.merge_in_place (_input->midi(0)->get_midi_buffer(nframes)); + } } + int MidiTrack::export_stuff (BufferSet& /*bufs*/, nframes_t /*nframes*/, sframes_t /*end_frame*/) { @@ -678,3 +694,15 @@ MidiTrack::set_step_editing (bool yn) { _step_editing = yn; } + +void +MidiTrack::set_default_channel (uint8_t chn) +{ + _default_channel = std::min ((unsigned int) chn, 15U); +} + +void +MidiTrack::set_midi_thru (bool yn) +{ + _midi_thru = yn; +} |