diff options
author | David Robillard <d@drobilla.net> | 2015-03-28 23:24:41 -0400 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2015-03-29 00:51:56 -0400 |
commit | c9023ae73d6d70fead3e827811b384e2b171e4d6 (patch) | |
tree | 3a6cb5a0a7d436bed457f961afb272b82f1626be /libs/ardour/midi_track.cc | |
parent | 050c9c3f7d695ea8736d050f3eac5c4f0a3158ca (diff) |
Fix mute of MIDI tracks with channel forcing.
This moves MIDI channel filtering into a reusable class and moves filtering to
the source, rather than modifying the buffer afterwards. This is necessary so
that the playlist trackers reflect the emitted notes (and thus are able to stop
them in situations like mute).
As a perk, this is also faster because events are just dropped on read, rather
than pushed into a buffer then later removed (which is very slow).
Really hammering on mute or solo still seems to produce stuck notes
occasionally (perhaps related to multiple-on warnings). I am not yet sure why,
but occasional beats always.
Diffstat (limited to 'libs/ardour/midi_track.cc')
-rw-r--r-- | libs/ardour/midi_track.cc | 86 |
1 files changed, 13 insertions, 73 deletions
diff --git a/libs/ardour/midi_track.cc b/libs/ardour/midi_track.cc index b8f53a87d0..3f15464481 100644 --- a/libs/ardour/midi_track.cc +++ b/libs/ardour/midi_track.cc @@ -29,7 +29,6 @@ #define isnan_local std::isnan #endif -#include "pbd/ffs.h" #include "pbd/enumwriter.h" #include "pbd/convert.h" #include "evoral/midi_util.h" @@ -72,8 +71,6 @@ MidiTrack::MidiTrack (Session& sess, string name, Route::Flag flag, TrackMode mo , _note_mode(Sustained) , _step_editing (false) , _input_active (true) - , _playback_channel_mask(0x0000ffff) - , _capture_channel_mask(0x0000ffff) { } @@ -387,7 +384,7 @@ MidiTrack::roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame fill_buffers_with_input (bufs, _input, nframes); /* filter captured data before meter sees it */ - filter_channels (bufs, get_capture_channel_mode(), get_capture_channel_mask()); + _capture_filter.filter (bufs); if (_meter_point == MeterInput && (_monitoring & MonitorInput || _diskstream->record_enabled())) { _meter->run (bufs, start_frame, end_frame, nframes, true); @@ -402,9 +399,7 @@ MidiTrack::roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame return dret; } - /* filter playback data before we do anything else */ - - filter_channels (bufs, get_playback_channel_mode(), get_playback_channel_mask ()); + /* note diskstream uses our filter to filter/map playback channels appropriately. */ if (monitoring_state() == MonitoringInput) { @@ -549,43 +544,6 @@ MidiTrack::push_midi_input_to_step_edit_ringbuffer (framecnt_t nframes) } } -void -MidiTrack::filter_channels (BufferSet& bufs, ChannelMode mode, uint32_t mask) -{ - if (mode == AllChannels) { - return; - } - - MidiBuffer& buf (bufs.get_midi (0)); - - for (MidiBuffer::iterator e = buf.begin(); e != buf.end(); ) { - - Evoral::MIDIEvent<framepos_t> ev(*e, false); - - if (ev.is_channel_event()) { - switch (mode) { - case FilterChannels: - if (0 == ((1<<ev.channel()) & mask)) { - e = buf.erase (e); - } else { - ++e; - } - break; - case ForceChannel: - ev.set_channel (PBD::ffs (mask) - 1); - ++e; - break; - case AllChannels: - /* handled by the opening if() */ - ++e; - break; - } - } else { - ++e; - } - } -} - void MidiTrack::write_out_of_band_data (BufferSet& bufs, framepos_t /*start*/, framepos_t /*end*/, framecnt_t nframes) { @@ -815,52 +773,34 @@ MidiTrack::write_source (uint32_t) } void -MidiTrack::set_playback_channel_mode(ChannelMode mode, uint16_t mask) +MidiTrack::set_playback_channel_mode(ChannelMode mode, uint16_t mask) { - ChannelMode old = get_playback_channel_mode (); - uint16_t old_mask = get_playback_channel_mask (); - - if (old != mode || mask != old_mask) { - _set_playback_channel_mode (mode, mask); - PlaybackChannelModeChanged (); - _session.set_dirty (); + if (_playback_filter.set_channel_mode(mode, mask)) { + _session.set_dirty(); } } void -MidiTrack::set_capture_channel_mode(ChannelMode mode, uint16_t mask) +MidiTrack::set_capture_channel_mode(ChannelMode mode, uint16_t mask) { - ChannelMode old = get_capture_channel_mode (); - uint16_t old_mask = get_capture_channel_mask (); - - if (old != mode || mask != old_mask) { - _set_capture_channel_mode (mode, mask); - CaptureChannelModeChanged (); - _session.set_dirty (); + if (_capture_filter.set_channel_mode(mode, mask)) { + _session.set_dirty(); } } void MidiTrack::set_playback_channel_mask (uint16_t mask) { - uint16_t old = get_playback_channel_mask(); - - if (old != mask) { - _set_playback_channel_mask (mask); - PlaybackChannelMaskChanged (); - _session.set_dirty (); + if (_playback_filter.set_channel_mask(mask)) { + _session.set_dirty(); } } void MidiTrack::set_capture_channel_mask (uint16_t mask) { - uint16_t old = get_capture_channel_mask(); - - if (old != mask) { - _set_capture_channel_mask (mask); - CaptureChannelMaskChanged (); - _session.set_dirty (); + if (_capture_filter.set_channel_mask(mask)) { + _session.set_dirty(); } } @@ -949,7 +889,7 @@ MidiTrack::act_on_mute () if (muted() || _mute_master->muted_by_others_at(MuteMaster::AllPoints)) { /* only send messages for channels we are using */ - uint16_t mask = get_playback_channel_mask(); + uint16_t mask = _playback_filter.get_channel_mask(); for (uint8_t channel = 0; channel <= 0xF; channel++) { |