Respond to MMC even when synced to JACK. Fixes #3700.
[ardour.git] / libs / ardour / buffer_set.cc
index 4c802b1443e26d815828a3846349b747f47301ca..159a24c217c9fb105c64fa851c68900a26a6d4ef 100644 (file)
@@ -82,10 +82,12 @@ BufferSet::clear()
 #endif 
 }
 
-/** Make this BufferSet a direct mirror of a PortSet's buffers.
+/** Set up this BufferSet so that its data structures mirror a PortSet's buffers.
+ *  This is quite expensive and not RT-safe, so it should not be called in a process context;
+ *  get_jack_port_addresses() will fill in a structure set up by this method.
  */
 void
-BufferSet::attach_buffers(PortSet& ports, nframes_t nframes, nframes_t offset)
+BufferSet::attach_buffers (PortSet& ports)
 {
        clear();
 
@@ -95,7 +97,7 @@ BufferSet::attach_buffers(PortSet& ports, nframes_t nframes, nframes_t offset)
 
                for (PortSet::iterator p = ports.begin(*t); p != ports.end(*t); ++p) {
                        assert(p->type() == *t);
-                       v.push_back(&(p->get_buffer(nframes, offset)));
+                       v.push_back (0);
                }
        }
 
@@ -105,6 +107,32 @@ BufferSet::attach_buffers(PortSet& ports, nframes_t nframes, nframes_t offset)
        _is_mirror = true;
 }
 
+/** Write the JACK port addresses from a PortSet into our data structures.  This
+ *  call assumes that attach_buffers() has already been called for the same PortSet.
+ *  Does not allocate, so RT-safe.
+ */
+void
+BufferSet::get_jack_port_addresses (PortSet& ports, framecnt_t nframes, framecnt_t offset)
+{
+       assert (_count == ports.count ());
+       assert (_available == ports.count ());
+       assert (_is_mirror);
+
+       assert (_buffers.size() == DataType::num_types);
+
+       for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
+               BufferVec& v = _buffers[*t];
+
+               assert (v.size() == ports.num_ports (*t));
+
+               int i = 0;
+               for (PortSet::iterator p = ports.begin(*t); p != ports.end(*t); ++p) {
+                       v[i] = &p->get_buffer (nframes, offset);
+                       ++i;
+               }
+       }
+}
+
 /** Ensure that there are @a num_buffers buffers of type @a type available,
  * each of size at least @a buffer_size
  */
@@ -224,7 +252,7 @@ BufferSet::get_lv2_midi(bool input, size_t i)
        ebuf->reset();
        if (input) {
                for (MidiBuffer::iterator e = mbuf.begin(); e != mbuf.end(); ++e) {
-                       const Evoral::MIDIEvent<nframes_t> ev(*e, false);
+                       const Evoral::MIDIEvent<framepos_t> ev(*e, false);
                        uint32_t type = LV2Plugin::midi_event_type();
                        ebuf->append(ev.time(), 0, type, ev.size(), ev.buffer());
                }
@@ -299,7 +327,7 @@ BufferSet::VSTBuffer::clear ()
 }
 
 void
-BufferSet::VSTBuffer::push_back (Evoral::MIDIEvent<nframes_t> const & ev)
+BufferSet::VSTBuffer::push_back (Evoral::MIDIEvent<framepos_t> const & ev)
 {
        if (ev.size() > 3) {
                /* XXX: this will silently drop MIDI messages longer than 3 bytes, so
@@ -333,7 +361,7 @@ BufferSet::VSTBuffer::push_back (Evoral::MIDIEvent<nframes_t> const & ev)
 #endif /* VST_SUPPORT */
 
 void
-BufferSet::read_from (const BufferSet& in, nframes_t nframes)
+BufferSet::read_from (const BufferSet& in, framecnt_t nframes)
 {
        assert(available() >= in.count());
 
@@ -349,7 +377,7 @@ BufferSet::read_from (const BufferSet& in, nframes_t nframes)
 }
 
 void
-BufferSet::merge_from (const BufferSet& in, nframes_t nframes)
+BufferSet::merge_from (const BufferSet& in, framecnt_t nframes)
 {
        /* merge all input buffers into out existing buffers.
 
@@ -367,7 +395,7 @@ BufferSet::merge_from (const BufferSet& in, nframes_t nframes)
 }
 
 void
-BufferSet::silence (nframes_t nframes, nframes_t offset)
+BufferSet::silence (framecnt_t nframes, framecnt_t offset)
 {
        for (std::vector<BufferVec>::iterator i = _buffers.begin(); i != _buffers.end(); ++i) {
                for (BufferVec::iterator b = i->begin(); b != i->end(); ++b) {