29 #include "midi++/parser.h"
46 , line_count_adjustment (200, 1, 2000, 1, 10)
47 , line_count_spinner (line_count_adjustment)
48 , line_count_label (
_(
"Line history: "))
51 , show_delta_time (false)
54 , buffer_pool (
"miditracer", buffer_size, 1024)
55 , autoscroll_button (
_(
"Auto-Scroll"))
56 , base_button (
_(
"Decimal"))
57 , collect_button (
_(
"Enabled"))
58 , delta_time_button (
_(
"Delta times"))
66 VBox* vbox = manage (
new VBox);
67 vbox->set_spacing (4);
69 HBox* pbox = manage (
new HBox);
70 pbox->set_spacing (6);
71 pbox->pack_start (*manage (
new Label (
_(
"Port:"))),
false,
false);
76 vbox->pack_start (*pbox,
false,
false);
79 vbox->set_border_width (12);
80 vbox->pack_start (
scroller,
true,
true);
83 text.set_name (
"MidiTracerTextView");
85 scroller.set_size_request (400, 400);
99 HBox* bbox = manage (
new HBox);
107 vbox->pack_start (*bbox,
false,
false);
143 for (ARDOUR::PortManager::PortList::const_iterator i = pl.begin(); i != pl.end(); ++i) {
164 std::cerr <<
"port not found\n";
212 gettimeofday (&tv, 0);
218 struct timeval delta;
220 s = snprintf (buf, bufsize,
"+%02" PRId64
":%06" PRId64, (int64_t) delta.tv_sec, (int64_t) delta.tv_usec);
224 s = strftime (buf, bufsize,
"%H:%M:%S", &now);
226 s += snprintf (&buf[s], bufsize,
".%06" PRId64, (int64_t) tv.tv_usec);
232 switch ((eventType) msg[0]&0xf0) {
235 s += snprintf (&buf[s], bufsize,
"%16s chn %2d %02x %02x\n",
"NoteOff", (msg[0]&0xf)+1, (
int) msg[1], (
int) msg[2]);
237 s += snprintf (&buf[s], bufsize,
"%16s chn %2d %-3d %-3d\n",
"NoteOff", (msg[0]&0xf)+1, (
int) msg[1], (
int) msg[2]);
243 s += snprintf (&buf[s], bufsize,
"%16s chn %2d %02x %02x\n",
"NoteOn", (msg[0]&0xf)+1, (
int) msg[1], (
int) msg[2]);
245 s += snprintf (&buf[s], bufsize,
"%16s chn %2d %-3d %-3d\n",
"NoteOn", (msg[0]&0xf)+1, (
int) msg[1], (
int) msg[2]);
251 s += snprintf (&buf[s], bufsize,
"%16s chn %2d %02x\n",
"PolyPressure", (msg[0]&0xf)+1, (
int) msg[1]);
253 s += snprintf (&buf[s], bufsize,
"%16s chn %2d %-3d\n",
"PolyPressure", (msg[0]&0xf)+1, (
int) msg[1]);
257 case MIDI::controller:
259 s += snprintf (&buf[s], bufsize,
"%16s chn %2d %02x %02x\n",
"Controller", (msg[0]&0xf)+1, (
int) msg[1], (
int) msg[2]);
261 s += snprintf (&buf[s], bufsize,
"%16s chn %2d %2d %-3d\n",
"Controller", (msg[0]&0xf)+1, (
int) msg[1], (
int) msg[2]);
267 s += snprintf (&buf[s], bufsize,
"%16s chn %2d %02x\n",
"Program Change", (msg[0]&0xf)+1, (
int) msg[1]);
269 s += snprintf (&buf[s], bufsize,
"%16s chn %2d %-3d\n",
"Program Change", (msg[0]&0xf)+1, (
int) msg[1]);
275 s += snprintf (&buf[s], bufsize,
"%16s chn %2d %02x/%-3d\n",
"Channel Pressure", (msg[0]&0xf)+1, (
int) msg[1], (
int) msg[1]);
277 s += snprintf (&buf[s], bufsize,
"%16s chn %2d %02x/%-3d\n",
"Channel Pressure", (msg[0]&0xf)+1, (
int) msg[1], (
int) msg[1]);
281 case MIDI::pitchbend:
283 s += snprintf (&buf[s], bufsize,
"%16s chn %2d %02x\n",
"Pitch Bend", (msg[0]&0xf)+1, (
int) msg[1]);
285 s += snprintf (&buf[s], bufsize,
"%16s chn %2d %-3d\n",
"Pitch Bend", (msg[0]&0xf)+1, (
int) msg[1]);
293 s += snprintf (&buf[s], bufsize,
"%16s\n",
"Clock");
296 s += snprintf (&buf[s], bufsize,
"%16s\n",
"Start");
299 s += snprintf (&buf[s], bufsize,
"%16s\n",
"Continue");
302 s += snprintf (&buf[s], bufsize,
"%16s\n",
"Stop");
305 s += snprintf (&buf[s], bufsize,
"%16s\n",
"Active Sense");
308 s += snprintf (&buf[s], bufsize,
"%16s\n",
"Reset");
311 s += snprintf (&buf[s], bufsize,
"%16s %02x\n",
"Sysex", (
int) msg[1]);
315 }
else if (len > 5 && msg[0] == 0xf0 && msg[1] == 0x7f && msg[3] == 0x06) {
318 if (cmd == 0x44 && msg[5] == 0x06 && msg[6] == 0x01) {
320 &buf[s], bufsize,
" MMC locate to %02d:%02d:%02d:%02d.%02d\n",
321 msg[7], msg[8], msg[9], msg[10], msg[11]
327 }
else if (cmd == 0x3) {
328 name =
"DEFERRED PLAY";
329 }
else if (cmd == 0x6) {
330 name =
"RECORD STROBE";
331 }
else if (cmd == 0x7) {
332 name =
"RECORD EXIT";
333 }
else if (cmd == 0x8) {
334 name =
"RECORD PAUSE";
337 s += snprintf (&buf[s], bufsize,
" MMC command %s\n", name.c_str());
339 s += snprintf (&buf[s], bufsize,
" MMC command %02x\n", cmd);
343 }
else if (len == 10 && msg[0] == 0xf0 && msg[1] == 0x7f && msg[9] == 0xf7) {
347 &buf[s], bufsize,
" MTC full frame to %02d:%02d:%02d:%02d\n", msg[5] & 0x1f, msg[6], msg[7], msg[8]
352 int midi_beats = (msg[2] << 7) | msg[1];
353 s += snprintf (&buf[s], bufsize,
"%16s %d\n",
"Position", (
int) midi_beats);
358 s += snprintf (&buf[s], bufsize,
"%16s (%d) = [",
"Sysex", (
int) len);
361 for (
unsigned int i = 0; i < len && bufsize > 3; ++i) {
363 s += snprintf (&buf[s], bufsize,
" %02x", msg[i]);
365 s += snprintf (&buf[s], bufsize,
"%02x", msg[i]);
369 s += snprintf (&buf[s], bufsize,
"]\n");
374 s += snprintf (&buf[s], bufsize,
"%16s\n",
"Song");
378 s += snprintf (&buf[s], bufsize,
"%16s\n",
"Tune");
382 s += snprintf (&buf[s], bufsize,
"%16s\n",
"EOX");
386 s += snprintf (&buf[s], bufsize,
"%16s\n",
"Timing");
390 s += snprintf (&buf[s], bufsize,
"%16s\n",
"Start");
394 s += snprintf (&buf[s], bufsize,
"%16s\n",
"Stop");
398 s += snprintf (&buf[s], bufsize,
"%16s\n",
"Continue");
402 s += snprintf (&buf[s], bufsize,
"%16s\n",
"Active Sense");
406 s += snprintf (&buf[s], bufsize,
"%16s\n",
"Unknown");
417 if (g_atomic_int_get (const_cast<gint*> (&
_update_queued)) == 0) {
426 bool updated =
false;
429 RefPtr<TextBuffer> buf (
text.get_buffer());
434 buf->erase (buf->begin(), buf->get_iter_at_line (excess));
440 buf->insert (buf->end(), string (str));
446 scroller.get_vadjustment()->set_value (
scroller.get_vadjustment()->get_upper());
boost::shared_ptr< ARDOUR::MidiPort > traced_port
Gtk::CheckButton collect_button
Gtk::SpinButton line_count_spinner
struct tm * localtime_r(const time_t *const timep, struct tm *p_tm)
shared_ptr< T > dynamic_pointer_cast(shared_ptr< U > const &r)
struct timeval _last_receipt
MIDI::Parser & self_parser()
Gtk::CheckButton delta_time_button
LIBARDOUR_API PBD::PropertyDescriptor< framepos_t > start
static AudioEngine * instance()
Gtk::CheckButton autoscroll_button
guint read(T *dest, guint cnt)
PBD::ScopedConnection _parser_connection
virtual void release(void *)
std::list< boost::shared_ptr< Port > > PortList
RingBuffer< char * > fifo
PBD::ScopedConnection _manager_connection
guint write(T const *src, guint cnt)
static const size_t buffer_size
Gtk::ScrolledWindow scroller
LIBARDOUR_API PBD::PropertyDescriptor< bool > active
volatile gint _update_queued
Gtk::ComboBoxText _port_combo
Gtk::Label line_count_label
LIBARDOUR_API PBD::PropertyDescriptor< framepos_t > position
void set_trace_on(bool yn)
PBD::Signal0< void > PortRegisteredOrUnregistered
Gtk::CheckButton base_button
void tracer(MIDI::Parser &, MIDI::byte *, size_t)
#define timersub(a, b, result)
Gtk::Adjustment line_count_adjustment
int get_ports(const std::string &port_name_pattern, DataType type, PortFlags flags, std::vector< std::string > &)