Remove MIDI track default channel and its menu, and choose the channel for new notes using MidiTimeAxisView::get_channel_for_add() (fixes #3998 and #3865).

git-svn-id: svn://localhost/ardour2/branches/3.0@9585 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
Carl Hetherington 2011-05-25 15:19:47 +00:00
parent e984220eaa
commit 711db34a81
8 changed files with 49 additions and 89 deletions

View File

@ -36,7 +36,6 @@ public:
MidiChannelSelector(int n_rows = 4, int n_columns = 4, int start_row = 0, int start_column = 0);
virtual ~MidiChannelSelector() = 0;
sigc::signal<void, ARDOUR::ChannelMode, uint16_t> mode_changed;
sigc::signal<void> clicked;
void set_channel_colors(const uint32_t new_channel_colors[16]);
@ -74,6 +73,12 @@ public:
virtual ~MidiMultipleChannelSelector();
/** The channel mode or selected channel(s) has changed.
* First parameter is the new channel mode, second parameter is a bitmask
* of the currently selected channels.
*/
sigc::signal<void, ARDOUR::ChannelMode, uint16_t> mode_changed;
void set_channel_mode(ARDOUR::ChannelMode mode, uint16_t mask);
/**

View File

@ -827,7 +827,7 @@ MidiRegionView::create_note_at(double x, double y, double length, bool sh)
length = frames_to_beats (beats_to_frames (length) - 1);
}
const boost::shared_ptr<NoteType> new_note (new NoteType (get_channel_for_add (),
const boost::shared_ptr<NoteType> new_note (new NoteType (mtv->get_channel_for_add (),
frames_to_beats(start_frames + _region->start()), length,
(uint8_t)note, 0x40));
@ -1725,15 +1725,17 @@ MidiRegionView::change_patch_change (MidiModel::PatchChangePtr old_change, const
/** Add a patch change to the region.
* @param t Time in frames relative to region position
* @param patch Patch to add; time and channel are ignored (time is converted from t, and channel comes from
* get_channel_for_add())
* MidiTimeAxisView::get_channel_for_add())
*/
void
MidiRegionView::add_patch_change (framecnt_t t, Evoral::PatchChange<Evoral::MusicalTime> const & patch)
{
MidiTimeAxisView* const mtv = dynamic_cast<MidiTimeAxisView*>(&trackview);
MidiModel::PatchChangeDiffCommand* c = _model->new_patch_change_diff_command (_("add patch change"));
c->add (MidiModel::PatchChangePtr (
new Evoral::PatchChange<Evoral::MusicalTime> (
frames_to_beats (t + midi_region()->start()), get_channel_for_add(), patch.program(), patch.bank()
frames_to_beats (t + midi_region()->start()), mtv->get_channel_for_add(), patch.program(), patch.bank()
)
));
@ -3154,6 +3156,8 @@ MidiRegionView::selection_as_notelist (Notes& selected, bool allow_all_if_none_s
void
MidiRegionView::update_ghost_note (double x, double y)
{
MidiTimeAxisView* const mtv = dynamic_cast<MidiTimeAxisView*>(&trackview);
_last_ghost_x = x;
_last_ghost_y = y;
@ -3172,6 +3176,7 @@ MidiRegionView::update_ghost_note (double x, double y)
_ghost_note->note()->set_time (frames_to_beats (f + _region->start()));
_ghost_note->note()->set_length (length);
_ghost_note->note()->set_note (midi_stream_view()->y_to_note (y));
_ghost_note->note()->set_channel (mtv->get_channel_for_add ());
/* the ghost note does not appear in ghost regions, so pass false in here */
update_note (_ghost_note, false);
@ -3394,35 +3399,6 @@ MidiRegionView::trim_front_ending ()
}
}
/** @return channel (counted from 0) to add an event to, based on the current setting
* of the channel selector.
*/
uint8_t
MidiRegionView::get_channel_for_add () const
{
MidiTimeAxisView* const mtv = dynamic_cast<MidiTimeAxisView*>(&trackview);
uint16_t const chn_mask = mtv->channel_selector().get_selected_channels();
int chn_cnt = 0;
uint8_t channel = 0;
/* pick the highest selected channel, unless all channels are selected,
which is interpreted to mean channel 1 (zero)
*/
for (uint16_t i = 0; i < 16; ++i) {
if (chn_mask & (1<<i)) {
channel = i;
chn_cnt++;
}
}
if (chn_cnt == 16) {
channel = 0;
}
return channel;
}
void
MidiRegionView::edit_patch_change (ArdourCanvas::CanvasPatchChange* pc)
{

View File

@ -333,8 +333,6 @@ private:
void add_to_selection (ArdourCanvas::CanvasNoteEvent*);
void remove_from_selection (ArdourCanvas::CanvasNoteEvent*);
uint8_t get_channel_for_add () const;
void show_verbose_cursor (std::string const &, double, double) const;
void show_verbose_cursor (boost::shared_ptr<NoteType>) const;

View File

@ -115,7 +115,6 @@ MidiTimeAxisView::MidiTimeAxisView (PublicEditor& ed, Session* sess,
, _track_color_mode_item(0)
, _step_edit_item (0)
, _midi_thru_item (0)
, default_channel_menu (0)
, controller_menu (0)
, _step_editor (0)
{
@ -367,7 +366,6 @@ MidiTimeAxisView::append_extra_display_menu_items ()
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"), sigc::mem_fun(*this, &MidiTimeAxisView::toggle_midi_thru)));
_midi_thru_item = dynamic_cast<CheckMenuItem*>(&items.back());
@ -375,37 +373,6 @@ MidiTimeAxisView::append_extra_display_menu_items ()
items.push_back (SeparatorElem ());
}
Gtk::Menu*
MidiTimeAxisView::build_def_channel_menu ()
{
using namespace Menu_Helpers;
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,
sigc::bind (sigc::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 ()
{
@ -1133,3 +1100,32 @@ MidiTimeAxisView::stop_step_editing ()
_step_editor->stop_step_editing ();
}
}
/** @return channel (counted from 0) to add an event to, based on the current setting
* of the channel selector.
*/
uint8_t
MidiTimeAxisView::get_channel_for_add () const
{
uint16_t const chn_mask = _channel_selector.get_selected_channels ();
int chn_cnt = 0;
uint8_t channel = 0;
/* pick the highest selected channel, unless all channels are selected,
which is interpreted to mean channel 1 (zero)
*/
for (uint16_t i = 0; i < 16; ++i) {
if (chn_mask & (1<<i)) {
channel = i;
chn_cnt++;
}
}
if (chn_cnt == 16) {
channel = 0;
}
return channel;
}

View File

@ -101,6 +101,8 @@ class MidiTimeAxisView : public RouteTimeAxisView
void first_idle ();
uint8_t get_channel_for_add () const;
protected:
void start_step_editing ();
void stop_step_editing ();
@ -141,9 +143,6 @@ class MidiTimeAxisView : public RouteTimeAxisView
Gtk::CheckMenuItem* _midi_thru_item;
Gtk::Menu* default_channel_menu;
Gtk::Menu* build_def_channel_menu();
void set_default_channel (int);
void toggle_midi_thru ();
void change_all_channel_tracks_visibility (bool yn, Evoral::Parameter param);

View File

@ -656,11 +656,12 @@ void
PianoRollHeader::send_note_on(uint8_t note)
{
boost::shared_ptr<ARDOUR::MidiTrack> track = _view.trackview().midi_track();
MidiTimeAxisView* mtv = dynamic_cast<MidiTimeAxisView*> (&_view.trackview ());
//cerr << "note on: " << (int) note << endl;
if (track) {
_event[0] = (MIDI_CMD_NOTE_ON | track->default_channel());
_event[0] = (MIDI_CMD_NOTE_ON | mtv->get_channel_for_add ());
_event[1] = note;
_event[2] = 100;
@ -672,9 +673,10 @@ void
PianoRollHeader::send_note_off(uint8_t note)
{
boost::shared_ptr<ARDOUR::MidiTrack> track = _view.trackview().midi_track();
MidiTimeAxisView* mtv = dynamic_cast<MidiTimeAxisView*> (&_view.trackview ());
if (track) {
_event[0] = (MIDI_CMD_NOTE_OFF | track->default_channel());
_event[0] = (MIDI_CMD_NOTE_OFF | mtv->get_channel_for_add ());
_event[1] = note;
_event[2] = 100;

View File

@ -89,9 +89,6 @@ public:
PBD::Signal1<void,bool> StepEditStatusChange;
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);
@ -126,7 +123,6 @@ protected:
MidiRingBuffer<framepos_t> _step_edit_ring_buffer;
NoteMode _note_mode;
bool _step_editing;
uint8_t _default_channel;
bool _midi_thru;
int no_roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame,

View File

@ -56,7 +56,6 @@ 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)
{
}
@ -150,10 +149,6 @@ MidiTrack::_set_state (const XMLNode& node, int version, bool call_base)
set_midi_thru (prop->value() == "yes");
}
if ((prop = node.property ("default-channel")) != 0) {
set_default_channel ((uint8_t) atoi (prop->value()));
}
XMLNodeList nlist;
XMLNodeConstIterator niter;
XMLNode *child;
@ -227,7 +222,6 @@ 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;
@ -604,12 +598,6 @@ MidiTrack::set_step_editing (bool yn)
}
}
void
MidiTrack::set_default_channel (uint8_t chn)
{
_default_channel = std::min ((unsigned int) chn, 15U);
}
void
MidiTrack::set_midi_thru (bool yn)
{