X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Fmidi_port.cc;h=55280eb9428e82aed7fc611a53d866991f0b0b82;hb=944c32346b3c6bb87fccb22f159bdd9297bae50d;hp=9191a570803ac3b4f4640fe4ced310fc50fab606;hpb=9ac6bb9befa047a6c349bed02d40da84600b67cc;p=ardour.git diff --git a/libs/ardour/midi_port.cc b/libs/ardour/midi_port.cc index 9191a57080..55280eb942 100644 --- a/libs/ardour/midi_port.cc +++ b/libs/ardour/midi_port.cc @@ -33,6 +33,7 @@ MidiPort::MidiPort (const std::string& name, PortFlags flags) , _has_been_mixed_down (false) , _resolve_required (false) , _input_active (true) + , _always_parse (false) { _buffer = new MidiBuffer (AudioEngine::instance()->raw_buffer_size (DataType::MIDI)); } @@ -45,6 +46,8 @@ MidiPort::~MidiPort() void MidiPort::cycle_start (pframes_t nframes) { + framepos_t now = AudioEngine::instance()->sample_time_at_cycle_start(); + Port::cycle_start (nframes); _buffer->clear (); @@ -52,6 +55,24 @@ MidiPort::cycle_start (pframes_t nframes) if (sends_output ()) { port_engine.midi_clear (port_engine.get_buffer (_port_handle, nframes)); } + + if (_always_parse) { + MidiBuffer& mb (get_midi_buffer (nframes)); + + /* dump incoming MIDI to parser */ + + for (MidiBuffer::iterator b = mb.begin(); b != mb.end(); ++b) { + uint8_t* buf = (*b).buffer(); + + _self_parser.set_timestamp (now + (*b).time()); + + uint32_t limit = (*b).size(); + + for (size_t n = 0; n < limit; ++n) { + _self_parser.scanner (buf[n]); + } + } + } } MidiBuffer & @@ -67,11 +88,11 @@ MidiPort::get_midi_buffer (pframes_t nframes) void* buffer = port_engine.get_buffer (_port_handle, nframes); const pframes_t event_count = port_engine.get_midi_event_count (buffer); - + /* suck all relevant MIDI events from the MIDI port buffer into our MidiBuffer */ - + for (pframes_t i = 0; i < event_count; ++i) { pframes_t timestamp; @@ -137,13 +158,13 @@ MidiPort::resolve_notes (void* port_buffer, MidiBuffer::TimeType when) */ if (port_engine.midi_event_put (port_buffer, when, ev, 3) != 0) { - cerr << "failed to deliver sustain-zero on channel " << channel << " on port " << name() << endl; + cerr << "failed to deliver sustain-zero on channel " << (int)channel << " on port " << name() << endl; } ev[1] = MIDI_CTL_ALL_NOTES_OFF; if (port_engine.midi_event_put (port_buffer, 0, ev, 3) != 0) { - cerr << "failed to deliver ALL NOTES OFF on channel " << channel << " on port " << name() << endl; + cerr << "failed to deliver ALL NOTES OFF on channel " << (int)channel << " on port " << name() << endl; } } } @@ -153,12 +174,21 @@ MidiPort::flush_buffers (pframes_t nframes) { if (sends_output ()) { - void* port_buffer = port_engine.get_buffer (_port_handle, nframes); + void* port_buffer = 0; if (_resolve_required) { + port_buffer = port_engine.get_buffer (_port_handle, nframes); /* resolve all notes at the start of the buffer */ resolve_notes (port_buffer, 0); _resolve_required = false; + } + + if (_buffer->empty()) { + return; + } + + if (!port_buffer) { + port_buffer = port_engine.get_buffer (_port_handle, nframes); } for (MidiBuffer::iterator i = _buffer->begin(); i != _buffer->end(); ++i) { @@ -175,11 +205,16 @@ MidiPort::flush_buffers (pframes_t nframes) << ev.time() << " > " << _global_port_buffer_offset + _port_buffer_offset << endl; } } else { - cerr << "drop flushed event on the floor, time " << ev + cerr << "drop flushed event on the floor, time " << ev.time() << " to early for " << _global_port_buffer_offset << " + " << _port_buffer_offset << endl; } } + + /* done.. the data has moved to the port buffer, mark it so + */ + + _buffer->clear (); } } @@ -206,6 +241,7 @@ MidiPort::reset () { Port::reset (); delete _buffer; + cerr << name() << " new MIDI buffer of size " << AudioEngine::instance()->raw_buffer_size (DataType::MIDI) << endl; _buffer = new MidiBuffer (AudioEngine::instance()->raw_buffer_size (DataType::MIDI)); } @@ -214,3 +250,9 @@ MidiPort::set_input_active (bool yn) { _input_active = yn; } + +void +MidiPort::set_always_parse (bool yn) +{ + _always_parse = yn; +}