Introduce "virtual" async MIDI ports
authorRobin Gareus <robin@gareus.org>
Sun, 23 Oct 2016 20:25:40 +0000 (22:25 +0200)
committerRobin Gareus <robin@gareus.org>
Sun, 23 Oct 2016 20:25:40 +0000 (22:25 +0200)
This allows to flush an async MIDI port's ringbuffer at cycle-start,
to makes its data available as "input/source" during process(), while
collecting data in the background for the next cycle.

This facilitates virtual MIDI Ports for eg. Control Surface Pads:
output from a surface, input to Ardour channels.

libs/ardour/ardour/async_midi_port.h
libs/ardour/async_midi_port.cc

index 46d5f94a91b315368b89ca3d7081371b4bf56ffd..4e578b5ed1e1573cfb065cbe8b6e9c41699aa5f1 100644 (file)
@@ -47,8 +47,10 @@ class LIBARDOUR_API AsyncMIDIPort : public ARDOUR::MidiPort, public MIDI::Port {
                AsyncMIDIPort (std::string const &, PortFlags);
                ~AsyncMIDIPort ();
 
-               /* called from an RT context */
+               bool flush_at_cycle_start () const { return _flush_at_cycle_start; }
+               void set_flush_at_cycle_start (bool en) { _flush_at_cycle_start = en; }
 
+               /* called from an RT context */
                void cycle_start (pframes_t nframes);
                void cycle_end (pframes_t nframes);
 
@@ -79,6 +81,7 @@ class LIBARDOUR_API AsyncMIDIPort : public ARDOUR::MidiPort, public MIDI::Port {
        private:
                bool                    _currently_in_cycle;
                MIDI::timestamp_t       _last_write_timestamp;
+               bool                    _flush_at_cycle_start;
                bool                    have_timer;
                boost::function<framecnt_t (void)> timer;
                RingBuffer< Evoral::Event<double> > output_fifo;
index eee585fd96f1603923d5a6fb6aa394b1d8166eb3..388aaf1935ca8f8daf3ad0b44a12a65333e1242b 100644 (file)
@@ -46,6 +46,7 @@ AsyncMIDIPort::AsyncMIDIPort (string const & name, PortFlags flags)
        , MIDI::Port (name, MIDI::Port::Flags (0))
        , _currently_in_cycle (false)
        , _last_write_timestamp (0)
+       , _flush_at_cycle_start (false)
        , have_timer (false)
        , output_fifo (2048)
        , input_fifo (1024)
@@ -119,6 +120,9 @@ AsyncMIDIPort::cycle_start (MIDI::pframes_t nframes)
 
        if (ARDOUR::Port::sends_output()) {
                flush_output_fifo (nframes);
+               if (_flush_at_cycle_start) {
+                       flush_buffers (nframes);
+               }
        }
 
        /* copy incoming data from the port buffer into the input FIFO
@@ -152,7 +156,7 @@ AsyncMIDIPort::cycle_start (MIDI::pframes_t nframes)
 void
 AsyncMIDIPort::cycle_end (MIDI::pframes_t nframes)
 {
-       if (ARDOUR::Port::sends_output()) {
+       if (ARDOUR::Port::sends_output() && !_flush_at_cycle_start) {
                /* move any additional data from output FIFO into the port
                   buffer.
                */