From e05c5791e829481704ba0ac267a2be3d0c96c7b0 Mon Sep 17 00:00:00 2001 From: paul Date: Mon, 1 Feb 2010 03:33:52 +0000 Subject: [PATCH] improve efficiency of MIDI tracer window with a lock-free FIFO and lock-free msg pool and buffered queing; use a monospace font too git-svn-id: http://subversion.ardour.org/svn/ardour2/ardour2/branches/3.0@6603 d708f5d6-7413-0410-9779-e7cbd77b26cf --- gtk2_ardour/ardour3_ui_dark.rc.in | 13 ++++++++++- gtk2_ardour/midi_tracer.cc | 48 ++++++++++++++++++++++++++++----------- gtk2_ardour/midi_tracer.h | 8 ++++++- 3 files changed, 54 insertions(+), 15 deletions(-) diff --git a/gtk2_ardour/ardour3_ui_dark.rc.in b/gtk2_ardour/ardour3_ui_dark.rc.in index 0e81e576e..cea780a76 100644 --- a/gtk2_ardour/ardour3_ui_dark.rc.in +++ b/gtk2_ardour/ardour3_ui_dark.rc.in @@ -27,6 +27,11 @@ style "medium_text" font_name = "@FONT_NORMAL@" } +style "medium_monospace_text" +{ + font_name = "@FONT_MONOSPACE_NORMAL@" +} + style "red_medium_text" = "medium_text" { fg[NORMAL] = { 1.0, 0, 0 } @@ -76,6 +81,11 @@ style "marker_text" font_name = "@FONT_SMALL@" } +style "midi_tracer_textview" = "medium_monospace_text" +{ + +} + style "time_axis_view_item_name" { font_name = "@FONT_SMALLER@" @@ -1669,4 +1679,5 @@ widget "*OddPortGroups" style:highest "odd_port_groups" widget "*EvenPortGroups" style:highest "even_port_groups" widget "*MidiListView*" style:highest "white_tree_view" widget "*ProcessorSelector*" style:highest "processor_list_display" -widget "*PortMatrixLabel*" style:highest "small_text" \ No newline at end of file +widget "*PortMatrixLabel*" style:highest "small_text" +widget "*MidiTracerTextView" style:highest "midi_tracer_textview" diff --git a/gtk2_ardour/midi_tracer.cc b/gtk2_ardour/midi_tracer.cc index f294b73ce..e78271e01 100644 --- a/gtk2_ardour/midi_tracer.cc +++ b/gtk2_ardour/midi_tracer.cc @@ -25,6 +25,9 @@ MidiTracer::MidiTracer (const std::string& name, Parser& p) , autoscroll (true) , show_hex (true) , collect (true) + , update_queued (false) + , fifo (1024) + , buffer_pool ("miditracer", buffer_size, 1024) // 1024 256 byte buffers , autoscroll_button (_("Auto-Scroll")) , base_button (_("Decimal")) , collect_button (_("Enabled")) @@ -34,6 +37,7 @@ MidiTracer::MidiTracer (const std::string& name, Parser& p) get_vbox()->pack_start (scroller, true, true); text.show (); + text.set_name ("MidiTracerTextView"); scroller.show (); scroller.set_size_request (400, 400); @@ -65,6 +69,7 @@ MidiTracer::MidiTracer (const std::string& name, Parser& p) connect (); } + MidiTracer::~MidiTracer() { } @@ -87,7 +92,7 @@ MidiTracer::tracer (Parser&, byte* msg, size_t len) { stringstream ss; struct timeval tv; - char buf[256]; + char* buf; struct tm now; size_t bufsize; size_t s; @@ -95,11 +100,14 @@ MidiTracer::tracer (Parser&, byte* msg, size_t len) gettimeofday (&tv, 0); localtime_r (&tv.tv_sec, &now); - s = strftime (buf, sizeof (buf), "%H:%M:%S", &now); - bufsize = sizeof (buf) - s; - s += snprintf (&buf[s], bufsize, ".%-9" PRId64, (int64_t) tv.tv_usec); - bufsize = sizeof (buf) - s; - + buf = (char *) buffer_pool.alloc (); + bufsize = buffer_size; + + s = strftime (buf, bufsize, "%H:%M:%S", &now); + bufsize -= s; + s = snprintf (&buf[s], bufsize, ".%-9" PRId64, (int64_t) tv.tv_usec); + bufsize -= s; + switch ((eventType) msg[0]&0xf0) { case off: if (show_hex) { @@ -182,10 +190,10 @@ MidiTracer::tracer (Parser&, byte* msg, size_t len) s += snprintf (&buf[s], bufsize, "%16s %02x\n", "Sysex", (int) msg[1]); break; } - bufsize = sizeof (buf) - s; + bufsize -= s; } else { s += snprintf (&buf[s], bufsize, " %16s (%d) = [", "Sysex", (int) len); - bufsize = sizeof (buf) - s; + bufsize -= s; for (unsigned int i = 0; i < len && s < sizeof (buf)-3; ++i) { if (i > 0) { @@ -237,14 +245,22 @@ MidiTracer::tracer (Parser&, byte* msg, size_t len) } // If you want to append more to the line, uncomment this first - // bufsize = sizeof (buf) - s; + // bufsize -= s; + + fifo.write (&buf, 1); - gui_context()->call_slot (boost::bind (&MidiTracer::add_string, this, string (buf))); + if (!update_queued) { + gui_context()->call_slot (boost::bind (&MidiTracer::update, this)); + update_queued = true; + } } void -MidiTracer::add_string (std::string s) +MidiTracer::update () { + bool updated = false; + update_queued = false; + RefPtr buf (text.get_buffer()); int excess = buf->get_line_count() - line_count_adjustment.get_value(); @@ -253,9 +269,15 @@ MidiTracer::add_string (std::string s) buf->erase (buf->begin(), buf->get_iter_at_line (excess)); } - buf->insert (buf->end(), s); + char *str; + + while (fifo.read (&str, 1)) { + buf->insert (buf->end(), string (str)); + buffer_pool.release (str); + updated = true; + } - if (autoscroll) { + if (updated && autoscroll) { scroller.get_vadjustment()->set_value (scroller.get_vadjustment()->get_upper()); } } diff --git a/gtk2_ardour/midi_tracer.h b/gtk2_ardour/midi_tracer.h index 58cdd6776..a3429e926 100644 --- a/gtk2_ardour/midi_tracer.h +++ b/gtk2_ardour/midi_tracer.h @@ -9,6 +9,8 @@ #include #include "pbd/signals.h" +#include "pbd/ringbuffer.h" +#include "pbd/pool.h" #include "midi++/types.h" #include "ardour_dialog.h" @@ -34,9 +36,13 @@ class MidiTracer : public ArdourDialog bool autoscroll; bool show_hex; bool collect; + volatile bool update_queued; + RingBuffer fifo; + Pool buffer_pool; + static const size_t buffer_size = 256; void tracer (MIDI::Parser&, MIDI::byte*, size_t); - void add_string (std::string); + void update (); Gtk::ToggleButton autoscroll_button; Gtk::ToggleButton base_button; -- 2.11.4.GIT