Fix crash on out of range MIDI events (though this shouldn't be possible at all....
[ardour.git] / libs / ardour / midi_port.cc
index bd7252879465c456066ce0454dae727704ba28b7..fc48218efad747c4ad073f0202373c7d923201c5 100644 (file)
 #include <iostream>
 
 #include <ardour/midi_port.h>
+#include <ardour/jack_midi_port.h>
 #include <ardour/data_type.h>
 
 using namespace ARDOUR;
 using namespace std;
 
-MidiPort::MidiPort (Flags flags, nframes_t bufsize)
-       : Port (flags), _buffer (bufsize) 
+MidiPort::MidiPort (const std::string& name, Flags flags, bool external, nframes_t capacity)
+       : Port (name, flags)
+       , BaseMidiPort (name, flags)
+       , PortFacade (name, flags)
 {
-       _type = DataType::MIDI;
-       reset();
+       _buffer = new MidiBuffer (capacity);
 
+       if (external) {
+               /* external ports use the same buffer for the jack port (_ext_port)
+                * and internal ports (this) */
+               _ext_port = new JackMidiPort (name, flags, _buffer);
+               Port::set_name (_ext_port->name());
+       } else {
+               /* internal ports just have a single buffer, no jack port */
+               _ext_port = 0;
+               set_name (name);
+       }
 
+       reset ();
 }
 
 MidiPort::~MidiPort()
 {
+       if (_ext_port) {
+               delete _ext_port;
+               _ext_port = 0;
+       }
+}
+
+void
+MidiPort::reset()
+{
+       BaseMidiPort::reset();
+
+       if (_ext_port) {
+               _ext_port->reset ();
+       }
+}
+
+void
+MidiPort::cycle_start (nframes_t nframes, nframes_t offset)
+{
+       if (_ext_port) {
+               _ext_port->cycle_start (nframes, offset);
+       }
+       
+       if (_flags & IsInput) {
+                       
+               if (_ext_port) {
+               
+                       BaseMidiPort* mprt = dynamic_cast<BaseMidiPort*>(_ext_port);
+                       assert(mprt);
+                       assert(&mprt->get_midi_buffer() == _buffer);
+
+                       if (!_connections.empty()) {
+                               (*_mixdown) (_connections, _buffer, nframes, offset, false);
+                       }
+
+               } else {
+               
+                       if (_connections.empty()) {
+                               _buffer->silence (nframes, offset);
+                       } else {
+                               (*_mixdown) (_connections, _buffer, nframes, offset, true);
+                       }
+               }
+
+       } else {
+                       
+               _buffer->silence (nframes, offset);
+       }
+}
+
+       
+void
+MidiPort::cycle_end (nframes_t nframes, nframes_t offset)
+{
+       if (_ext_port) {
+               _ext_port->cycle_end (nframes, offset);
+       }
 }