#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(jack_port_t* p)
- : Port(p)
- , _buffer(4096) // FIXME FIXME FIXME Jack needs to tell us this
- , _nframes_this_cycle(0)
+MidiPort::MidiPort (const std::string& name, Flags flags, bool publish, nframes_t bufsize)
+ : Port (name, flags)
+ , BaseMidiPort (name, flags)
+ , PortFacade (name, flags)
{
- DataType dt(_type);
- assert(dt == DataType::MIDI);
+ set_name (name);
- reset();
+ _buffer = new MidiBuffer (bufsize);
+ if (!publish) {
+ _ext_port = 0;
+ } else {
+ _ext_port = new JackMidiPort (name, flags, _buffer);
+ }
+ reset ();
}
-
MidiPort::~MidiPort()
{
+ if (_ext_port) {
+ delete _ext_port;
+ _ext_port = 0;
+ }
}
void
-MidiPort::cycle_start (nframes_t nframes)
+MidiPort::reset()
{
- _buffer.clear();
- assert(_buffer.size() == 0);
-
- _nframes_this_cycle = nframes;
-
- if (_flags & JackPortIsOutput) {
- _buffer.silence(nframes);
- assert(_buffer.size() == 0);
- return;
- }
-
- // We're an input - copy Jack events to internal buffer
-
- void* jack_buffer = jack_port_get_buffer(_port, nframes);
-
- const nframes_t event_count
- = jack_midi_get_event_count(jack_buffer);
-
- assert(event_count < _buffer.capacity());
+ BaseMidiPort::reset();
- MidiEvent ev;
-
- // FIXME: too slow, event struct is copied twice (here and MidiBuffer::push_back)
- for (nframes_t i=0; i < event_count; ++i) {
-
- // This will fail to compile if we change MidiEvent to our own class
- jack_midi_event_get(static_cast<jack_midi_event_t*>(&ev), jack_buffer, i);
-
- _buffer.push_back(ev);
- // Convert note ons with velocity 0 to proper note offs
- // FIXME: Jack MIDI should guarantee this - does it?
- //if (ev->buffer[0] == MIDI_CMD_NOTE_ON && ev->buffer[2] == 0)
- // ev->buffer[0] = MIDI_CMD_NOTE_OFF;
+ if (_ext_port) {
+ _ext_port->reset ();
}
-
- assert(_buffer.size() == event_count);
-
- //if (_buffer.size() > 0)
- // cerr << "MIDIPort got " << event_count << " events." << endl;
}
void
-MidiPort::cycle_end()
+MidiPort::cycle_start (nframes_t nframes, nframes_t offset)
{
- if (_flags & JackPortIsInput) {
- _nframes_this_cycle = 0;
- return;
- }
-
- // We're an output - copy events from internal buffer to Jack buffer
+ /* caller must hold process lock */
- void* jack_buffer = jack_port_get_buffer(_port, _nframes_this_cycle);
+ if (_ext_port) {
+ _ext_port->cycle_start (nframes, offset);
+ }
- const nframes_t event_count = _buffer.size();
-
- //if (event_count > 0)
- // cerr << "MIDIPort writing " << event_count << " events." << endl;
-
- jack_midi_clear_buffer(jack_buffer);
- for (nframes_t i=0; i < event_count; ++i) {
- const jack_midi_event_t& ev = _buffer[i];
- assert(ev.time < _nframes_this_cycle);
- jack_midi_event_write(jack_buffer, ev.time, ev.buffer, ev.size);
+ if (_flags & IsInput) {
+
+ if (_ext_port) {
+ _buffer->read_from (dynamic_cast<BaseMidiPort*>(_ext_port)->get_midi_buffer(), nframes, offset);
+ 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);
}
-
- _nframes_this_cycle = 0;
}