summaryrefslogtreecommitdiff
path: root/libs/ardour/disk_writer.cc
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2019-09-26 18:39:01 -0600
committerPaul Davis <paul@linuxaudiosystems.com>2019-09-26 18:39:56 -0600
commitf5f452bf9c9637063a819a69980456767ea5da59 (patch)
tree166ebcce3aebf378dd1b21c811f416b737fe2a02 /libs/ardour/disk_writer.cc
parent9d65350600560abfbf324177c0bad66becb0ca50 (diff)
Don't try to process MIDI input in a DiskWriter if it has no _midi_buf
... which implies it has no MIDI input port(s) either. This fixes behaviour caused by BufferSet::get...() returning a valid MidiBuffer because it was based on using the _available count within the BufferSet, even though the _count value indicated there was no buffer available (to match the I/O configuration of the Route).
Diffstat (limited to 'libs/ardour/disk_writer.cc')
-rw-r--r--libs/ardour/disk_writer.cc135
1 files changed, 69 insertions, 66 deletions
diff --git a/libs/ardour/disk_writer.cc b/libs/ardour/disk_writer.cc
index d9bf2fac1e..8f6a868f9f 100644
--- a/libs/ardour/disk_writer.cc
+++ b/libs/ardour/disk_writer.cc
@@ -515,88 +515,91 @@ DiskWriter::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_samp
/* MIDI */
- // Pump entire port buffer into the ring buffer (TODO: split cycles?)
- MidiBuffer& buf = bufs.get_midi (0);
- boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack>(_route);
- MidiChannelFilter* filter = mt ? &mt->capture_filter() : 0;
+ if (_midi_buf) {
- assert (buf.size() == 0 || _midi_buf);
+ // Pump entire port buffer into the ring buffer (TODO: split cycles?)
+ MidiBuffer& buf = bufs.get_midi (0);
+ boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack>(_route);
+ MidiChannelFilter* filter = mt ? &mt->capture_filter() : 0;
- for (MidiBuffer::iterator i = buf.begin(); i != buf.end(); ++i) {
- Evoral::Event<MidiBuffer::TimeType> ev (*i, false);
- if (ev.time() + rec_offset > rec_nframes) {
- break;
- }
+ assert (buf.size() == 0 || _midi_buf);
+
+ for (MidiBuffer::iterator i = buf.begin(); i != buf.end(); ++i) {
+ Evoral::Event<MidiBuffer::TimeType> ev (*i, false);
+ if (ev.time() + rec_offset > rec_nframes) {
+ break;
+ }
#ifndef NDEBUG
- 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(), start_sample, ev.size()));
- for (size_t i=0; i < ev.size(); ++i) {
- DEBUG_STR_APPEND(a,hex);
- DEBUG_STR_APPEND(a,"0x");
- DEBUG_STR_APPEND(a,(int)__data[i]);
- DEBUG_STR_APPEND(a,' ');
+ 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(), start_sample, ev.size()));
+ for (size_t i=0; i < ev.size(); ++i) {
+ DEBUG_STR_APPEND(a,hex);
+ DEBUG_STR_APPEND(a,"0x");
+ DEBUG_STR_APPEND(a,(int)__data[i]);
+ DEBUG_STR_APPEND(a,' ');
+ }
+ DEBUG_STR_APPEND(a,'\n');
+ DEBUG_TRACE (DEBUG::MidiIO, DEBUG_STR(a).str());
}
- DEBUG_STR_APPEND(a,'\n');
- DEBUG_TRACE (DEBUG::MidiIO, DEBUG_STR(a).str());
- }
#endif
- /* Write events to the capture buffer in samples from session start,
- but ignoring looping so event time progresses monotonically.
- The source knows the loop length so it knows exactly where the
- event occurs in the series of recorded loops and can implement
- any desirable behaviour. We don't want to send event with
- transport time here since that way the source can not
- reconstruct their actual time; future clever MIDI looping should
- probably be implemented in the source instead of here.
- */
- const samplecnt_t loop_offset = _num_captured_loops * loop_length;
- const samplepos_t event_time = start_sample + loop_offset - _accumulated_capture_offset + ev.time();
- if (event_time < 0 || event_time < _first_recordable_sample) {
- /* Event out of range, skip */
- continue;
- }
+ /* Write events to the capture buffer in samples from session start,
+ but ignoring looping so event time progresses monotonically.
+ The source knows the loop length so it knows exactly where the
+ event occurs in the series of recorded loops and can implement
+ any desirable behaviour. We don't want to send event with
+ transport time here since that way the source can not
+ reconstruct their actual time; future clever MIDI looping should
+ probably be implemented in the source instead of here.
+ */
+ const samplecnt_t loop_offset = _num_captured_loops * loop_length;
+ const samplepos_t event_time = start_sample + loop_offset - _accumulated_capture_offset + ev.time();
+ if (event_time < 0 || event_time < _first_recordable_sample) {
+ /* Event out of range, skip */
+ continue;
+ }
- bool skip_event = false;
- if (mt) {
- /* skip injected immediate/out-of-band events */
- MidiBuffer const& ieb (mt->immediate_event_buffer());
- for (MidiBuffer::const_iterator j = ieb.begin(); j != ieb.end(); ++j) {
- if (*j == ev) {
- skip_event = true;
+ bool skip_event = false;
+ if (mt) {
+ /* skip injected immediate/out-of-band events */
+ MidiBuffer const& ieb (mt->immediate_event_buffer());
+ for (MidiBuffer::const_iterator j = ieb.begin(); j != ieb.end(); ++j) {
+ if (*j == ev) {
+ skip_event = true;
+ }
}
}
- }
- if (skip_event) {
- continue;
- }
+ if (skip_event) {
+ continue;
+ }
- if (!filter || !filter->filter(ev.buffer(), ev.size())) {
- _midi_buf->write (event_time, ev.event_type(), ev.size(), ev.buffer());
+ if (!filter || !filter->filter(ev.buffer(), ev.size())) {
+ _midi_buf->write (event_time, ev.event_type(), ev.size(), ev.buffer());
+ }
}
- }
-
- g_atomic_int_add (const_cast<gint*>(&_samples_pending_write), nframes);
- if (buf.size() != 0) {
- Glib::Threads::Mutex::Lock lm (_gui_feed_buffer_mutex, Glib::Threads::TRY_LOCK);
+ g_atomic_int_add (const_cast<gint*>(&_samples_pending_write), nframes);
- if (lm.locked ()) {
- /* Copy this data into our GUI feed buffer and tell the GUI
- that it can read it if it likes.
- */
- _gui_feed_buffer.clear ();
+ if (buf.size() != 0) {
+ Glib::Threads::Mutex::Lock lm (_gui_feed_buffer_mutex, Glib::Threads::TRY_LOCK);
- for (MidiBuffer::iterator i = buf.begin(); i != buf.end(); ++i) {
- /* This may fail if buf is larger than _gui_feed_buffer, but it's not really
- the end of the world if it does.
+ if (lm.locked ()) {
+ /* Copy this data into our GUI feed buffer and tell the GUI
+ that it can read it if it likes.
*/
- _gui_feed_buffer.push_back ((*i).time() + start_sample, (*i).size(), (*i).buffer());
+ _gui_feed_buffer.clear ();
+
+ for (MidiBuffer::iterator i = buf.begin(); i != buf.end(); ++i) {
+ /* This may fail if buf is larger than _gui_feed_buffer, but it's not really
+ the end of the world if it does.
+ */
+ _gui_feed_buffer.push_back ((*i).time() + start_sample, (*i).size(), (*i).buffer());
+ }
}
- }
- DataRecorded (_midi_write_source); /* EMIT SIGNAL */
+ DataRecorded (_midi_write_source); /* EMIT SIGNAL */
+ }
}
_capture_captured += rec_nframes;