X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Fmidi_port.cc;h=2942aded75012b34e6b2114e5468bc5f38613642;hb=11f069f11869284b8f32bd3564abbb7cd63a4ff1;hp=8dcf4d42fc2f46049ac16560d2c5c400d53a139b;hpb=2588b1cac9a50353c65c671ee2a5efe569b96c36;p=ardour.git diff --git a/libs/ardour/midi_port.cc b/libs/ardour/midi_port.cc index 8dcf4d42fc..2942aded75 100644 --- a/libs/ardour/midi_port.cc +++ b/libs/ardour/midi_port.cc @@ -40,6 +40,7 @@ MidiPort::MidiPort (const std::string& name, PortFlags flags) , _resolve_required (false) , _input_active (true) , _always_parse (false) + , _trace_on (false) { _buffer = new MidiBuffer (AudioEngine::instance()->raw_buffer_size (DataType::MIDI)); } @@ -62,18 +63,18 @@ MidiPort::cycle_start (pframes_t nframes) port_engine.midi_clear (port_engine.get_buffer (_port_handle, nframes)); } - if (_always_parse) { + if (_always_parse || (receives_input() && _trace_on)) { 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]); } @@ -106,20 +107,24 @@ MidiPort::get_midi_buffer (pframes_t nframes) */ for (pframes_t i = 0; i < event_count; ++i) { - + pframes_t timestamp; size_t size; uint8_t* buf; - + port_engine.midi_event_get (timestamp, size, &buf, buffer, i); - + if (buf[0] == 0xfe) { /* throw away active sensing */ continue; + } else if ((buf[0] & 0xF0) == 0x90 && buf[2] == 0) { + /* normalize note on with velocity 0 to proper note off */ + buf[0] = 0x80 | (buf[0] & 0x0F); /* note off */ + buf[2] = 0x40; /* default velocity */ } - + /* check that the event is in the acceptable time range */ - + if ((timestamp >= (_global_port_buffer_offset + _port_buffer_offset)) && (timestamp < (_global_port_buffer_offset + _port_buffer_offset + nframes))) { _buffer->push_back (timestamp, size, buf); @@ -128,7 +133,7 @@ MidiPort::get_midi_buffer (pframes_t nframes) << _global_port_buffer_offset << " limit=" << (_global_port_buffer_offset + _port_buffer_offset + nframes) << "\n"; } - } + } } else { _buffer->silence (nframes); @@ -175,7 +180,7 @@ MidiPort::resolve_notes (void* port_buffer, MidiBuffer::TimeType when) ev[1] = MIDI_CTL_ALL_NOTES_OFF; - if (port_engine.midi_event_put (port_buffer, 0, ev, 3) != 0) { + if (port_engine.midi_event_put (port_buffer, when, ev, 3) != 0) { cerr << "failed to deliver ALL NOTES OFF on channel " << (int)channel << " on port " << name() << endl; } } @@ -187,14 +192,14 @@ MidiPort::flush_buffers (pframes_t nframes) if (sends_output ()) { 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_notes (port_buffer, _global_port_buffer_offset); _resolve_required = false; - } - + } + if (_buffer->empty()) { return; } @@ -203,25 +208,41 @@ MidiPort::flush_buffers (pframes_t nframes) port_buffer = port_engine.get_buffer (_port_handle, nframes); } + for (MidiBuffer::iterator i = _buffer->begin(); i != _buffer->end(); ++i) { const Evoral::MIDIEvent ev (*i, false); + + if (sends_output() && _trace_on) { + uint8_t const * const buf = ev.buffer(); + const framepos_t now = AudioEngine::instance()->sample_time_at_cycle_start(); + + _self_parser.set_timestamp (now + ev.time()); + + uint32_t limit = ev.size(); + + for (size_t n = 0; n < limit; ++n) { + _self_parser.scanner (buf[n]); + } + } + + // event times are in frames, relative to cycle start #ifndef NDEBUG - if (DEBUG::MidiIO & PBD::debug_bits) { - DEBUG_STR_DECL(a); - DEBUG_STR_APPEND(a, string_compose ("MidiPort %1 pop event @ %2 sz %3 ", _buffer, ev.time(), 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)(ev.buffer()[i])); - DEBUG_STR_APPEND(a,' '); - } - DEBUG_STR_APPEND(a,'\n'); - DEBUG_TRACE (DEBUG::MidiIO, DEBUG_STR(a).str()); - } + if (DEBUG_ENABLED (DEBUG::MidiIO)) { + DEBUG_STR_DECL(a); + DEBUG_STR_APPEND(a, string_compose ("MidiPort %1 pop event @ %2 sz %3 ", _buffer, ev.time(), 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)(ev.buffer()[i])); + DEBUG_STR_APPEND(a,' '); + } + DEBUG_STR_APPEND(a,'\n'); + DEBUG_TRACE (DEBUG::MidiIO, DEBUG_STR(a).str()); + } #endif assert (ev.time() < (nframes + _global_port_buffer_offset + _port_buffer_offset)); @@ -242,7 +263,7 @@ MidiPort::flush_buffers (pframes_t nframes) } } - /* done.. the data has moved to the port buffer, mark it so + /* done.. the data has moved to the port buffer, mark it so */ _buffer->clear (); @@ -287,3 +308,9 @@ MidiPort::set_always_parse (bool yn) { _always_parse = yn; } + +void +MidiPort::set_trace_on (bool yn) +{ + _trace_on = yn; +}