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: svn://localhost/ardour2/branches/3.0@6603 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
Paul Davis 2010-02-01 03:33:52 +00:00
parent beb4a36016
commit 85eb944c83
3 changed files with 54 additions and 15 deletions

View File

@ -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"
widget "*PortMatrixLabel*" style:highest "small_text"
widget "*MidiTracerTextView" style:highest "midi_tracer_textview"

View File

@ -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;
gui_context()->call_slot (boost::bind (&MidiTracer::add_string, this, string (buf)));
fifo.write (&buf, 1);
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<TextBuffer> 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;
if (autoscroll) {
while (fifo.read (&str, 1)) {
buf->insert (buf->end(), string (str));
buffer_pool.release (str);
updated = true;
}
if (updated && autoscroll) {
scroller.get_vadjustment()->set_value (scroller.get_vadjustment()->get_upper());
}
}

View File

@ -9,6 +9,8 @@
#include <gtkmm/label.h>
#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<char *> 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;