diff options
-rw-r--r-- | src/Configuration.cpp | 6 | ||||
-rw-r--r-- | src/Configuration.hpp | 4 | ||||
-rw-r--r-- | src/JackDriver.cpp | 39 | ||||
-rw-r--r-- | src/JackDriver.hpp | 2 | ||||
-rw-r--r-- | src/Patchage.cpp | 87 | ||||
-rw-r--r-- | src/Patchage.hpp | 14 | ||||
-rw-r--r-- | src/patchage.ui | 161 |
7 files changed, 275 insertions, 38 deletions
diff --git a/src/Configuration.cpp b/src/Configuration.cpp index 3c4b5f0..8653591 100644 --- a/src/Configuration.cpp +++ b/src/Configuration.cpp @@ -38,6 +38,7 @@ Configuration::Configuration() , _window_size(640, 480) , _zoom(1.0) , _font_size(12.0) + , _show_toolbar(true) { _port_colors[JACK_AUDIO] = _default_port_colors[JACK_AUDIO] = 0x244678FF; _port_colors[JACK_MIDI] = _default_port_colors[JACK_MIDI] = 0x960909FF; @@ -164,7 +165,7 @@ Configuration::load() while (file.good()) { std::string key; if (file.peek() == '\"') { - /* Old versions ommitted the module_position key and listed + /* Old versions omitted the module_position key and listed positions starting with module name in quotes. */ key = "module_position"; } else { @@ -179,6 +180,8 @@ Configuration::load() file >> _zoom; } else if (key == "font_size") { file >> _font_size; + } else if (key == "show_toolbar") { + file >> _show_toolbar; } else if (key == "port_color") { std::string type_name; uint32_t rgba; @@ -275,6 +278,7 @@ Configuration::save() file << "window_size " << _window_size.x << " " << _window_size.y << std::endl; file << "zoom_level " << _zoom << std::endl; file << "font_size " << _font_size << std::endl; + file << "show_toolbar " << _show_toolbar << std::endl; file << std::hex << std::uppercase; for (int i = 0; i < N_PORT_TYPES; ++i) { diff --git a/src/Configuration.hpp b/src/Configuration.hpp index 1fc786b..06c5978 100644 --- a/src/Configuration.hpp +++ b/src/Configuration.hpp @@ -56,6 +56,9 @@ public: float get_font_size() const { return _font_size; } void set_font_size(float font_size) { _font_size = font_size; } + float get_show_toolbar() const { return _show_toolbar; } + void set_show_toolbar(float show_toolbar) { _show_toolbar = show_toolbar; } + uint32_t get_port_color(PortType type) const { return _port_colors[type]; } void set_port_color(PortType type, uint32_t rgba) { _port_colors[type] = rgba; @@ -84,6 +87,7 @@ private: Coord _window_size; float _zoom; float _font_size; + bool _show_toolbar; }; #endif // PATCHAGE_CONFIGURATION_HPP diff --git a/src/JackDriver.cpp b/src/JackDriver.cpp index db06480..bb40647 100644 --- a/src/JackDriver.cpp +++ b/src/JackDriver.cpp @@ -86,14 +86,6 @@ JackDriver::attach(bool launch_daemon) signal_attached.emit(); std::stringstream ss; _app->info_msg("Jack: Attached."); - const jack_nframes_t buffer_size = this->buffer_size(); - const jack_nframes_t sample_rate = this->sample_rate(); - if (sample_rate != 0) { - const int latency_ms = lrintf((buffer_size * 1000 / (float)sample_rate)); - ss << "Jack: Latency: " << buffer_size << " frames @ " - << (sample_rate / 1000) << "kHz (" << latency_ms << "ms)."; - _app->info_msg(ss.str()); - } } else { _app->error_msg("Jack: Client activation failed."); _is_activated = false; @@ -463,9 +455,6 @@ JackDriver::jack_xrun_cb(void* jack_driver) ++me->_xruns; me->_xrun_delay = jack_get_xrun_delayed_usecs(me->_client); - me->_app->warning_msg((format("Jack: xrun of %1%ms.") - % me->_xrun_delay).str()); - jack_reset_max_delayed_usecs(me->_client); return 0; @@ -499,6 +488,34 @@ JackDriver::reset_xruns() _xrun_delay = 0; } +float +JackDriver::get_max_dsp_load() +{ + float max_load = 0.0f; + if (_client) { + const float max_delay = jack_get_max_delayed_usecs(_client); + const float rate = sample_rate(); + const float size = buffer_size(); + const float period = size / rate * 1000000; // usec + + if (max_delay > period) { + max_load = 1.0; + jack_reset_max_delayed_usecs(_client); + } else { + max_load = max_delay / period; + } + } + return max_load; +} + +void +JackDriver::reset_max_dsp_load() +{ + if (_client) { + jack_reset_max_delayed_usecs(_client); + } +} + bool JackDriver::set_buffer_size(jack_nframes_t size) { diff --git a/src/JackDriver.hpp b/src/JackDriver.hpp index 9722f0f..1789704 100644 --- a/src/JackDriver.hpp +++ b/src/JackDriver.hpp @@ -67,6 +67,8 @@ public: uint32_t get_xruns() { return _xruns; } void reset_xruns(); + float get_max_dsp_load(); + void reset_max_dsp_load(); jack_client_t* client() { return _client; } diff --git a/src/Patchage.cpp b/src/Patchage.cpp index 6c47eb8..85d950f 100644 --- a/src/Patchage.cpp +++ b/src/Patchage.cpp @@ -101,7 +101,7 @@ Patchage::Patchage(int argc, char** argv) , INIT_WIDGET(_menu_save_close_session) , INIT_WIDGET(_menu_view_arrange) , INIT_WIDGET(_menu_view_messages) - , INIT_WIDGET(_menu_view_legend) + , INIT_WIDGET(_menu_view_toolbar) , INIT_WIDGET(_menu_view_refresh) , INIT_WIDGET(_menu_view_human_names) , INIT_WIDGET(_menu_zoom_in) @@ -114,6 +114,11 @@ Patchage::Patchage(int argc, char** argv) , INIT_WIDGET(_messages_clear_but) , INIT_WIDGET(_messages_close_but) , INIT_WIDGET(_messages_win) + , INIT_WIDGET(_toolbar) + , INIT_WIDGET(_clear_load_but) + , INIT_WIDGET(_xrun_progress) + , INIT_WIDGET(_latency_label) + , INIT_WIDGET(_legend_alignment) , INIT_WIDGET(_status_text) , _legend(NULL) , _attach(true) @@ -164,6 +169,9 @@ Patchage::Patchage(int argc, char** argv) _main_scrolledwin->signal_scroll_event().connect( sigc::mem_fun(this, &Patchage::on_scroll)); + _clear_load_but->signal_clicked().connect( + sigc::mem_fun(this, &Patchage::clear_load)); + #ifdef PATCHAGE_JACK_SESSION _menu_open_session->signal_activate().connect( sigc::mem_fun(this, &Patchage::show_open_session_dialog)); @@ -197,8 +205,8 @@ Patchage::Patchage(int argc, char** argv) sigc::mem_fun(this, &Patchage::on_arrange)); _menu_view_messages->signal_activate().connect( sigc::mem_fun(this, &Patchage::on_show_messages)); - _menu_view_legend->signal_activate().connect( - sigc::mem_fun(this, &Patchage::on_view_legend)); + _menu_view_toolbar->signal_activate().connect( + sigc::mem_fun(this, &Patchage::on_view_toolbar)); _menu_help_about->signal_activate().connect( sigc::mem_fun(this, &Patchage::on_help_about)); _menu_zoom_in->signal_activate().connect( @@ -248,8 +256,9 @@ Patchage::Patchage(int argc, char** argv) _legend = new Legend(*_conf); _legend->signal_color_changed.connect( sigc::mem_fun(this, &Patchage::on_legend_color_change)); - _main_vbox->pack_end(*Gtk::manage(_legend), false, false); - + _legend_alignment->add(*Gtk::manage(_legend)); + _legend->show_all(); + _about_win->set_transient_for(*_main_win); #if defined(PATCHAGE_LIBJACK) || defined(HAVE_JACK_DBUS) @@ -268,6 +277,7 @@ Patchage::Patchage(int argc, char** argv) connect_widgets(); update_state(); + _menu_view_toolbar->set_active(_conf->get_show_toolbar()); _canvas->widget().grab_focus(); @@ -328,6 +338,7 @@ Patchage::attach() _enable_refresh = true; refresh(); + update_toolbar(); } bool @@ -370,6 +381,53 @@ Patchage::idle_callback() _refresh = false; _driver_detached = false; + // Update load every 5 idle callbacks + static int count = 0; + if (++count == 5) { + update_load(); + count = 0; + } + + return true; +} + +void +Patchage::update_toolbar() +{ +#if defined(PATCHAGE_LIBJACK) || defined(HAVE_JACK_DBUS) + if (_jack_driver->is_attached()) { + const jack_nframes_t buffer_size = _jack_driver->buffer_size(); + const jack_nframes_t sample_rate = _jack_driver->sample_rate(); + if (sample_rate != 0) { + const int latency_ms = lrintf(buffer_size * 1000 / (float)sample_rate); + std::stringstream ss; + ss << buffer_size << " frames @ " + << (sample_rate / 1000) << "kHz (" << latency_ms << "ms)"; + _latency_label->set_label(ss.str()); + _latency_label->set_visible(true); + return; + } + } +#endif + _latency_label->set_visible(false); +} + +bool +Patchage::update_load() +{ +#if defined(PATCHAGE_LIBJACK) || defined(HAVE_JACK_DBUS) + if (_jack_driver->is_attached()) { + char buf[8]; + snprintf(tmp_buf, sizeof(tmp_buf), "%u", _jack_driver->get_xruns()); + _xrun_progress->set_text(std::string(tmp_buf) + " Dropouts"); + + const float max_dsp_load = _jack_driver->get_max_dsp_load(); + if (max_dsp_load != last_max_dsp_load) { + _xrun_progress->set_fraction(max_dsp_load); + } + } +#endif + return true; } @@ -415,6 +473,16 @@ Patchage::store_window_location() } void +Patchage::clear_load() +{ +#if defined(PATCHAGE_LIBJACK) || defined(HAVE_JACK_DBUS) + _xrun_progress->set_fraction(0.0); + _jack_driver->reset_xruns(); + _jack_driver->reset_max_dsp_load(); +#endif +} + +void Patchage::error_msg(const std::string& msg) { Glib::RefPtr<Gtk::TextBuffer> buffer = _status_text->get_buffer(); @@ -833,13 +901,14 @@ Patchage::on_show_messages() } void -Patchage::on_view_legend() +Patchage::on_view_toolbar() { - if (_menu_view_legend->get_active()) { - _legend->show(); + if (_menu_view_toolbar->get_active()) { + _toolbar->show(); } else { - _legend->hide(); + _toolbar->hide(); } + _conf->set_show_toolbar(_menu_view_toolbar->get_active()); } bool diff --git a/src/Patchage.hpp b/src/Patchage.hpp index f620fa4..06cbace 100644 --- a/src/Patchage.hpp +++ b/src/Patchage.hpp @@ -23,6 +23,7 @@ #include <boost/shared_ptr.hpp> #include <gtkmm/aboutdialog.h> +#include <gtkmm/alignment.h> #include <gtkmm/builder.h> #include <gtkmm/button.h> #include <gtkmm/checkmenuitem.h> @@ -35,6 +36,8 @@ #include <gtkmm/progressbar.h> #include <gtkmm/scrolledwindow.h> #include <gtkmm/textview.h> +#include <gtkmm/toolbar.h> +#include <gtkmm/toolbutton.h> #include <gtkmm/viewport.h> #include <gtkmm/window.h> @@ -97,7 +100,7 @@ protected: void on_quit(); void on_export_dot(); void on_show_messages(); - void on_view_legend(); + void on_view_toolbar(); void on_store_positions(); void on_view_human_names(); void on_zoom_in(); @@ -113,7 +116,9 @@ protected: void zoom(double z); bool idle_callback(); + void clear_load(); bool update_load(); + void update_toolbar(); void buffer_size_changed(); @@ -153,7 +158,7 @@ protected: Widget<Gtk::MenuItem> _menu_save_close_session; Widget<Gtk::MenuItem> _menu_view_arrange; Widget<Gtk::MenuItem> _menu_view_messages; - Widget<Gtk::CheckMenuItem> _menu_view_legend; + Widget<Gtk::CheckMenuItem> _menu_view_toolbar; Widget<Gtk::MenuItem> _menu_view_refresh; Widget<Gtk::CheckMenuItem> _menu_view_human_names; Widget<Gtk::ImageMenuItem> _menu_zoom_in; @@ -166,6 +171,11 @@ protected: Widget<Gtk::Button> _messages_clear_but; Widget<Gtk::Button> _messages_close_but; Widget<Gtk::Dialog> _messages_win; + Widget<Gtk::Toolbar> _toolbar; + Widget<Gtk::ToolButton> _clear_load_but; + Widget<Gtk::ProgressBar> _xrun_progress; + Widget<Gtk::Label> _latency_label; + Widget<Gtk::Alignment> _legend_alignment; Widget<Gtk::TextView> _status_text; Legend* _legend; diff --git a/src/patchage.ui b/src/patchage.ui index b23e915..c8f7a25 100644 --- a/src/patchage.ui +++ b/src/patchage.ui @@ -1,6 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> <interface> <requires lib="gtk+" version="2.16"/> + <!-- interface-naming-policy toplevel-contextual --> <object class="GtkAboutDialog" id="about_win"> <property name="can_focus">False</property> <property name="destroy_with_parent">True</property> @@ -693,10 +694,10 @@ Nedko Arnaudov <nedko@arnaudov.name></property> Lapo Calamandrei</property> <property name="logo_icon_name">patchage</property> <child internal-child="vbox"> - <object class="GtkBox" id="dialog-vbox1"> + <object class="GtkVBox" id="dialog-vbox1"> <property name="can_focus">False</property> <child internal-child="action_area"> - <object class="GtkButtonBox" id="dialog-action_area1"> + <object class="GtkHButtonBox" id="dialog-action_area1"> <property name="can_focus">False</property> </object> <packing> @@ -889,14 +890,14 @@ Nedko Arnaudov <nedko@arnaudov.name></property> </object> </child> <child> - <object class="GtkCheckMenuItem" id="menu_view_legend"> + <object class="GtkCheckMenuItem" id="menu_view_toolbar"> <property name="use_action_appearance">False</property> <property name="visible">True</property> <property name="can_focus">False</property> - <property name="label" translatable="yes">_Legend...</property> + <property name="label" translatable="yes">_Toolbar...</property> <property name="use_underline">True</property> - <property name="active">False</property> - <accelerator key="L" signal="activate" modifiers="GDK_CONTROL_MASK"/> + <property name="active">True</property> + <accelerator key="t" signal="activate" modifiers="GDK_CONTROL_MASK"/> </object> </child> <child> @@ -930,8 +931,8 @@ Nedko Arnaudov <nedko@arnaudov.name></property> <property name="can_focus">False</property> <property name="use_underline">True</property> <property name="use_stock">True</property> - <accelerator key="plus" signal="activate" modifiers="GDK_CONTROL_MASK"/> <accelerator key="equal" signal="activate" modifiers="GDK_CONTROL_MASK"/> + <accelerator key="plus" signal="activate" modifiers="GDK_CONTROL_MASK"/> </object> </child> <child> @@ -975,30 +976,30 @@ Nedko Arnaudov <nedko@arnaudov.name></property> </child> <child> <object class="GtkMenuItem" id="menu_increase_font_size"> - <property name="label" translatable="yes">_Increase Font Size</property> <property name="use_action_appearance">False</property> <property name="visible">True</property> <property name="can_focus">False</property> + <property name="label" translatable="yes">_Increase Font Size</property> <property name="use_underline">True</property> <accelerator key="Up" signal="activate" modifiers="GDK_CONTROL_MASK"/> </object> </child> <child> <object class="GtkMenuItem" id="menu_decrease_font_size"> - <property name="label" translatable="yes">_Decrease Font Size</property> <property name="use_action_appearance">False</property> <property name="visible">True</property> <property name="can_focus">False</property> + <property name="label" translatable="yes">_Decrease Font Size</property> <property name="use_underline">True</property> <accelerator key="Down" signal="activate" modifiers="GDK_CONTROL_MASK"/> </object> </child> <child> <object class="GtkMenuItem" id="menu_normal_font_size"> - <property name="label" translatable="yes">_Normal Font Size</property> <property name="use_action_appearance">False</property> <property name="visible">True</property> <property name="can_focus">False</property> + <property name="label" translatable="yes">_Normal Font Size</property> <property name="use_underline">True</property> <accelerator key="1" signal="activate" modifiers="GDK_CONTROL_MASK"/> </object> @@ -1070,6 +1071,138 @@ Nedko Arnaudov <nedko@arnaudov.name></property> </packing> </child> <child> + <object class="GtkToolbar" id="toolbar"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="toolbar_style">icons</property> + <property name="show_arrow">False</property> + <property name="icon_size">1</property> + <property name="icon_size_set">True</property> + <child> + <object class="GtkToolButton" id="clear_load_but"> + <property name="use_action_appearance">False</property> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="has_tooltip">True</property> + <property name="tooltip_markup">Clear the dropout indicator</property> + <property name="tooltip_text" translatable="yes">Clear dropout indicator.</property> + <property name="stock_id">gtk-clear</property> + </object> + <packing> + <property name="expand">False</property> + <property name="homogeneous">True</property> + </packing> + </child> + <child> + <object class="GtkToolItem" id="toolitem30"> + <property name="use_action_appearance">False</property> + <property name="visible">True</property> + <property name="can_focus">False</property> + <child> + <object class="GtkAlignment" id="alignment3"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="yscale">0</property> + <child> + <object class="GtkProgressBar" id="xrun_progress"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="has_tooltip">True</property> + <property name="tooltip_markup">Drouput (XRun) Indicator + +The bar represents the percentage of available time used for audio processing (i.e. the DSP load). If the bar reaches 100%, a dropout will occur.</property> + <property name="tooltip_text" translatable="yes">Load and dropout gauge. The bar shows the percentage of available time used for audio processing. If it reaches 100%, a dropout will occur, and the bar is reset. Click to reset.</property> + <property name="show_text">True</property> + <property name="pulse_step">0.10000000149</property> + <property name="text" translatable="yes">0 Dropouts</property> + <property name="discrete_blocks">100</property> + </object> + </child> + </object> + </child> + </object> + <packing> + <property name="expand">False</property> + </packing> + </child> + <child> + <object class="GtkToolItem" id="toolitem28"> + <property name="use_action_appearance">False</property> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="visible_vertical">False</property> + <child> + <object class="GtkAlignment" id="alignment2"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="tooltip_text" translatable="yes">Jack buffer size and sample rate.</property> + <property name="yscale">0</property> + <child> + <object class="GtkHBox" id="hbox4"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <child> + <object class="GtkLabel" id="label10"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes"> / </property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="latency_label"> + <property name="can_focus">False</property> + <property name="label" translatable="yes">? frames @ ? kHz (? ms)</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="padding">1</property> + <property name="position">1</property> + </packing> + </child> + </object> + </child> + </object> + </child> + </object> + <packing> + <property name="expand">False</property> + </packing> + </child> + <child> + <object class="GtkToolItem" id="toolitem1"> + <property name="use_action_appearance">False</property> + <property name="visible">True</property> + <property name="can_focus">False</property> + <child> + <object class="GtkAlignment" id="legend_alignment"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xalign">1</property> + <property name="xscale">0</property> + <child> + <placeholder/> + </child> + </object> + </child> + </object> + <packing> + <property name="expand">True</property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + <child> <object class="GtkScrolledWindow" id="main_scrolledwin"> <property name="visible">True</property> <property name="can_focus">True</property> @@ -1084,7 +1217,7 @@ Nedko Arnaudov <nedko@arnaudov.name></property> <packing> <property name="expand">True</property> <property name="fill">True</property> - <property name="position">1</property> + <property name="position">2</property> </packing> </child> </object> @@ -1103,13 +1236,13 @@ Nedko Arnaudov <nedko@arnaudov.name></property> <property name="type_hint">dialog</property> <property name="transient_for">main_win</property> <child internal-child="vbox"> - <object class="GtkBox" id="dialog-vbox3"> + <object class="GtkVBox" id="dialog-vbox3"> <property name="visible">True</property> <property name="can_focus">False</property> <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> <property name="spacing">2</property> <child internal-child="action_area"> - <object class="GtkButtonBox" id="dialog-action_area3"> + <object class="GtkHButtonBox" id="dialog-action_area3"> <property name="visible">True</property> <property name="can_focus">False</property> <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> @@ -1122,7 +1255,6 @@ Nedko Arnaudov <nedko@arnaudov.name></property> <property name="can_focus">True</property> <property name="receives_default">False</property> <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> - <property name="use_action_appearance">False</property> <property name="use_stock">True</property> </object> <packing> @@ -1142,7 +1274,6 @@ Nedko Arnaudov <nedko@arnaudov.name></property> <property name="has_default">True</property> <property name="receives_default">True</property> <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> - <property name="use_action_appearance">False</property> <property name="use_stock">True</property> </object> <packing> |