summaryrefslogtreecommitdiff
path: root/libs/ardour/midi_track.cc
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2015-03-28 23:24:41 -0400
committerDavid Robillard <d@drobilla.net>2015-03-29 00:51:56 -0400
commitc9023ae73d6d70fead3e827811b384e2b171e4d6 (patch)
tree3a6cb5a0a7d436bed457f961afb272b82f1626be /libs/ardour/midi_track.cc
parent050c9c3f7d695ea8736d050f3eac5c4f0a3158ca (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.cc86
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++) {