}
if (nominally_recording || rec_nframes) {
-
- // Pump entire port buffer into the ring buffer (FIXME: split cycles?)
- MidiBuffer& buf = sp->get_midi_buffer(nframes);
- ChannelMode mode = AllChannels;
- uint32_t mask = 0xffff;
-
- MidiTrack * mt = dynamic_cast<MidiTrack*> (_track);
- if (mt) {
- mode = mt->get_capture_channel_mode ();
- mask = mt->get_capture_channel_mask ();
- }
+ // Pump entire port buffer into the ring buffer (TODO: split cycles?)
+ MidiBuffer& buf = sp->get_midi_buffer(nframes);
+ MidiTrack* mt = dynamic_cast<MidiTrack*>(_track);
+ MidiChannelFilter* filter = mt ? &mt->capture_filter() : NULL;
for (MidiBuffer::iterator i = buf.begin(); i != buf.end(); ++i) {
Evoral::MIDIEvent<MidiBuffer::TimeType> ev(*i, false);
break;
}
#ifndef NDEBUG
- if (DEBUG::MidiIO & PBD::debug_bits) {
+ if (DEBUG_ENABLED(DEBUG::MidiIO)) {
const uint8_t* __data = ev.buffer();
DEBUG_STR_DECL(a);
DEBUG_STR_APPEND(a, string_compose ("mididiskstream %1 capture event @ %2 + %3 sz %4 ", this, ev.time(), transport_frame, ev.size()));
const framecnt_t loop_offset = _num_captured_loops * loop_length;
const framepos_t event_time = transport_frame + loop_offset - _accumulated_capture_offset + ev.time();
if (event_time < 0 || event_time < first_recordable_frame) {
+ /* Event out of range, skip */
continue;
}
- switch (mode) {
- case AllChannels:
- _capture_buf->write(event_time,
- ev.type(), ev.size(), ev.buffer());
- break;
- case FilterChannels:
- if (ev.is_channel_event()) {
- if ((1<<ev.channel()) & mask) {
- _capture_buf->write(event_time,
- ev.type(), ev.size(), ev.buffer());
- }
- } else {
- _capture_buf->write(event_time,
- ev.type(), ev.size(), ev.buffer());
- }
- break;
- case ForceChannel:
- if (ev.is_channel_event()) {
- ev.set_channel (PBD::ffs(mask) - 1);
- }
- _capture_buf->write(event_time,
- ev.type(), ev.size(), ev.buffer());
- break;
+
+ if (!filter || !filter->filter(ev.buffer(), ev.size())) {
+ _capture_buf->write(event_time, ev.type(), ev.size(), ev.buffer());
}
}
g_atomic_int_add(const_cast<gint*>(&_frames_pending_write), nframes);
*
* In those cases the butler needs to be summed to refill the buffer (done now)
* AND we need to skip (frames_read - frames_written). ie remove old events
- * before playback_sample from the rinbuffer. (not yet done)
+ * before playback_sample from the rinbuffer.
*
* [1] one way to do so is described at #6170.
* For me just popping up the context-menu on a MIDI-track header
framecnt_t loop_length = 0;
Location* loc = 0;
+ MidiTrack* mt = dynamic_cast<MidiTrack*>(_track);
+ MidiChannelFilter* filter = mt ? &mt->playback_filter() : NULL;
+
if (!reversed) {
loc = loop_location;
this_read = min(dur,this_read);
- if (midi_playlist()->read (*_playback_buf, start, this_read) != this_read) {
+ if (midi_playlist()->read (*_playback_buf, start, this_read, 0, filter) != this_read) {
error << string_compose(
_("MidiDiskstream %1: cannot read %2 from playlist at frame %3"),
id(), this_read, start) << endmsg;
}
int
-MidiDiskstream::do_refill_with_alloc ()
+MidiDiskstream::_do_refill_with_alloc (bool /* partial_fill */)
{
return do_refill();
}
void
MidiDiskstream::set_record_enabled (bool yn)
{
- if (!recordable() || !_session.record_enabling_legal() || _io->n_ports().n_midi() == 0) {
+ if (!recordable() || !_session.record_enabling_legal() || _io->n_ports().n_midi() == 0 || record_safe ()) {
return;
}
}
}
+void
+MidiDiskstream::set_record_safe (bool yn)
+{
+ if (!recordable() || !_session.record_enabling_legal() || _io->n_ports().n_midi() == 0) { // REQUIRES REVIEW
+ return;
+ }
+
+ /* yes, i know that this not proof against race conditions, but its
+ good enough. i think.
+ */
+
+ if (record_safe () != yn) {
+ if (yn) {
+ engage_record_safe ();
+ } else {
+ disengage_record_safe ();
+ }
+
+ RecordSafeChanged (); /* EMIT SIGNAL */
+ }
+}
+
bool
MidiDiskstream::prep_record_enable ()
{
- if (!recordable() || !_session.record_enabling_legal() || _io->n_ports().n_midi() == 0) {
+ if (!recordable() || !_session.record_enabling_legal() || _io->n_ports().n_midi() == 0 || record_safe ()) { // REQUIRES REVIEW "|| record_safe ()"
return false;
}
_playback_buf->resolve_tracker (dst, 0);
}
+ _playback_buf->skip_to (effective_start);
+
if (loc->end() >= effective_start && loc->end() < effective_start + nframes) {
/* end of loop is within the range we are reading, so
split the read in two, and lie about the location
events_read = _playback_buf->read (dst, effective_start, effective_start + nframes);
}
} else {
+ _playback_buf->skip_to (playback_sample);
events_read = _playback_buf->read (dst, playback_sample, playback_sample + nframes);
}
}
}
+void
+MidiDiskstream::resolve_tracker (Evoral::EventSink<framepos_t>& buffer, framepos_t time)
+{
+ _playback_buf->resolve_tracker(buffer, time);
+
+ boost::shared_ptr<MidiPlaylist> mp (midi_playlist());
+
+ if (mp) {
+ mp->reset_note_trackers ();
+ }
+}
+
+
boost::shared_ptr<MidiPlaylist>
MidiDiskstream::midi_playlist ()
{