diff options
author | Paul Davis <paul@linuxaudiosystems.com> | 2009-12-09 03:05:14 +0000 |
---|---|---|
committer | Paul Davis <paul@linuxaudiosystems.com> | 2009-12-09 03:05:14 +0000 |
commit | c38e02285fda1fd7966c9e4ad85994445247e6a6 (patch) | |
tree | a5f46d4350b8df3e0a74558169c696cbb837ce7f /libs/midi++2 | |
parent | 90f95df20707995e267bd624b28980cfd9200bed (diff) |
major design changes: use glib event loop for MIDI thread/UI; rework design of BaseUI and AbstractUI; solo & mute are both temporarily broken; OSC control up next; may segfault during exit
git-svn-id: svn://localhost/ardour2/branches/3.0@6328 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs/midi++2')
-rw-r--r-- | libs/midi++2/coremidi_midiport.cc | 31 | ||||
-rw-r--r-- | libs/midi++2/jack_midiport.cc | 65 | ||||
-rw-r--r-- | libs/midi++2/manager.cc | 7 | ||||
-rw-r--r-- | libs/midi++2/midi++/jack.h | 25 | ||||
-rw-r--r-- | libs/midi++2/midi++/manager.h | 2 | ||||
-rw-r--r-- | libs/midi++2/midi++/port.h | 1 |
6 files changed, 85 insertions, 46 deletions
diff --git a/libs/midi++2/coremidi_midiport.cc b/libs/midi++2/coremidi_midiport.cc index e950da2949..4349ea45f4 100644 --- a/libs/midi++2/coremidi_midiport.cc +++ b/libs/midi++2/coremidi_midiport.cc @@ -122,22 +122,29 @@ void CoreMidi_MidiPort::read_proc (const MIDIPacketList *pktlist, void *refCon, if (driver->firstrecv) { driver->firstrecv = false; - PBD::notify_gui_about_thread_creation (pthread_self(), "COREMIDI"); + PBD::notify_gui_about_thread_creation ("gui", pthread_self(), "COREMIDI", 256); } for (unsigned int i = 0; i < pktlist->numPackets; ++i) { - - driver->bytes_read += packet->length; - + + driver->bytes_read += packet->length; + if (driver->input_parser) { - driver->input_parser->raw_preparse (*driver->input_parser, packet->data, packet->length); - for (int i = 0; i < packet->length; i++) { - driver->input_parser->scanner (packet->data[i]); - } - driver->input_parser->raw_postparse (*driver->input_parser, packet->data, packet->length); - } - - packet = MIDIPacketNext(packet); + //driver->input_parser->raw_preparse (*driver->input_parser, packet->data, packet->length); + + /* XXX This is technically the wrong timebase, since it is based on + host time. + */ + driver->input_parser->set_timestamp (packet->timestamp); + + for (int i = 0; i < packet->length; i++) { + driver->input_parser->scanner (packet->data[i]); + } + + //driver->input_parser->raw_postparse (*driver->input_parser, packet->data, packet->length); + } + + packet = MIDIPacketNext(packet); } } diff --git a/libs/midi++2/jack_midiport.cc b/libs/midi++2/jack_midiport.cc index ada72f1be6..9b96155b88 100644 --- a/libs/midi++2/jack_midiport.cc +++ b/libs/midi++2/jack_midiport.cc @@ -20,9 +20,11 @@ #include <fcntl.h> #include <cerrno> #include <cassert> +#include <cstring> #include <cstdlib> #include "pbd/error.h" +#include "pbd/compose.h" #include "midi++/types.h" #include "midi++/jack.h" @@ -39,11 +41,10 @@ JACK_MidiPort::JACK_MidiPort(const XMLNode& node, jack_client_t* jack_client) , _jack_input_port(NULL) , _jack_output_port(NULL) , _last_read_index(0) - , non_process_thread_fifo (512) + , output_fifo (512) + , input_fifo (1024) { - int err = create_ports (node); - - if (!err) { + if (!create_ports (node)) { _ok = true; } } @@ -82,19 +83,16 @@ JACK_MidiPort::cycle_start (nframes_t nframes) const nframes_t event_count = jack_midi_get_event_count(jack_buffer); jack_midi_event_t ev; - nframes_t cycle_start_frame = jack_last_frame_time (_jack_client); - - for (nframes_t i=0; i < event_count; ++i) { + timestamp_t cycle_start_frame = jack_last_frame_time (_jack_client); + for (nframes_t i = 0; i < event_count; ++i) { jack_midi_event_get (&ev, jack_buffer, i); - - if (input_parser) { - for (size_t i = 0; i < ev.size; i++) { - input_parser->set_timestamp (cycle_start_frame + ev.time); - input_parser->scanner (ev.buffer[i]); - } - } + input_fifo.write (cycle_start_frame + ev.time, (Evoral::EventType) 0, ev.size, ev.buffer); } + + if (event_count) { + xthread.wakeup (); + } } } @@ -104,6 +102,8 @@ JACK_MidiPort::cycle_end () if (_jack_output_port != 0) { flush (jack_port_get_buffer (_jack_output_port, _nframes_this_cycle)); } + + Port::cycle_end(); } int @@ -113,10 +113,10 @@ JACK_MidiPort::write(byte * msg, size_t msglen, timestamp_t timestamp) if (!is_process_thread()) { - Glib::Mutex::Lock lm (non_process_thread_fifo_lock); + Glib::Mutex::Lock lm (output_fifo_lock); RingBuffer< Evoral::Event<double> >::rw_vector vec; - non_process_thread_fifo.get_write_vector (&vec); + output_fifo.get_write_vector (&vec); if (vec.len[0] + vec.len[1] < 1) { error << "no space in FIFO for non-process thread MIDI write" << endmsg; @@ -129,10 +129,10 @@ JACK_MidiPort::write(byte * msg, size_t msglen, timestamp_t timestamp) vec.buf[1]->set (msg, msglen, timestamp); } - non_process_thread_fifo.increment_write_idx (1); + output_fifo.increment_write_idx (1); ret = msglen; - + } else { assert(_jack_output_port); @@ -164,11 +164,13 @@ JACK_MidiPort::write(byte * msg, size_t msglen, timestamp_t timestamp) } if (ret > 0 && output_parser) { - output_parser->raw_preparse (*output_parser, msg, ret); + // ardour doesn't care about this and neither should your app, probably + // output_parser->raw_preparse (*output_parser, msg, ret); for (int i = 0; i < ret; i++) { output_parser->scanner (msg[i]); } - output_parser->raw_postparse (*output_parser, msg, ret); + // ardour doesn't care about this and neither should your app, probably + // output_parser->raw_postparse (*output_parser, msg, ret); } return ret; @@ -180,7 +182,7 @@ JACK_MidiPort::flush (void* jack_port_buffer) RingBuffer< Evoral::Event<double> >::rw_vector vec; size_t written; - non_process_thread_fifo.get_read_vector (&vec); + output_fifo.get_read_vector (&vec); if (vec.len[0] + vec.len[1]) { // cerr << "Flush " << vec.len[0] + vec.len[1] << " events from non-process FIFO\n"; @@ -205,15 +207,28 @@ JACK_MidiPort::flush (void* jack_port_buffer) } if ((written = vec.len[0] + vec.len[1]) != 0) { - non_process_thread_fifo.increment_read_idx (written); + output_fifo.increment_read_idx (written); } } int -JACK_MidiPort::read(byte * buf, size_t bufsize) +JACK_MidiPort::read (byte * buf, size_t bufsize) { - cerr << "This program is improperly written. JACK_MidiPort::read() should never be called\n"; - abort (); + timestamp_t time; + Evoral::EventType type; + uint32_t size; + byte buffer[input_fifo.capacity()]; + + while (input_fifo.read (&time, &type, &size, buffer)) { + if (input_parser) { + input_parser->set_timestamp (time); + for (uint32_t i = 0; i < size; ++i) { + input_parser->scanner (buffer[i]); + } + } + } + + return 0; } int diff --git a/libs/midi++2/manager.cc b/libs/midi++2/manager.cc index b6bbd40b0b..ffc8f4e1bc 100644 --- a/libs/midi++2/manager.cc +++ b/libs/midi++2/manager.cc @@ -115,6 +115,8 @@ Manager::add_port (const XMLNode& node) outputPort = port; } + PortsChanged (); /* EMIT SIGNAL */ + return port; } @@ -124,11 +126,16 @@ Manager::remove_port (Port* port) if (inputPort == port) { inputPort = 0; } + if (outputPort == port) { outputPort = 0; } + _ports.remove (port); delete port; + + PortsChanged (); /* EMIT SIGNAL */ + return 0; } diff --git a/libs/midi++2/midi++/jack.h b/libs/midi++2/midi++/jack.h index a449a8c554..18a6f3df68 100644 --- a/libs/midi++2/midi++/jack.h +++ b/libs/midi++2/midi++/jack.h @@ -30,9 +30,13 @@ #include <glibmm/thread.h> -#include "pbd/ringbuffer.h" #include <jack/jack.h> #include <jack/midiport.h> + +#include "pbd/ringbuffer.h" +#include "pbd/crossthread.h" +#include "evoral/EventRingBuffer.hpp" + #include "midi++/port.h" #include "midi++/event.h" @@ -49,16 +53,16 @@ public: int write(byte *msg, size_t msglen, timestamp_t timestamp); int read(byte *buf, size_t max); - /* No select(2)/poll(2)-based I/O */ - virtual int selectable() const { return -1; } + int selectable() const { return xthread.selectable(); } + bool must_drain_selectable() const { return true; } - virtual void cycle_start(nframes_t nframes); - virtual void cycle_end(); + void cycle_start(nframes_t nframes); + void cycle_end(); static std::string typestring; - virtual XMLNode& get_state () const; - virtual void set_state (const XMLNode&); + XMLNode& get_state () const; + void set_state (const XMLNode&); static void set_process_thread (pthread_t); static pthread_t get_process_thread () { return _process_thread; } @@ -79,13 +83,16 @@ private: jack_port_t* _jack_output_port; nframes_t _last_read_index; timestamp_t _last_write_timestamp; + CrossThreadChannel xthread; void flush (void* jack_port_buffer); static pthread_t _process_thread; - RingBuffer< Evoral::Event<double> > non_process_thread_fifo; - Glib::Mutex non_process_thread_fifo_lock; + RingBuffer< Evoral::Event<double> > output_fifo; + Evoral::EventRingBuffer<timestamp_t> input_fifo; + + Glib::Mutex output_fifo_lock; }; diff --git a/libs/midi++2/midi++/manager.h b/libs/midi++2/midi++/manager.h index 0698e969c0..8c665d0086 100644 --- a/libs/midi++2/midi++/manager.h +++ b/libs/midi++2/midi++/manager.h @@ -83,6 +83,8 @@ class Manager { int get_known_ports (std::vector<PortSet>&); + sigc::signal<void> PortsChanged; + private: /* This is a SINGLETON pattern */ diff --git a/libs/midi++2/midi++/port.h b/libs/midi++2/midi++/port.h index 1bab068f85..23a9a01200 100644 --- a/libs/midi++2/midi++/port.h +++ b/libs/midi++2/midi++/port.h @@ -112,6 +112,7 @@ class Port : public sigc::trackable { * @return File descriptor, or -1 if not selectable. */ virtual int selectable() const = 0; + virtual bool must_drain_selectable() const { return false; } static void gtk_read_callback (void *ptr, int fd, int cond); static void write_callback (byte *msg, unsigned int len, void *); |